[PATCH 3/5] pre-process: add support for builtin macros

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Sparse support the expansion of one-symbol-builtin macros like __FILE__.
It also support builtin macros with an argument, like 'defined()'
or '__has_attribute()'.

However, these last one are only expanded inside a pre-processor
conditional expression. This is correct for 'defined()' but macros
like '__has_attribute()' should be expanded in all contexts,
like user defined macros.

So, add support for the general expansion of such macros.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 pre-process.c | 34 ++++++++++++++++++++++++++++++++++
 symbol.h      |  2 ++
 2 files changed, 36 insertions(+)

diff --git a/pre-process.c b/pre-process.c
index 059a7c1d9b7b..d2e13400711e 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -777,6 +777,9 @@ static int expand(struct token **list, struct symbol *sym)
 		expand_arguments(nargs, args);
 	}
 
+	if (sym->expand)
+		return sym->expand(token, args) ? 0 : 1;
+
 	expanding->tainted = 1;
 
 	last = token->next;
@@ -2000,6 +2003,34 @@ static int handle_nondirective(struct stream *stream, struct token **line, struc
 	return 1;
 }
 
+static void create_arglist(struct symbol *sym, int count)
+{
+	struct token *token;
+	struct token **next;
+
+	if (!count)
+		return;
+
+	token = __alloc_token(0);
+	token_type(token) = TOKEN_ARG_COUNT;
+	token->count.normal = count;
+	sym->arglist = token;
+	next = &token->next;
+
+	while (count--) {
+		struct token *id, *uses;
+		id = __alloc_token(0);
+		token_type(id) = TOKEN_IDENT;
+		uses = __alloc_token(0);
+		token_type(uses) = TOKEN_ARG_COUNT;
+		uses->count.normal = 1;
+
+		*next = id;
+		id->next = uses;
+		next = &uses->next;
+	}
+	*next = &eof_token_entry;
+}
 
 static void init_preprocessor(void)
 {
@@ -2041,6 +2072,7 @@ static void init_preprocessor(void)
 	static struct {
 		const char *name;
 		void (*expand_simple)(struct token *);
+		bool (*expand)(struct token *, struct arg *args);
 	} dynamic[] = {
 		{ "__LINE__",		expand_line },
 		{ "__FILE__",		expand_file },
@@ -2067,6 +2099,8 @@ static void init_preprocessor(void)
 		struct symbol *sym;
 		sym = create_symbol(stream, dynamic[i].name, SYM_NODE, NS_MACRO);
 		sym->expand_simple = dynamic[i].expand_simple;
+		if ((sym->expand = dynamic[i].expand) != NULL)
+			create_arglist(sym, 1);
 	}
 
 	counter_macro = 0;
diff --git a/symbol.h b/symbol.h
index 6b483101548a..e256322e83a2 100644
--- a/symbol.h
+++ b/symbol.h
@@ -114,6 +114,7 @@ struct decl_state {
 
 struct pseudo;
 struct entrypoint;
+struct arg;
 
 struct symbol_op {
 	enum keyword type;
@@ -161,6 +162,7 @@ struct symbol {
 			struct token *arglist;
 			struct scope *used_in;
 			void (*expand_simple)(struct token *);
+			bool (*expand)(struct token *, struct arg *args);
 		};
 		struct /* NS_PREPROCESSOR */ {
 			int (*handler)(struct stream *, struct token **, struct token *);
-- 
2.27.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux