Correctly register declarations for compound types and enums.
[cparser] / parser.c
index 1fc7cea..0dfaec2 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -50,6 +50,7 @@ static declaration_t  *last_declaration  = NULL;
 static declaration_t  *current_function  = NULL;
 static struct obstack  temp_obst;
 
+/** The current source position. */
 #define HERE token.source_position
 
 static type_t *type_valist;
@@ -1280,7 +1281,7 @@ static initializer_t *parse_initializer(type_t *type)
        return result;
 }
 
-
+static declaration_t *append_declaration(declaration_t *declaration);
 
 static declaration_t *parse_compound_type_specifier(bool is_struct)
 {
@@ -1329,7 +1330,11 @@ static declaration_t *parse_compound_type_specifier(bool is_struct)
                }
                declaration->source_position = token.source_position;
                declaration->symbol          = symbol;
-               record_declaration(declaration);
+               declaration->parent_context  = context;
+               if (symbol != NULL) {
+                       environment_push(declaration);
+               }
+               append_declaration(declaration);
        }
 
        if(token.type == '{') {
@@ -1424,6 +1429,7 @@ static type_t *parse_enum_specifier(void)
                declaration->namespc       = NAMESPACE_ENUM;
                declaration->source_position = token.source_position;
                declaration->symbol          = symbol;
+               declaration->parent_context  = context;
        }
 
        type_t *const type      = allocate_type_zero(TYPE_ENUM);
@@ -1433,7 +1439,8 @@ static type_t *parse_enum_specifier(void)
                if(declaration->init.is_defined) {
                        errorf(HERE, "multiple definitions of enum %Y", symbol);
                }
-               record_declaration(declaration);
+               environment_push(declaration);
+               append_declaration(declaration);
                declaration->init.is_defined = 1;
 
                parse_enum_entries(&type->enumt);
@@ -4008,6 +4015,9 @@ static void semantic_dereference(unary_expression_t *expression)
        expression->expression.datatype = result_type;
 }
 
+/**
+ * Check the semantic of the address taken expression.
+ */
 static void semantic_take_addr(unary_expression_t *expression)
 {
        expression_t *value  = expression->value;
@@ -4021,6 +4031,11 @@ static void semantic_take_addr(unary_expression_t *expression)
                reference_expression_t *reference   = (reference_expression_t*) value;
                declaration_t          *declaration = reference->declaration;
                if(declaration != NULL) {
+                       if (declaration->storage_class == STORAGE_CLASS_REGISTER) {
+                               errorf(expression->expression.source_position,
+                                       "address of register variable '%Y' requested",
+                                       declaration->symbol);
+                       }
                        declaration->address_taken = 1;
                }
        }
@@ -4032,13 +4047,14 @@ static void semantic_take_addr(unary_expression_t *expression)
 static expression_t *parse_##unexpression_type(unsigned precedence)            \
 {                                                                              \
        eat(token_type);                                                           \
-                                                                               \
+                                                                                  \
        expression_t *unary_expression                                             \
                = allocate_expression_zero(unexpression_type);                         \
+       unary_expression->base.source_position = HERE;                             \
        unary_expression->unary.value = parse_sub_expression(precedence);          \
                                                                                   \
        sfunc(&unary_expression->unary);                                           \
-                                                                               \
+                                                                                  \
        return unary_expression;                                                   \
 }
 
@@ -4847,7 +4863,7 @@ static statement_t *parse_label_statement(void)
        label_statement->statement.source_position = token.source_position;
        label_statement->label                     = label;
 
-       expect(':');
+       eat(':');
 
        if(token.type == '}') {
                /* TODO only warn? */