ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

typetree.c
Go to the documentation of this file.
00001 /*
00002  * IDL Type Tree
00003  *
00004  * Copyright 2008 Robert Shearman
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include "config.h"
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 
00027 #include "widl.h"
00028 #include "utils.h"
00029 #include "parser.h"
00030 #include "typetree.h"
00031 #include "header.h"
00032 
00033 type_t *duptype(type_t *t, int dupname)
00034 {
00035   type_t *d = alloc_type();
00036 
00037   *d = *t;
00038   if (dupname && t->name)
00039     d->name = xstrdup(t->name);
00040 
00041   return d;
00042 }
00043 
00044 type_t *make_type(enum type_type type)
00045 {
00046     type_t *t = alloc_type();
00047     t->name = NULL;
00048     t->type_type = type;
00049     t->attrs = NULL;
00050     t->orig = NULL;
00051     memset(&t->details, 0, sizeof(t->details));
00052     t->typestring_offset = 0;
00053     t->ptrdesc = 0;
00054     t->ignore = (parse_only != 0);
00055     t->defined = FALSE;
00056     t->written = FALSE;
00057     t->user_types_registered = FALSE;
00058     t->tfswrite = FALSE;
00059     t->checked = FALSE;
00060     t->is_alias = FALSE;
00061     t->typelib_idx = -1;
00062     init_loc_info(&t->loc_info);
00063     return t;
00064 }
00065 
00066 static const var_t *find_arg(const var_list_t *args, const char *name)
00067 {
00068     const var_t *arg;
00069 
00070     if (args) LIST_FOR_EACH_ENTRY(arg, args, const var_t, entry)
00071     {
00072         if (arg->name && !strcmp(name, arg->name))
00073             return arg;
00074     }
00075 
00076     return NULL;
00077 }
00078 
00079 type_t *type_new_function(var_list_t *args)
00080 {
00081     var_t *arg;
00082     type_t *t;
00083     unsigned int i = 0;
00084 
00085     if (args)
00086     {
00087         arg = LIST_ENTRY(list_head(args), var_t, entry);
00088         if (list_count(args) == 1 && !arg->name && arg->type && type_get_type(arg->type) == TYPE_VOID)
00089         {
00090             list_remove(&arg->entry);
00091             free(arg);
00092             free(args);
00093             args = NULL;
00094         }
00095     }
00096     if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
00097     {
00098         if (arg->type && type_get_type(arg->type) == TYPE_VOID)
00099             error_loc("argument '%s' has void type\n", arg->name);
00100         if (!arg->name)
00101         {
00102             if (i > 26 * 26)
00103                 error_loc("too many unnamed arguments\n");
00104             else
00105             {
00106                 int unique;
00107                 do
00108                 {
00109                     char name[3];
00110                     name[0] = i > 26 ? 'a' + i / 26 : 'a' + i;
00111                     name[1] = i > 26 ? 'a' + i % 26 : 0;
00112                     name[2] = 0;
00113                     unique = !find_arg(args, name);
00114                     if (unique)
00115                         arg->name = xstrdup(name);
00116                     i++;
00117                 } while (!unique);
00118             }
00119         }
00120     }
00121 
00122     t = make_type(TYPE_FUNCTION);
00123     t->details.function = xmalloc(sizeof(*t->details.function));
00124     t->details.function->args = args;
00125     t->details.function->idx = -1;
00126     return t;
00127 }
00128 
00129 type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
00130 {
00131     type_t *t = make_type(TYPE_POINTER);
00132     t->details.pointer.def_fc = pointer_default;
00133     t->details.pointer.ref = ref;
00134     t->attrs = attrs;
00135     return t;
00136 }
00137 
00138 type_t *type_new_alias(type_t *t, const char *name)
00139 {
00140     type_t *a = duptype(t, 0);
00141 
00142     a->name = xstrdup(name);
00143     a->attrs = NULL;
00144     a->orig = t;
00145     a->is_alias = TRUE;
00146     /* for pointer types */
00147     a->details = t->details;
00148     init_loc_info(&a->loc_info);
00149 
00150     return a;
00151 }
00152 
00153 type_t *type_new_module(char *name)
00154 {
00155     type_t *type = get_type(TYPE_MODULE, name, 0);
00156     if (type->type_type != TYPE_MODULE || type->defined)
00157         error_loc("%s: redefinition error; original definition was at %s:%d\n",
00158                   type->name, type->loc_info.input_name, type->loc_info.line_number);
00159     type->name = name;
00160     return type;
00161 }
00162 
00163 type_t *type_new_coclass(char *name)
00164 {
00165     type_t *type = get_type(TYPE_COCLASS, name, 0);
00166     if (type->type_type != TYPE_COCLASS || type->defined)
00167         error_loc("%s: redefinition error; original definition was at %s:%d\n",
00168                   type->name, type->loc_info.input_name, type->loc_info.line_number);
00169     type->name = name;
00170     return type;
00171 }
00172 
00173 
00174 type_t *type_new_array(const char *name, type_t *element, int declptr,
00175                        unsigned int dim, expr_t *size_is, expr_t *length_is,
00176                        unsigned char ptr_default_fc)
00177 {
00178     type_t *t = make_type(TYPE_ARRAY);
00179     if (name) t->name = xstrdup(name);
00180     t->details.array.declptr = declptr;
00181     t->details.array.length_is = length_is;
00182     if (size_is)
00183         t->details.array.size_is = size_is;
00184     else
00185         t->details.array.dim = dim;
00186     t->details.array.elem = element;
00187     t->details.array.ptr_def_fc = ptr_default_fc;
00188     return t;
00189 }
00190 
00191 type_t *type_new_basic(enum type_basic_type basic_type)
00192 {
00193     type_t *t = make_type(TYPE_BASIC);
00194     t->details.basic.type = basic_type;
00195     t->details.basic.sign = 0;
00196     return t;
00197 }
00198 
00199 type_t *type_new_int(enum type_basic_type basic_type, int sign)
00200 {
00201     static type_t *int_types[TYPE_BASIC_INT_MAX+1][3];
00202 
00203     assert(basic_type <= TYPE_BASIC_INT_MAX);
00204 
00205     /* map sign { -1, 0, 1 } -> { 0, 1, 2 } */
00206     if (!int_types[basic_type][sign + 1])
00207     {
00208         int_types[basic_type][sign + 1] = type_new_basic(basic_type);
00209         int_types[basic_type][sign + 1]->details.basic.sign = sign;
00210     }
00211     return int_types[basic_type][sign + 1];
00212 }
00213 
00214 type_t *type_new_void(void)
00215 {
00216     static type_t *void_type = NULL;
00217     if (!void_type)
00218         void_type = make_type(TYPE_VOID);
00219     return void_type;
00220 }
00221 
00222 type_t *type_new_enum(const char *name, int defined, var_list_t *enums)
00223 {
00224     type_t *tag_type = name ? find_type(name, tsENUM) : NULL;
00225     type_t *t = make_type(TYPE_ENUM);
00226     t->name = name;
00227 
00228     if (tag_type && tag_type->details.enumeration)
00229         t->details.enumeration = tag_type->details.enumeration;
00230     else if (defined)
00231     {
00232         t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
00233         t->details.enumeration->enums = enums;
00234         t->defined = TRUE;
00235     }
00236 
00237     if (name)
00238     {
00239         if (defined)
00240             reg_type(t, name, tsENUM);
00241         else
00242             add_incomplete(t);
00243     }
00244     return t;
00245 }
00246 
00247 type_t *type_new_struct(char *name, int defined, var_list_t *fields)
00248 {
00249     type_t *tag_type = name ? find_type(name, tsSTRUCT) : NULL;
00250     type_t *t = make_type(TYPE_STRUCT);
00251     t->name = name;
00252     if (tag_type && tag_type->details.structure)
00253         t->details.structure = tag_type->details.structure;
00254     else if (defined)
00255     {
00256         t->details.structure = xmalloc(sizeof(*t->details.structure));
00257         t->details.structure->fields = fields;
00258         t->defined = TRUE;
00259     }
00260     if (name)
00261     {
00262         if (defined)
00263             reg_type(t, name, tsSTRUCT);
00264         else
00265             add_incomplete(t);
00266     }
00267     return t;
00268 }
00269 
00270 type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
00271 {
00272     type_t *tag_type = name ? find_type(name, tsUNION) : NULL;
00273     type_t *t = make_type(TYPE_UNION);
00274     t->name = name;
00275     if (tag_type && tag_type->details.structure)
00276         t->details.structure = tag_type->details.structure;
00277     else if (defined)
00278     {
00279         t->details.structure = xmalloc(sizeof(*t->details.structure));
00280         t->details.structure->fields = fields;
00281         t->defined = TRUE;
00282     }
00283     if (name)
00284     {
00285         if (defined)
00286             reg_type(t, name, tsUNION);
00287         else
00288             add_incomplete(t);
00289     }
00290     return t;
00291 }
00292 
00293 type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases)
00294 {
00295     type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, tsUNION);
00296     if (!union_field) union_field = make_var( xstrdup("tagged_union") );
00297     union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases);
00298     t->details.structure = xmalloc(sizeof(*t->details.structure));
00299     t->details.structure->fields = append_var( NULL, switch_field );
00300     t->details.structure->fields = append_var( t->details.structure->fields, union_field );
00301     t->defined = TRUE;
00302     return t;
00303 }
00304 
00305 static int is_valid_bitfield_type(const type_t *type)
00306 {
00307     switch (type_get_type(type))
00308     {
00309     case TYPE_ENUM:
00310         return TRUE;
00311     case TYPE_BASIC:
00312         switch (type_basic_get_type(type))
00313         {
00314         case TYPE_BASIC_INT8:
00315         case TYPE_BASIC_INT16:
00316         case TYPE_BASIC_INT32:
00317         case TYPE_BASIC_INT64:
00318         case TYPE_BASIC_INT:
00319         case TYPE_BASIC_INT3264:
00320         case TYPE_BASIC_CHAR:
00321         case TYPE_BASIC_HYPER:
00322         case TYPE_BASIC_BYTE:
00323         case TYPE_BASIC_WCHAR:
00324         case TYPE_BASIC_ERROR_STATUS_T:
00325             return TRUE;
00326         case TYPE_BASIC_FLOAT:
00327         case TYPE_BASIC_DOUBLE:
00328         case TYPE_BASIC_HANDLE:
00329             return FALSE;
00330         }
00331         return FALSE;
00332     default:
00333         return FALSE;
00334     }
00335 }
00336 
00337 type_t *type_new_bitfield(type_t *field, const expr_t *bits)
00338 {
00339     type_t *t;
00340 
00341     if (!is_valid_bitfield_type(field))
00342         error_loc("bit-field has invalid type\n");
00343 
00344     if (bits->cval < 0)
00345         error_loc("negative width for bit-field\n");
00346 
00347     /* FIXME: validate bits->cval <= memsize(field) * 8 */
00348 
00349     t = make_type(TYPE_BITFIELD);
00350     t->details.bitfield.field = field;
00351     t->details.bitfield.bits = bits;
00352     return t;
00353 }
00354 
00355 static int compute_method_indexes(type_t *iface)
00356 {
00357     int idx;
00358     statement_t *stmt;
00359 
00360     if (!iface->details.iface)
00361         return 0;
00362 
00363     if (type_iface_get_inherit(iface))
00364         idx = compute_method_indexes(type_iface_get_inherit(iface));
00365     else
00366         idx = 0;
00367 
00368     STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
00369     {
00370         var_t *func = stmt->u.var;
00371         if (!is_callas(func->attrs))
00372             func->type->details.function->idx = idx++;
00373     }
00374 
00375     return idx;
00376 }
00377 
00378 void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
00379 {
00380     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
00381     iface->details.iface->disp_props = NULL;
00382     iface->details.iface->disp_methods = NULL;
00383     iface->details.iface->stmts = stmts;
00384     iface->details.iface->inherit = inherit;
00385     iface->defined = TRUE;
00386     compute_method_indexes(iface);
00387 }
00388 
00389 void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
00390 {
00391     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
00392     iface->details.iface->disp_props = props;
00393     iface->details.iface->disp_methods = methods;
00394     iface->details.iface->stmts = NULL;
00395     iface->details.iface->inherit = find_type("IDispatch", 0);
00396     if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n");
00397     iface->defined = TRUE;
00398     compute_method_indexes(iface);
00399 }
00400 
00401 void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
00402 {
00403     type_dispinterface_define(dispiface, iface->details.iface->disp_props,
00404                               iface->details.iface->disp_methods);
00405 }
00406 
00407 void type_module_define(type_t *module, statement_list_t *stmts)
00408 {
00409     if (module->details.module) error_loc("multiple definition error\n");
00410     module->details.module = xmalloc(sizeof(*module->details.module));
00411     module->details.module->stmts = stmts;
00412     module->defined = TRUE;
00413 }
00414 
00415 type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
00416 {
00417     coclass->details.coclass.ifaces = ifaces;
00418     coclass->defined = TRUE;
00419     return coclass;
00420 }
00421 
00422 int type_is_equal(const type_t *type1, const type_t *type2)
00423 {
00424     if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
00425         return FALSE;
00426 
00427     if (type1->name && type2->name)
00428         return !strcmp(type1->name, type2->name);
00429     else if ((!type1->name && type2->name) || (type1->name && !type2->name))
00430         return FALSE;
00431 
00432     /* FIXME: do deep inspection of types to determine if they are equal */
00433 
00434     return FALSE;
00435 }

Generated on Thu May 24 2012 04:38:14 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.