aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/pre-process.c
diff options
authorLinus Torvalds <torvalds@home.transmeta.com>2003-03-24 00:14:03 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 20:59:39 -0700
commitf983c19d1df534c4b6b26495c34dca17781574ed (patch)
tree678a0a967e4dcb2fc959fcce7fc088ea01ff9128 /pre-process.c
parent6339a225b130f6bb59033f0ac5a98dd346176a19 (diff)
downloadsparse-dev-f983c19d1df534c4b6b26495c34dca17781574ed.tar.gz
Teach ## expansion about the magic gcc behaviour: x ## arg goes
away entirely if 'arg' is empty.
Diffstat (limited to 'pre-process.c')
-rw-r--r--pre-process.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/pre-process.c b/pre-process.c
index 7ccb0c1e..3f8717d8 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -218,6 +218,8 @@ static int arg_number(struct token *arglist, struct ident *ident)
return -1;
}
+static struct token empty_arg_token = { .type = TOKEN_EOF };
+
static struct token *expand_one_arg(struct token *head, struct token *token,
struct token *arglist, struct token *arguments)
{
@@ -227,6 +229,16 @@ static struct token *expand_one_arg(struct token *head, struct token *token,
struct token *arg = get_argument(nr, arguments);
struct token *last = token->next;
token->next = &eof_token_entry;
+
+ /*
+ * Special case for gcc 'x ## arg' semantics: if 'arg' is empty
+ * then the 'x' goes away too.
+ */
+ if (match_op(head, SPECIAL_HASHHASH) && eof_token(arg)) {
+ arg = &empty_arg_token;
+ empty_arg_token.next = &eof_token_entry;
+ }
+
replace(token, head, arg);
head = expand_list(head);
head->next = last;
@@ -267,6 +279,7 @@ static void expand_arguments(struct token *token, struct token *head,
/*
* Possibly valid combinations:
+ * - anything + 'empty_arg_token' is empty.
* - ident + ident - combine (==ident)
* - ident + number - combine (==ident)
* - number + number - combine (==number)
@@ -283,6 +296,17 @@ static struct token *hashhash(struct token *head, struct token *first, struct to
first->next = second;
+ /*
+ * Special case for gcc 'x ## arg' semantics: if 'arg' is empty
+ * then the 'x' goes away too.
+ *
+ * See expand_one_arg.
+ */
+ if (second->type == TOKEN_EOF) {
+ head->next = second->next;
+ return head;
+ }
+
p = buffer;
switch (first->type) {
case TOKEN_INTEGER: