aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2019-09-30 16:27:17 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-06-18 22:02:01 +0200
commit05e59dea673e07ab9a5ef98946d57857bf335c26 (patch)
treed57df17621fe8e40018e8c21586b90f208f8d863
parentbe9df1ee611da4eb40ca77f51eb64388b53ca58c (diff)
downloadsparse-05e59dea673e07ab9a5ef98946d57857bf335c26.tar.gz
pre-process: make __has_{attribute,builtin}() true builtin macros
The macros __has_atribute() & __has_builtin() are only expanded in the context of a preprocessor conditional but they should be expanded like usual user defined macros. Fix this by using the new infrastructure for builtin macros. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--ident-list.h2
-rw-r--r--lib.c2
-rw-r--r--pre-process.c84
3 files changed, 32 insertions, 56 deletions
diff --git a/ident-list.h b/ident-list.h
index a3a28258..8049b694 100644
--- a/ident-list.h
+++ b/ident-list.h
@@ -59,8 +59,6 @@ IDENT_RESERVED(__label__);
* sparse. */
IDENT(defined);
IDENT(once);
-IDENT(__has_attribute);
-IDENT(__has_builtin);
IDENT(c_alignas);
IDENT(c_alignof);
IDENT(c_generic_selections);
diff --git a/lib.c b/lib.c
index 8f071bfe..7ba758bc 100644
--- a/lib.c
+++ b/lib.c
@@ -1452,8 +1452,6 @@ static void create_builtin_stream(void)
add_pre_buffer("#add_system \"%s/include\"\n", gcc_base_dir);
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");
diff --git a/pre-process.c b/pre-process.c
index 7a39b171..38167802 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -160,18 +160,6 @@ static void replace_with_defined(struct token *token)
replace_with_bool(token, token_defined(token));
}
-static void replace_with_has_builtin(struct token *token)
-{
- struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL);
- 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);
@@ -1609,14 +1597,6 @@ static int expression_value(struct token **where)
state = 1;
beginning = list;
break;
- } else if (p->ident == &__has_builtin_ident) {
- state = 4;
- beginning = list;
- break;
- } else if (p->ident == &__has_attribute_ident) {
- state = 6;
- beginning = list;
- break;
}
if (!expand_one_symbol(list))
continue;
@@ -1647,38 +1627,6 @@ static int expression_value(struct token **where)
sparse_error(p->pos, "missing ')' after \"defined\"");
*list = p->next;
continue;
-
- // __has_builtin(x) or __has_attribute(x)
- case 4: case 6:
- if (match_op(p, '(')) {
- state++;
- } else {
- sparse_error(p->pos, "missing '(' after \"__has_%s\"",
- state == 4 ? "builtin" : "attribute");
- state = 0;
- }
- *beginning = p;
- break;
- 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_%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 8:
- state = 0;
- *list = p->next;
- continue;
}
list = &p->next;
}
@@ -2003,6 +1951,36 @@ static int handle_nondirective(struct stream *stream, struct token **line, struc
return 1;
}
+static bool expand_has_attribute(struct token *token, struct arg *args)
+{
+ struct token *arg = args[0].expanded;
+ struct symbol *sym;
+
+ if (token_type(arg) != TOKEN_IDENT) {
+ sparse_error(arg->pos, "identifier expected");
+ return false;
+ }
+
+ sym = lookup_symbol(arg->ident, NS_KEYWORD);
+ replace_with_bool(token, sym && sym->op && sym->op->attribute);
+ return true;
+}
+
+static bool expand_has_builtin(struct token *token, struct arg *args)
+{
+ struct token *arg = args[0].expanded;
+ struct symbol *sym;
+
+ if (token_type(arg) != TOKEN_IDENT) {
+ sparse_error(arg->pos, "identifier expected");
+ return false;
+ }
+
+ sym = lookup_symbol(arg->ident, NS_SYMBOL);
+ replace_with_bool(token, sym && sym->builtin);
+ return true;
+}
+
static bool expand_has_extension(struct token *token, struct arg *args)
{
struct token *arg = args[0].expanded;
@@ -2133,6 +2111,8 @@ static void init_preprocessor(void)
{ "__TIME__", expand_time },
{ "__COUNTER__", expand_counter },
{ "__INCLUDE_LEVEL__", expand_include_level },
+ { "__has_attribute", NULL, expand_has_attribute },
+ { "__has_builtin", NULL, expand_has_builtin },
{ "__has_extension", NULL, expand_has_extension },
{ "__has_feature", NULL, expand_has_feature },
};