00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "ctrump/ast/types.h"
00037 #include <stdlib.h>
00038
00039 #define DEFINE_BUILTIN_TYPE(str_name,c,sym) \
00040 struct ctrump_texpr ctrump_builtin_##str_name = { \
00041 .code = CTRUMP_TYPE_BUILTIN, \
00042 .u.builtin.code = c, \
00043 .u.builtin.name = sym, \
00044 .pointer_type = NULL, \
00045 .incomplete_array_type = NULL, \
00046 .array_types = NULL, \
00047 .func_types = NULL, \
00048 .qualified_types = NULL, \
00049 };
00050
00051 #include "ctrump/ast/builtin-types.def"
00052 #undef DEFINE_BUILTIN_TYPE
00053
00054 #include <stdio.h>
00055
00059 static struct ctrump_texpr *
00060 alloc_texpr(struct ctrump_type_env *env)
00061 {
00062 struct ctrump_mempool *p = &env->type_allocator;
00063 struct ctrump_texpr *t = ctrump_mempool_alloc(p, sizeof(struct ctrump_texpr));
00064
00065 t->id = env->id;
00066 t->pointer_type = NULL;
00067 t->incomplete_array_type = NULL;
00068 t->array_types = NULL;
00069 t->func_types = NULL;
00070 t->qualified_types = NULL;
00071
00072 env->id++;
00073
00074 return t;
00075 }
00076
00077 struct ctrump_texpr *
00078 ctrump_alloc_texpr(struct ctrump_type_env *env, enum ctrump_texpr_code code)
00079 {
00080 struct ctrump_texpr *t = alloc_texpr(env);
00081 t->code = code;
00082 return t;
00083 }
00084
00085
00086 struct ctrump_texpr *
00087 ctrump_get_typedef_name(struct ctrump_type_env *env,
00088 struct ctrump_texpr *orig_type,
00089 const struct ctrump_symbol *name)
00090 {
00091 struct ctrump_texpr *ret = alloc_texpr(env);
00092
00093 ret->code = CTRUMP_TYPE_TYPEDEF_NAME;
00094 ret->u.typedef_name.defined_to = orig_type;
00095 ret->u.typedef_name.def_name = name;
00096
00097 return ret;
00098 }
00099
00100
00101 struct ctrump_texpr *
00102 ctrump_get_qualified_attr_type(struct ctrump_type_env *env,
00103 struct ctrump_texpr *orig_t,
00104 int qual_flags,
00105 const struct ctrump_gccext_attribute *attr)
00106 {
00107 int attr_aligned;
00108 int attr_flags = 0;
00109 struct ctrump_qualified_type_chain *qc, **chain;
00110 struct ctrump_texpr *t;
00111
00112 if (orig_t->code == CTRUMP_TYPE_QUALIFIED) {
00113
00114 if (attr->aligned != CTRUMP_ALIGN_UNSPECIFIED) {
00115 attr_aligned = attr->aligned;
00116 } else {
00117 attr_aligned = orig_t->u.qualified.attr.aligned;
00118 }
00119 qual_flags = qual_flags | orig_t->u.qualified.qual_flags;
00120 orig_t = orig_t->u.qualified.unqualified_type;
00121 } else {
00122 attr_aligned = attr->aligned;
00123 }
00124
00125 if (attr_aligned == CTRUMP_ALIGN_UNSPECIFIED &&
00126 attr_flags == 0 &&
00127 qual_flags == 0) {
00128
00129 return orig_t;
00130 }
00131
00132
00133 qc = orig_t->qualified_types;
00134 chain = &orig_t->qualified_types;
00135
00136 while (qc) {
00137 if (qc->qual_flags == qual_flags &&
00138 qc->attr.aligned == attr_aligned &&
00139 qc->attr.flags == attr_flags)
00140 break;
00141
00142 chain = &qc->chain;
00143 qc = qc->chain;
00144 }
00145
00146 if (qc == NULL) {
00147
00148 t = alloc_texpr(env);
00149 t->code = CTRUMP_TYPE_QUALIFIED;
00150 t->u.qualified.qual_flags = qual_flags;
00151 t->u.qualified.attr.aligned = attr_aligned;
00152 t->u.qualified.attr.flags = attr_flags;
00153
00154 t->u.qualified.unqualified_type = orig_t;
00155 qc = ctrump_mempool_alloc(&env->type_allocator,
00156 sizeof(*t));
00157 qc->type = t;
00158 qc->attr.aligned = attr_aligned;
00159 qc->attr.flags = attr_flags;
00160 qc->qual_flags = qual_flags;
00161 qc->chain = NULL;
00162
00163 *chain = qc;
00164 } else {
00165 t = qc->type;
00166 }
00167
00168 return t;
00169 }
00170
00171 struct ctrump_texpr *
00172 ctrump_get_qualified_type(struct ctrump_type_env *env,
00173 struct ctrump_texpr *orig_t,
00174 int qual_flags)
00175 {
00176 struct ctrump_gccext_attribute attr;
00177
00178 if (orig_t->code == CTRUMP_TYPE_QUALIFIED) {
00179 attr = orig_t->u.qualified.attr;
00180 } else {
00181 attr.flags = 0;
00182 attr.aligned = CTRUMP_ALIGN_UNSPECIFIED;
00183 }
00184 return ctrump_get_qualified_attr_type(env, orig_t, qual_flags, &attr);
00185 }
00186
00187 struct ctrump_texpr *
00188 ctrump_get_unqualified_type(struct ctrump_texpr *texpr)
00189 {
00190 if (texpr->code == CTRUMP_TYPE_QUALIFIED) {
00191 return texpr->u.qualified.unqualified_type;
00192 } else {
00193 return texpr;
00194 }
00195 }
00196
00197
00198 struct ctrump_texpr *
00199 ctrump_get_pointer_type(struct ctrump_type_env *env,
00200 struct ctrump_texpr *texpr)
00201 {
00202 struct ctrump_texpr *t;
00203 if (texpr->pointer_type)
00204 return texpr->pointer_type;
00205
00206 t = alloc_texpr(env);
00207
00208 t->code = CTRUMP_TYPE_POINTER;
00209
00210 t->u.pointer_to = texpr;
00211 texpr->pointer_type = t;
00212
00213 return t;
00214 }
00215
00216 struct ctrump_texpr *
00217 ctrump_get_incomplete_array_type(struct ctrump_type_env *env,
00218 struct ctrump_texpr *texpr)
00219 {
00220 struct ctrump_texpr *t;
00221 if (texpr->incomplete_array_type)
00222 return texpr->incomplete_array_type;
00223
00224 t = alloc_texpr(env);
00225
00226 t->code = CTRUMP_TYPE_INCOMPLETE_ARRAY;
00227
00228 t->u.incomplete_array_of = texpr;
00229
00230 texpr->incomplete_array_type = t;
00231
00232 return t;
00233 }
00234
00235 struct ctrump_texpr *
00236 ctrump_get_varlen_array_type(struct ctrump_type_env *env,
00237 struct ctrump_texpr *texpr)
00238 {
00239 struct ctrump_texpr *t;
00240 t = alloc_texpr(env);
00241 t->code = CTRUMP_TYPE_VARLEN_ARRAY;
00242 t->u.varlen_array_of = texpr;
00243 return t;
00244 }
00245
00246 struct ctrump_texpr *
00247 ctrump_get_array_type(struct ctrump_type_env *env,
00248 struct ctrump_texpr *texpr,
00249 int size)
00250 {
00251 struct ctrump_array_type_chain *t = texpr->array_types;
00252 struct ctrump_texpr *array_type;
00253 struct ctrump_array_type_chain **chain_ptr = &texpr->array_types;
00254
00255 while (t) {
00256 if (t->size == size)
00257 break;
00258 chain_ptr = &t->chain;
00259 t = t->chain;
00260 }
00261
00262 if (t) {
00263 return t->t;
00264 }
00265
00266 t = ctrump_mempool_alloc(&env->type_allocator, sizeof(*t));
00267
00268 array_type = alloc_texpr(env);
00269 array_type->code = CTRUMP_TYPE_ARRAY;
00270
00271 array_type->u.array.array_of = texpr;
00272 array_type->u.array.size = size;
00273
00274 *chain_ptr = t;
00275 t->t = array_type;
00276 t->size = size;
00277 t->chain = NULL;
00278
00279 return array_type;
00280 }
00281
00282 void
00283 ctrump_get_functype_begin(struct ctrump_get_functype_iterator *iter,
00284 struct ctrump_type_env *env,
00285 struct ctrump_texpr *ret_type,
00286 int num_args)
00287 {
00288 struct ctrump_func_type_node *n;
00289
00290 n = ret_type->func_types;
00291
00292 if (n == NULL) {
00293 n = ctrump_mempool_alloc(&env->type_allocator, sizeof(*n));
00294 n->arg_type = NULL;
00295 n->brother = NULL;
00296 n->child = NULL;
00297 n->func_type = NULL;
00298 ret_type->func_types = n;
00299 }
00300
00301 iter->cur = n;
00302 iter->args = NULL;
00303 if (num_args) {
00304 iter->args = malloc(sizeof(struct ctrump_texpr*) * num_args);
00305 }
00306 iter->ret = ret_type;
00307 iter->cur_arg = 0;
00308 }
00309
00310 void
00311 ctrump_get_functype_next(struct ctrump_type_env *env,
00312 struct ctrump_get_functype_iterator *iter,
00313 struct ctrump_texpr *arg)
00314 {
00315 int cur_arg = iter->cur_arg;
00316 struct ctrump_func_type_node *n, **chain;
00317
00318 chain = &iter->cur->child;
00319 n = *chain;
00320
00321 while (n) {
00322 if (n->arg_type == arg) {
00323 break;
00324 }
00325
00326 chain = &n->brother;
00327 n = *chain;
00328 }
00329
00330 if (n == NULL) {
00331 n = ctrump_mempool_alloc(&env->type_allocator, sizeof(*n));
00332 *chain = n;
00333 n->arg_type = arg;
00334 n->brother = NULL;
00335 n->child = NULL;
00336 n->func_type = NULL;
00337 }
00338
00339 iter->cur = n;
00340 iter->args[cur_arg++] = arg;
00341 iter->cur_arg = cur_arg;
00342 }
00343
00344 struct ctrump_texpr *
00345 ctrump_get_functype_end(struct ctrump_type_env *env,
00346 struct ctrump_get_functype_iterator *iter,
00347 int has_unspec_arg)
00348 {
00349 int arg_num = iter->cur_arg;
00350 struct ctrump_func_type_node *n;
00351 struct ctrump_texpr *fun_type;
00352 int i;
00353
00354 n = iter->cur;
00355 fun_type = n->func_type;
00356
00357 if (fun_type == NULL) {
00358 fun_type = alloc_texpr(env);
00359 fun_type->code = CTRUMP_TYPE_FUNC;
00360 fun_type->u.func.has_unspecified_arg = has_unspec_arg;
00361 fun_type->u.func.arg_num = arg_num;
00362 fun_type->u.func.ret = iter->ret;
00363 fun_type->u.func.args = ctrump_mempool_alloc(&env->type_allocator,
00364 sizeof(struct ctrump_texpr *)*arg_num);
00365
00366 for (i=0; i<arg_num; i++) {
00367 fun_type->u.func.args[i] = iter->args[i];
00368 }
00369
00370 n->func_type = fun_type;
00371 }
00372 if (iter->args)
00373 free(iter->args);
00374
00375 return fun_type;
00376 }
00377
00378 void
00379 ctrump_get_functype_cancel(struct ctrump_get_functype_iterator *iter)
00380 {
00381 if (iter->args)
00382 free(iter->args);
00383 }
00384
00385 struct ctrump_texpr *
00386 ctrump_get_incomplete_struct_type(struct ctrump_type_env *env,
00387 enum ctrump_texpr_code code,
00388 const struct ctrump_symbol *name)
00389 {
00390 struct ctrump_texpr *ret = alloc_texpr(env);
00391 ret->code = code;
00392 ret->u.struct_.is_completed = 0;
00393 ret->u.struct_.name = name;
00394
00395 return ret;
00396 }
00397
00398 void
00399 ctrump_complete_struct_type(struct ctrump_record_type *record_type,
00400 int nfield,
00401 struct ctrump_record_type_field *fields,
00402 struct ctrump_gccext_attribute *attr)
00403 {
00404 record_type->is_completed = 1;
00405 record_type->nfield = nfield;
00406 record_type->fields = fields;
00407 record_type->attr = *attr;
00408 }
00409
00410 struct ctrump_texpr *
00411 ctrump_get_incomplete_enum_type(struct ctrump_type_env *env,
00412 const struct ctrump_symbol *name)
00413 {
00414 struct ctrump_texpr *ret = alloc_texpr(env);
00415 ret->code = CTRUMP_TYPE_ENUM;
00416 ret->u.enum_.name = name;
00417 ret->u.enum_.is_completed = 0;
00418 return ret;
00419 }
00420
00421 void
00422 ctrump_complete_enum_type(struct ctrump_enum_type *enum_type,
00423 int nfield,
00424 struct ctrump_enum_type_field *fields)
00425 {
00426 enum_type->is_completed = 1;
00427 enum_type->nfield = nfield;
00428 enum_type->fields = fields;
00429 }
00430
00431
00432 void
00433 ctrump_type_env_init(struct ctrump_type_env *env,
00434 int is_char_signed)
00435 {
00436 int id = 0;
00437 ctrump_mempool_init(&env->type_allocator, 1024);
00438
00439 if (is_char_signed) {
00440 env->builtin_char_type = &ctrump_builtin_schar_type;
00441 } else {
00442 env->builtin_char_type = &ctrump_builtin_uchar_type;
00443 }
00444
00445 #define DEFINE_BUILTIN_TYPE(str_name, code, sym) \
00446 ctrump_builtin_##str_name.id = id++;
00447 #include "ctrump/ast/builtin-types.def"
00448 #undef DEFINE_BUILTIN_TYPE
00449
00450 env->id = id;
00451 }
00452
00453 void
00454 ctrump_type_env_destroy(struct ctrump_type_env *env)
00455 {
00456 ctrump_mempool_destroy(&env->type_allocator);
00457 }
00458
00459
00460
00461 int
00462 ctrump_texpr_is_pointer(struct ctrump_texpr *texpr)
00463 {
00464 tailcall:
00465 switch (texpr->code) {
00466 case CTRUMP_TYPE_POINTER:
00467 return 1;
00468
00469 case CTRUMP_TYPE_QUALIFIED:
00470 texpr = texpr->u.qualified.unqualified_type;
00471 goto tailcall;
00472
00473 case CTRUMP_TYPE_TYPEDEF_NAME:
00474 texpr = texpr->u.typedef_name.defined_to;
00475 goto tailcall;
00476
00477 default:
00478 return 0;
00479 }
00480 }
00481
00482
00483 struct ctrump_texpr *
00484 ctrump_texpr_apply_unary_pointer_conversion(struct ctrump_type_env *env, struct ctrump_texpr *texpr)
00485 {
00486 tailcall:
00487 switch (texpr->code) {
00488 case CTRUMP_TYPE_POINTER:
00489 return texpr;
00490
00491 case CTRUMP_TYPE_ARRAY:
00492 texpr = texpr->u.array.array_of;
00493 return ctrump_get_pointer_type(env, texpr);
00494
00495 case CTRUMP_TYPE_FUNC:
00496 return ctrump_get_pointer_type(env, texpr);
00497
00498 case CTRUMP_TYPE_QUALIFIED:
00499 texpr = texpr->u.qualified.unqualified_type;
00500 goto tailcall;
00501
00502 case CTRUMP_TYPE_TYPEDEF_NAME:
00503 texpr = texpr->u.typedef_name.defined_to;
00504 goto tailcall;
00505
00506 default:
00507 return 0;
00508 }
00509 }
00510
00511
00512
00513 struct ctrump_texpr *
00514 ctrump_retrieve_pointer_type(struct ctrump_texpr *t)
00515 {
00516 tailcall:
00517 switch (t->code) {
00518 case CTRUMP_TYPE_POINTER:
00519 return t->u.pointer_to;
00520
00521 case CTRUMP_TYPE_QUALIFIED:
00522 t = t->u.qualified.unqualified_type;
00523 goto tailcall;
00524
00525
00526 case CTRUMP_TYPE_TYPEDEF_NAME:
00527 t = t->u.typedef_name.defined_to;
00528 goto tailcall;
00529
00530 default:
00531 return NULL;
00532 }
00533 }
00534
00535 struct ctrump_texpr *
00536 ctrump_retrieve_address_type(struct ctrump_texpr *t)
00537 {
00538 tailcall:
00539 switch (t->code) {
00540 case CTRUMP_TYPE_POINTER:
00541 return t->u.pointer_to;
00542
00543 case CTRUMP_TYPE_ARRAY:
00544 return t->u.array.array_of;
00545
00546 case CTRUMP_TYPE_QUALIFIED:
00547 t = t->u.qualified.unqualified_type;
00548 goto tailcall;
00549
00550
00551 case CTRUMP_TYPE_TYPEDEF_NAME:
00552 t = t->u.typedef_name.defined_to;
00553 goto tailcall;
00554
00555 default:
00556 return NULL;
00557 }
00558 }
00559
00560
00561
00562 struct ctrump_gccext_attribute
00563 ctrump_merge_attr(const struct ctrump_gccext_attribute *decl_attr,
00564 const struct ctrump_gccext_attribute *var_attr)
00565 {
00566 struct ctrump_gccext_attribute ret;
00567 ret.flags = var_attr->flags | decl_attr->flags;
00568
00569
00570 if (decl_attr->aligned == CTRUMP_ALIGN_UNSPECIFIED) {
00571 ret.aligned = var_attr->aligned;
00572 } else {
00573 ret.aligned = decl_attr->aligned;
00574 }
00575
00576 return ret;
00577 }
00578
00579 const int ctrump_builtin_type_is_float_table[] = {
00580 [CTRUMP_BOOL] = 0,
00581 [CTRUMP_CHAR] = 0,
00582 [CTRUMP_SCHAR] = 0,
00583 [CTRUMP_UCHAR] = 0,
00584 [CTRUMP_SSHORT] = 0,
00585 [CTRUMP_USHORT] = 0,
00586 [CTRUMP_SINT] = 0,
00587 [CTRUMP_UINT] = 0,
00588 [CTRUMP_SLONG] = 0,
00589 [CTRUMP_ULONG] = 0,
00590 [CTRUMP_SLONGLONG] = 0,
00591 [CTRUMP_ULONGLONG] = 0,
00592 [CTRUMP_FLOAT] = 1,
00593 [CTRUMP_DOUBLE] = 1,
00594 [CTRUMP_LONG_DOUBLE] = 1,
00595 [CTRUMP_VOID] = 0,
00596
00597
00598 [CTRUMP_VEC_SCHAR] = 0,
00599 [CTRUMP_VEC_UCHAR] = 0,
00600 [CTRUMP_VEC_SSHORT] = 0,
00601 [CTRUMP_VEC_USHORT] = 0,
00602 [CTRUMP_VEC_SINT] = 0,
00603 [CTRUMP_VEC_UINT] = 0,
00604 [CTRUMP_VEC_SLONG] = 0,
00605 [CTRUMP_VEC_ULONG] = 0,
00606 [CTRUMP_VEC_SLONGLONG] = 0,
00607 [CTRUMP_VEC_ULONGLONG] = 0,
00608 [CTRUMP_VEC_FLOAT] = 1,
00609 [CTRUMP_VEC_DOUBLE] = 1,
00610 };
00611 const int ctrump_builtin_type_is_scalar_table[] = {
00612 [CTRUMP_BOOL] = 1,
00613 [CTRUMP_CHAR] = 1,
00614 [CTRUMP_SCHAR] = 1,
00615 [CTRUMP_UCHAR] = 1,
00616 [CTRUMP_SSHORT] = 1,
00617 [CTRUMP_USHORT] = 1,
00618 [CTRUMP_SINT] = 1,
00619 [CTRUMP_UINT] = 1,
00620 [CTRUMP_SLONG] = 1,
00621 [CTRUMP_ULONG] = 1,
00622 [CTRUMP_SLONGLONG] = 1,
00623 [CTRUMP_ULONGLONG] = 1,
00624 [CTRUMP_FLOAT] = 1,
00625 [CTRUMP_DOUBLE] = 1,
00626 [CTRUMP_LONG_DOUBLE] = 1,
00627
00628 [CTRUMP_VOID] = 0,
00629
00630
00631 [CTRUMP_VEC_SCHAR] = 0,
00632 [CTRUMP_VEC_UCHAR] = 0,
00633 [CTRUMP_VEC_SSHORT] = 0,
00634 [CTRUMP_VEC_USHORT] = 0,
00635 [CTRUMP_VEC_SINT] = 0,
00636 [CTRUMP_VEC_UINT] = 0,
00637 [CTRUMP_VEC_SLONG] = 0,
00638 [CTRUMP_VEC_ULONG] = 0,
00639 [CTRUMP_VEC_SLONGLONG] = 0,
00640 [CTRUMP_VEC_ULONGLONG] = 0,
00641 [CTRUMP_VEC_FLOAT] = 0,
00642 [CTRUMP_VEC_DOUBLE] = 0,
00643 };
00644
00645
00646 int
00647 ctrump_type_is_float(const struct ctrump_texpr *texpr)
00648 {
00649 return ((texpr->code == CTRUMP_TYPE_BUILTIN) &&
00650 ctrump_builtin_type_is_float_table[texpr->u.builtin.code]);
00651 }
00652
00653 int
00654 ctrump_type_is_scalar(const struct ctrump_texpr *type)
00655 {
00656 tailcall:
00657 switch (type->code) {
00658 case CTRUMP_TYPE_UNION:
00659 case CTRUMP_TYPE_STRUCT:
00660 case CTRUMP_TYPE_ARRAY:
00661 case CTRUMP_TYPE_INCOMPLETE_ARRAY:
00662 case CTRUMP_TYPE_VARLEN_ARRAY:
00663 case CTRUMP_TYPE_FUNC:
00664 return 0;
00665
00666 case CTRUMP_TYPE_TYPEDEF_NAME:
00667 type = type->u.typedef_name.defined_to;
00668 goto tailcall;
00669
00670 case CTRUMP_TYPE_QUALIFIED:
00671 type = type->u.qualified.unqualified_type;
00672 goto tailcall;
00673
00674
00675 case CTRUMP_TYPE_POINTER:
00676 case CTRUMP_TYPE_ENUM:
00677 return 1;
00678
00679 case CTRUMP_TYPE_BUILTIN:
00680 return ctrump_builtin_type_is_scalar_table[type->u.builtin.code];
00681 }
00682
00683 return 0;
00684 }
00685
00686 struct ctrump_texpr *
00687 ctrump_retrieve_typedef_name(struct ctrump_texpr *type)
00688 {
00689 while (type->code == CTRUMP_TYPE_TYPEDEF_NAME) {
00690 type = type->u.typedef_name.defined_to;
00691 }
00692
00693 return type;
00694 }
00695
00696 int
00697 ctrump_is_scalar_type(const struct ctrump_texpr *type)
00698 {
00699 enum ctrump_texpr_code tcode = type->code;
00700
00701 if (tcode == CTRUMP_TYPE_ARRAY ||
00702 tcode == CTRUMP_TYPE_STRUCT ||
00703 tcode == CTRUMP_TYPE_UNION ||
00704 tcode == CTRUMP_TYPE_INCOMPLETE_ARRAY ||
00705 tcode == CTRUMP_TYPE_VARLEN_ARRAY) {
00706 return 0;
00707 }
00708
00709 return 1;
00710 }