Slightly simplify stack_pop_to().
[cparser] / parser.c
index 3b23a67..b800fb8 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -761,28 +761,20 @@ static void stack_push(stack_entry_t **stack_ptr, declaration_t *declaration)
        namespace_t  namespc = (namespace_t) declaration->namespc;
 
        /* replace/add declaration into declaration list of the symbol */
-       declaration_t *iter = symbol->declaration;
-       if (iter == NULL) {
-               symbol->declaration = declaration;
-       } else {
-               declaration_t *iter_last = NULL;
-               for( ; iter != NULL; iter_last = iter, iter = iter->symbol_next) {
-                       /* replace an entry? */
-                       if (iter->namespc == namespc) {
-                               if (iter_last == NULL) {
-                                       symbol->declaration = declaration;
-                               } else {
-                                       iter_last->symbol_next = declaration;
-                               }
-                               declaration->symbol_next = iter->symbol_next;
-                               break;
-                       }
-               }
-               if (iter == NULL) {
-                       assert(iter_last->symbol_next == NULL);
-                       iter_last->symbol_next = declaration;
+       declaration_t **anchor;
+       declaration_t  *iter;
+       for (anchor = &symbol->declaration;; anchor = &iter->symbol_next) {
+               iter = *anchor;
+               if (iter == NULL)
+                       break;
+
+               /* replace an entry? */
+               if (iter->namespc == namespc) {
+                       declaration->symbol_next = iter->symbol_next;
+                       break;
                }
        }
+       *anchor = declaration;
 
        /* remember old declaration */
        stack_entry_t entry;
@@ -847,30 +839,20 @@ static void stack_pop_to(stack_entry_t **stack_ptr, size_t new_top)
                namespace_t    namespc         = (namespace_t)entry->namespc;
 
                /* replace/remove declaration */
-               declaration_t *declaration = symbol->declaration;
-               assert(declaration != NULL);
-               if (declaration->namespc == namespc) {
-                       if (old_declaration == NULL) {
-                               symbol->declaration = declaration->symbol_next;
-                       } else {
-                               symbol->declaration = old_declaration;
-                       }
-               } else {
-                       declaration_t *iter_last = declaration;
-                       declaration_t *iter      = declaration->symbol_next;
-                       for( ; iter != NULL; iter_last = iter, iter = iter->symbol_next) {
-                               /* replace an entry? */
-                               if (iter->namespc == namespc) {
-                                       assert(iter_last != NULL);
-                                       iter_last->symbol_next = old_declaration;
-                                       if (old_declaration != NULL) {
-                                               old_declaration->symbol_next = iter->symbol_next;
-                                       }
-                                       break;
-                               }
-                       }
+               declaration_t **anchor;
+               declaration_t  *iter;
+               for (anchor = &symbol->declaration;; anchor = &iter->symbol_next) {
+                       iter = *anchor;
                        assert(iter != NULL);
+                       /* replace an entry? */
+                       if (iter->namespc == namespc)
+                               break;
                }
+
+               /* Because of scopes and appending other namespaces to the end of
+                * the list, this must hold. */
+               assert((old_declaration != NULL ? old_declaration->symbol_next : NULL) == iter->symbol_next);
+               *anchor = old_declaration;
        }
 
        ARR_SHRINKLEN(*stack_ptr, (int) new_top);
@@ -4425,7 +4407,8 @@ static declaration_t *record_declaration(
 
        assert(declaration != previous_declaration);
        if (previous_declaration != NULL &&
-           previous_declaration->parent_scope->is_parameter) {
+           previous_declaration->parent_scope->is_parameter &&
+           scope->depth == previous_declaration->parent_scope->depth + 1) {
                errorf(&declaration->source_position,
                        "declaration '%#T' redeclares the parameter '%#T' (declared %P)",
                        orig_type, symbol, previous_declaration->type, symbol,
@@ -4801,7 +4784,7 @@ static void parse_kr_declaration_list(declaration_t *declaration)
        add_anchor_token('{');
 
        /* push function parameters */
-       int       top        = environment_top();
+       size_t const top = environment_top();
        scope_push(&declaration->scope);
 
        declaration_t *parameter = declaration->scope.declarations;
@@ -5516,7 +5499,7 @@ static void parse_external_declaration(void)
        type = skip_typeref(declaration->type);
 
        /* push function parameters and switch scope */
-       int top = environment_top();
+       size_t const top = environment_top();
        scope_push(&declaration->scope);
 
        declaration_t *parameter = declaration->scope.declarations;
@@ -9201,7 +9184,7 @@ static statement_t *parse_for(void)
 
        PUSH_PARENT(statement);
 
-       int top = environment_top();
+       size_t const top = environment_top();
        scope_push(&statement->fors.scope);
 
        expect('(');
@@ -9814,8 +9797,8 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
        eat('{');
        add_anchor_token('}');
 
-       int top       = environment_top();
-       int top_local = local_label_top();
+       size_t const top       = environment_top();
+       size_t const top_local = local_label_top();
        scope_push(&statement->compound.scope);
 
        statement_t **anchor            = &statement->compound.statements;