aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2018-10-12 18:44:48 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2018-10-12 18:44:48 +0000
commit7fa072dea587ff70bee5e059f3cd31a7b2ce9a3c (patch)
tree1082f25d05a37c2f027f3ccf3aaf511f018948ba /gcc/cp
parent47b92d22d3aea04ce6a936c768953dd0406f41c2 (diff)
downloadgcc-7fa072dea587ff70bee5e059f3cd31a7b2ce9a3c.zip
gcc-7fa072dea587ff70bee5e059f3cd31a7b2ce9a3c.tar.gz
gcc-7fa072dea587ff70bee5e059f3cd31a7b2ce9a3c.tar.bz2
[C++ PATCH] more TU parsing refactoring
https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00788.html * parser.h (struct cp_parser): Drop implicit_extern_c. * parser.c (cp_debug_parser): Drop implicit_extern_c. (cp_parser_new): Likewise. (cp_parser_translation_unit): Handle implicit extern c here. Call cp_parser_toplevel_declaration. (cp_parser_toplevel_declaration): New, broken out of ... (cp_parser_declaration_seq_opt): ... here. Call it. Drop implicit extern C handling. From-SVN: r265127
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/parser.c126
-rw-r--r--gcc/cp/parser.h4
3 files changed, 74 insertions, 67 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bbeb45c..701ec64 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2018-10-12 Nathan Sidwell <nathan@acm.org>
+
+ * parser.h (struct cp_parser): Drop implicit_extern_c.
+ * parser.c (cp_debug_parser): Drop implicit_extern_c.
+ (cp_parser_new): Likewise.
+ (cp_parser_translation_unit): Handle implicit extern c here. Call
+ cp_parser_toplevel_declaration.
+ (cp_parser_toplevel_declaration): New, broken out of ...
+ (cp_parser_declaration_seq_opt): ... here. Call it. Drop
+ implicit extern C handling.
+
2018-10-11 Will Wray <wjwray@gmail.com>
PR c++/87364
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 76ff836..c46b776 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -556,8 +556,6 @@ cp_debug_parser (FILE *file, cp_parser *parser)
parser->in_statement & IN_IF_STMT);
cp_debug_print_flag (file, "Parsing a type-id in an expression "
"context", parser->in_type_id_in_expr_p);
- cp_debug_print_flag (file, "Declarations are implicitly extern \"C\"",
- parser->implicit_extern_c);
cp_debug_print_flag (file, "String expressions should be translated "
"to execution character set",
parser->translate_strings_p);
@@ -2135,6 +2133,8 @@ static void cp_parser_declaration_seq_opt
(cp_parser *);
static void cp_parser_declaration
(cp_parser *);
+static void cp_parser_toplevel_declaration
+ (cp_parser *);
static void cp_parser_block_declaration
(cp_parser *, bool);
static void cp_parser_simple_declaration
@@ -3923,9 +3923,6 @@ 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;
@@ -4601,31 +4598,45 @@ cp_parser_translation_unit (cp_parser* parser)
/* Remember where the base of the declarator obstack lies. */
void *declarator_obstack_base = obstack_next_free (&declarator_obstack);
+ bool implicit_extern_c = false;
+
for (;;)
{
- cp_parser_declaration_seq_opt (parser);
- gcc_assert (!cp_parser_parsing_tentatively (parser));
- if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ /* If we're entering or exiting a region that's implicitly
+ extern "C", modify the lang context appropriately. */
+ if (implicit_extern_c
+ != cp_lexer_peek_token (parser->lexer)->implicit_extern_c)
+ {
+ implicit_extern_c = !implicit_extern_c;
+ if (implicit_extern_c)
+ push_lang_context (lang_name_c);
+ else
+ pop_lang_context ();
+ }
+
+ if (token->type == CPP_EOF)
break;
- /* Must have been an extra close-brace. */
- cp_parser_error (parser, "expected declaration");
- cp_lexer_consume_token (parser->lexer);
- /* If the next token is now a `;', consume it. */
- if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
- cp_lexer_consume_token (parser->lexer);
+
+ if (token->type == CPP_CLOSE_BRACE)
+ {
+ cp_parser_error (parser, "expected declaration");
+ cp_lexer_consume_token (parser->lexer);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ cp_parser_toplevel_declaration (parser);
}
/* Get rid of the token array; we don't need it any more. */
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;
- }
+
+ /* The EOF should have reset this. */
+ gcc_checking_assert (!implicit_extern_c);
/* Make sure the declarator obstack was fully cleaned up. */
gcc_assert (obstack_next_free (&declarator_obstack)
@@ -12732,50 +12743,13 @@ cp_parser_declaration_seq_opt (cp_parser* parser)
{
while (true)
{
- cp_token *token;
-
- token = cp_lexer_peek_token (parser->lexer);
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
if (token->type == CPP_CLOSE_BRACE
- || token->type == CPP_EOF
- || token->type == CPP_PRAGMA_EOL)
+ || token->type == CPP_EOF)
break;
-
- if (token->type == CPP_SEMICOLON)
- {
- /* A declaration consisting of a single semicolon is
- invalid. Allow it unless we're being pedantic. */
- cp_lexer_consume_token (parser->lexer);
- if (!in_system_header_at (input_location))
- pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
- 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.
- A nested declaration cannot, so this is done here and not
- in cp_parser_declaration. (A #pragma at block scope is
- handled in cp_parser_statement.) */
- cp_parser_pragma (parser, pragma_external, NULL);
- continue;
- }
-
- /* Parse the declaration itself. */
- cp_parser_declaration (parser);
+ else
+ cp_parser_toplevel_declaration (parser);
}
}
@@ -12905,6 +12879,32 @@ cp_parser_declaration (cp_parser* parser)
obstack_free (&declarator_obstack, p);
}
+/* Parse a namespace-scope declaration. */
+
+static void
+cp_parser_toplevel_declaration (cp_parser* parser)
+{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type == CPP_PRAGMA)
+ /* A top-level declaration can consist solely of a #pragma. A
+ nested declaration cannot, so this is done here and not in
+ cp_parser_declaration. (A #pragma at block scope is
+ handled in cp_parser_statement.) */
+ cp_parser_pragma (parser, pragma_external, NULL);
+ else if (token->type == CPP_SEMICOLON)
+ {
+ /* A declaration consisting of a single semicolon is
+ invalid. Allow it unless we're being pedantic. */
+ cp_lexer_consume_token (parser->lexer);
+ if (!in_system_header_at (input_location))
+ pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
+ }
+ else
+ /* Parse the declaration itself. */
+ cp_parser_declaration (parser);
+}
+
/* Parse a block-declaration.
block-declaration:
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index 81a2328..8bfa3f3 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -321,10 +321,6 @@ struct GTY(()) cp_parser {
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;