History

tccgen: C2x 'enum <tag> : <type> ...'

accept the new C2x typed enums (seems new android-NDK headers are using that now)

grischka committed 1 year ago

Commit 4b040281 parent 249a0b61 file · +52 −21Browse files

Unified · Split

tccgen.c+52−21
@@ -2791,6 +2791,13 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 2790 unmodified lines
2791{2791{
2792 int bt1, t1, t2;2792 int bt1, t1, t2;
2793 2793
2794 if (IS_ENUM(type1->t)) {
2795 if (IS_ENUM(type2->t))
2796 return type1->ref == type2->ref;
2797 type1 = &type1->ref->type;
2798 } else if (IS_ENUM(type2->t))
2799 type2 = &type2->ref->type;
2800
2794 t1 = type1->t & VT_TYPE;2801 t1 = type1->t & VT_TYPE;
2795 t2 = type2->t & VT_TYPE;2802 t2 = type2->t & VT_TYPE;
2796 if (unqualified) {2803 if (unqualified) {
@@ -2824,10 +2831,6 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 27 unmodified lines
2824 return (type1->ref == type2->ref);2831 return (type1->ref == type2->ref);
2825 } else if (bt1 == VT_FUNC) {2832 } else if (bt1 == VT_FUNC) {
2826 return is_compatible_func(type1, type2);2833 return is_compatible_func(type1, type2);
2827 } else if (IS_ENUM(type1->t) && IS_ENUM(type2->t)) {
2828 /* If both are enums then they must be the same, if only one is then
2829 t1 and t2 must be equal, which was checked above already. */
2830 return type1->ref == type2->ref;
2831 } else {2834 } else {
2832 return 1;2835 return 1;
2833 }2836 }
@@ -3191,6 +3194,9 @@ static void gen_cast(CType *type) · 357 unmodified lines
3191 if (vtop->type.t & VT_BITFIELD)3194 if (vtop->type.t & VT_BITFIELD)
3192 gv(RC_INT);3195 gv(RC_INT);
3193 3196
3197 if (IS_ENUM(type->t) && type->ref->c < 0)
3198 tcc_error("cast to incomplete type");
3199
3194 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);3200 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
3195 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);3201 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
3196 if (sbt == VT_FUNC)3202 if (sbt == VT_FUNC)
@@ -3313,9 +3319,6 @@ error: · 116 unmodified lines
3313 if (ds == 0 || ss == 0)3319 if (ds == 0 || ss == 0)
3314 goto error;3320 goto error;
3315 3321
3316 if (IS_ENUM(type->t) && type->ref->c < 0)
3317 tcc_error("cast to incomplete type");
3318
3319 /* same size and no sign conversion needed */3322 /* same size and no sign conversion needed */
3320 if (ds == ss && ds >= 4)3323 if (ds == ss && ds >= 4)
3321 goto done;3324 goto done;
@@ -4343,7 +4346,7 @@ static void do_Static_assert(void); · 1021 unmodified lines
4343static void struct_decl(CType *type, int u)4346static void struct_decl(CType *type, int u)
4344{4347{
4345 int v, c, size, align, flexible;4348 int v, c, size, align, flexible;
4346 int bit_size, bsize, bt;4349 int bit_size, bsize, bt, ut;
4347 Sym *s, *ss, **ps;4350 Sym *s, *ss, **ps;
4348 AttributeDef ad, ad1;4351 AttributeDef ad, ad1;
4349 CType type1, btype;4352 CType type1, btype;
@@ -4351,28 +4354,43 @@ static void struct_decl(CType *type, int u) · 1 unmodified line
4351 memset(&ad, 0, sizeof ad);4354 memset(&ad, 0, sizeof ad);
4352 next();4355 next();
4353 parse_attribute(&ad);4356 parse_attribute(&ad);
4354 if (tok != '{') {4357
4355 v = tok;4358 v = 0;
4356 next();4359 if (tok >= TOK_IDENT) /* struct/enum tag */
4360 v = tok, next();
4361
4362 bt = ut = 0;
4363 if (u == VT_ENUM) {
4364 ut = VT_INT;
4365 if (tok == ':') { /* C2x enum : <type> ... */
4366 next();
4367 if (!parse_btype(&btype, &ad1, 0)
4368 || !is_integer_btype(btype.t & VT_BTYPE))
4369 expect("enum type");
4370 bt = ut = btype.t & (VT_BTYPE|VT_LONG|VT_UNSIGNED|VT_DEFSIGN);
4371 }
4372 }
4373
4374 if (v) {
4357 /* struct already defined ? return it */4375 /* struct already defined ? return it */
4358 if (v < TOK_IDENT)
4359 expect("struct/union/enum name");
4360 s = struct_find(v);4376 s = struct_find(v);
4361 if (s && (s->sym_scope == local_scope || tok != '{')) {4377 if (s && (s->sym_scope == local_scope || (tok != '{' && tok != ';'))) {
4362 if (u == s->type.t)4378 if (u == s->type.t)
4363 goto do_decl;4379 goto do_decl;
4364 if (u == VT_ENUM && IS_ENUM(s->type.t))4380 if (u == VT_ENUM && IS_ENUM(s->type.t)) /* XXX: check integral types */
4365 goto do_decl;4381 goto do_decl;
4366 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));4382 tcc_error("redeclaration of '%s'", get_tok_str(v, NULL));
4367 }4383 }
4368 } else {4384 } else {
4385 if (tok != '{')
4386 expect("struct/union/enum name");
4369 v = anon_sym++;4387 v = anon_sym++;
4370 }4388 }
4371 /* Record the original enum/struct/union token. */4389 /* Record the original enum/struct/union token. */
4372 type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;4390 type1.t = u | ut;
4373 type1.ref = NULL;4391 type1.ref = NULL;
4374 /* we put an undefined size for struct/union */4392 /* we put an undefined size for struct/union */
4375 s = sym_push(v | SYM_STRUCT, &type1, 0, -1);4393 s = sym_push(v | SYM_STRUCT, &type1, 0, bt ? 0 : -1);
4376 s->r = 0; /* default alignment is zero as gcc */4394 s->r = 0; /* default alignment is zero as gcc */
4377do_decl:4395do_decl:
4378 type->t = s->type.t;4396 type->t = s->type.t;
@@ -4380,7 +4398,8 @@ do_decl: · 1 unmodified line
4380 4398
4381 if (tok == '{') {4399 if (tok == '{') {
4382 next();4400 next();
4383 if (s->c != -1)4401 if (s->c != -1
4402 && !(u == VT_ENUM && s->c == 0)) /* not yet defined typed enum */
4384 tcc_error("struct/union/enum already defined");4403 tcc_error("struct/union/enum already defined");
4385 s->c = -2;4404 s->c = -2;
4386 /* cannot be empty */4405 /* cannot be empty */
@@ -4392,6 +4411,8 @@ do_decl: · 5 unmodified lines
4392 t.ref = s;4411 t.ref = s;
4393 /* enum symbols have static storage */4412 /* enum symbols have static storage */
4394 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;4413 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
4414 if (bt)
4415 t.t = bt|VT_STATIC|VT_ENUM_VAL;
4395 for(;;) {4416 for(;;) {
4396 v = tok;4417 v = tok;
4397 if (v < TOK_UIDENT)4418 if (v < TOK_UIDENT)
@@ -4421,6 +4442,13 @@ do_decl: · 23 unmodified lines
4421 break;4442 break;
4422 }4443 }
4423 skip('}');4444 skip('}');
4445
4446 if (bt) {
4447 t.t = bt;
4448 s->c = 2;
4449 goto enum_done;
4450 }
4451
4424 /* set integral type of the enum */4452 /* set integral type of the enum */
4425 t.t = VT_INT;4453 t.t = VT_INT;
4426 if (nl >= 0) {4454 if (nl >= 0) {
@@ -4429,8 +4457,7 @@ do_decl: · 2 unmodified lines
4429 t.t |= VT_UNSIGNED;4457 t.t |= VT_UNSIGNED;
4430 } else if (pl != (int)pl || nl != (int)nl)4458 } else if (pl != (int)pl || nl != (int)nl)
4431 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);4459 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4432 s->type.t = type->t = t.t | VT_ENUM;4460
4433 s->c = 0;
4434 /* set type for enum members */4461 /* set type for enum members */
4435 for (ss = s->next; ss; ss = ss->next) {4462 for (ss = s->next; ss; ss = ss->next) {
4436 ll = ss->enum_val;4463 ll = ss->enum_val;
@@ -4444,6 +4471,10 @@ do_decl: · 7 unmodified lines
4444 ss->type.t = (ss->type.t & ~VT_BTYPE)4471 ss->type.t = (ss->type.t & ~VT_BTYPE)
4445 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);4472 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4446 }4473 }
4474 s->c = 1;
4475 enum_done:
4476 s->type.t = type->t = t.t | VT_ENUM;
4477
4447 } else {4478 } else {
4448 c = 0;4479 c = 0;
4449 flexible = 0;4480 flexible = 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t