Remove duplicate word from error message.
[cparser] / parser.c
index 94982af..d517bd8 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -109,6 +109,12 @@ static declaration_t      **incomplete_arrays;
 static elf_visibility_tag_t default_visibility = ELF_VISIBILITY_DEFAULT;
 
 
+#define PUSH_CURRENT_ENTITY(entity) \
+       entity_t *const new_current_entity = (entity); \
+       entity_t *const old_current_entity = current_entity; \
+       ((void)(current_entity = new_current_entity))
+#define POP_CURRENT_ENTITY() (assert(current_entity == new_current_entity), (void)(current_entity = old_current_entity))
+
 #define PUSH_PARENT(stmt) \
        statement_t *const new_parent = (stmt); \
        statement_t *const old_parent = current_parent; \
@@ -242,10 +248,7 @@ static void semantic_comparison(binary_expression_t *expression);
        case T_ANDAND:                    \
        case T_CHARACTER_CONSTANT:        \
        case T_FLOATINGPOINT:             \
-       case T_FLOATINGPOINT_HEXADECIMAL: \
        case T_INTEGER:                   \
-       case T_INTEGER_HEXADECIMAL:       \
-       case T_INTEGER_OCTAL:             \
        case T_MINUSMINUS:                \
        case T_PLUSPLUS:                  \
        case T_STRING_LITERAL:            \
@@ -324,10 +327,7 @@ static size_t get_expression_struct_size(expression_kind_t kind)
                [EXPR_ENUM_CONSTANT]              = sizeof(reference_expression_t),
                [EXPR_LITERAL_BOOLEAN]            = sizeof(literal_expression_t),
                [EXPR_LITERAL_INTEGER]            = sizeof(literal_expression_t),
-               [EXPR_LITERAL_INTEGER_OCTAL]      = sizeof(literal_expression_t),
-               [EXPR_LITERAL_INTEGER_HEXADECIMAL]= sizeof(literal_expression_t),
                [EXPR_LITERAL_FLOATINGPOINT]      = sizeof(literal_expression_t),
-               [EXPR_LITERAL_FLOATINGPOINT_HEXADECIMAL] = sizeof(literal_expression_t),
                [EXPR_LITERAL_CHARACTER]          = sizeof(literal_expression_t),
                [EXPR_LITERAL_WIDE_CHARACTER]     = sizeof(literal_expression_t),
                [EXPR_STRING_LITERAL]             = sizeof(string_literal_expression_t),
@@ -658,7 +658,7 @@ static symbol_t *expect_identifier(char const *const context, source_position_t
                if (token.kind != T_IDENTIFIER)
                        return NULL;
        }
-       symbol_t *const sym = token.identifier.symbol;
+       symbol_t *const sym = token.base.symbol;
        if (pos)
                *pos = *HERE;
        eat(T_IDENTIFIER);
@@ -1104,9 +1104,8 @@ static attribute_argument_t *parse_attribute_arguments(void)
                /* is it an identifier */
                if (token.kind == T_IDENTIFIER
                                && (look_ahead(1)->kind == ',' || look_ahead(1)->kind == ')')) {
-                       symbol_t *symbol   = token.identifier.symbol;
                        argument->kind     = ATTRIBUTE_ARGUMENT_SYMBOL;
-                       argument->v.symbol = symbol;
+                       argument->v.symbol = token.base.symbol;
                        next_token();
                } else {
                        /* must be an expression */
@@ -1133,30 +1132,10 @@ static attribute_t *parse_attribute_asm(void)
        return attribute;
 }
 
-static symbol_t *get_symbol_from_token(void)
-{
-       switch(token.kind) {
-       case T_CHARACTER_CONSTANT:
-       case T_EOF:
-       case T_FLOATINGPOINT:
-       case T_FLOATINGPOINT_HEXADECIMAL:
-       case T_INTEGER:
-       case T_INTEGER_HEXADECIMAL:
-       case T_INTEGER_OCTAL:
-       case T_STRING_LITERAL:
-       case T_WIDE_CHARACTER_CONSTANT:
-       case T_WIDE_STRING_LITERAL:
-               return NULL;
-
-       default:
-               return token.identifier.symbol;
-       }
-}
-
 static attribute_t *parse_attribute_gnu_single(void)
 {
        /* parse "any-word" */
-       symbol_t *symbol = get_symbol_from_token();
+       symbol_t *const symbol = token.base.symbol;
        if (symbol == NULL) {
                parse_error_expected("while parsing attribute((", T_IDENTIFIER, NULL);
                return NULL;
@@ -1999,7 +1978,7 @@ static initializer_t *parse_sub_initializer(type_path_t *path,
                        /* GNU-style designator ("identifier: value") */
                        designator = allocate_ast_zero(sizeof(designator[0]));
                        designator->source_position = token.base.source_position;
-                       designator->symbol          = token.identifier.symbol;
+                       designator->symbol          = token.base.symbol;
                        eat(T_IDENTIFIER);
                        eat(':');
 
@@ -2028,9 +2007,7 @@ finish_designator:
                        } else {
                                if (type == NULL) {
                                        if (env->entity != NULL) {
-                                               errorf(HERE,
-                                                    "extra brace group at end of initializer for '%Y'",
-                                                    env->entity->base.symbol);
+                                               errorf(HERE, "extra brace group at end of initializer for '%N'", env->entity);
                                        } else {
                                                errorf(HERE, "extra brace group at end of initializer");
                                        }
@@ -2075,7 +2052,7 @@ finish_designator:
 
                                source_position_t const* const pos = &expression->base.source_position;
                                if (env->entity != NULL) {
-                                       warningf(WARN_OTHER, pos, "excess elements in initializer for '%Y'", env->entity->base.symbol);
+                                       warningf(WARN_OTHER, pos, "excess elements in initializer for '%N'", env->entity);
                                } else {
                                        warningf(WARN_OTHER, pos, "excess elements in initializer");
                                }
@@ -2292,7 +2269,7 @@ static compound_t *parse_compound_type_specifier(bool is_struct)
        entity_kind_tag_t const kind = is_struct ? ENTITY_STRUCT : ENTITY_UNION;
        if (token.kind == T_IDENTIFIER) {
                /* the compound has a name, check if we have seen it already */
-               symbol = token.identifier.symbol;
+               symbol = token.base.symbol;
                entity = get_tag(symbol, kind);
                next_token();
 
@@ -2391,7 +2368,7 @@ static type_t *parse_enum_specifier(void)
        eat(T_enum);
        switch (token.kind) {
                case T_IDENTIFIER:
-                       symbol = token.identifier.symbol;
+                       symbol = token.base.symbol;
                        entity = get_tag(symbol, ENTITY_ENUM);
                        next_token();
 
@@ -2472,7 +2449,7 @@ static type_t *parse_typeof(void)
 
        switch (token.kind) {
        case T_IDENTIFIER:
-               if (is_typedef_symbol(token.identifier.symbol)) {
+               if (is_typedef_symbol(token.base.symbol)) {
        DECLARATION_START
                        type = parse_typename();
                } else {
@@ -2575,7 +2552,7 @@ static attribute_t *parse_microsoft_extended_decl_modifier_single(void)
        if (next_if(T_restrict)) {
                kind = ATTRIBUTE_MS_RESTRICT;
        } else if (token.kind == T_IDENTIFIER) {
-               const char *name = token.identifier.symbol->string;
+               char const *const name = token.base.symbol->string;
                for (attribute_kind_t k = ATTRIBUTE_MS_FIRST; k <= ATTRIBUTE_MS_LAST;
                     ++k) {
                        const char *attribute_name = get_attribute_name(k);
@@ -2835,7 +2812,7 @@ wrong_thread_storage_class:
                                }
                        }
 
-                       type_t *const typedef_type = get_typedef_type(token.identifier.symbol);
+                       type_t *const typedef_type = get_typedef_type(token.base.symbol);
                        if (typedef_type == NULL) {
                                /* Be somewhat resilient to typos like 'vodi f()' at the beginning of a
                                 * declaration, so it doesn't generate 'implicit int' followed by more
@@ -2848,9 +2825,7 @@ wrong_thread_storage_class:
                                        case '*': {
                                                errorf(HERE, "%K does not name a type", &token);
 
-                                               symbol_t *symbol = token.identifier.symbol;
-                                               entity_t *entity
-                                                       = create_error_entity(symbol, ENTITY_TYPEDEF);
+                                               entity_t *const entity = create_error_entity(token.base.symbol, ENTITY_TYPEDEF);
 
                                                type = allocate_type_zero(TYPE_TYPEDEF);
                                                type->typedeft.typedefe = &entity->typedefe;
@@ -3101,7 +3076,7 @@ static void parse_identifier_list(scope_t *scope)
 {
        assert(token.kind == T_IDENTIFIER);
        do {
-               entity_t *const entity = allocate_entity_zero(ENTITY_PARAMETER, NAMESPACE_NORMAL, token.identifier.symbol, HERE);
+               entity_t *const entity = allocate_entity_zero(ENTITY_PARAMETER, NAMESPACE_NORMAL, token.base.symbol, HERE);
                /* a K&R parameter has no type, yet */
                next_token();
 
@@ -3141,8 +3116,7 @@ static bool has_parameters(void)
        if (look_ahead(1)->kind != ')')
                return true;
        if (token.kind == T_IDENTIFIER) {
-               entity_t const *const entity
-                       = get_entity(token.identifier.symbol, NAMESPACE_NORMAL);
+               entity_t const *const entity = get_entity(token.base.symbol, NAMESPACE_NORMAL);
                if (entity == NULL)
                        return true;
                if (entity->kind != ENTITY_TYPEDEF)
@@ -3174,8 +3148,8 @@ static void parse_parameters(function_type_t *type, scope_t *scope)
        eat('(');
        add_anchor_token(')');
 
-       if (token.kind == T_IDENTIFIER                  &&
-           !is_typedef_symbol(token.identifier.symbol) &&
+       if (token.kind == T_IDENTIFIER            &&
+           !is_typedef_symbol(token.base.symbol) &&
            (look_ahead(1)->kind == ',' || look_ahead(1)->kind == ')')) {
                type->kr_style_parameters = true;
                parse_identifier_list(scope);
@@ -3430,7 +3404,7 @@ ptr_operator_end: ;
                if (env->must_be_abstract) {
                        errorf(HERE, "no identifier expected in typename");
                } else {
-                       env->symbol          = token.identifier.symbol;
+                       env->symbol          = token.base.symbol;
                        env->source_position = token.base.source_position;
                }
                next_token();
@@ -3441,7 +3415,7 @@ ptr_operator_end: ;
                token_t const *const la1 = look_ahead(1);
                switch (la1->kind) {
                        case T_IDENTIFIER:
-                               if (is_typedef_symbol(la1->identifier.symbol)) {
+                               if (is_typedef_symbol(la1->base.symbol)) {
                        case ')':
                                        /* ยง6.7.6:2 footnote 126:  Empty parentheses in a type name are
                                         * interpreted as ``function with no parameter specification'', rather
@@ -3713,15 +3687,12 @@ static entity_t *parse_declarator(const declaration_specifiers_t *specifiers,
 
                        if (env.symbol != NULL) {
                                if (specifiers->is_inline && is_type_valid(type)) {
-                                       errorf(&env.source_position,
-                                                       "compound member '%Y' declared 'inline'", env.symbol);
+                                       errorf(&env.source_position, "'%N' declared 'inline'", entity);
                                }
 
                                if (specifiers->thread_local ||
                                                specifiers->storage_class != STORAGE_CLASS_NONE) {
-                                       errorf(&env.source_position,
-                                                       "compound member '%Y' must have no storage class",
-                                                       env.symbol);
+                                       errorf(&env.source_position, "'%N' must have no storage class", entity);
                                }
                        }
                } else if (flags & DECL_IS_PARAMETER) {
@@ -3769,7 +3740,7 @@ static entity_t *parse_declarator(const declaration_specifiers_t *specifiers,
                                        }
                                }
                                if (invalid_storage_class) {
-                                       errorf(&env.source_position, "invalid storage class for variable '%N'", entity);
+                                       errorf(&env.source_position, "invalid storage class for '%N'", entity);
                                }
                        }
                }
@@ -3880,14 +3851,6 @@ warn_arg_count:
        }
 }
 
-/**
- * Check if a symbol is the equal to "main".
- */
-static bool is_sym_main(const symbol_t *const sym)
-{
-       return streq(sym->string, "main");
-}
-
 static void error_redefined_as_different_kind(const source_position_t *pos,
                const entity_t *old, entity_kind_t new_kind)
 {
@@ -3947,6 +3910,8 @@ static void merge_in_attributes(declaration_t *decl, attribute_t *attributes)
        }
 }
 
+static bool is_main(entity_t*);
+
 /**
  * record entities for the NAMESPACE_NORMAL, and produce error messages/warnings
  * for various problems that occur for multiple definitions
@@ -3961,6 +3926,10 @@ entity_t *record_entity(entity_t *entity, const bool is_definition)
        if (symbol == NULL)
                return entity;
 
+       assert(!entity->base.parent_scope);
+       assert(current_scope);
+       entity->base.parent_scope = current_scope;
+
        entity_t *const previous_entity = get_entity(symbol, namespc);
        /* pushing the same entity twice will break the stack structure */
        assert(previous_entity != entity);
@@ -3976,7 +3945,7 @@ entity_t *record_entity(entity_t *entity, const bool is_definition)
                        warningf(WARN_STRICT_PROTOTYPES, pos, "function declaration '%#N' is not a prototype", entity);
                }
 
-               if (current_scope == file_scope && is_sym_main(symbol)) {
+               if (is_main(entity)) {
                        check_main(entity);
                }
        }
@@ -4080,7 +4049,7 @@ entity_t *record_entity(entity_t *entity, const bool is_definition)
 
                                                case STORAGE_CLASS_EXTERN:
                                                        if (is_definition) {
-                                                               if (prev_type->function.unspecified_parameters && !is_sym_main(symbol)) {
+                                                               if (prev_type->function.unspecified_parameters && !is_main(entity)) {
                                                                        warningf(WARN_MISSING_PROTOTYPES, pos, "no previous prototype for '%#N'", entity);
                                                                }
                                                        } else if (new_storage_class == STORAGE_CLASS_NONE) {
@@ -4107,12 +4076,12 @@ warn_redundant_declaration: ;
                                        } else if (!is_definition        &&
                                                        is_type_valid(prev_type) &&
                                                        !pos->is_system_header) {
-                                               warningf(WARN_REDUNDANT_DECLS, pos, "redundant declaration for '%Y' (declared %P)", symbol, ppos);
+                                               warningf(WARN_REDUNDANT_DECLS, pos, "redundant declaration for '%N' (declared %P)", entity, ppos);
                                        }
                                } else if (current_function == NULL) {
                                        if (old_storage_class != STORAGE_CLASS_STATIC &&
                                                        new_storage_class == STORAGE_CLASS_STATIC) {
-                                               errorf(pos, "static declaration of '%Y' follows non-static declaration (declared %P)", symbol, ppos);
+                                               errorf(pos, "static declaration of '%N' follows non-static declaration (declared %P)", entity, ppos);
                                        } else if (old_storage_class == STORAGE_CLASS_EXTERN) {
                                                prev_decl->storage_class          = STORAGE_CLASS_NONE;
                                                prev_decl->declared_storage_class = STORAGE_CLASS_NONE;
@@ -4125,9 +4094,9 @@ warn_redundant_declaration: ;
                                } else if (is_type_valid(prev_type)) {
                                        if (old_storage_class == new_storage_class) {
 error_redeclaration:
-                                               errorf(pos, "redeclaration of '%Y' (declared %P)", symbol, ppos);
+                                               errorf(pos, "redeclaration of '%N' (declared %P)", entity, ppos);
                                        } else {
-                                               errorf(pos, "redeclaration of '%Y' with different linkage (declared %P)", symbol, ppos);
+                                               errorf(pos, "redeclaration of '%N' with different linkage (declared %P)", entity, ppos);
                                        }
                                }
                        }
@@ -4150,7 +4119,7 @@ error_redeclaration:
        if (entity->kind == ENTITY_FUNCTION) {
                if (is_definition &&
                                entity->declaration.storage_class != STORAGE_CLASS_STATIC &&
-                               !is_sym_main(symbol)) {
+                               !is_main(entity)) {
                        if (is_warn_on(WARN_MISSING_PROTOTYPES)) {
                                warningf(WARN_MISSING_PROTOTYPES, pos, "no previous prototype for '%#N'", entity);
                        } else {
@@ -4167,10 +4136,6 @@ warn_missing_declaration:
        }
 
 finish:
-       assert(entity->base.parent_scope == NULL);
-       assert(current_scope != NULL);
-
-       entity->base.parent_scope = current_scope;
        environment_push(entity);
        append_entity(current_scope, entity);
 
@@ -4180,8 +4145,7 @@ finish:
 static void parser_error_multiple_definition(entity_t *entity,
                const source_position_t *source_position)
 {
-       errorf(source_position, "multiple definition of '%Y' (declared %P)",
-              entity->base.symbol, &entity->base.source_position);
+       errorf(source_position, "redefinition of '%N' (declared %P)", entity, &entity->base.source_position);
 }
 
 static bool is_declaration_specifier(const token_t *token)
@@ -4190,7 +4154,7 @@ static bool is_declaration_specifier(const token_t *token)
                DECLARATION_START
                        return true;
                case T_IDENTIFIER:
-                       return is_typedef_symbol(token->identifier.symbol);
+                       return is_typedef_symbol(token->base.symbol);
 
                default:
                        return false;
@@ -4616,11 +4580,7 @@ static void check_declarations(void)
 {
        if (is_warn_on(WARN_UNUSED_PARAMETER)) {
                const scope_t *scope = &current_function->parameters;
-
-               /* do not issue unused warnings for main */
-               if (!is_sym_main(current_function->base.base.symbol)) {
-                       warn_unused_entity(WARN_UNUSED_PARAMETER, scope->entities, NULL);
-               }
+               warn_unused_entity(WARN_UNUSED_PARAMETER, scope->entities, NULL);
        }
        if (is_warn_on(WARN_UNUSED_VARIABLE)) {
                walk_statements(current_function->statement, check_unused_variables,
@@ -5037,7 +4997,7 @@ found_break_parent:
                        type_t *const ret  = skip_typeref(type->function.return_type);
                        if (!is_type_void(ret) &&
                            is_type_valid(ret) &&
-                           !is_sym_main(current_function->base.base.symbol)) {
+                           !is_main(current_entity)) {
                                source_position_t const *const pos = &stmt->base.source_position;
                                warningf(WARN_RETURN_TYPE, pos, "control reaches end of non-void function");
                        }
@@ -5253,6 +5213,8 @@ static bool is_main(entity_t *entity)
        return true;
 }
 
+static void prepare_main_collect2(entity_t*);
+
 static void parse_external_declaration(void)
 {
        /* function-definitions and declarations both start with declaration
@@ -5346,8 +5308,6 @@ static void parse_external_declaration(void)
        if (ndeclaration != entity) {
                function->parameters = ndeclaration->function.parameters;
        }
-       assert(is_declaration(entity));
-       type = skip_typeref(entity->declaration.type);
 
        PUSH_SCOPE(&function->parameters);
 
@@ -5373,9 +5333,8 @@ static void parse_external_declaration(void)
                /* parse function body */
                int         label_stack_top      = label_top();
                function_t *old_current_function = current_function;
-               entity_t   *old_current_entity   = current_entity;
                current_function                 = function;
-               current_entity                   = entity;
+               PUSH_CURRENT_ENTITY(entity);
                PUSH_PARENT(NULL);
 
                goto_first   = NULL;
@@ -5402,13 +5361,23 @@ static void parse_external_declaration(void)
                        }
                }
 
-               if (is_main(entity) && enable_main_collect2_hack)
-                       prepare_main_collect2(entity);
+               if (is_main(entity)) {
+                       /* Force main to C linkage. */
+                       type_t *const type = entity->declaration.type;
+                       assert(is_type_function(type));
+                       if (type->function.linkage != LINKAGE_C) {
+                               type_t *new_type           = duplicate_type(type);
+                               new_type->function.linkage = LINKAGE_C;
+                               entity->declaration.type   = identify_new_type(new_type);
+                       }
+
+                       if (enable_main_collect2_hack)
+                               prepare_main_collect2(entity);
+               }
 
+               POP_CURRENT_ENTITY();
                POP_PARENT();
                assert(current_function == function);
-               assert(current_entity   == entity);
-               current_entity   = old_current_entity;
                current_function = old_current_function;
                label_pop_to(label_stack_top);
        }
@@ -5620,7 +5589,7 @@ static void parse_compound_declarators(compound_t *compound,
                                        entity_t *prev = find_compound_entry(compound, symbol);
                                        if (prev != NULL) {
                                                source_position_t const *const ppos = &prev->base.source_position;
-                                               errorf(pos, "multiple declarations of symbol '%Y' (declared %P)", symbol, ppos);
+                                               errorf(pos, "multiple declarations of '%N' (declared %P)", entity, ppos);
                                        }
                                }
 
@@ -5857,24 +5826,12 @@ static expression_t *parse_number_literal(void)
                check_integer_suffix();
                type = type_int;
                break;
-       case T_INTEGER_OCTAL:
-               kind = EXPR_LITERAL_INTEGER_OCTAL;
-               check_integer_suffix();
-               type = type_int;
-               break;
-       case T_INTEGER_HEXADECIMAL:
-               kind = EXPR_LITERAL_INTEGER_HEXADECIMAL;
-               check_integer_suffix();
-               type = type_int;
-               break;
+
        case T_FLOATINGPOINT:
                kind = EXPR_LITERAL_FLOATINGPOINT;
                type = check_floatingpoint_suffix();
                break;
-       case T_FLOATINGPOINT_HEXADECIMAL:
-               kind = EXPR_LITERAL_FLOATINGPOINT_HEXADECIMAL;
-               type = check_floatingpoint_suffix();
-               break;
+
        default:
                panic("unexpected token type in parse_number_literal");
        }
@@ -6105,9 +6062,8 @@ static entity_t *parse_qualified_identifier(void)
        if (entity == NULL) {
                if (!strict_mode && token.kind == '(') {
                        /* an implicitly declared function */
-                       warningf(WARN_IMPLICIT_FUNCTION_DECLARATION, &pos,
-                                "implicit declaration of function '%Y'", symbol);
                        entity = create_implicit_function(symbol, &pos);
+                       warningf(WARN_IMPLICIT_FUNCTION_DECLARATION, &pos, "implicit declaration of '%N'", entity);
                } else {
                        errorf(&pos, "unknown identifier '%Y' found.", symbol);
                        entity = create_error_entity(symbol, ENTITY_VARIABLE);
@@ -6310,7 +6266,7 @@ static expression_t *parse_parenthesized_expression(void)
                return parse_statement_expression();
 
        case T_IDENTIFIER:
-               if (is_typedef_symbol(la1->identifier.symbol)) {
+               if (is_typedef_symbol(la1->base.symbol)) {
        DECLARATION_START
                        return parse_cast();
                }
@@ -6689,7 +6645,7 @@ static label_t *get_label(void)
        assert(token.kind == T_IDENTIFIER);
        assert(current_function != NULL);
 
-       entity_t *label = get_entity(token.identifier.symbol, NAMESPACE_LABEL);
+       entity_t *label = get_entity(token.base.symbol, NAMESPACE_LABEL);
        /* If we find a local label, we already created the declaration. */
        if (label != NULL && label->kind == ENTITY_LOCAL_LABEL) {
                if (label->base.parent_scope != current_scope) {
@@ -6699,7 +6655,7 @@ static label_t *get_label(void)
        } else if (label == NULL || label->base.parent_scope != &current_function->parameters) {
                /* There is no matching label in the same function, so create a new one. */
                source_position_t const nowhere = { NULL, 0, 0, false };
-               label = allocate_entity_zero(ENTITY_LABEL, NAMESPACE_LABEL, token.identifier.symbol, &nowhere);
+               label = allocate_entity_zero(ENTITY_LABEL, NAMESPACE_LABEL, token.base.symbol, &nowhere);
                label_push(label);
        }
 
@@ -6772,10 +6728,7 @@ static expression_t *parse_primary_expression(void)
        case T_false:                        return parse_boolean_literal(false);
        case T_true:                         return parse_boolean_literal(true);
        case T_INTEGER:
-       case T_INTEGER_OCTAL:
-       case T_INTEGER_HEXADECIMAL:
-       case T_FLOATINGPOINT:
-       case T_FLOATINGPOINT_HEXADECIMAL:    return parse_number_literal();
+       case T_FLOATINGPOINT:                return parse_number_literal();
        case T_CHARACTER_CONSTANT:           return parse_character_constant();
        case T_WIDE_CHARACTER_CONSTANT:      return parse_wide_character_constant();
        case T_STRING_LITERAL:
@@ -6810,7 +6763,7 @@ static expression_t *parse_primary_expression(void)
        case T_COLONCOLON:
                return parse_reference();
        case T_IDENTIFIER:
-               if (!is_typedef_symbol(token.identifier.symbol)) {
+               if (!is_typedef_symbol(token.base.symbol)) {
                        return parse_reference();
                }
                /* FALLTHROUGH */
@@ -8423,10 +8376,7 @@ static bool expression_has_effect(const expression_t *const expr)
                case EXPR_LITERAL_CHARACTER:
                case EXPR_LITERAL_WIDE_CHARACTER:
                case EXPR_LITERAL_INTEGER:
-               case EXPR_LITERAL_INTEGER_OCTAL:
-               case EXPR_LITERAL_INTEGER_HEXADECIMAL:
                case EXPR_LITERAL_FLOATINGPOINT:
-               case EXPR_LITERAL_FLOATINGPOINT_HEXADECIMAL: return false;
                case EXPR_STRING_LITERAL:             return false;
                case EXPR_WIDE_STRING_LITERAL:        return false;
 
@@ -9753,7 +9703,7 @@ static void parse_namespace_definition(void)
        symbol_t *symbol = NULL;
 
        if (token.kind == T_IDENTIFIER) {
-               symbol = token.identifier.symbol;
+               symbol = token.base.symbol;
                next_token();
 
                entity = get_entity(symbol, NAMESPACE_NORMAL);
@@ -9782,9 +9732,7 @@ static void parse_namespace_definition(void)
        append_entity(current_scope, entity);
 
        PUSH_SCOPE(&entity->namespacee.members);
-
-       entity_t     *old_current_entity = current_entity;
-       current_entity = entity;
+       PUSH_CURRENT_ENTITY(entity);
 
        add_anchor_token('}');
        expect('{');
@@ -9792,8 +9740,7 @@ static void parse_namespace_definition(void)
        rem_anchor_token('}');
        expect('}');
 
-       assert(current_entity == entity);
-       current_entity = old_current_entity;
+       POP_CURRENT_ENTITY();
        POP_SCOPE();
 }
 
@@ -9811,7 +9758,7 @@ static statement_t *intern_parse_statement(void)
                token_kind_t la1_type = (token_kind_t)look_ahead(1)->kind;
                if (la1_type == ':') {
                        statement = parse_label_statement();
-               } else if (is_typedef_symbol(token.identifier.symbol)) {
+               } else if (is_typedef_symbol(token.base.symbol)) {
                        statement = parse_declaration_statement();
                } else {
                        /* it's an identifier, the grammar says this must be an
@@ -9821,7 +9768,7 @@ static statement_t *intern_parse_statement(void)
                        switch (la1_type) {
                        case '&':
                        case '*':
-                               if (get_entity(token.identifier.symbol, NAMESPACE_NORMAL) != NULL) {
+                               if (get_entity(token.base.symbol, NAMESPACE_NORMAL) != NULL) {
                        default:
                                        statement = parse_expression_statement();
                                } else {
@@ -10402,7 +10349,7 @@ static void complete_incomplete_arrays(void)
        }
 }
 
-void prepare_main_collect2(entity_t *entity)
+static void prepare_main_collect2(entity_t *const entity)
 {
        PUSH_SCOPE(&entity->function.statement->compound.scope);