diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-03-24 00:14:03 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 20:59:39 -0700 |
| commit | f983c19d1df534c4b6b26495c34dca17781574ed (patch) | |
| tree | 678a0a967e4dcb2fc959fcce7fc088ea01ff9128 | |
| parent | 6339a225b130f6bb59033f0ac5a98dd346176a19 (diff) | |
| download | sparse-dev-f983c19d1df534c4b6b26495c34dca17781574ed.tar.gz | |
Teach ## expansion about the magic gcc behaviour: x ## arg goes
away entirely if 'arg' is empty.
| -rw-r--r-- | pre-process.c | 24 |
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: |
