Skip to content

Commit

Permalink
fix: Reduce the amount of backtracing when parsing simple declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
robertoraggi committed Oct 19, 2023
1 parent cbcd44e commit 1c54417
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 43 deletions.
88 changes: 51 additions & 37 deletions src/parser/cxx/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3793,60 +3793,59 @@ auto Parser::parse_structured_binding(DeclarationAST*& yyast,
return true;
}

auto Parser::parse_function_definition(
auto Parser::parse_simple_declaration(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
const std::vector<TemplateDeclarationAST*>& templateDeclarations,
BindingContext ctx) -> bool {
LookaheadParser lookahead{this};

if (!context_allows_function_definition(ctx)) return false;

DeclaratorAST* declarator = nullptr;
Decl decl{specs};
if (!parse_declarator(declarator, decl)) return false;

auto functionDeclarator = getFunctionPrototype(declarator);
if (!functionDeclarator) return false;
auto lookat_function_definition = [&] {
if (!context_allows_function_definition(ctx)) return false;

RequiresClauseAST* requiresClause = nullptr;
(void)parse_requires_clause(requiresClause);
LookaheadParser lookahead{this};

if (!lookat_function_body()) return false;
auto functionDeclarator = getFunctionPrototype(declarator);
if (!functionDeclarator) return false;

if (ctx == BindingContext::kTemplate) {
mark_maybe_template_name(declarator);
}
RequiresClauseAST* requiresClause = nullptr;
(void)parse_requires_clause(requiresClause);

FunctionBodyAST* functionBody = nullptr;
if (!parse_function_body(functionBody)) parse_error("expected function body");
if (!lookat_function_body()) return false;

lookahead.commit();
if (ctx == BindingContext::kTemplate) {
mark_maybe_template_name(declarator);
}

auto ast = new (pool_) FunctionDefinitionAST();
yyast = ast;
FunctionBodyAST* functionBody = nullptr;
if (!parse_function_body(functionBody))
parse_error("expected function body");

ast->attributeList = attributes;
ast->declSpecifierList = declSpecifierList;
ast->declarator = declarator;
ast->requiresClause = requiresClause;
ast->functionBody = functionBody;
lookahead.commit();

if (classDepth_) pendingFunctionDefinitions_.push_back(ast);
auto ast = new (pool_) FunctionDefinitionAST();
yyast = ast;

return true;
}
ast->attributeList = attributes;
ast->declSpecifierList = declSpecifierList;
ast->declarator = declarator;
ast->requiresClause = requiresClause;
ast->functionBody = functionBody;

if (classDepth_) pendingFunctionDefinitions_.push_back(ast);

return true;
};

if (lookat_function_definition()) return true;

auto Parser::parse_simple_declaration(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
const std::vector<TemplateDeclarationAST*>& templateDeclarations,
BindingContext ctx) -> bool {
List<InitDeclaratorAST*>* initDeclaratorList = nullptr;
auto declIt = &initDeclaratorList;

InitDeclaratorAST* initDeclarator = nullptr;
if (!parse_init_declarator(initDeclarator, specs)) return false;
if (!parse_init_declarator(initDeclarator, declarator, specs)) return false;

if (ctx == BindingContext::kTemplate) {
auto declarator = initDeclarator->declarator;
Expand Down Expand Up @@ -3893,6 +3892,17 @@ auto Parser::parse_simple_declaration(
List<AttributeSpecifierAST*>* attributes = nullptr;
parse_optional_attribute_specifier_seq(attributes);

if (SourceLocation semicolonLoc;
ctx != BindingContext::kTemplate && attributes &&
match(TokenKind::T_SEMICOLON, semicolonLoc)) {
auto ast = new (pool_) AttributeDeclarationAST();
yyast = ast;

ast->attributeList = attributes;
ast->semicolonLoc = semicolonLoc;
return true;
}

if (parse_template_class_declaration(yyast, attributes, templateDeclarations,
ctx))
return true;
Expand All @@ -3918,11 +3928,9 @@ auto Parser::parse_simple_declaration(
if (parse_type_or_forward_declaration(yyast, attributes, declSpecifierList,
specs, templateDeclarations, ctx))
return true;
else if (parse_structured_binding(yyast, attributes, declSpecifierList, specs,
ctx))
return true;
else if (parse_function_definition(yyast, attributes, declSpecifierList,
specs, templateDeclarations, ctx))

if (parse_structured_binding(yyast, attributes, declSpecifierList, specs,
ctx))
return true;

return parse_simple_declaration(yyast, attributes, declSpecifierList, specs,
Expand Down Expand Up @@ -4919,6 +4927,12 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
Decl decl{specs};
if (!parse_declarator(declarator, decl)) return false;

return parse_init_declarator(yyast, declarator, specs);
}

auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
DeclaratorAST* declarator,
const DeclSpecs& specs) -> bool {
RequiresClauseAST* requiresClause = nullptr;
ExpressionAST* initializer = nullptr;

Expand Down
9 changes: 3 additions & 6 deletions src/parser/cxx/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,6 @@ class Parser final {
List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
BindingContext ctx) -> bool;

[[nodiscard]] auto parse_function_definition(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
const std::vector<TemplateDeclarationAST*>& templateDeclarations,
BindingContext ctx) -> bool;

[[nodiscard]] auto parse_simple_declaration(
DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
Expand Down Expand Up @@ -425,6 +419,9 @@ class Parser final {
DeclSpecs& specs) -> bool;
[[nodiscard]] auto parse_init_declarator(InitDeclaratorAST*& yyast,
const DeclSpecs& specs) -> bool;
[[nodiscard]] auto parse_init_declarator(InitDeclaratorAST*& yyast,
DeclaratorAST* declarator,
const DeclSpecs& specs) -> bool;
[[nodiscard]] auto parse_declarator_initializer(
RequiresClauseAST*& requiresClause, ExpressionAST*& yyast) -> bool;
void parse_optional_declarator_or_abstract_declarator(DeclaratorAST*& yyast,
Expand Down

0 comments on commit 1c54417

Please sign in to comment.