diff options
-rw-r--r-- | parse.c | 11 | ||||
-rw-r--r-- | scope.c | 1 | ||||
-rw-r--r-- | symbol.c | 18 | ||||
-rw-r--r-- | symbol.h | 1 |
4 files changed, 27 insertions, 4 deletions
@@ -607,7 +607,7 @@ static void start_iterator(struct statement *stmt) static void end_iterator(void) { - start_symbol_scope(); + end_symbol_scope(); } static void start_switch(struct statement *stmt) @@ -625,7 +625,7 @@ static void start_switch(struct statement *stmt) static void end_switch(void) { - start_symbol_scope(); + end_symbol_scope(); } struct token *statement(struct token *token, struct statement **tree) @@ -944,8 +944,9 @@ static struct token *external_declaration(struct token *token, struct symbol_lis if (decl->ctype.modifiers & MOD_EXTERN) { if (!(decl->ctype.modifiers & MOD_INLINE)) warn(decl->pos, "function with external linkage has definition"); - decl->ctype.modifiers &= ~MOD_EXTERN; } + if (!(decl->ctype.modifiers & MOD_STATIC)) + decl->ctype.modifiers |= MOD_EXTERN; base_type->stmt = alloc_statement(token->pos, STMT_COMPOUND); start_function_scope(); symbol_iterate(base_type->arguments, declare_argument, decl); @@ -953,6 +954,7 @@ static struct token *external_declaration(struct token *token, struct symbol_lis end_function_scope(); if (!(decl->ctype.modifiers & MOD_INLINE)) add_symbol(list, decl); + check_declaration(decl); return expect(token, '}', "at end of function"); } if (!(decl->ctype.modifiers & MOD_STATIC)) @@ -969,7 +971,8 @@ static struct token *external_declaration(struct token *token, struct symbol_lis } if (!is_typedef && !(decl->ctype.modifiers & (MOD_EXTERN | MOD_INLINE))) add_symbol(list, decl); - + check_declaration(decl); + if (!match_op(token, ',')) break; @@ -20,6 +20,7 @@ struct scope *block_scope = &toplevel_scope, void bind_scope(struct symbol *sym, struct scope *scope) { + sym->scope = scope; add_symbol(&scope->symbols, sym); } @@ -267,6 +267,24 @@ struct symbol *examine_symbol_type(struct symbol * sym) return sym; } +void check_declaration(struct symbol *sym) +{ + struct symbol *next = sym; + + while ((next = next->next_id) != NULL) { + if (next->namespace != sym->namespace) + continue; + if (sym->scope == next->scope) { + sym->same_symbol = next; + return; + } + if (sym->ctype.modifiers & next->ctype.modifiers & MOD_EXTERN) { + sym->same_symbol = next; + return; + } + } +} + void bind_symbol(struct symbol *sym, struct ident *ident, enum namespace ns) { struct scope *scope; @@ -191,5 +191,6 @@ extern const char *show_typename(struct symbol *sym); extern void debug_symbol(struct symbol *); extern void merge_type(struct symbol *sym, struct symbol *base_type); +extern void check_declaration(struct symbol *sym); #endif /* SEMANTIC_H */ |