1 /* 2 * IDL Type Tree 3 * 4 * Copyright 2008 Robert Shearman 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "config.h" 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 #include "widl.h" 28 #include "utils.h" 29 #include "parser.h" 30 #include "typetree.h" 31 #include "header.h" 32 33 type_t *duptype(type_t *t, int dupname) 34 { 35 type_t *d = alloc_type(); 36 37 *d = *t; 38 if (dupname && t->name) 39 d->name = xstrdup(t->name); 40 41 return d; 42 } 43 44 type_t *make_type(enum type_type type) 45 { 46 type_t *t = alloc_type(); 47 t->name = NULL; 48 t->namespace = NULL; 49 t->type_type = type; 50 t->attrs = NULL; 51 t->c_name = NULL; 52 t->orig = NULL; 53 memset(&t->details, 0, sizeof(t->details)); 54 t->typestring_offset = 0; 55 t->ptrdesc = 0; 56 t->ignore = (parse_only != 0); 57 t->defined = FALSE; 58 t->written = FALSE; 59 t->user_types_registered = FALSE; 60 t->tfswrite = FALSE; 61 t->checked = FALSE; 62 t->is_alias = FALSE; 63 t->typelib_idx = -1; 64 init_loc_info(&t->loc_info); 65 return t; 66 } 67 68 static const var_t *find_arg(const var_list_t *args, const char *name) 69 { 70 const var_t *arg; 71 72 if (args) LIST_FOR_EACH_ENTRY(arg, args, const var_t, entry) 73 { 74 if (arg->name && !strcmp(name, arg->name)) 75 return arg; 76 } 77 78 return NULL; 79 } 80 81 const char *type_get_name(const type_t *type, enum name_type name_type) 82 { 83 switch(name_type) { 84 case NAME_DEFAULT: 85 return type->name; 86 case NAME_C: 87 return type->c_name; 88 } 89 90 assert(0); 91 return NULL; 92 } 93 94 static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator) 95 { 96 if(is_global_namespace(namespace)) { 97 if(!use_abi_namespace) 98 return ptr; 99 strcpy(ptr, "ABI"); 100 strcat(ptr, separator); 101 return ptr + strlen(ptr); 102 } 103 104 ptr = append_namespace(ptr, namespace->parent, separator); 105 strcpy(ptr, namespace->name); 106 strcat(ptr, separator); 107 return ptr + strlen(ptr); 108 } 109 110 char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix) 111 { 112 unsigned len = strlen(prefix) + strlen(suffix); 113 unsigned sep_len = strlen(separator); 114 struct namespace *iter; 115 char *ret, *ptr; 116 117 if(use_abi_namespace && !is_global_namespace(namespace)) 118 len += 3 /* strlen("ABI") */ + sep_len; 119 120 for(iter = namespace; !is_global_namespace(iter); iter = iter->parent) 121 len += strlen(iter->name) + sep_len; 122 123 ret = xmalloc(len+1); 124 strcpy(ret, prefix); 125 ptr = append_namespace(ret + strlen(ret), namespace, separator); 126 strcpy(ptr, suffix); 127 128 return ret; 129 } 130 131 type_t *type_new_function(var_list_t *args) 132 { 133 var_t *arg; 134 type_t *t; 135 unsigned int i = 0; 136 137 if (args) 138 { 139 arg = LIST_ENTRY(list_head(args), var_t, entry); 140 if (list_count(args) == 1 && !arg->name && arg->type && type_get_type(arg->type) == TYPE_VOID) 141 { 142 list_remove(&arg->entry); 143 free(arg); 144 free(args); 145 args = NULL; 146 } 147 } 148 if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry) 149 { 150 if (arg->type && type_get_type(arg->type) == TYPE_VOID) 151 error_loc("argument '%s' has void type\n", arg->name); 152 if (!arg->name) 153 { 154 if (i > 26 * 26) 155 error_loc("too many unnamed arguments\n"); 156 else 157 { 158 int unique; 159 do 160 { 161 char name[3]; 162 name[0] = i > 26 ? 'a' + i / 26 : 'a' + i; 163 name[1] = i > 26 ? 'a' + i % 26 : 0; 164 name[2] = 0; 165 unique = !find_arg(args, name); 166 if (unique) 167 arg->name = xstrdup(name); 168 i++; 169 } while (!unique); 170 } 171 } 172 } 173 174 t = make_type(TYPE_FUNCTION); 175 t->details.function = xmalloc(sizeof(*t->details.function)); 176 t->details.function->args = args; 177 t->details.function->idx = -1; 178 return t; 179 } 180 181 type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs) 182 { 183 type_t *t = make_type(TYPE_POINTER); 184 t->details.pointer.def_fc = pointer_default; 185 t->details.pointer.ref = ref; 186 t->attrs = attrs; 187 return t; 188 } 189 190 type_t *type_new_alias(type_t *t, const char *name) 191 { 192 type_t *a = duptype(t, 0); 193 194 a->name = xstrdup(name); 195 a->attrs = NULL; 196 a->orig = t; 197 a->is_alias = TRUE; 198 /* for pointer types */ 199 a->details = t->details; 200 init_loc_info(&a->loc_info); 201 202 return a; 203 } 204 205 type_t *type_new_module(char *name) 206 { 207 type_t *type = get_type(TYPE_MODULE, name, NULL, 0); 208 if (type->type_type != TYPE_MODULE || type->defined) 209 error_loc("%s: redefinition error; original definition was at %s:%d\n", 210 type->name, type->loc_info.input_name, type->loc_info.line_number); 211 type->name = name; 212 return type; 213 } 214 215 type_t *type_new_coclass(char *name) 216 { 217 type_t *type = get_type(TYPE_COCLASS, name, NULL, 0); 218 if (type->type_type != TYPE_COCLASS || type->defined) 219 error_loc("%s: redefinition error; original definition was at %s:%d\n", 220 type->name, type->loc_info.input_name, type->loc_info.line_number); 221 type->name = name; 222 return type; 223 } 224 225 226 type_t *type_new_array(const char *name, type_t *element, int declptr, 227 unsigned int dim, expr_t *size_is, expr_t *length_is, 228 unsigned char ptr_default_fc) 229 { 230 type_t *t = make_type(TYPE_ARRAY); 231 if (name) t->name = xstrdup(name); 232 t->details.array.declptr = declptr; 233 t->details.array.length_is = length_is; 234 if (size_is) 235 t->details.array.size_is = size_is; 236 else 237 t->details.array.dim = dim; 238 t->details.array.elem = element; 239 t->details.array.ptr_def_fc = ptr_default_fc; 240 return t; 241 } 242 243 type_t *type_new_basic(enum type_basic_type basic_type) 244 { 245 type_t *t = make_type(TYPE_BASIC); 246 t->details.basic.type = basic_type; 247 t->details.basic.sign = 0; 248 return t; 249 } 250 251 type_t *type_new_int(enum type_basic_type basic_type, int sign) 252 { 253 static type_t *int_types[TYPE_BASIC_INT_MAX+1][3]; 254 255 assert(basic_type <= TYPE_BASIC_INT_MAX); 256 257 /* map sign { -1, 0, 1 } -> { 0, 1, 2 } */ 258 if (!int_types[basic_type][sign + 1]) 259 { 260 int_types[basic_type][sign + 1] = type_new_basic(basic_type); 261 int_types[basic_type][sign + 1]->details.basic.sign = sign; 262 } 263 return int_types[basic_type][sign + 1]; 264 } 265 266 type_t *type_new_void(void) 267 { 268 static type_t *void_type = NULL; 269 if (!void_type) 270 void_type = make_type(TYPE_VOID); 271 return void_type; 272 } 273 274 type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums) 275 { 276 type_t *tag_type = name ? find_type(name, namespace, tsENUM) : NULL; 277 type_t *t = make_type(TYPE_ENUM); 278 t->name = name; 279 t->namespace = namespace; 280 281 if (tag_type && tag_type->details.enumeration) 282 t->details.enumeration = tag_type->details.enumeration; 283 else if (defined) 284 { 285 t->details.enumeration = xmalloc(sizeof(*t->details.enumeration)); 286 t->details.enumeration->enums = enums; 287 t->defined = TRUE; 288 } 289 290 if (name) 291 { 292 if (defined) 293 reg_type(t, name, namespace, tsENUM); 294 else 295 add_incomplete(t); 296 } 297 return t; 298 } 299 300 type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields) 301 { 302 type_t *tag_type = name ? find_type(name, namespace, tsSTRUCT) : NULL; 303 type_t *t; 304 305 /* avoid creating duplicate typelib type entries */ 306 if (tag_type && do_typelib) return tag_type; 307 308 t = make_type(TYPE_STRUCT); 309 t->name = name; 310 t->namespace = namespace; 311 312 if (tag_type && tag_type->details.structure) 313 t->details.structure = tag_type->details.structure; 314 else if (defined) 315 { 316 t->details.structure = xmalloc(sizeof(*t->details.structure)); 317 t->details.structure->fields = fields; 318 t->defined = TRUE; 319 } 320 if (name) 321 { 322 if (defined) 323 reg_type(t, name, namespace, tsSTRUCT); 324 else 325 add_incomplete(t); 326 } 327 return t; 328 } 329 330 type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields) 331 { 332 type_t *tag_type = name ? find_type(name, NULL, tsUNION) : NULL; 333 type_t *t = make_type(TYPE_UNION); 334 t->name = name; 335 if (tag_type && tag_type->details.structure) 336 t->details.structure = tag_type->details.structure; 337 else if (defined) 338 { 339 t->details.structure = xmalloc(sizeof(*t->details.structure)); 340 t->details.structure->fields = fields; 341 t->defined = TRUE; 342 } 343 if (name) 344 { 345 if (defined) 346 reg_type(t, name, NULL, tsUNION); 347 else 348 add_incomplete(t); 349 } 350 return t; 351 } 352 353 type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases) 354 { 355 type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, NULL, tsUNION); 356 if (!union_field) union_field = make_var( xstrdup("tagged_union") ); 357 union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases); 358 t->details.structure = xmalloc(sizeof(*t->details.structure)); 359 t->details.structure->fields = append_var( NULL, switch_field ); 360 t->details.structure->fields = append_var( t->details.structure->fields, union_field ); 361 t->defined = TRUE; 362 return t; 363 } 364 365 static int is_valid_bitfield_type(const type_t *type) 366 { 367 switch (type_get_type(type)) 368 { 369 case TYPE_ENUM: 370 return TRUE; 371 case TYPE_BASIC: 372 switch (type_basic_get_type(type)) 373 { 374 case TYPE_BASIC_INT8: 375 case TYPE_BASIC_INT16: 376 case TYPE_BASIC_INT32: 377 case TYPE_BASIC_INT64: 378 case TYPE_BASIC_INT: 379 case TYPE_BASIC_INT3264: 380 case TYPE_BASIC_LONG: 381 case TYPE_BASIC_CHAR: 382 case TYPE_BASIC_HYPER: 383 case TYPE_BASIC_BYTE: 384 case TYPE_BASIC_WCHAR: 385 case TYPE_BASIC_ERROR_STATUS_T: 386 return TRUE; 387 case TYPE_BASIC_FLOAT: 388 case TYPE_BASIC_DOUBLE: 389 case TYPE_BASIC_HANDLE: 390 return FALSE; 391 } 392 return FALSE; 393 default: 394 return FALSE; 395 } 396 } 397 398 type_t *type_new_bitfield(type_t *field, const expr_t *bits) 399 { 400 type_t *t; 401 402 if (!is_valid_bitfield_type(field)) 403 error_loc("bit-field has invalid type\n"); 404 405 if (bits->cval < 0) 406 error_loc("negative width for bit-field\n"); 407 408 /* FIXME: validate bits->cval <= memsize(field) * 8 */ 409 410 t = make_type(TYPE_BITFIELD); 411 t->details.bitfield.field = field; 412 t->details.bitfield.bits = bits; 413 return t; 414 } 415 416 static int compute_method_indexes(type_t *iface) 417 { 418 int idx; 419 statement_t *stmt; 420 421 if (!iface->details.iface) 422 return 0; 423 424 if (type_iface_get_inherit(iface)) 425 idx = compute_method_indexes(type_iface_get_inherit(iface)); 426 else 427 idx = 0; 428 429 STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) 430 { 431 var_t *func = stmt->u.var; 432 if (!is_callas(func->attrs)) 433 func->type->details.function->idx = idx++; 434 } 435 436 return idx; 437 } 438 439 void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts) 440 { 441 iface->details.iface = xmalloc(sizeof(*iface->details.iface)); 442 iface->details.iface->disp_props = NULL; 443 iface->details.iface->disp_methods = NULL; 444 iface->details.iface->stmts = stmts; 445 iface->details.iface->inherit = inherit; 446 iface->details.iface->disp_inherit = NULL; 447 iface->details.iface->async_iface = NULL; 448 iface->defined = TRUE; 449 compute_method_indexes(iface); 450 } 451 452 void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods) 453 { 454 iface->details.iface = xmalloc(sizeof(*iface->details.iface)); 455 iface->details.iface->disp_props = props; 456 iface->details.iface->disp_methods = methods; 457 iface->details.iface->stmts = NULL; 458 iface->details.iface->inherit = find_type("IDispatch", NULL, 0); 459 if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n"); 460 iface->details.iface->disp_inherit = NULL; 461 iface->details.iface->async_iface = NULL; 462 iface->defined = TRUE; 463 compute_method_indexes(iface); 464 } 465 466 void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface) 467 { 468 dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface)); 469 dispiface->details.iface->disp_props = NULL; 470 dispiface->details.iface->disp_methods = NULL; 471 dispiface->details.iface->stmts = NULL; 472 dispiface->details.iface->inherit = find_type("IDispatch", NULL, 0); 473 if (!dispiface->details.iface->inherit) error_loc("IDispatch is undefined\n"); 474 dispiface->details.iface->disp_inherit = iface; 475 dispiface->details.iface->async_iface = NULL; 476 dispiface->defined = TRUE; 477 compute_method_indexes(dispiface); 478 } 479 480 void type_module_define(type_t *module, statement_list_t *stmts) 481 { 482 if (module->details.module) error_loc("multiple definition error\n"); 483 module->details.module = xmalloc(sizeof(*module->details.module)); 484 module->details.module->stmts = stmts; 485 module->defined = TRUE; 486 } 487 488 type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces) 489 { 490 coclass->details.coclass.ifaces = ifaces; 491 coclass->defined = TRUE; 492 return coclass; 493 } 494 495 int type_is_equal(const type_t *type1, const type_t *type2) 496 { 497 if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2)) 498 return FALSE; 499 500 if (type1->name && type2->name) 501 return !strcmp(type1->name, type2->name); 502 else if ((!type1->name && type2->name) || (type1->name && !type2->name)) 503 return FALSE; 504 505 /* FIXME: do deep inspection of types to determine if they are equal */ 506 507 return FALSE; 508 } 509