History

tccgen: scope levels for local symbols

... for fast redeclaration checks Also, check function parameters too: void foo(int a) { int a; ... } Also, try to fix struct/union/enum's on different scopes: { struct xxx { int x; }; { struct xxx { int y; }; ... }} and some (probably not all) combination with incomplete declarations "struct xxx;" Replaces 2bfedb18675228c3837c23fa523231f55e102c12 and 07d896c8e5d1b46bf4aebd403c78e5f7ffebe02a Fixes cf95ac399cbce1ea8a519f91dd36a5cfd4ea7943

grischka committed 10 years ago

Commit caebbc31 parent 0fbc77c3 files · +30 −26Browse files

Unified · Split

3 files
  1. libtcc.c +0 −1
  2. tcc.h +4 −2
  3. tccgen.c +26 −23
libtcc.c+0−1
@@ -1764,7 +1764,6 @@ static const FlagDef flag_defs[] = { · 1763 unmodified lines
1764 { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" },1764 { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" },
1765 { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },1765 { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
1766 { offsetof(TCCState, normalize_inc_dirs), 0, "normalize-inc-dirs" },1766 { offsetof(TCCState, normalize_inc_dirs), 0, "normalize-inc-dirs" },
1767 { offsetof(TCCState, no_type_redef_check), FD_INVERT, "type-redefinition-check" },
1768};1767};
1769 1768
1770/* set/reset a flag */1769/* set/reset a flag */
tcc.h+4−2
@@ -459,7 +459,10 @@ typedef struct AttributeDef { · 458 unmodified lines
459/* symbol management */459/* symbol management */
460typedef struct Sym {460typedef struct Sym {
461 int v; /* symbol token */461 int v; /* symbol token */
462 int asm_label; /* associated asm label */462 union {
463 int asm_label; /* associated asm label */
464 int scope; /* scope level for locals */
465 };
463 union {466 union {
464 long r; /* associated register */467 long r; /* associated register */
465 struct Attribute a;468 struct Attribute a;
@@ -707,7 +710,6 @@ struct TCCState { · 241 unmodified lines
707 Liuux 2.4.26 can't find initrd when compiled with a new algorithm */710 Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
708 int dollars_in_identifiers; /* allows '$' char in indentifiers */711 int dollars_in_identifiers; /* allows '$' char in indentifiers */
709 int normalize_inc_dirs; /* remove non-existent or duplicate directories from include paths */712 int normalize_inc_dirs; /* remove non-existent or duplicate directories from include paths */
710 int no_type_redef_check; /* no local vars redefinition check */
711 713
712 /* warning switches */714 /* warning switches */
713 int warn_write_strings;715 int warn_write_strings;
tccgen.c+26−23
@@ -50,10 +50,10 @@ ST_DATA int nb_sym_pools; · 49 unmodified lines
50 50
51ST_DATA Sym *global_stack;51ST_DATA Sym *global_stack;
52ST_DATA Sym *local_stack;52ST_DATA Sym *local_stack;
53ST_DATA Sym *scope_stack_bottom;
54ST_DATA Sym *define_stack;53ST_DATA Sym *define_stack;
55ST_DATA Sym *global_label_stack;54ST_DATA Sym *global_label_stack;
56ST_DATA Sym *local_label_stack;55ST_DATA Sym *local_label_stack;
56static int local_scope;
57 57
58ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */58ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
59ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */59ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
@@ -166,14 +166,7 @@ ST_INLN void sym_free(Sym *sym) · 106 unmodified lines
166ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)166ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
167{167{
168 Sym *s;168 Sym *s;
169 if (!tcc_state->no_type_redef_check) {169
170 if ((ps == &local_stack) && !(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
171 for (s = *ps; s != scope_stack_bottom; s = s->prev)
172 if (s->v == v)
173 tcc_error("incompatible types for redefinition of '%s'",
174 get_tok_str(v, NULL));
175 }
176 }
177 s = sym_malloc();170 s = sym_malloc();
178 s->asm_label = 0;171 s->asm_label = 0;
179 s->v = v;172 s->v = v;
@@ -246,6 +239,11 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 66 unmodified lines
246 ps = &ts->sym_identifier;239 ps = &ts->sym_identifier;
247 s->prev_tok = *ps;240 s->prev_tok = *ps;
248 *ps = s;241 *ps = s;
242 if (local_scope) {
243 s->scope = local_scope;
244 if (s->prev_tok && s->prev_tok->scope == s->scope)
245 tcc_error("redeclaration of '%s'", get_tok_str(v & ~SYM_STRUCT, NULL));
246 }
249 }247 }
250 return s;248 return s;
251}249}
@@ -2930,10 +2928,11 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 2678 unmodified lines
2930 if (v < TOK_IDENT)2928 if (v < TOK_IDENT)
2931 expect("struct/union/enum name");2929 expect("struct/union/enum name");
2932 s = struct_find(v);2930 s = struct_find(v);
2933 if (s) {2931 if (s && s->type.t == a) {
2934 if (s->type.t != a)2932 if (tok != '{' && tok != ';')
2935 tcc_error("invalid type");2933 goto do_decl; /* variable declaration: 'struct s x;' */
2936 goto do_decl;2934 if (s->scope == local_scope && (s->c == -1 || tok != '{'))
2935 goto do_decl; /* at least one must be incomplete type */
2937 }2936 }
2938 } else {2937 } else {
2939 v = anon_sym++;2938 v = anon_sym++;
@@ -3435,6 +3434,8 @@ static void post_type(CType *type, AttributeDef *ad) · 495 unmodified lines
3435 plast = &first;3434 plast = &first;
3436 arg_size = 0;3435 arg_size = 0;
3437 if (tok != ')') {3436 if (tok != ')') {
3437 int ls = local_scope;
3438 local_scope = 1; /* for struct decl inside function params */
3438 for(;;) {3439 for(;;) {
3439 /* read param name and compute offset */3440 /* read param name and compute offset */
3440 if (l != FUNC_OLD) {3441 if (l != FUNC_OLD) {
@@ -3474,6 +3475,7 @@ static void post_type(CType *type, AttributeDef *ad) · 33 unmodified lines
3474 break;3475 break;
3475 }3476 }
3476 }3477 }
3478 local_scope = ls;
3477 }3479 }
3478 /* if no parameters, then old type prototype */3480 /* if no parameters, then old type prototype */
3479 if (l == 0)3481 if (l == 0)
@@ -4879,7 +4881,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 1399 unmodified lines
4879 int case_reg, int is_expr)4881 int case_reg, int is_expr)
4880{4882{
4881 int a, b, c, d;4883 int a, b, c, d;
4882 Sym *s, *frame_bottom;4884 Sym *s;
4883 4885
4884 /* generate line number info */4886 /* generate line number info */
4885 if (tcc_state->do_debug &&4887 if (tcc_state->do_debug &&
@@ -4933,10 +4935,8 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 47 unmodified lines
4933 next();4935 next();
4934 /* record local declaration stack position */4936 /* record local declaration stack position */
4935 s = local_stack;4937 s = local_stack;
4936 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
4937 frame_bottom->next = scope_stack_bottom;
4938 scope_stack_bottom = frame_bottom;
4939 llabel = local_label_stack;4938 llabel = local_label_stack;
4939 ++local_scope;
4940 4940
4941 /* handle local labels declarations */4941 /* handle local labels declarations */
4942 if (tok == TOK_LABEL) {4942 if (tok == TOK_LABEL) {
@@ -4983,7 +4983,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 40 unmodified lines
4983 }4983 }
4984 }4984 }
4985 /* pop locally defined symbols */4985 /* pop locally defined symbols */
4986 scope_stack_bottom = scope_stack_bottom->next;4986 --local_scope;
4987 sym_pop(&local_stack, s);4987 sym_pop(&local_stack, s);
4988 4988
4989 /* Pop VLA frames and restore stack pointer if required */4989 /* Pop VLA frames and restore stack pointer if required */
@@ -5082,9 +5082,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 92 unmodified lines
5082 next();5082 next();
5083 skip('(');5083 skip('(');
5084 s = local_stack;5084 s = local_stack;
5085 frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);5085 ++local_scope;
5086 frame_bottom->next = scope_stack_bottom;
5087 scope_stack_bottom = frame_bottom;
5088 if (tok != ';') {5086 if (tok != ';') {
5089 /* c99 for-loop init decl? */5087 /* c99 for-loop init decl? */
5090 if (!decl0(VT_LOCAL, 1)) {5088 if (!decl0(VT_LOCAL, 1)) {
@@ -5119,8 +5117,9 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 28 unmodified lines
5119 gjmp_addr(c);5117 gjmp_addr(c);
5120 gsym(a);5118 gsym(a);
5121 gsym_addr(b, c);5119 gsym_addr(b, c);
5122 scope_stack_bottom = scope_stack_bottom->next;5120 --local_scope;
5123 sym_pop(&local_stack, s);5121 sym_pop(&local_stack, s);
5122
5124 } else 5123 } else
5125 if (tok == TOK_DO) {5124 if (tok == TOK_DO) {
5126 next();5125 next();
@@ -6154,9 +6153,13 @@ static void gen_function(Sym *sym) · 1027 unmodified lines
6154 /* put debug symbol */6153 /* put debug symbol */
6155 if (tcc_state->do_debug)6154 if (tcc_state->do_debug)
6156 put_func_debug(sym);6155 put_func_debug(sym);
6156
6157 /* push a dummy symbol to enable local sym storage */6157 /* push a dummy symbol to enable local sym storage */
6158 sym_push2(&local_stack, SYM_FIELD, 0, 0);6158 sym_push2(&local_stack, SYM_FIELD, 0, 0);
6159 local_scope = 1; /* for function parameters */
6159 gfunc_prolog(&sym->type);6160 gfunc_prolog(&sym->type);
6161 local_scope = 0;
6162
6160#ifdef CONFIG_TCC_BCHECK6163#ifdef CONFIG_TCC_BCHECK
6161 if (tcc_state->do_bounds_check && !strcmp(funcname, "main")) {6164 if (tcc_state->do_bounds_check && !strcmp(funcname, "main")) {
6162 int i;6165 int i;
@@ -6177,7 +6180,7 @@ static void gen_function(Sym *sym) · 14 unmodified lines
6177 cur_text_section->data_offset = ind;6180 cur_text_section->data_offset = ind;
6178 label_pop(&global_label_stack, NULL);6181 label_pop(&global_label_stack, NULL);
6179 /* reset local stack */6182 /* reset local stack */
6180 scope_stack_bottom = NULL;6183 local_scope = 0;
6181 sym_pop(&local_stack, NULL);6184 sym_pop(&local_stack, NULL);
6182 /* end of function */6185 /* end of function */
6183 /* patch symbol size */6186 /* patch symbol size */

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