This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++] PATCH: fix implicit extern "C" breakage


This patch fixes a bug in implicit extern "C" that Zack's and my patch introduced. The problem is that the parser looked at pending_lang_change to see if a declaration was in a context where it should implicitly be treated as extern "C", but doing all of the preprocessing and lexing before any of the parsing destroys that information. We have to save that information in the tokens.

No regressions on mainline, and it seems to fix the problem (at least on Darwin, I haven't tested it on AIX).

OK to commit to mainline?

--Matt


Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.4389
diff -p -r1.4389 ChangeLog
*** ChangeLog 27 Sep 2004 18:47:27 -0000 1.4389
--- ChangeLog 27 Sep 2004 19:41:49 -0000
***************
*** 1,3 ****
--- 1,15 ----
+ 2004-09-27 Matt Austern <austern@apple.com>
+
+ * cp/parser.c (struct cp_token): new one-bit field , implicit_extern_c
+ (cp_lexer_get_preprocessor_token): Set implicit_extern_c for
+ tokens that come from headers that are implicitly extern "C".
+ (struct cp_parser): new one-bit field, implicit_extern_c.
+ (cp_parser_new): Set parser's implicit_extern_c to false.
+ (cp_parser_translation_unit): Pop lang context if we were in a
+ header that was implicitly extern "C".
+ (cp_parser_declaration_seq_opt): Push/pop lang context as
+ required by the token's and parser's implicit_extern_c.
+
2004-09-27 Mark Mitchell <mark@codesourcery.com>


PR c++/17585
Index: parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.256
diff -p -r1.256 parser.c
*** parser.c 24 Sep 2004 15:23:05 -0000 1.256
--- parser.c 27 Sep 2004 19:41:49 -0000
*************** typedef struct cp_token GTY (())
*** 55,60 ****
--- 55,62 ----
unsigned char flags;
/* True if this token is from a system header. */
BOOL_BITFIELD in_system_header : 1;
+ /* True if this token is from a context where it is implicitly extern "C" */
+ BOOL_BITFIELD implicit_extern_c : 1;
/* The value associated with this token, if any. */
tree value;
/* The location at which this token was found. */
*************** static void
*** 418,423 ****
--- 420,426 ----
cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
cp_token *token)
{
+ static int is_extern_c = 0;
bool done;


    done = false;
*************** cp_lexer_get_preprocessor_token (cp_lexe
*** 445,450 ****
--- 448,460 ----
    token->location = input_location;
    token->in_system_header = in_system_header;

+   /* On some systems, some header files are surrounded by an
+      implicit extern "C" block.  Set a flag in the token if it
+      comes from such a header. */
+   is_extern_c += pending_lang_change;
+   pending_lang_change = 0;
+   token->implicit_extern_c = is_extern_c > 0;
+
    /* Check to see if this token is a keyword.  */
    if (token->type == CPP_NAME
        && C_IS_RESERVED_WORD (token->value))
*************** typedef struct cp_parser GTY(())
*** 1317,1322 ****
--- 1327,1336 ----
       alternatives.  */
    bool in_type_id_in_expr_p;

+ /* TRUE if we are currently in a header file where declarations are
+ implicitly extern "C". */
+ bool implicit_extern_c;
+
/* TRUE if strings in expressions should be translated to the execution
character set. */
bool translate_strings_p;
*************** cp_parser_new (void)
*** 2425,2430 ****
--- 2439,2447 ----
/* We are not parsing a type-id inside an expression. */
parser->in_type_id_in_expr_p = false;


+ /* Declarations aren't implicitly extern "C". */
+ parser->implicit_extern_c = false;
+
/* String literals should be translated to the execution character set. */
parser->translate_strings_p = true;


*************** cp_parser_translation_unit (cp_parser* p
*** 2625,2630 ****
--- 2642,2655 ----
  	  cp_lexer_destroy (parser->lexer);
  	  parser->lexer = NULL;

+ 	  /* This file might have been a context that's implicitly extern
+ 	     "C".  If so, pop the lang context.  (Only relevant for PCH.) */
+ 	  if (parser->implicit_extern_c)
+ 	    {
+ 	      pop_lang_context ();
+ 	      parser->implicit_extern_c = false;
+ 	    }
+
  	  /* Finish up.  */
  	  finish_translation_unit ();

*************** cp_parser_declaration_seq_opt (cp_parser
*** 6634,6639 ****
--- 6659,6677 ----
  	  continue;
  	}

+       /* If we're entering or exiting a region that's implicitly
+ 	 extern "C", modify the lang context appropriately. */
+       if (!parser->implicit_extern_c && token->implicit_extern_c)
+ 	{
+ 	  push_lang_context (lang_name_c);
+ 	  parser->implicit_extern_c = true;
+ 	}
+       else if (parser->implicit_extern_c && !token->implicit_extern_c)
+ 	{
+ 	  pop_lang_context ();
+ 	  parser->implicit_extern_c = false;
+ 	}
+
        if (token->type == CPP_PRAGMA)
  	{
  	  /* A top-level declaration can consist solely of a #pragma.
*************** cp_parser_declaration_seq_opt (cp_parser
*** 6644,6662 ****
  	  continue;
  	}

-       /* The C lexer modifies PENDING_LANG_CHANGE when it wants the
- 	 parser to enter or exit implicit `extern "C"' blocks.  */
-       while (pending_lang_change > 0)
- 	{
- 	  push_lang_context (lang_name_c);
- 	  --pending_lang_change;
- 	}
-       while (pending_lang_change < 0)
- 	{
- 	  pop_lang_context ();
- 	  ++pending_lang_change;
- 	}
-
        /* Parse the declaration itself.  */
        cp_parser_declaration (parser);
      }
--- 6682,6687 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]