diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-04-01 15:45:33 +0200 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-05-21 17:27:45 +0200 |
commit | db0a795b145501e456cac5180be03ef697810845 (patch) | |
tree | 9b6d3d16c6322970b4dbea9260cde61ec97478f6 | |
parent | dbaf79f0e3abc46002fbf918240e1c09c6e4697a (diff) | |
download | sparse-db0a795b145501e456cac5180be03ef697810845.tar.gz |
scope: let labels have their own scope
It's invalid to jump inside a statement expression.
So, concerning labels & gotos, a statement expression is
like a kind of scope.
So, in preparation for the detection of such jumps, create
these new scopes and open/close them when entering/leaving
statement expressions.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | expression.c | 2 | ||||
-rw-r--r-- | scope.c | 17 | ||||
-rw-r--r-- | scope.h | 4 |
3 files changed, 21 insertions, 2 deletions
diff --git a/expression.c b/expression.c index ffb3c2dc..f8a8f03e 100644 --- a/expression.c +++ b/expression.c @@ -71,7 +71,9 @@ struct token *parens_expression(struct token *token, struct expression **expr, c struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND); *expr = e; e->statement = stmt; + start_label_scope(); token = compound_statement(token->next, stmt); + end_label_scope(); token = expect(token, '}', "at end of statement expression"); } else token = parse_expression(token, expr); @@ -36,6 +36,7 @@ static struct scope builtin_scope = { .next = &builtin_scope }; struct scope *block_scope = &builtin_scope, // regular automatic variables etc + *label_scope = NULL, // expr-stmt labels *function_scope = &builtin_scope, // labels, arguments etc *file_scope = &builtin_scope, // static *global_scope = &builtin_scope; // externally visible @@ -91,8 +92,9 @@ void start_block_scope(void) void start_function_scope(void) { - start_scope(&function_scope); start_scope(&block_scope); + start_scope(&label_scope); + function_scope = label_scope; } static void remove_symbol_scope(struct symbol *sym) @@ -137,7 +139,18 @@ void end_block_scope(void) void end_function_scope(void) { end_scope(&block_scope); - end_scope(&function_scope); + end_label_scope(); + function_scope = label_scope; +} + +void start_label_scope(void) +{ + start_scope(&label_scope); +} + +void end_label_scope(void) +{ + end_scope(&label_scope); } int is_outer_scope(struct scope *scope) @@ -34,6 +34,7 @@ struct scope { extern struct scope *block_scope, + *label_scope, *function_scope, *file_scope, *global_scope; @@ -53,6 +54,9 @@ extern void end_block_scope(void); extern void start_function_scope(void); extern void end_function_scope(void); +extern void start_label_scope(void); +extern void end_label_scope(void); + extern void set_current_scope(struct symbol *); extern void bind_scope(struct symbol *, struct scope *); extern void rebind_scope(struct symbol *, struct scope *); |