mirror of git://gcc.gnu.org/git/gcc.git
[C++ PATCH] parser simplification
https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00689.html cp/ * parser.c (cp_parser_translation_unit): Return void. Don't fail at first extra }, simplify logic. (c_parse_file): Call finish_translation_unit here. testsuite/ * g++.dg/parse/close-brace.C: New. * g++.dg/cpp0x/noexcept16.C: Avoid warning. * g++.old-deja/g++.other/crash32.C: Add another error From-SVN: r265055
This commit is contained in:
parent
13c4e4031a
commit
c7f45560c7
|
|
@ -1,3 +1,9 @@
|
|||
2018-10-11 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* parser.c (cp_parser_translation_unit): Return void. Don't fail
|
||||
at first extra }, simplify logic.
|
||||
(c_parse_file): Call finish_translation_unit here.
|
||||
|
||||
2018-10-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/87582
|
||||
|
|
|
|||
|
|
@ -2015,8 +2015,7 @@ static cp_expr cp_parser_userdef_numeric_literal
|
|||
|
||||
/* Basic concepts [gram.basic] */
|
||||
|
||||
static bool cp_parser_translation_unit
|
||||
(cp_parser *);
|
||||
static void cp_parser_translation_unit (cp_parser *);
|
||||
|
||||
/* Expressions [gram.expr] */
|
||||
|
||||
|
|
@ -4585,66 +4584,52 @@ cp_parser_userdef_string_literal (tree literal)
|
|||
/* Parse a translation-unit.
|
||||
|
||||
translation-unit:
|
||||
declaration-seq [opt]
|
||||
declaration-seq [opt] */
|
||||
|
||||
Returns TRUE if all went well. */
|
||||
|
||||
static bool
|
||||
static void
|
||||
cp_parser_translation_unit (cp_parser* parser)
|
||||
{
|
||||
/* The address of the first non-permanent object on the declarator
|
||||
obstack. */
|
||||
static void *declarator_obstack_base;
|
||||
gcc_checking_assert (!cp_error_declarator);
|
||||
|
||||
/* Create the declarator obstack. */
|
||||
gcc_obstack_init (&declarator_obstack);
|
||||
/* Create the error declarator. */
|
||||
cp_error_declarator = make_declarator (cdk_error);
|
||||
/* Create the empty parameter list. */
|
||||
no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE,
|
||||
UNKNOWN_LOCATION);
|
||||
/* Remember where the base of the declarator obstack lies. */
|
||||
void *declarator_obstack_base = obstack_next_free (&declarator_obstack);
|
||||
|
||||
bool success;
|
||||
|
||||
/* Create the declarator obstack, if necessary. */
|
||||
if (!cp_error_declarator)
|
||||
{
|
||||
gcc_obstack_init (&declarator_obstack);
|
||||
/* Create the error declarator. */
|
||||
cp_error_declarator = make_declarator (cdk_error);
|
||||
/* Create the empty parameter list. */
|
||||
no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE,
|
||||
UNKNOWN_LOCATION);
|
||||
/* Remember where the base of the declarator obstack lies. */
|
||||
declarator_obstack_base = obstack_next_free (&declarator_obstack);
|
||||
}
|
||||
|
||||
cp_parser_declaration_seq_opt (parser);
|
||||
|
||||
/* If there are no tokens left then all went well. */
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Finish up. */
|
||||
finish_translation_unit ();
|
||||
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
for (;;)
|
||||
{
|
||||
cp_parser_declaration_seq_opt (parser);
|
||||
gcc_assert (!cp_parser_parsing_tentatively (parser));
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
|
||||
break;
|
||||
/* Must have been an extra close-brace. */
|
||||
cp_parser_error (parser, "expected declaration");
|
||||
success = false;
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Make sure the declarator obstack was fully cleaned up. */
|
||||
gcc_assert (obstack_next_free (&declarator_obstack)
|
||||
== declarator_obstack_base);
|
||||
|
||||
/* All went well. */
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Return the appropriate tsubst flags for parsing, possibly in N3276
|
||||
|
|
@ -39130,6 +39115,8 @@ c_parse_file (void)
|
|||
? dk_no_deferred : dk_no_check);
|
||||
cp_parser_translation_unit (the_parser);
|
||||
the_parser = NULL;
|
||||
|
||||
finish_translation_unit ();
|
||||
}
|
||||
|
||||
/* Create an identifier for a generic parameter type (a synthesized
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
2018-10-11 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* g++.dg/parse/close-brace.C: New.
|
||||
* g++.dg/cpp0x/noexcept16.C: Avoid warning.
|
||||
* g++.old-deja/g++.other/crash32.C: Add another error
|
||||
|
||||
2018-10-11 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/85070
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ swap(_Tp&, _Tp&)
|
|||
;
|
||||
typedef lexertl::basic_state_machine<char32_t> lexstate;
|
||||
lexstate m_state_machine;
|
||||
GenerateLexer()
|
||||
void GenerateLexer()
|
||||
{
|
||||
m_state_machine.minimise();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
// We used to stop parsing at the first top-level '}' !
|
||||
|
||||
} // { dg-error "expected declaration" }
|
||||
|
||||
float int c; // { dg-error "two or more data types" }
|
||||
|
|
@ -5,7 +5,9 @@ struct foo
|
|||
{
|
||||
enum e
|
||||
{
|
||||
not // { dg-error "" }
|
||||
not // { dg-error "" }
|
||||
// We think the next close-brace closes the definition of struct
|
||||
// foo, not enum e. Things go downhill from there
|
||||
}; // { dg-bogus "" }
|
||||
~foo(); // { dg-bogus "" "" { xfail *-*-* } }
|
||||
void x (foo *&a, bool b = (unsigned char)0);
|
||||
|
|
@ -24,6 +26,6 @@ namespace N
|
|||
typedef baz<bar> c;
|
||||
}
|
||||
|
||||
{
|
||||
{ // { dg-error "expected" }
|
||||
int a;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue