diff options
| -rw-r--r-- | ident-list.h | 1 | ||||
| -rw-r--r-- | lib.c | 1 | ||||
| -rw-r--r-- | parse.c | 4 | ||||
| -rw-r--r-- | pre-process.c | 33 | ||||
| -rw-r--r-- | validation/preprocessor/has-attribute.c | 56 |
5 files changed, 85 insertions, 10 deletions
diff --git a/ident-list.h b/ident-list.h index a37a4a1b..75740b9d 100644 --- a/ident-list.h +++ b/ident-list.h @@ -59,6 +59,7 @@ IDENT_RESERVED(__label__); * sparse. */ IDENT(defined); IDENT(once); +IDENT(__has_attribute); IDENT(__has_builtin); __IDENT(pragma_ident, "__pragma__", 0); __IDENT(__VA_ARGS___ident, "__VA_ARGS__", 0); @@ -1287,6 +1287,7 @@ static void create_builtin_stream(void) add_pre_buffer("#add_system \"%s/include-fixed\"\n", gcc_base_dir); add_pre_buffer("#define __has_builtin(x) 0\n"); + add_pre_buffer("#define __has_attribute(x) 0\n"); add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n"); add_pre_buffer("#define __builtin_ms_va_start(a,b) ((a) = (__builtin_ms_va_list)(&(b)))\n"); @@ -531,9 +531,10 @@ static struct init_keyword { { "bitwise", NS_KEYWORD, MOD_BITWISE, .op = &attr_bitwise_op }, { "__bitwise__",NS_KEYWORD, MOD_BITWISE, .op = &attr_bitwise_op }, { "address_space",NS_KEYWORD, .op = &address_space_op }, - { "mode", NS_KEYWORD, .op = &mode_op }, { "context", NS_KEYWORD, .op = &context_op }, { "designated_init", NS_KEYWORD, .op = &designated_init_op }, + { "__designated_init__", NS_KEYWORD, .op = &designated_init_op }, + { "transparent_union", NS_KEYWORD, .op = &transparent_union_op }, { "__transparent_union__", NS_KEYWORD, .op = &transparent_union_op }, { "noreturn", NS_KEYWORD, MOD_NORETURN, .op = &attr_mod_op }, { "__noreturn__", NS_KEYWORD, MOD_NORETURN, .op = &attr_mod_op }, @@ -543,6 +544,7 @@ static struct init_keyword { {"__const", NS_KEYWORD, MOD_PURE, .op = &attr_mod_op }, {"__const__", NS_KEYWORD, MOD_PURE, .op = &attr_mod_op }, + { "mode", NS_KEYWORD, .op = &mode_op }, { "__mode__", NS_KEYWORD, .op = &mode_op }, { "QI", NS_KEYWORD, .op = &mode_QI_op }, { "__QI__", NS_KEYWORD, .op = &mode_QI_op }, 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; diff --git a/validation/preprocessor/has-attribute.c b/validation/preprocessor/has-attribute.c new file mode 100644 index 00000000..3149cbfa --- /dev/null +++ b/validation/preprocessor/has-attribute.c @@ -0,0 +1,56 @@ +#ifndef __has_attribute +__has_attribute()??? Quesako? +#define __has_attribute(x) 0 +#else +"has __has_attribute(), yeah!" +#endif + +123 __has_attribute(nothinx) def + +#if __has_attribute(nothinx) +#error "not a attribute!" +#endif + +#if 1 \ + && __has_attribute(packed) \ + && __has_attribute(aligned) \ + && __has_attribute(const) \ + && __has_attribute(pure) \ + && __has_attribute(noreturn) \ + && __has_attribute(designated_init) \ + && __has_attribute(transparent_union) \ + +"ok gcc" +#endif + +#if 1 \ + && __has_attribute(fastcall) \ + +"ok gcc ignore" +#endif + +#if 1 \ + && __has_attribute(nocast) \ + && __has_attribute(noderef) \ + && __has_attribute(safe) \ + && __has_attribute(force) \ + && __has_attribute(bitwise) \ + && __has_attribute(address_space) \ + && __has_attribute(context) \ + +"ok sparse specific" +#endif + +/* + * check-name: has-attribute + * check-command: sparse -E $file + * + * check-output-start + +"has __has_attribute(), yeah!" +123 0 def +"ok gcc" +"ok gcc ignore" +"ok sparse specific" + * check-output-end + */ |
