TYPE_QUALIFIERS \
TYPE_SPECIFIERS
-#define TYPENAME_START \
- TYPE_QUALIFIERS \
- TYPE_SPECIFIERS
-
#define EXPRESSION_START \
case '!': \
case '&': \
switch (token.type) {
case T_IDENTIFIER:
if (is_typedef_symbol(token.symbol)) {
- TYPENAME_START
+ DECLARATION_START
type = parse_typename();
} else {
default:
entity->base.symbol, &entity->base.source_position);
}
-static bool is_declaration_specifier(const token_t *token,
- bool only_specifiers_qualifiers)
+static bool is_declaration_specifier(const token_t *token)
{
switch (token->type) {
- TYPE_SPECIFIERS
- TYPE_QUALIFIERS
+ DECLARATION_START
return true;
case T_IDENTIFIER:
return is_typedef_symbol(token->symbol);
- case T___extension__:
- STORAGE_CLASSES
- return !only_specifiers_qualifiers;
-
default:
return false;
}
case T_IDENTIFIER:
if (is_typedef_symbol(la1->symbol)) {
- TYPE_QUALIFIERS
- TYPE_SPECIFIERS
+ DECLARATION_START
return parse_cast();
}
}
return parse_reference();
}
/* FALLTHROUGH */
- TYPENAME_START {
- source_position_t const pos = *HERE;
- type_t const *const type = parse_typename();
+ DECLARATION_START {
+ source_position_t const pos = *HERE;
+ declaration_specifiers_t specifiers;
+ parse_declaration_specifiers(&specifiers);
+ type_t const *const type = parse_abstract_declarator(specifiers.type);
errorf(&pos, "encountered type '%T' while parsing expression", type);
return create_invalid_expression();
}
type_t *orig_type;
expression_t *expression;
- if (token.type == '(' && is_declaration_specifier(look_ahead(1), true)) {
+ if (token.type == '(' && is_declaration_specifier(look_ahead(1))) {
next_token();
add_anchor_token(')');
orig_type = parse_typename();
}
if (next_if(';')) {
- } else if (is_declaration_specifier(&token, false)) {
+ } else if (is_declaration_specifier(&token)) {
parse_declaration(record_entity, DECL_FLAGS_NONE);
} else {
add_anchor_token(';');