diff options
Diffstat (limited to 'pre-process.c')
| -rw-r--r-- | pre-process.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/pre-process.c b/pre-process.c index da4b7acd..bf4b8e76 100644 --- a/pre-process.c +++ b/pre-process.c @@ -165,6 +165,12 @@ static void replace_with_has_builtin(struct token *token) replace_with_bool(token, sym && sym->builtin); } +static void replace_with_has_attribute(struct token *token) +{ + struct symbol *sym = lookup_symbol(token->ident, NS_KEYWORD); + replace_with_bool(token, sym && sym->op && sym->op->attribute); +} + static void expand_line(struct token *token) { replace_with_integer(token, token->pos.line); @@ -1592,6 +1598,10 @@ static int expression_value(struct token **where) state = 4; beginning = list; break; + } else if (p->ident == &__has_attribute_ident) { + state = 6; + beginning = list; + break; } if (!expand_one_symbol(list)) continue; @@ -1623,29 +1633,34 @@ static int expression_value(struct token **where) *list = p->next; continue; - // __has_builtin(xyz) - case 4: + // __has_builtin(x) or __has_attribute(x) + case 4: case 6: if (match_op(p, '(')) { - state = 5; + state++; } else { - sparse_error(p->pos, "missing '(' after \"__has_builtin\""); + sparse_error(p->pos, "missing '(' after \"__has_%s\"", + state == 4 ? "builtin" : "attribute"); state = 0; } *beginning = p; break; - case 5: + case 5: case 7: if (token_type(p) != TOKEN_IDENT) { sparse_error(p->pos, "identifier expected"); state = 0; break; } if (!match_op(p->next, ')')) - sparse_error(p->pos, "missing ')' after \"__has_builtin\""); - state = 6; - replace_with_has_builtin(p); + sparse_error(p->pos, "missing ')' after \"__has_%s\"", + state == 5 ? "builtin" : "attribute"); + if (state == 5) + replace_with_has_builtin(p); + else + replace_with_has_attribute(p); + state = 8; *beginning = p; break; - case 6: + case 8: state = 0; *list = p->next; continue; |
