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
27912791 {
27922792 int bt1, t1, t2;
27932793
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+
27942801 t1 = type1->t & VT_TYPE;
27952802 t2 = type2->t & VT_TYPE;
27962803 if (unqualified) {
@@ -2824,10 +2831,6 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 27 unmodified lines
28242831 return (type1->ref == type2->ref);
28252832 } else if (bt1 == VT_FUNC) {
28262833 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;
28312834 } else {
28322835 return 1;
28332836 }
@@ -3191,6 +3194,9 @@ static void gen_cast(CType *type) · 357 unmodified lines
31913194 if (vtop->type.t & VT_BITFIELD)
31923195 gv(RC_INT);
31933196
3197+ if (IS_ENUM(type->t) && type->ref->c < 0)
3198+ tcc_error("cast to incomplete type");
3199+
31943200 dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
31953201 sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
31963202 if (sbt == VT_FUNC)
@@ -3313,9 +3319,6 @@ error: · 116 unmodified lines
33133319 if (ds == 0 || ss == 0)
33143320 goto error;
33153321
3316− if (IS_ENUM(type->t) && type->ref->c < 0)
3317− tcc_error("cast to incomplete type");
3318−
33193322 /* same size and no sign conversion needed */
33203323 if (ds == ss && ds >= 4)
33213324 goto done;
@@ -4343,7 +4346,7 @@ static void do_Static_assert(void); · 1021 unmodified lines
43434346 static void struct_decl(CType *type, int u)
43444347 {
43454348 int v, c, size, align, flexible;
4346− int bit_size, bsize, bt;
4349+ int bit_size, bsize, bt, ut;
43474350 Sym *s, *ss, **ps;
43484351 AttributeDef ad, ad1;
43494352 CType type1, btype;
@@ -4351,28 +4354,43 @@ static void struct_decl(CType *type, int u) · 1 unmodified line
43514354 memset(&ad, 0, sizeof ad);
43524355 next();
43534356 parse_attribute(&ad);
4354− if (tok != '{') {
4355− v = tok;
4356− next();
4357+
4358+ v = 0;
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) {
43574375 /* struct already defined ? return it */
4358− if (v < TOK_IDENT)
4359− expect("struct/union/enum name");
43604376 s = struct_find(v);
4361− if (s && (s->sym_scope == local_scope || tok != '{')) {
4377+ if (s && (s->sym_scope == local_scope || (tok != '{' && tok != ';'))) {
43624378 if (u == s->type.t)
43634379 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 */
43654381 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));
43674383 }
43684384 } else {
4385+ if (tok != '{')
4386+ expect("struct/union/enum name");
43694387 v = anon_sym++;
43704388 }
43714389 /* Record the original enum/struct/union token. */
4372− type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
4390+ type1.t = u | ut;
43734391 type1.ref = NULL;
43744392 /* 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);
43764394 s->r = 0; /* default alignment is zero as gcc */
43774395 do_decl:
43784396 type->t = s->type.t;
@@ -4380,7 +4398,8 @@ do_decl: · 1 unmodified line
43804398
43814399 if (tok == '{') {
43824400 next();
4383− if (s->c != -1)
4401+ if (s->c != -1
4402+ && !(u == VT_ENUM && s->c == 0)) /* not yet defined typed enum */
43844403 tcc_error("struct/union/enum already defined");
43854404 s->c = -2;
43864405 /* cannot be empty */
@@ -4392,6 +4411,8 @@ do_decl: · 5 unmodified lines
43924411 t.ref = s;
43934412 /* enum symbols have static storage */
43944413 t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
4414+ if (bt)
4415+ t.t = bt|VT_STATIC|VT_ENUM_VAL;
43954416 for(;;) {
43964417 v = tok;
43974418 if (v < TOK_UIDENT)
@@ -4421,6 +4442,13 @@ do_decl: · 23 unmodified lines
44214442 break;
44224443 }
44234444 skip('}');
4445+
4446+ if (bt) {
4447+ t.t = bt;
4448+ s->c = 2;
4449+ goto enum_done;
4450+ }
4451+
44244452 /* set integral type of the enum */
44254453 t.t = VT_INT;
44264454 if (nl >= 0) {
@@ -4429,8 +4457,7 @@ do_decl: · 2 unmodified lines
44294457 t.t |= VT_UNSIGNED;
44304458 } else if (pl != (int)pl || nl != (int)nl)
44314459 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
4432− s->type.t = type->t = t.t | VT_ENUM;
4433− s->c = 0;
4460+
44344461 /* set type for enum members */
44354462 for (ss = s->next; ss; ss = ss->next) {
44364463 ll = ss->enum_val;
@@ -4444,6 +4471,10 @@ do_decl: · 7 unmodified lines
44444471 ss->type.t = (ss->type.t & ~VT_BTYPE)
44454472 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
44464473 }
4474+ s->c = 1;
4475+ enum_done:
4476+ s->type.t = type->t = t.t | VT_ENUM;
4477+
44474478 } else {
44484479 c = 0;
44494480 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