[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
This commit is contained in:
parent
47b92d22d3
commit
7fa072dea5
3 changed files with 74 additions and 67 deletions
|
@ -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
|
||||
|
|
126
gcc/cp/parser.c
126
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:
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue