diff options
author | austern <austern@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-09-27 22:24:35 +0000 |
---|---|---|
committer | austern <austern@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-09-27 22:24:35 +0000 |
commit | 2e1f41a9715c471f4681d98cac6cc8f76ac0a1a3 (patch) | |
tree | eaabda6d357ad0b18ff320a27dd73bc59f30f80b /gcc/cp/parser.c | |
parent | 0ff89ae1c734efa3ef15396372ce4d97dd50cc01 (diff) | |
download | gcc-2e1f41a9715c471f4681d98cac6cc8f76ac0a1a3.tar.gz |
Fix implicit extern "C" breakage introduced by tokenization patch.
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88203 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 89a96014d49..184ae5434e4 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -55,6 +55,8 @@ typedef struct cp_token GTY (()) 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. */ @@ -418,6 +420,7 @@ static void cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED , cp_token *token) { + static int is_extern_c = 0; bool done; done = false; @@ -445,6 +448,13 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED , 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)) @@ -1317,6 +1327,10 @@ typedef struct cp_parser GTY(()) 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; @@ -2425,6 +2439,9 @@ cp_parser_new (void) /* 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; @@ -2625,6 +2642,14 @@ cp_parser_translation_unit (cp_parser* parser) 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 (); @@ -6634,6 +6659,19 @@ cp_parser_declaration_seq_opt (cp_parser* parser) 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. @@ -6644,19 +6682,6 @@ cp_parser_declaration_seq_opt (cp_parser* parser) 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); } |