diff mbox

[04/11] Fix expansion point loc for macro-like tokens

Message ID m3lilea372.fsf@redhat.com
State New
Headers show

Commit Message

Dodji Seketeli April 29, 2012, 4:54 p.m. UTC
Jason Merrill <jason@redhat.com> writes:

> On 04/25/2012 05:07 AM, Dodji Seketeli wrote:
>> +	  /* If the first token we got was a padding token, let's put
>> +	     it back into the stream so that cpp_get_token will get it
>> +	     first; and if we are currently expanding a macro, don't
>> +	     forget that information.  */
>> +	  cpp_hashnode *macro =
>> +	    (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED)
>> +	    ? pfile->context->c.mc->macro_node
>> +	    : pfile->context->c.macro;
>> +	  _cpp_push_token_context (pfile, macro, padding, 1);
>
> What about the other places that call _cpp_push_token_context with a
> NULL macro argument?  Don't we want to continue the current macro
> context in that case, too?  Perhaps we should move this new code
> inside _cpp_push_token_context for the case when the macro parameter
> is NULL.

Right.  I did that.

But then, now that there can be some contiguous contexts representing
the same macro, I had to adjust how _cpp_pop_context was re-enabling the
'expandability' of a given macro M.

For the background, When M is being expanded, it's flagged by
enter_macro_context as being non-expandable, to prevent its possible
recursive expansions.  And it's flagged back to being expandable when we
get out of its expansion context.

Now, getting out of the expansion context means to test that have
actually popped all the possibly contiguous contexts that are related to
M.  Otherwise, we get into situations of recursive expansion of M.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

libcpp/
	* macro.c (macro_of_context): New static function.
	(_cpp_push_token_context, push_extended_tokens_context): If the
	macro argument is NULL, it means we are continuing the expansion
	of the current macro, if any.  Update comments.
	(_cpp_pop_context): Re-enable expansion of the macro only when we
	are really out of the context of the current expansion.

gcc/testsuite/

	* gcc.dg/debug/dwarf2/pr41445-5.c: Adjust.
	* gcc.dg/debug/dwarf2/pr41445-6.c: Likewise.
---
 gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c |    5 ++-
 gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c |    5 ++-
 libcpp/macro.c                                |   56 +++++++++++++++++++++----
 3 files changed, 56 insertions(+), 10 deletions(-)

Comments

Jason Merrill April 30, 2012, 3:20 a.m. UTC | #1
OK.

Jason
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
index 03af604..d21acd5 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
@@ -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 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
index 8aa37d1..d6d79cc 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
@@ -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" } } */
diff --git a/libcpp/macro.c b/libcpp/macro.c
index f4638c4..ab3e8f6 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -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;
     }