@@ -9,6 +9,9 @@
#define B , varj
int A(B) ;
-/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0x)?7\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */
+/* We want to check that both vari and varj have the same line
+ number. */
+
+/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */
/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"varj\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */
/* { dg-final { cleanup-saved-temps } } */
@@ -4,5 +4,8 @@
#include "pr41445-5.c"
-/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0x)?7\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */
+/* We want to check that both vari and varj have the same line
+ number. */
+
+/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)?\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */
/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"varj\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */
@@ -165,6 +165,8 @@ static void consume_next_token_from_context (cpp_reader *pfile,
source_location *);
static const cpp_token* cpp_get_token_1 (cpp_reader *, source_location *);
+static cpp_hashnode* macro_of_context (cpp_context *context);
+
/* Statistical counter tracking the number of macros that got
expanded. */
unsigned num_expanded_macros_counter = 0;
@@ -1808,18 +1810,27 @@ push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff,
LAST (context).ptoken = first + count;
}
-/* Push a list of tokens. */
+/* Push a list of tokens.
+
+ A NULL macro means that we should continue the current macro
+ expansion, in essence. That means that if we are currently in a
+ macro expansion context, we'll make the new pfile->context refer to
+ the current macro. */
void
_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
const cpp_token *first, unsigned int count)
{
- cpp_context *context = next_context (pfile);
-
+ cpp_context *context;
+
+ if (macro == NULL)
+ macro = macro_of_context (pfile->context);
+
+ context = next_context (pfile);
context->tokens_kind = TOKENS_KIND_DIRECT;
context->c.macro = macro;
context->buff = NULL;
- FIRST (context).token = first;
- LAST (context).token = first + count;
+ FIRST (context).token = first;
+ LAST (context).token = first + count;
}
/* Build a context containing a list of tokens as well as their
@@ -1827,7 +1838,12 @@ _cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
contains the tokens pointed to by FIRST. If TOKENS_BUFF is
non-NULL, it means that the context owns it, meaning that
_cpp_pop_context will free it as well as VIRT_LOCS_BUFF that
- contains the virtual locations. */
+ contains the virtual locations.
+
+ A NULL macro means that we should continue the current macro
+ expansion, in essence. That means that if we are currently in a
+ macro expansion context, we'll make the new pfile->context refer to
+ the current macro. */
static void
push_extended_tokens_context (cpp_reader *pfile,
cpp_hashnode *macro,
@@ -1836,9 +1852,13 @@ push_extended_tokens_context (cpp_reader *pfile,
const cpp_token **first,
unsigned int count)
{
- cpp_context *context = next_context (pfile);
+ cpp_context *context;
macro_context *m;
+ if (macro == NULL)
+ macro = macro_of_context (pfile->context);
+
+ context = next_context (pfile);
context->tokens_kind = TOKENS_KIND_EXTENDED;
context->buff = token_buff;
@@ -2110,6 +2130,19 @@ expand_arg (cpp_reader *pfile, macro_arg *arg)
CPP_WTRADITIONAL (pfile) = saved_warn_trad;
}
+/* Returns the macro associated to the current context if we are in
+ the context a macro expansion, NULL otherwise. */
+static cpp_hashnode*
+macro_of_context (cpp_context *context)
+{
+ if (context == NULL)
+ return NULL;
+
+ return (context->tokens_kind == TOKENS_KIND_EXTENDED)
+ ? context->c.mc->macro_node
+ : context->c.macro;
+}
+
/* Pop the current context off the stack, re-enabling the macro if the
context represented a macro's replacement list. Initially the
context structure was not freed so that we can re-use it later, but
@@ -2146,7 +2179,14 @@ _cpp_pop_context (cpp_reader *pfile)
tokens is pushed just for the purpose of walking them using
cpp_get_token_1. In that case, no 'macro' field is set into
the dummy context. */
- if (macro != NULL)
+ if (macro != NULL
+ /* Several contiguous macro expansion contexts can be
+ associated to the same macro; that means it's the same
+ macro expansion that spans accross all these (sub)
+ contexts. So we should re-enable an expansion-disabled
+ macro only when we are sure we are really out of that
+ macro expansion. */
+ && macro_of_context (context->prev) != macro)
macro->flags &= ~NODE_DISABLED;
}