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>
|
2018-10-11 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c++/87582
|
PR c++/87582
|
||||||
|
|
|
||||||
|
|
@ -2015,8 +2015,7 @@ static cp_expr cp_parser_userdef_numeric_literal
|
||||||
|
|
||||||
/* Basic concepts [gram.basic] */
|
/* Basic concepts [gram.basic] */
|
||||||
|
|
||||||
static bool cp_parser_translation_unit
|
static void cp_parser_translation_unit (cp_parser *);
|
||||||
(cp_parser *);
|
|
||||||
|
|
||||||
/* Expressions [gram.expr] */
|
/* Expressions [gram.expr] */
|
||||||
|
|
||||||
|
|
@ -4585,66 +4584,52 @@ cp_parser_userdef_string_literal (tree literal)
|
||||||
/* Parse a translation-unit.
|
/* Parse a translation-unit.
|
||||||
|
|
||||||
translation-unit:
|
translation-unit:
|
||||||
declaration-seq [opt]
|
declaration-seq [opt] */
|
||||||
|
|
||||||
Returns TRUE if all went well. */
|
static void
|
||||||
|
|
||||||
static bool
|
|
||||||
cp_parser_translation_unit (cp_parser* parser)
|
cp_parser_translation_unit (cp_parser* parser)
|
||||||
{
|
{
|
||||||
/* The address of the first non-permanent object on the declarator
|
gcc_checking_assert (!cp_error_declarator);
|
||||||
obstack. */
|
|
||||||
static void *declarator_obstack_base;
|
|
||||||
|
|
||||||
bool success;
|
/* 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);
|
||||||
|
|
||||||
/* Create the declarator obstack, if necessary. */
|
for (;;)
|
||||||
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
|
|
||||||
{
|
{
|
||||||
|
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");
|
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. */
|
/* Make sure the declarator obstack was fully cleaned up. */
|
||||||
gcc_assert (obstack_next_free (&declarator_obstack)
|
gcc_assert (obstack_next_free (&declarator_obstack)
|
||||||
== declarator_obstack_base);
|
== declarator_obstack_base);
|
||||||
|
|
||||||
/* All went well. */
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the appropriate tsubst flags for parsing, possibly in N3276
|
/* Return the appropriate tsubst flags for parsing, possibly in N3276
|
||||||
|
|
@ -39130,6 +39115,8 @@ c_parse_file (void)
|
||||||
? dk_no_deferred : dk_no_check);
|
? dk_no_deferred : dk_no_check);
|
||||||
cp_parser_translation_unit (the_parser);
|
cp_parser_translation_unit (the_parser);
|
||||||
the_parser = NULL;
|
the_parser = NULL;
|
||||||
|
|
||||||
|
finish_translation_unit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an identifier for a generic parameter type (a synthesized
|
/* 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>
|
2018-10-11 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c++/85070
|
PR c++/85070
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ swap(_Tp&, _Tp&)
|
||||||
;
|
;
|
||||||
typedef lexertl::basic_state_machine<char32_t> lexstate;
|
typedef lexertl::basic_state_machine<char32_t> lexstate;
|
||||||
lexstate m_state_machine;
|
lexstate m_state_machine;
|
||||||
GenerateLexer()
|
void GenerateLexer()
|
||||||
{
|
{
|
||||||
m_state_machine.minimise();
|
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" }
|
||||||
|
|
@ -6,6 +6,8 @@ struct foo
|
||||||
enum e
|
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 "" }
|
}; // { dg-bogus "" }
|
||||||
~foo(); // { dg-bogus "" "" { xfail *-*-* } }
|
~foo(); // { dg-bogus "" "" { xfail *-*-* } }
|
||||||
void x (foo *&a, bool b = (unsigned char)0);
|
void x (foo *&a, bool b = (unsigned char)0);
|
||||||
|
|
@ -24,6 +26,6 @@ namespace N
|
||||||
typedef baz<bar> c;
|
typedef baz<bar> c;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{ // { dg-error "expected" }
|
||||||
int a;
|
int a;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue