| @@ -341,8 +341,8 @@ ST_FUNC void check_vstack(void) · 340 unmodified lines |
| 341 | (int)(vtop - vstack + 1)); | 341 | (int)(vtop - vstack + 1)); |
| 342 | } | 342 | } |
| 343 | | 343 | |
| 344 | /* vstack debugging aid */ | | |
| 345 | #if 0 | 344 | #if 0 |
| | 345 | /* dump 'b' vstack entries starting with 'a' */ |
| 346 | void pv (const char *lbl, int a, int b) | 346 | void pv (const char *lbl, int a, int b) |
| 347 | { | 347 | { |
| 348 | int i; | 348 | int i; |
| @@ -352,6 +352,27 @@ void pv (const char *lbl, int a, int b) · 3 unmodified lines |
| 352 | lbl, i, p->type.t, p->r, p->r2, (int)p->c.i); | 352 | lbl, i, p->type.t, p->r, p->r2, (int)p->c.i); |
| 353 | } | 353 | } |
| 354 | } | 354 | } |
| | 355 | |
| | 356 | /* dump symbols on stack from s ... last */ |
| | 357 | static inline void psyms(const char *msg, Sym *s, Sym *last) |
| | 358 | { |
| | 359 | printf("%-8s scope v c r type.t\n", msg); |
| | 360 | while (s && s != last) { |
| | 361 | printf(" %8x %08x %08x %08x %08x %s\n", |
| | 362 | s->sym_scope, s->v, s->c, s->r, s->type.t, get_tok_str(s->v, 0)); |
| | 363 | s = s->prev; |
| | 364 | } |
| | 365 | } |
| | 366 | |
| | 367 | static void type_to_str(char *buf, int buf_size, CType *type, const char *varstr); |
| | 368 | |
| | 369 | /* print type */ |
| | 370 | static void ptype(CType *type, int v) |
| | 371 | { |
| | 372 | char buf[500]; |
| | 373 | type_to_str(buf, sizeof(buf), type, get_tok_str(v, NULL)); |
| | 374 | printf("type = '%s'\n", buf); |
| | 375 | } |
| 355 | #endif | 376 | #endif |
| 356 | | 377 | |
| 357 | /* ------------------------------------------------------------------------- */ | 378 | /* ------------------------------------------------------------------------- */ |
| @@ -506,7 +527,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, · 148 unmodified lines |
| 506 | sym_type = STT_FUNC; | 527 | sym_type = STT_FUNC; |
| 507 | } else if ((t & VT_BTYPE) == VT_VOID) { | 528 | } else if ((t & VT_BTYPE) == VT_VOID) { |
| 508 | sym_type = STT_NOTYPE; | 529 | sym_type = STT_NOTYPE; |
| 509 | if ((t & (VT_BTYPE|VT_ASM_FUNC)) == VT_ASM_FUNC) | 530 | if (IS_ASM_FUNC(t)) |
| 510 | sym_type = STT_FUNC; | 531 | sym_type = STT_FUNC; |
| 511 | } else { | 532 | } else { |
| 512 | sym_type = STT_OBJECT; | 533 | sym_type = STT_OBJECT; |
| @@ -575,8 +596,18 @@ ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, · 62 unmodified lines |
| 575 | return; | 596 | return; |
| 576 | | 597 | |
| 577 | if (sym) { | 598 | if (sym) { |
| 578 | if (0 == sym->c) | 599 | if (0 == sym->c) { |
| 579 | put_extern_sym(sym, NULL, 0, 0); | 600 | put_extern_sym(sym, NULL, 0, 0); |
| | 601 | if (sym->sym_scope |
| | 602 | && (sym->type.t & (VT_STATIC|VT_EXTERN)) == (VT_STATIC|VT_EXTERN)) { |
| | 603 | /* when a local function declaraion redeclares a global static one |
| | 604 | then tccelf would not resolve them to the same symbol. */ |
| | 605 | Sym *s = sym; |
| | 606 | while (s->prev_tok) |
| | 607 | s = s->prev_tok; |
| | 608 | s->c = sym->c; |
| | 609 | } |
| | 610 | } |
| 580 | c = sym->c; | 611 | c = sym->c; |
| 581 | } | 612 | } |
| 582 | | 613 | |
| @@ -683,6 +714,13 @@ ST_INLN Sym *sym_find(int v) · 100 unmodified lines |
| 683 | return table_ident[v]->sym_identifier; | 714 | return table_ident[v]->sym_identifier; |
| 684 | } | 715 | } |
| 685 | | 716 | |
| | 717 | static int sym_scope_e(Sym *s) |
| | 718 | { |
| | 719 | return IS_ENUM_VAL (s->type.t) |
| | 720 | ? s->type.ref->sym_scope |
| | 721 | : s->sym_scope; |
| | 722 | } |
| | 723 | |
| 686 | /* make sym in-/visible to the parser */ | 724 | /* make sym in-/visible to the parser */ |
| 687 | static inline void sym_link(Sym *s, int yes) | 725 | static inline void sym_link(Sym *s, int yes) |
| 688 | { | 726 | { |
| @@ -692,10 +730,14 @@ static inline void sym_link(Sym *s, int yes) · 3 unmodified lines |
| 692 | ps = &ts->sym_struct; | 730 | ps = &ts->sym_struct; |
| 693 | else | 731 | else |
| 694 | ps = &ts->sym_identifier; | 732 | ps = &ts->sym_identifier; |
| 695 | if (yes) | 733 | if (yes) { |
| | 734 | if (*ps && sym_scope_e(*ps) == local_scope) |
| | 735 | tcc_error("redeclaration of '%s'", get_tok_str(s->v, NULL)); |
| 696 | s->prev_tok = *ps, *ps = s; | 736 | s->prev_tok = *ps, *ps = s; |
| 697 | else | 737 | s->sym_scope = local_scope; |
| | 738 | } else { |
| 698 | *ps = s->prev_tok; | 739 | *ps = s->prev_tok; |
| | 740 | } |
| 699 | } | 741 | } |
| 700 | | 742 | |
| 701 | /* push a given symbol on the symbol stack */ | 743 | /* push a given symbol on the symbol stack */ |
| @@ -710,18 +752,9 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 8 unmodified lines |
| 710 | s->type.ref = type->ref; | 752 | s->type.ref = type->ref; |
| 711 | s->r = r; | 753 | s->r = r; |
| 712 | /* don't record fields or anonymous symbols */ | 754 | /* don't record fields or anonymous symbols */ |
| 713 | /* XXX: simplify */ | | |
| 714 | if ((v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { | 755 | if ((v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { |
| 715 | /* record symbol in token array */ | 756 | /* record symbol in token array */ |
| 716 | sym_link(s, 1); | 757 | sym_link(s, 1); |
| 717 | s->sym_scope = local_scope; | | |
| 718 | if (s->prev_tok | | |
| 719 | && (IS_ENUM_VAL (s->prev_tok->type.t) | | |
| 720 | ? s->prev_tok->type.ref->sym_scope | | |
| 721 | : s->prev_tok->sym_scope) | | |
| 722 | == s->sym_scope) | | |
| 723 | tcc_error("redeclaration of '%s'", | | |
| 724 | get_tok_str(v & ~SYM_STRUCT, NULL)); | | |
| 725 | } | 758 | } |
| 726 | return s; | 759 | return s; |
| 727 | } | 760 | } |
| @@ -824,19 +857,6 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep) · 96 unmodified lines |
| 824 | *ptop = slast; | 857 | *ptop = slast; |
| 825 | } | 858 | } |
| 826 | | 859 | |
| 827 | #if 0 | | |
| 828 | /* debug: print symbols on stack from s ... last */ | | |
| 829 | static inline void psyms(const char *msg, Sym *s, Sym *last) | | |
| 830 | { | | |
| 831 | printf("%-8s scope v c r type.t\n", msg); | | |
| 832 | while (s && s != last) { | | |
| 833 | printf(" %8x %08x %08x %08x %08x %s\n", | | |
| 834 | s->sym_scope, s->v, s->c, s->r, s->type.t, get_tok_str(s->v, 0)); | | |
| 835 | s = s->prev; | | |
| 836 | } | | |
| 837 | } | | |
| 838 | #endif | | |
| 839 | | | |
| 840 | /* ------------------------------------------------------------------------- */ | 860 | /* ------------------------------------------------------------------------- */ |
| 841 | static void vcheck_cmp(void) | 861 | static void vcheck_cmp(void) |
| 842 | { | 862 | { |
| @@ -1294,27 +1314,47 @@ static Sym *sym_copy(Sym *s0, Sym **ps) · 451 unmodified lines |
| 1294 | Sym *s; | 1314 | Sym *s; |
| 1295 | s = sym_malloc(), *s = *s0; | 1315 | s = sym_malloc(), *s = *s0; |
| 1296 | s->prev = *ps, *ps = s; | 1316 | s->prev = *ps, *ps = s; |
| 1297 | if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM && ps == &local_stack) | 1317 | if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) |
| 1298 | sym_link(s, 1); | 1318 | sym_link(s, 1); |
| 1299 | return s; | 1319 | return s; |
| 1300 | } | 1320 | } |
| 1301 | | 1321 | |
| 1302 | /* Symbol 's' was locally declared 'extern' (or as function), and | 1322 | /* Symbol 's' was locally declared 'extern' (or as function), and is |
| 1303 | is on global_stack. Now must copy its 'ref' to global_stack too */ | 1323 | on global_stack. Now must copy its 'ref' to global_stack too */ |
| 1304 | static void sym_copy_ref(Sym *s, Sym **ps) | 1324 | static void move_ref_to_global(Sym *s) |
| 1305 | { | 1325 | { |
| 1306 | int bt = s->type.t & VT_BTYPE; | 1326 | Sym *l, **lp; |
| 1307 | if (bt == VT_PTR | 1327 | int n, bt; |
| 1308 | || bt == VT_FUNC | 1328 | |
| 1309 | || ((bt == VT_STRUCT || IS_ENUM(s->type.t)) | 1329 | bt = s->type.t & VT_BTYPE; |
| 1310 | && s->type.ref | 1330 | if (!(bt == VT_PTR |
| 1311 | && s->type.ref->sym_scope)) { | 1331 | || bt == VT_FUNC |
| 1312 | Sym **sp = &s->type.ref; | 1332 | || bt == VT_STRUCT |
| 1313 | for (s = *sp, *sp = NULL; s; s = s->next) { | 1333 | || (IS_ENUM(s->type.t)) && (bt = VT_ENUM,1))) |
| 1314 | Sym *s2 = sym_copy(s, ps); | 1334 | return; |
| 1315 | sp = &(*sp = s2)->next; | 1335 | |
| 1316 | sym_copy_ref(s2, ps); | 1336 | for (s = s->type.ref, n = 0; s; s = s->next) { |
| | 1337 | for (lp = &local_stack; !!(l = *lp); lp = &l->prev) { |
| | 1338 | if (l == s) { |
| | 1339 | *lp = s->prev; |
| | 1340 | s->prev = global_stack, global_stack = s; |
| | 1341 | if (n || bt == VT_PTR) { |
| | 1342 | move_ref_to_global(s); |
| | 1343 | } else { |
| | 1344 | if ((bt == VT_STRUCT || bt == VT_ENUM) |
| | 1345 | && (s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { |
| | 1346 | /* copy struct/enum tag to local scope */ |
| | 1347 | s->v |= SYM_FIELD; |
| | 1348 | l = sym_copy(s, lp); |
| | 1349 | l->v &= ~SYM_FIELD; |
| | 1350 | } |
| | 1351 | n = 1; |
| | 1352 | } |
| | 1353 | break; |
| | 1354 | } |
| 1317 | } | 1355 | } |
| | 1356 | if (n == 0) /* no next (VT_PTR) or ref not on local_stack */ |
| | 1357 | break; |
| 1318 | } | 1358 | } |
| 1319 | } | 1359 | } |
| 1320 | | 1360 | |
| @@ -1335,15 +1375,15 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad) · 14 unmodified lines |
| 1335 | s->a = ad->a; | 1375 | s->a = ad->a; |
| 1336 | s->asm_label = ad->asm_label; | 1376 | s->asm_label = ad->asm_label; |
| 1337 | s->type.ref = type->ref; | 1377 | s->type.ref = type->ref; |
| 1338 | /* copy type to the global stack */ | | |
| 1339 | if (local_stack) | | |
| 1340 | sym_copy_ref(s, &global_stack); | | |
| 1341 | } else { | 1378 | } else { |
| 1342 | patch_storage(s, ad, type); | 1379 | patch_storage(s, ad, type); |
| 1343 | } | 1380 | } |
| 1344 | /* push variables on local_stack if any */ | 1381 | if (local_stack) { |
| 1345 | if (local_stack && (s->type.t & VT_BTYPE) != VT_FUNC) | 1382 | /* make sure that type->ref is on global stack */ |
| | 1383 | move_ref_to_global(s); |
| | 1384 | /* put into local scope */ |
| 1346 | s = sym_copy(s, &local_stack); | 1385 | s = sym_copy(s, &local_stack); |
| | 1386 | } |
| 1347 | return s; | 1387 | return s; |
| 1348 | } | 1388 | } |
| 1349 | | 1389 | |
| @@ -3457,8 +3497,8 @@ ST_FUNC int type_size(CType *type, int *a) · 2107 unmodified lines |
| 3457 | int ts; | 3497 | int ts; |
| 3458 | s = type->ref; | 3498 | s = type->ref; |
| 3459 | ts = type_size(&s->type, a); | 3499 | ts = type_size(&s->type, a); |
| 3460 | if (ts < 0 && s->c < 0) | 3500 | if (s->c < 0) |
| 3461 | ts = -ts; | 3501 | return s->c; |
| 3462 | return ts * s->c; | 3502 | return ts * s->c; |
| 3463 | } else { | 3503 | } else { |
| 3464 | *a = PTR_SIZE; | 3504 | *a = PTR_SIZE; |
| @@ -4367,6 +4407,15 @@ static void struct_layout(CType *type, AttributeDef *ad) · 902 unmodified lines |
| 4367 | } | 4407 | } |
| 4368 | } | 4408 | } |
| 4369 | | 4409 | |
| | 4410 | /* Does 'n' fit into integer type 't' ? */ |
| | 4411 | static int in_range(long long n, int t) |
| | 4412 | { |
| | 4413 | unsigned long long m = (1ULL << (btype_size(t & VT_BTYPE) * 8 - 1)) - 1; |
| | 4414 | if (t & VT_UNSIGNED) |
| | 4415 | return n <= (m << 1) + 1; |
| | 4416 | return n >= -(long long)m - 1 && n <= (long long)m; |
| | 4417 | } |
| | 4418 | |
| 4370 | /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ | 4419 | /* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */ |
| 4371 | static void struct_decl(CType *type, int u) | 4420 | static void struct_decl(CType *type, int u) |
| 4372 | { | 4421 | { |
| @@ -4431,36 +4480,26 @@ do_decl: · 58 unmodified lines |
| 4431 | /* non empty enums are not allowed */ | 4480 | /* non empty enums are not allowed */ |
| 4432 | ps = &s->next; | 4481 | ps = &s->next; |
| 4433 | if (u == VT_ENUM) { | 4482 | if (u == VT_ENUM) { |
| 4434 | long long ll = 0, pl = 0, nl = 0, ni = 0, pi = 0; | 4483 | long long ll = 0, pl = 0, nl = 0; |
| 4435 | unsigned long long mu = 0; | | |
| 4436 | CType t; | 4484 | CType t; |
| 4437 | t.ref = s; | 4485 | t.ref = s; |
| | 4486 | s->sym_scope = local_scope; /* anonymous symbol won't have set */ |
| 4438 | /* enum symbols have static storage */ | 4487 | /* enum symbols have static storage */ |
| 4439 | t.t = VT_INT|VT_STATIC|VT_ENUM_VAL; | 4488 | t.t = VT_INT|VT_STATIC|VT_ENUM_VAL; |
| 4440 | if (bt) { | 4489 | if (bt) |
| 4441 | t.t = bt|VT_STATIC|VT_ENUM_VAL; | 4490 | t.t = bt|VT_STATIC|VT_ENUM_VAL; |
| 4442 | mu = 1llu << (type_size(&t, &align) * 8 - 1); | | |
| 4443 | pi = mu - 1; | | |
| 4444 | ni = -mu; | | |
| 4445 | mu = (mu << 1) - 1u; | | |
| 4446 | } | | |
| 4447 | for(;;) { | 4491 | for(;;) { |
| 4448 | v = tok; | 4492 | v = tok; |
| 4449 | if (v < TOK_UIDENT) | 4493 | if (v < TOK_UIDENT) |
| 4450 | expect("identifier"); | 4494 | expect("identifier"); |
| 4451 | ss = sym_find(v); | | |
| 4452 | if (ss && !local_stack) | | |
| 4453 | tcc_error("redefinition of enumerator '%s'", | | |
| 4454 | get_tok_str(v, NULL)); | | |
| 4455 | next(); | 4495 | next(); |
| 4456 | if (tok == '=') { | 4496 | if (tok == '=') { |
| 4457 | next(); | 4497 | next(); |
| 4458 | ll = expr_const64(); | 4498 | ll = expr_const64(); |
| 4459 | } | 4499 | } |
| 4460 | if (bt && (t.t & VT_UNSIGNED ? (unsigned long long)ll > mu | 4500 | if (bt && !in_range(ll, t.t)) |
| 4461 | : ll < ni || ll > pi)) | 4501 | tcc_error("enumerator '%s' out of range of its type", |
| 4462 | tcc_error("enumerator value outside the range of underlying type '%s'", | 4502 | get_tok_str(v, NULL)); |
| 4463 | get_tok_str(v, NULL)); | | |
| 4464 | ss = sym_push(v, &t, VT_CONST, 0); | 4503 | ss = sym_push(v, &t, VT_CONST, 0); |
| 4465 | ss->enum_val = ll; | 4504 | ss->enum_val = ll; |
| 4466 | *ps = ss, ps = &ss->next; | 4505 | *ps = ss, ps = &ss->next; |
| @@ -4626,9 +4665,9 @@ do_decl: · 159 unmodified lines |
| 4626 | check_fields(type, 1); | 4665 | check_fields(type, 1); |
| 4627 | check_fields(type, 0); | 4666 | check_fields(type, 0); |
| 4628 | struct_layout(type, &ad); | 4667 | struct_layout(type, &ad); |
| 4629 | if (debug_modes) | | |
| 4630 | tcc_debug_fix_forw(tcc_state, type); | | |
| 4631 | } | 4668 | } |
| | 4669 | if (debug_modes) |
| | 4670 | tcc_debug_fix_forw(tcc_state, type); |
| 4632 | } | 4671 | } |
| 4633 | } | 4672 | } |
| 4634 | | 4673 | |
| @@ -4860,8 +4899,11 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label) · 225 unmodified lines |
| 4860 | parse_expr_type(&type1); | 4899 | parse_expr_type(&type1); |
| 4861 | /* remove all storage modifiers except typedef */ | 4900 | /* remove all storage modifiers except typedef */ |
| 4862 | type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); | 4901 | type1.t &= ~(VT_STORAGE&~VT_TYPEDEF); |
| 4863 | if (type1.ref) | 4902 | if (type1.ref) { |
| 4864 | sym_to_attr(ad, type1.ref); | 4903 | sym_to_attr(ad, type1.ref); |
| | 4904 | if (type1.t & VT_ARRAY) |
| | 4905 | type1.t |= VT_BT_ARRAY; |
| | 4906 | } |
| 4865 | goto basic_type2; | 4907 | goto basic_type2; |
| 4866 | case TOK_THREAD_LOCAL: | 4908 | case TOK_THREAD_LOCAL: |
| 4867 | tcc_error("_Thread_local is not implemented"); | 4909 | tcc_error("_Thread_local is not implemented"); |
| @@ -4886,12 +4928,12 @@ static int parse_btype(CType *type, AttributeDef *ad, int ignore_label) · 18 unmodified lines |
| 4886 | if (t) | 4928 | if (t) |
| 4887 | parse_btype_qualify(type, t); | 4929 | parse_btype_qualify(type, t); |
| 4888 | t = type->t; | 4930 | t = type->t; |
| | 4931 | if (t & VT_ARRAY) |
| | 4932 | t |= VT_BT_ARRAY; |
| 4889 | /* get attributes from typedef */ | 4933 | /* get attributes from typedef */ |
| 4890 | sym_to_attr(ad, s); | 4934 | sym_to_attr(ad, s); |
| 4891 | typespec_found = 1; | 4935 | typespec_found = 1; |
| 4892 | st = bt = -2; | 4936 | st = bt = -2; |
| 4893 | if (type->ref && (t & VT_ARRAY) && type->ref->c < 0) | | |
| 4894 | type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); | | |
| 4895 | break; | 4937 | break; |
| 4896 | } | 4938 | } |
| 4897 | type_found = 1; | 4939 | type_found = 1; |
| @@ -4994,15 +5036,15 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 96 unmodified lines |
| 4994 | type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT | TYPE_PARAM); | 5036 | type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT | TYPE_PARAM); |
| 4995 | if ((pt.t & VT_BTYPE) == VT_VOID) | 5037 | if ((pt.t & VT_BTYPE) == VT_VOID) |
| 4996 | tcc_error("parameter declared as void"); | 5038 | tcc_error("parameter declared as void"); |
| 4997 | if (local_scope > 1 || n == 0) | 5039 | if (n == 0 || (td & TYPE_PARAM)) |
| 4998 | n = SYM_FIELD; | 5040 | n |= SYM_FIELD; |
| 4999 | } else { | 5041 | } else { |
| 5000 | n = tok; | 5042 | n = tok; |
| 5001 | pt.t = VT_INT | VT_EXTERN; /* default type */ | 5043 | pt.t = VT_INT | VT_EXTERN; /* default type */ |
| 5002 | pt.ref = NULL; | 5044 | pt.ref = NULL; |
| 5003 | next(); | 5045 | next(); |
| 5004 | } | 5046 | } |
| 5005 | if (local_scope == 1 && n < TOK_UIDENT) | 5047 | if (n < TOK_UIDENT) |
| 5006 | expect("identifier"); | 5048 | expect("identifier"); |
| 5007 | convert_parameter_type(&pt); | 5049 | convert_parameter_type(&pt); |
| 5008 | arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; | 5050 | arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE; |
| @@ -5026,7 +5068,6 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 17 unmodified lines |
| 5026 | /* if no parameters, then old type prototype */ | 5068 | /* if no parameters, then old type prototype */ |
| 5027 | l = FUNC_OLD; | 5069 | l = FUNC_OLD; |
| 5028 | skip(')'); | 5070 | skip(')'); |
| 5029 | --local_scope; | | |
| 5030 | /* NOTE: const is ignored in returned type as it has a special | 5071 | /* NOTE: const is ignored in returned type as it has a special |
| 5031 | meaning in gcc / C++ */ | 5072 | meaning in gcc / C++ */ |
| 5032 | type->t &= ~VT_CONSTANT; | 5073 | type->t &= ~VT_CONSTANT; |
| @@ -5046,10 +5087,9 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td) · 13 unmodified lines |
| 5046 | s->next = first; | 5087 | s->next = first; |
| 5047 | type->t = VT_FUNC; | 5088 | type->t = VT_FUNC; |
| 5048 | type->ref = s; | 5089 | type->ref = s; |
| 5049 | | 5090 | /* unlink parameter symbols from the token table, keep on stack */ |
| 5050 | /* unlink symbols from the token table, keep on stack */ | | |
| 5051 | sym_pop(ps, sr, 1); | 5091 | sym_pop(ps, sr, 1); |
| 5052 | //psyms("---", *ps, sr); | 5092 | --local_scope; |
| 5053 | | 5093 | |
| 5054 | } else if (tok == '[') { | 5094 | } else if (tok == '[') { |
| 5055 | int saved_nocode_wanted = nocode_wanted; | 5095 | int saved_nocode_wanted = nocode_wanted; |
| @@ -6901,7 +6941,7 @@ static void try_call_scope_cleanup(Sym *stop) · 1845 unmodified lines |
| 6901 | Sym *cls = cur_scope->cl.s; | 6941 | Sym *cls = cur_scope->cl.s; |
| 6902 | for (; cls != stop; cls = cls->next) { | 6942 | for (; cls != stop; cls = cls->next) { |
| 6903 | Sym *fs = cls->cleanup_func; | 6943 | Sym *fs = cls->cleanup_func; |
| 6904 | Sym *vs = cls->prev_tok; | 6944 | Sym *vs = cls->cleanup_sym; |
| 6905 | save_lvalues(); | 6945 | save_lvalues(); |
| 6906 | vpushsym(&fs->type, fs); | 6946 | vpushsym(&fs->type, fs); |
| 6907 | vset(&vs->type, vs->r, vs->c); | 6947 | vset(&vs->type, vs->r, vs->c); |
| @@ -6912,6 +6952,7 @@ static void try_call_scope_cleanup(Sym *stop) · 4 unmodified lines |
| 6912 | } | 6952 | } |
| 6913 | } | 6953 | } |
| 6914 | | 6954 | |
| | 6955 | |
| 6915 | static void try_call_cleanup_goto(Sym *cleanupstate) | 6956 | static void try_call_cleanup_goto(Sym *cleanupstate) |
| 6916 | { | 6957 | { |
| 6917 | Sym *oc, *cc; | 6958 | Sym *oc, *cc; |
| @@ -6938,7 +6979,7 @@ static void block_cleanup(struct scope *o) · 20 unmodified lines |
| 6938 | int jmp = 0; | 6979 | int jmp = 0; |
| 6939 | Sym *g, **pg; | 6980 | Sym *g, **pg; |
| 6940 | for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) { | 6981 | for (pg = &pending_gotos; (g = *pg) && g->c > o->cl.n;) { |
| 6941 | if (g->prev_tok->r & LABEL_FORWARD) { | 6982 | if (g->cleanup_label->r & LABEL_FORWARD) { |
| 6942 | Sym *pcl = g->next; | 6983 | Sym *pcl = g->next; |
| 6943 | if (!jmp) | 6984 | if (!jmp) |
| 6944 | jmp = gjmp(0); | 6985 | jmp = gjmp(0); |
| @@ -7360,7 +7401,7 @@ again: · 415 unmodified lines |
| 7360 | /* start new goto chain for cleanups, linked via label->next */ | 7401 | /* start new goto chain for cleanups, linked via label->next */ |
| 7361 | if (cur_scope->cl.s && !nocode_wanted) { | 7402 | if (cur_scope->cl.s && !nocode_wanted) { |
| 7362 | sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n); | 7403 | sym_push2(&pending_gotos, SYM_FIELD, 0, cur_scope->cl.n); |
| 7363 | pending_gotos->prev_tok = s; | 7404 | pending_gotos->cleanup_label = s; |
| 7364 | s = sym_push2(&s->next, SYM_FIELD, 0, 0); | 7405 | s = sym_push2(&s->next, SYM_FIELD, 0, 0); |
| 7365 | pending_gotos->next = s; | 7406 | pending_gotos->next = s; |
| 7366 | } | 7407 | } |
| @@ -7570,7 +7611,7 @@ static void decl_design_flex(init_params *p, Sym *ref, int index) · 203 unmodified lines |
| 7570 | if (ref == p->flex_array_ref) { | 7611 | if (ref == p->flex_array_ref) { |
| 7571 | if (index >= ref->c) | 7612 | if (index >= ref->c) |
| 7572 | ref->c = index + 1; | 7613 | ref->c = index + 1; |
| 7573 | } else if (ref->c < 0) | 7614 | } else if (ref->c < 0 && index >= 0) |
| 7574 | tcc_error("flexible array has zero size in this context"); | 7615 | tcc_error("flexible array has zero size in this context"); |
| 7575 | } | 7616 | } |
| 7576 | | 7617 | |
| @@ -8029,7 +8070,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f · 452 unmodified lines |
| 8029 | /* GNU extension: if the initializer is empty for a flex array, | 8070 | /* GNU extension: if the initializer is empty for a flex array, |
| 8030 | it's size is zero. We won't enter the loop, so set the size | 8071 | it's size is zero. We won't enter the loop, so set the size |
| 8031 | now. */ | 8072 | now. */ |
| 8032 | decl_design_flex(p, s, len); | 8073 | decl_design_flex(p, s, len - 1); |
| 8033 | while (tok != '}' || (flags & DIF_HAVE_ELEM)) { | 8074 | while (tok != '}' || (flags & DIF_HAVE_ELEM)) { |
| 8034 | len = decl_designator(p, type, c, &f, flags, len); | 8075 | len = decl_designator(p, type, c, &f, flags, len); |
| 8035 | flags &= ~DIF_HAVE_ELEM; | 8076 | flags &= ~DIF_HAVE_ELEM; |
| @@ -8165,6 +8206,13 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 129 unmodified lines |
| 8165 | // (arrays of incomplete types are handled in array parsing) | 8206 | // (arrays of incomplete types are handled in array parsing) |
| 8166 | if (!(type->t & VT_ARRAY)) | 8207 | if (!(type->t & VT_ARRAY)) |
| 8167 | tcc_error("initialization of incomplete type"); | 8208 | tcc_error("initialization of incomplete type"); |
| | 8209 | /* If the base type itself was an array type of unspecified |
| | 8210 | size (like in 'typedef int arr[]; arr x = {1};') then |
| | 8211 | we will overwrite the unknown size by the real one for |
| | 8212 | this decl. We need to unshare the ref symbol holding |
| | 8213 | that size. */ |
| | 8214 | if (type->t & VT_BT_ARRAY) |
| | 8215 | type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); |
| 8168 | p.flex_array_ref = type->ref; | 8216 | p.flex_array_ref = type->ref; |
| 8169 | | 8217 | |
| 8170 | } else if (has_init && (type->t & VT_BTYPE) == VT_STRUCT) { | 8218 | } else if (has_init && (type->t & VT_BTYPE) == VT_STRUCT) { |
| @@ -8182,8 +8230,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 11 unmodified lines |
| 8182 | | 8230 | |
| 8183 | if (size < 0) { | 8231 | if (size < 0) { |
| 8184 | /* If unknown size, do a dry-run 1st pass */ | 8232 | /* If unknown size, do a dry-run 1st pass */ |
| 8185 | if (!has_init) | 8233 | if (!has_init) |
| 8186 | tcc_error("unknown type size"); | 8234 | goto err_size; |
| 8187 | if (has_init == 2) { | 8235 | if (has_init == 2) { |
| 8188 | /* only get strings */ | 8236 | /* only get strings */ |
| 8189 | init_str = tok_str_alloc(); | 8237 | init_str = tok_str_alloc(); |
| @@ -8206,7 +8254,8 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 16 unmodified lines |
| 8206 | | 8254 | |
| 8207 | /* if still unknown size, error */ | 8255 | /* if still unknown size, error */ |
| 8208 | size = type_size(type, &align); | 8256 | size = type_size(type, &align); |
| 8209 | if (size < 0) | 8257 | if (size < 0) |
| | 8258 | err_size: |
| 8210 | tcc_error("unknown type size"); | 8259 | tcc_error("unknown type size"); |
| 8211 | | 8260 | |
| 8212 | /* If there's a flex member and it was used in the initializer | 8261 | /* If there's a flex member and it was used in the initializer |
| @@ -8258,7 +8307,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 45 unmodified lines |
| 8258 | if (ad->cleanup_func) { | 8307 | if (ad->cleanup_func) { |
| 8259 | Sym *cls = sym_push2(&all_cleanups, | 8308 | Sym *cls = sym_push2(&all_cleanups, |
| 8260 | SYM_FIELD | ++cur_scope->cl.n, 0, 0); | 8309 | SYM_FIELD | ++cur_scope->cl.n, 0, 0); |
| 8261 | cls->prev_tok = sym; | 8310 | cls->cleanup_sym = sym; |
| 8262 | cls->cleanup_func = ad->cleanup_func; | 8311 | cls->cleanup_func = ad->cleanup_func; |
| 8263 | cls->next = cur_scope->cl.s; | 8312 | cls->next = cur_scope->cl.s; |
| 8264 | cur_scope->cl.s = cls; | 8313 | cur_scope->cl.s = cls; |
| @@ -8423,19 +8472,21 @@ ST_FUNC Sym *gfunc_set_param(Sym *s, int c, int byref) · 158 unmodified lines |
| 8423 | return NULL; | 8472 | return NULL; |
| 8424 | s->c = c; | 8473 | s->c = c; |
| 8425 | if (byref) | 8474 | if (byref) |
| 8426 | s->r = VT_LLOCAL | VT_LVAL; | 8475 | s->r = VT_LLOCAL | VT_LVAL; /* otherwise VT_LOCAL */ |
| 8427 | return s; | 8476 | return s; |
| 8428 | } | 8477 | } |
| 8429 | | 8478 | |
| 8430 | /* push parameters (and their types), last first */ | 8479 | /* push parameters (and their types), last first */ |
| 8431 | static void sym_push_params(Sym *ref) | 8480 | static void sym_push_params(Sym *ref) |
| 8432 | { | 8481 | { |
| 8433 | Sym *s; | 8482 | Sym *s = ref; |
| 8434 | for (s = ref; s->next; s = s->next) | 8483 | while (s->next) |
| 8435 | ; | 8484 | s = s->next; |
| 8436 | for (; s && s != ref; s = s->prev) | 8485 | while (s != ref) { |
| 8437 | if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) | 8486 | if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM) |
| 8438 | sym_copy(s, &local_stack); | 8487 | sym_copy(s, &local_stack); |
| | 8488 | s = s->prev; |
| | 8489 | } |
| 8439 | } | 8490 | } |
| 8440 | | 8491 | |
| 8441 | /* parse a function defined by symbol 'sym' and generate its code in | 8492 | /* parse a function defined by symbol 'sym' and generate its code in |
| @@ -8473,8 +8524,8 @@ static void gen_function(Sym *sym) · 31 unmodified lines |
| 8473 | /* push a dummy symbol to enable local sym storage */ | 8524 | /* push a dummy symbol to enable local sym storage */ |
| 8474 | sym_push2(&local_stack, SYM_FIELD, 0, 0); | 8525 | sym_push2(&local_stack, SYM_FIELD, 0, 0); |
| 8475 | /* push parameters */ | 8526 | /* push parameters */ |
| | 8527 | local_scope = 1; |
| 8476 | sym_push_params(sym->type.ref); | 8528 | sym_push_params(sym->type.ref); |
| 8477 | //psyms(funcname, local_stack, 0); | | |
| 8478 | | 8529 | |
| 8479 | local_scope = 0; | 8530 | local_scope = 0; |
| 8480 | rsym = 0; | 8531 | rsym = 0; |
| @@ -8608,7 +8659,7 @@ static int decl(int l) · 127 unmodified lines |
| 8608 | { | 8659 | { |
| 8609 | int v, has_init, r, oldint; | 8660 | int v, has_init, r, oldint; |
| 8610 | CType type, btype; | 8661 | CType type, btype; |
| 8611 | Sym *sym; | 8662 | Sym *sym, *sa; |
| 8612 | AttributeDef ad, adbase; | 8663 | AttributeDef ad, adbase; |
| 8613 | ElfSym *esym; | 8664 | ElfSym *esym; |
| 8614 | | 8665 | |
| @@ -8663,22 +8714,8 @@ static int decl(int l) · 48 unmodified lines |
| 8663 | while (1) { /* iterate thru each declaration */ | 8714 | while (1) { /* iterate thru each declaration */ |
| 8664 | type = btype; | 8715 | type = btype; |
| 8665 | ad = adbase; | 8716 | ad = adbase; |
| 8666 | if ((btype.t & VT_ARRAY) && btype.ref->c < 0) { | | |
| 8667 | /* If the base type itself was an array type of unspecified | | |
| 8668 | size (like in 'typedef int arr[]; arr x = {1};') then | | |
| 8669 | we will overwrite the unknown size by the real one for | | |
| 8670 | this decl. We need to unshare the ref symbol holding | | |
| 8671 | that size. */ | | |
| 8672 | type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c); | | |
| 8673 | } | | |
| 8674 | type_decl(&type, &ad, &v, TYPE_DIRECT); | 8717 | type_decl(&type, &ad, &v, TYPE_DIRECT); |
| 8675 | #if 0 | 8718 | |
| 8676 | { | | |
| 8677 | char buf[500]; | | |
| 8678 | type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL)); | | |
| 8679 | printf("type = '%s'\n", buf); | | |
| 8680 | } | | |
| 8681 | #endif | | |
| 8682 | if ((type.t & VT_BTYPE) == VT_FUNC) { | 8719 | if ((type.t & VT_BTYPE) == VT_FUNC) { |
| 8683 | if ((type.t & VT_STATIC) && (l != VT_CONST)) | 8720 | if ((type.t & VT_STATIC) && (l != VT_CONST)) |
| 8684 | tcc_error("function without file scope cannot be static"); | 8721 | tcc_error("function without file scope cannot be static"); |
| @@ -8722,8 +8759,6 @@ static int decl(int l) · 37 unmodified lines |
| 8722 | pe_check_linkage(&type, &ad); | 8759 | pe_check_linkage(&type, &ad); |
| 8723 | #endif | 8760 | #endif |
| 8724 | if (tok == '{') { | 8761 | if (tok == '{') { |
| 8725 | Sym *sa; | | |
| 8726 | | | |
| 8727 | if (l != VT_CONST) | 8762 | if (l != VT_CONST) |
| 8728 | tcc_error("cannot use local functions"); | 8763 | tcc_error("cannot use local functions"); |
| 8729 | if ((type.t & VT_BTYPE) != VT_FUNC) | 8764 | if ((type.t & VT_BTYPE) != VT_FUNC) |