From a9f60ed53cb577f8c0c90a53e4637301174bc76a Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Sat, 16 Sep 2023 11:47:13 +0200 Subject: [PATCH] fix: Reimplemented the support for nested name specifiers --- packages/cxx-frontend/src/AST.ts | 119 ++++++++-- packages/cxx-frontend/src/ASTKind.ts | 7 +- packages/cxx-frontend/src/ASTVisitor.ts | 22 +- .../cxx-frontend/src/RecursiveASTVisitor.ts | 37 ++- src/frontend/cxx/ast_printer.cc | 35 +-- src/frontend/cxx/ast_printer.h | 6 +- src/parser/cxx/ast.cc | 66 +++++- src/parser/cxx/ast.fbs | 39 +++- src/parser/cxx/ast.h | 80 +++++-- src/parser/cxx/ast_cloner.cc | 70 ++++-- src/parser/cxx/ast_cloner.h | 6 +- src/parser/cxx/ast_decoder.cc | 136 +++++++---- src/parser/cxx/ast_encoder.cc | 211 +++++++++++++----- src/parser/cxx/ast_fwd.h | 8 +- src/parser/cxx/ast_kind.h | 7 +- src/parser/cxx/ast_slot.cc | 91 ++++++-- src/parser/cxx/ast_slot.h | 6 +- src/parser/cxx/ast_visitor.h | 7 +- src/parser/cxx/default_ast_visitor.cc | 21 +- src/parser/cxx/default_ast_visitor.h | 7 +- src/parser/cxx/parser.cc | 192 ++++++++-------- src/parser/cxx/parser.h | 5 +- src/parser/cxx/private/ast_decoder.h | 17 +- src/parser/cxx/private/ast_encoder.h | 9 +- src/parser/cxx/recursive_ast_visitor.cc | 36 ++- src/parser/cxx/recursive_ast_visitor.h | 10 +- 26 files changed, 908 insertions(+), 342 deletions(-) diff --git a/packages/cxx-frontend/src/AST.ts b/packages/cxx-frontend/src/AST.ts index aba342f3..1052439a 100644 --- a/packages/cxx-frontend/src/AST.ts +++ b/packages/cxx-frontend/src/AST.ts @@ -95,6 +95,7 @@ export abstract class FunctionBodyAST extends AST {} export abstract class LambdaCaptureAST extends AST {} export abstract class MemInitializerAST extends AST {} export abstract class NameAST extends AST {} +export abstract class NestedNameSpecifierAST extends AST {} export abstract class NewInitializerAST extends AST {} export abstract class PtrOperatorAST extends AST {} export abstract class RequirementAST extends AST {} @@ -127,27 +128,6 @@ export class TypeIdAST extends AST { } } -export class NestedNameSpecifierAST extends AST { - accept( - visitor: ASTVisitor, - context: Context, - ): Result { - return visitor.visitNestedNameSpecifier(this, context); - } - getScopeToken(): Token | undefined { - return Token.from(cxx.getASTSlot(this.getHandle(), 0), this.parser); - } - *getNameList(): Generator { - for ( - let it = cxx.getASTSlot(this.getHandle(), 1); - it; - it = cxx.getListNext(it) - ) { - yield AST.from(cxx.getListValue(it), this.parser); - } - } -} - export class UsingDeclaratorAST extends AST { accept( visitor: ASTVisitor, @@ -977,6 +957,94 @@ export class NewPlacementAST extends AST { } } +export class GlobalNestedNameSpecifierAST extends NestedNameSpecifierAST { + accept( + visitor: ASTVisitor, + context: Context, + ): Result { + return visitor.visitGlobalNestedNameSpecifier(this, context); + } + getScopeToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 0), this.parser); + } +} + +export class SimpleNestedNameSpecifierAST extends NestedNameSpecifierAST { + accept( + visitor: ASTVisitor, + context: Context, + ): Result { + return visitor.visitSimpleNestedNameSpecifier(this, context); + } + getNestedNameSpecifier(): NestedNameSpecifierAST | undefined { + return AST.from( + cxx.getASTSlot(this.getHandle(), 0), + this.parser, + ); + } + getIdentifierToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 1), this.parser); + } + getIdentifier(): string | undefined { + const slot = cxx.getASTSlot(this.getHandle(), 2); + return cxx.getIdentifierValue(slot); + } + getScopeToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 3), this.parser); + } +} + +export class DecltypeNestedNameSpecifierAST extends NestedNameSpecifierAST { + accept( + visitor: ASTVisitor, + context: Context, + ): Result { + return visitor.visitDecltypeNestedNameSpecifier(this, context); + } + getNestedNameSpecifier(): NestedNameSpecifierAST | undefined { + return AST.from( + cxx.getASTSlot(this.getHandle(), 0), + this.parser, + ); + } + getDecltypeSpecifier(): DecltypeSpecifierAST | undefined { + return AST.from( + cxx.getASTSlot(this.getHandle(), 1), + this.parser, + ); + } + getScopeToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 2), this.parser); + } +} + +export class TemplateNestedNameSpecifierAST extends NestedNameSpecifierAST { + accept( + visitor: ASTVisitor, + context: Context, + ): Result { + return visitor.visitTemplateNestedNameSpecifier(this, context); + } + getNestedNameSpecifier(): NestedNameSpecifierAST | undefined { + return AST.from( + cxx.getASTSlot(this.getHandle(), 0), + this.parser, + ); + } + getTemplateToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 1), this.parser); + } + getTemplateName(): TemplateNameAST | undefined { + return AST.from( + cxx.getASTSlot(this.getHandle(), 2), + this.parser, + ); + } + getScopeToken(): Token | undefined { + return Token.from(cxx.getASTSlot(this.getHandle(), 3), this.parser); + } +} + export class ThrowExceptionSpecifierAST extends ExceptionSpecifierAST { accept( visitor: ASTVisitor, @@ -4206,8 +4274,8 @@ export class DecltypeNameAST extends NameAST { ): Result { return visitor.visitDecltypeName(this, context); } - getDecltypeSpecifier(): SpecifierAST | undefined { - return AST.from( + getDecltypeSpecifier(): DecltypeSpecifierAST | undefined { + return AST.from( cxx.getASTSlot(this.getHandle(), 0), this.parser, ); @@ -5293,7 +5361,6 @@ const AST_CONSTRUCTORS: Array< new (handle: number, kind: ASTKind, parser: TranslationUnitLike) => AST > = [ TypeIdAST, - NestedNameSpecifierAST, UsingDeclaratorAST, HandlerAST, EnumBaseAST, @@ -5325,6 +5392,10 @@ const AST_CONSTRUCTORS: Array< AttributeUsingPrefixAST, DesignatorAST, NewPlacementAST, + GlobalNestedNameSpecifierAST, + SimpleNestedNameSpecifierAST, + DecltypeNestedNameSpecifierAST, + TemplateNestedNameSpecifierAST, ThrowExceptionSpecifierAST, NoexceptSpecifierAST, PackExpansionExpressionAST, diff --git a/packages/cxx-frontend/src/ASTKind.ts b/packages/cxx-frontend/src/ASTKind.ts index d2c99d70..771aea5b 100644 --- a/packages/cxx-frontend/src/ASTKind.ts +++ b/packages/cxx-frontend/src/ASTKind.ts @@ -21,7 +21,6 @@ export enum ASTKind { // AST TypeId, - NestedNameSpecifier, UsingDeclarator, Handler, EnumBase, @@ -54,6 +53,12 @@ export enum ASTKind { Designator, NewPlacement, + // NestedNameSpecifierAST + GlobalNestedNameSpecifier, + SimpleNestedNameSpecifier, + DecltypeNestedNameSpecifier, + TemplateNestedNameSpecifier, + // ExceptionSpecifierAST ThrowExceptionSpecifier, NoexceptSpecifier, diff --git a/packages/cxx-frontend/src/ASTVisitor.ts b/packages/cxx-frontend/src/ASTVisitor.ts index b8c788ce..942f68fd 100644 --- a/packages/cxx-frontend/src/ASTVisitor.ts +++ b/packages/cxx-frontend/src/ASTVisitor.ts @@ -25,10 +25,6 @@ export abstract class ASTVisitor { // AST abstract visitTypeId(node: ast.TypeIdAST, context: Context): Result; - abstract visitNestedNameSpecifier( - node: ast.NestedNameSpecifierAST, - context: Context, - ): Result; abstract visitUsingDeclarator( node: ast.UsingDeclaratorAST, context: Context, @@ -124,6 +120,24 @@ export abstract class ASTVisitor { context: Context, ): Result; + // NestedNameSpecifierAST + abstract visitGlobalNestedNameSpecifier( + node: ast.GlobalNestedNameSpecifierAST, + context: Context, + ): Result; + abstract visitSimpleNestedNameSpecifier( + node: ast.SimpleNestedNameSpecifierAST, + context: Context, + ): Result; + abstract visitDecltypeNestedNameSpecifier( + node: ast.DecltypeNestedNameSpecifierAST, + context: Context, + ): Result; + abstract visitTemplateNestedNameSpecifier( + node: ast.TemplateNestedNameSpecifierAST, + context: Context, + ): Result; + // ExceptionSpecifierAST abstract visitThrowExceptionSpecifier( node: ast.ThrowExceptionSpecifierAST, diff --git a/packages/cxx-frontend/src/RecursiveASTVisitor.ts b/packages/cxx-frontend/src/RecursiveASTVisitor.ts index 59347081..9db14fd3 100644 --- a/packages/cxx-frontend/src/RecursiveASTVisitor.ts +++ b/packages/cxx-frontend/src/RecursiveASTVisitor.ts @@ -37,15 +37,6 @@ export class RecursiveASTVisitor extends ASTVisitor { this.accept(node.getDeclarator(), context); } - visitNestedNameSpecifier( - node: ast.NestedNameSpecifierAST, - context: Context, - ): void { - for (const element of node.getNameList()) { - this.accept(element, context); - } - } - visitUsingDeclarator(node: ast.UsingDeclaratorAST, context: Context): void { this.accept(node.getNestedNameSpecifier(), context); this.accept(node.getName(), context); @@ -255,6 +246,34 @@ export class RecursiveASTVisitor extends ASTVisitor { } } + visitGlobalNestedNameSpecifier( + node: ast.GlobalNestedNameSpecifierAST, + context: Context, + ): void {} + + visitSimpleNestedNameSpecifier( + node: ast.SimpleNestedNameSpecifierAST, + context: Context, + ): void { + this.accept(node.getNestedNameSpecifier(), context); + } + + visitDecltypeNestedNameSpecifier( + node: ast.DecltypeNestedNameSpecifierAST, + context: Context, + ): void { + this.accept(node.getNestedNameSpecifier(), context); + this.accept(node.getDecltypeSpecifier(), context); + } + + visitTemplateNestedNameSpecifier( + node: ast.TemplateNestedNameSpecifierAST, + context: Context, + ): void { + this.accept(node.getNestedNameSpecifier(), context); + this.accept(node.getTemplateName(), context); + } + visitThrowExceptionSpecifier( node: ast.ThrowExceptionSpecifierAST, context: Context, diff --git a/src/frontend/cxx/ast_printer.cc b/src/frontend/cxx/ast_printer.cc index 6a16ea1d..8a924a61 100644 --- a/src/frontend/cxx/ast_printer.cc +++ b/src/frontend/cxx/ast_printer.cc @@ -69,19 +69,6 @@ void ASTPrinter::visit(TypeIdAST* ast) { accept(ast->declarator, "declarator"); } -void ASTPrinter::visit(NestedNameSpecifierAST* ast) { - fmt::print(out_, "{}\n", "nested-name-specifier"); - if (ast->nameList) { - ++indent_; - fmt::print(out_, "{:{}}", "", indent_ * 2); - fmt::print(out_, "{}\n", "name-list"); - for (auto it = ast->nameList; it; it = it->next) { - accept(it->value); - } - --indent_; - } -} - void ASTPrinter::visit(UsingDeclaratorAST* ast) { fmt::print(out_, "{}\n", "using-declarator"); accept(ast->nestedNameSpecifier, "nested-name-specifier"); @@ -457,6 +444,28 @@ void ASTPrinter::visit(NewPlacementAST* ast) { } } +void ASTPrinter::visit(GlobalNestedNameSpecifierAST* ast) { + fmt::print(out_, "{}\n", "global-nested-name-specifier"); +} + +void ASTPrinter::visit(SimpleNestedNameSpecifierAST* ast) { + fmt::print(out_, "{}\n", "simple-nested-name-specifier"); + accept(ast->identifier, "identifier"); + accept(ast->nestedNameSpecifier, "nested-name-specifier"); +} + +void ASTPrinter::visit(DecltypeNestedNameSpecifierAST* ast) { + fmt::print(out_, "{}\n", "decltype-nested-name-specifier"); + accept(ast->nestedNameSpecifier, "nested-name-specifier"); + accept(ast->decltypeSpecifier, "decltype-specifier"); +} + +void ASTPrinter::visit(TemplateNestedNameSpecifierAST* ast) { + fmt::print(out_, "{}\n", "template-nested-name-specifier"); + accept(ast->nestedNameSpecifier, "nested-name-specifier"); + accept(ast->templateName, "template-name"); +} + void ASTPrinter::visit(ThrowExceptionSpecifierAST* ast) { fmt::print(out_, "{}\n", "throw-exception-specifier"); } diff --git a/src/frontend/cxx/ast_printer.h b/src/frontend/cxx/ast_printer.h index 4175e8ed..2d905991 100644 --- a/src/frontend/cxx/ast_printer.h +++ b/src/frontend/cxx/ast_printer.h @@ -43,7 +43,6 @@ class ASTPrinter : ASTVisitor { void accept(const Identifier* id, std::string_view field = {}); void visit(TypeIdAST* ast) override; - void visit(NestedNameSpecifierAST* ast) override; void visit(UsingDeclaratorAST* ast) override; void visit(HandlerAST* ast) override; void visit(EnumBaseAST* ast) override; @@ -76,6 +75,11 @@ class ASTPrinter : ASTVisitor { void visit(DesignatorAST* ast) override; void visit(NewPlacementAST* ast) override; + void visit(GlobalNestedNameSpecifierAST* ast) override; + void visit(SimpleNestedNameSpecifierAST* ast) override; + void visit(DecltypeNestedNameSpecifierAST* ast) override; + void visit(TemplateNestedNameSpecifierAST* ast) override; + void visit(ThrowExceptionSpecifierAST* ast) override; void visit(NoexceptSpecifierAST* ast) override; diff --git a/src/parser/cxx/ast.cc b/src/parser/cxx/ast.cc index d0490188..ce60c159 100644 --- a/src/parser/cxx/ast.cc +++ b/src/parser/cxx/ast.cc @@ -36,18 +36,6 @@ auto TypeIdAST::lastSourceLocation() -> SourceLocation { return {}; } -auto NestedNameSpecifierAST::firstSourceLocation() -> SourceLocation { - if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; - if (auto loc = cxx::firstSourceLocation(nameList)) return loc; - return {}; -} - -auto NestedNameSpecifierAST::lastSourceLocation() -> SourceLocation { - if (auto loc = cxx::lastSourceLocation(nameList)) return loc; - if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; - return {}; -} - auto UsingDeclaratorAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(typenameLoc)) return loc; if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; @@ -502,6 +490,60 @@ auto NewPlacementAST::lastSourceLocation() -> SourceLocation { return {}; } +auto GlobalNestedNameSpecifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; + return {}; +} + +auto GlobalNestedNameSpecifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; + return {}; +} + +auto SimpleNestedNameSpecifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; + return {}; +} + +auto SimpleNestedNameSpecifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(identifierLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + return {}; +} + +auto DecltypeNestedNameSpecifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(decltypeSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; + return {}; +} + +auto DecltypeNestedNameSpecifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(decltypeSpecifier)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + return {}; +} + +auto TemplateNestedNameSpecifierAST::firstSourceLocation() -> SourceLocation { + if (auto loc = cxx::firstSourceLocation(nestedNameSpecifier)) return loc; + if (auto loc = cxx::firstSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::firstSourceLocation(templateName)) return loc; + if (auto loc = cxx::firstSourceLocation(scopeLoc)) return loc; + return {}; +} + +auto TemplateNestedNameSpecifierAST::lastSourceLocation() -> SourceLocation { + if (auto loc = cxx::lastSourceLocation(scopeLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(templateName)) return loc; + if (auto loc = cxx::lastSourceLocation(templateLoc)) return loc; + if (auto loc = cxx::lastSourceLocation(nestedNameSpecifier)) return loc; + return {}; +} + auto ThrowExceptionSpecifierAST::firstSourceLocation() -> SourceLocation { if (auto loc = cxx::firstSourceLocation(throwLoc)) return loc; if (auto loc = cxx::firstSourceLocation(lparenLoc)) return loc; diff --git a/src/parser/cxx/ast.fbs b/src/parser/cxx/ast.fbs index 65a7c235..b7c6fc94 100644 --- a/src/parser/cxx/ast.fbs +++ b/src/parser/cxx/ast.fbs @@ -32,7 +32,6 @@ table SourceLocation { union AST { TypeId, - NestedNameSpecifier, UsingDeclarator, Handler, EnumBase, @@ -215,6 +214,13 @@ union Name { QualifiedName, } +union NestedNameSpecifier { + GlobalNestedNameSpecifier, + SimpleNestedNameSpecifier, + DecltypeNestedNameSpecifier, + TemplateNestedNameSpecifier, +} + union NewInitializer { NewParenInitializer, NewBracedInitializer, @@ -304,11 +310,6 @@ table TypeId /* AST */ { declarator: Declarator; } -table NestedNameSpecifier /* AST */ { - name_list: [Name]; - scope_loc: SourceLocation; -} - table UsingDeclarator /* AST */ { nested_name_specifier: NestedNameSpecifier; name: Name; @@ -1247,7 +1248,7 @@ table DestructorName /* NameAST */ { } table DecltypeName /* NameAST */ { - decltype_specifier: Specifier; + decltype_specifier: DecltypeSpecifier; } table OperatorName /* NameAST */ { @@ -1283,6 +1284,30 @@ table QualifiedName /* NameAST */ { template_loc: SourceLocation; } +table GlobalNestedNameSpecifier /* NestedNameSpecifierAST */ { + scope_loc: SourceLocation; +} + +table SimpleNestedNameSpecifier /* NestedNameSpecifierAST */ { + nested_name_specifier: NestedNameSpecifier; + identifier: string; + identifier_loc: SourceLocation; + scope_loc: SourceLocation; +} + +table DecltypeNestedNameSpecifier /* NestedNameSpecifierAST */ { + nested_name_specifier: NestedNameSpecifier; + decltype_specifier: DecltypeSpecifier; + scope_loc: SourceLocation; +} + +table TemplateNestedNameSpecifier /* NestedNameSpecifierAST */ { + nested_name_specifier: NestedNameSpecifier; + template_name: TemplateName; + template_loc: SourceLocation; + scope_loc: SourceLocation; +} + table NewParenInitializer /* NewInitializerAST */ { expression_list: [Expression]; lparen_loc: SourceLocation; diff --git a/src/parser/cxx/ast.h b/src/parser/cxx/ast.h index 77a83a04..966dc04e 100644 --- a/src/parser/cxx/ast.h +++ b/src/parser/cxx/ast.h @@ -162,6 +162,11 @@ class NameAST : public AST { using AST::AST; }; +class NestedNameSpecifierAST : public AST { + public: + using AST::AST; +}; + class NewInitializerAST : public AST { public: using AST::AST; @@ -210,19 +215,6 @@ class TypeIdAST final : public AST { auto lastSourceLocation() -> SourceLocation override; }; -class NestedNameSpecifierAST final : public AST { - public: - NestedNameSpecifierAST() : AST(ASTKind::NestedNameSpecifier) {} - - SourceLocation scopeLoc; - List* nameList = nullptr; - - void accept(ASTVisitor* visitor) override { visitor->visit(this); } - - auto firstSourceLocation() -> SourceLocation override; - auto lastSourceLocation() -> SourceLocation override; -}; - class UsingDeclaratorAST final : public AST { public: UsingDeclaratorAST() : AST(ASTKind::UsingDeclarator) {} @@ -673,6 +665,66 @@ class NewPlacementAST final : public AST { auto lastSourceLocation() -> SourceLocation override; }; +class GlobalNestedNameSpecifierAST final : public NestedNameSpecifierAST { + public: + GlobalNestedNameSpecifierAST() + : NestedNameSpecifierAST(ASTKind::GlobalNestedNameSpecifier) {} + + SourceLocation scopeLoc; + + void accept(ASTVisitor* visitor) override { visitor->visit(this); } + + auto firstSourceLocation() -> SourceLocation override; + auto lastSourceLocation() -> SourceLocation override; +}; + +class SimpleNestedNameSpecifierAST final : public NestedNameSpecifierAST { + public: + SimpleNestedNameSpecifierAST() + : NestedNameSpecifierAST(ASTKind::SimpleNestedNameSpecifier) {} + + NestedNameSpecifierAST* nestedNameSpecifier = nullptr; + SourceLocation identifierLoc; + const Identifier* identifier = nullptr; + SourceLocation scopeLoc; + + void accept(ASTVisitor* visitor) override { visitor->visit(this); } + + auto firstSourceLocation() -> SourceLocation override; + auto lastSourceLocation() -> SourceLocation override; +}; + +class DecltypeNestedNameSpecifierAST final : public NestedNameSpecifierAST { + public: + DecltypeNestedNameSpecifierAST() + : NestedNameSpecifierAST(ASTKind::DecltypeNestedNameSpecifier) {} + + NestedNameSpecifierAST* nestedNameSpecifier = nullptr; + DecltypeSpecifierAST* decltypeSpecifier = nullptr; + SourceLocation scopeLoc; + + void accept(ASTVisitor* visitor) override { visitor->visit(this); } + + auto firstSourceLocation() -> SourceLocation override; + auto lastSourceLocation() -> SourceLocation override; +}; + +class TemplateNestedNameSpecifierAST final : public NestedNameSpecifierAST { + public: + TemplateNestedNameSpecifierAST() + : NestedNameSpecifierAST(ASTKind::TemplateNestedNameSpecifier) {} + + NestedNameSpecifierAST* nestedNameSpecifier = nullptr; + SourceLocation templateLoc; + TemplateNameAST* templateName = nullptr; + SourceLocation scopeLoc; + + void accept(ASTVisitor* visitor) override { visitor->visit(this); } + + auto firstSourceLocation() -> SourceLocation override; + auto lastSourceLocation() -> SourceLocation override; +}; + class ThrowExceptionSpecifierAST final : public ExceptionSpecifierAST { public: ThrowExceptionSpecifierAST() @@ -2542,7 +2594,7 @@ class DecltypeNameAST final : public NameAST { public: DecltypeNameAST() : NameAST(ASTKind::DecltypeName) {} - SpecifierAST* decltypeSpecifier = nullptr; + DecltypeSpecifierAST* decltypeSpecifier = nullptr; void accept(ASTVisitor* visitor) override { visitor->visit(this); } diff --git a/src/parser/cxx/ast_cloner.cc b/src/parser/cxx/ast_cloner.cc index d61b9e5c..4d533414 100644 --- a/src/parser/cxx/ast_cloner.cc +++ b/src/parser/cxx/ast_cloner.cc @@ -48,24 +48,6 @@ void ASTCloner::visit(TypeIdAST* ast) { copy->declarator = accept(ast->declarator); } -void ASTCloner::visit(NestedNameSpecifierAST* ast) { - auto copy = new (arena_) NestedNameSpecifierAST(); - copy_ = copy; - - copy->setChecked(ast->checked()); - - copy->scopeLoc = ast->scopeLoc; - - if (auto it = ast->nameList) { - auto out = ©->nameList; - - for (; it; it = it->next) { - *out = new (arena_) List(accept(it->value)); - out = &(*out)->next; - } - } -} - void ASTCloner::visit(UsingDeclaratorAST* ast) { auto copy = new (arena_) UsingDeclaratorAST(); copy_ = copy; @@ -655,6 +637,58 @@ void ASTCloner::visit(NewPlacementAST* ast) { copy->rparenLoc = ast->rparenLoc; } +void ASTCloner::visit(GlobalNestedNameSpecifierAST* ast) { + auto copy = new (arena_) GlobalNestedNameSpecifierAST(); + copy_ = copy; + + copy->setChecked(ast->checked()); + + copy->scopeLoc = ast->scopeLoc; +} + +void ASTCloner::visit(SimpleNestedNameSpecifierAST* ast) { + auto copy = new (arena_) SimpleNestedNameSpecifierAST(); + copy_ = copy; + + copy->setChecked(ast->checked()); + + copy->nestedNameSpecifier = accept(ast->nestedNameSpecifier); + + copy->identifierLoc = ast->identifierLoc; + + copy->identifier = ast->identifier; + + copy->scopeLoc = ast->scopeLoc; +} + +void ASTCloner::visit(DecltypeNestedNameSpecifierAST* ast) { + auto copy = new (arena_) DecltypeNestedNameSpecifierAST(); + copy_ = copy; + + copy->setChecked(ast->checked()); + + copy->nestedNameSpecifier = accept(ast->nestedNameSpecifier); + + copy->decltypeSpecifier = accept(ast->decltypeSpecifier); + + copy->scopeLoc = ast->scopeLoc; +} + +void ASTCloner::visit(TemplateNestedNameSpecifierAST* ast) { + auto copy = new (arena_) TemplateNestedNameSpecifierAST(); + copy_ = copy; + + copy->setChecked(ast->checked()); + + copy->nestedNameSpecifier = accept(ast->nestedNameSpecifier); + + copy->templateLoc = ast->templateLoc; + + copy->templateName = accept(ast->templateName); + + copy->scopeLoc = ast->scopeLoc; +} + void ASTCloner::visit(ThrowExceptionSpecifierAST* ast) { auto copy = new (arena_) ThrowExceptionSpecifierAST(); copy_ = copy; diff --git a/src/parser/cxx/ast_cloner.h b/src/parser/cxx/ast_cloner.h index b21f00d9..3c813f9a 100644 --- a/src/parser/cxx/ast_cloner.h +++ b/src/parser/cxx/ast_cloner.h @@ -31,7 +31,6 @@ class ASTCloner : public ASTVisitor { virtual auto clone(AST* ast, Arena* arena) -> AST*; void visit(TypeIdAST* ast) override; - void visit(NestedNameSpecifierAST* ast) override; void visit(UsingDeclaratorAST* ast) override; void visit(HandlerAST* ast) override; void visit(EnumBaseAST* ast) override; @@ -64,6 +63,11 @@ class ASTCloner : public ASTVisitor { void visit(DesignatorAST* ast) override; void visit(NewPlacementAST* ast) override; + void visit(GlobalNestedNameSpecifierAST* ast) override; + void visit(SimpleNestedNameSpecifierAST* ast) override; + void visit(DecltypeNestedNameSpecifierAST* ast) override; + void visit(TemplateNestedNameSpecifierAST* ast) override; + void visit(ThrowExceptionSpecifierAST* ast) override; void visit(NoexceptSpecifierAST* ast) override; diff --git a/src/parser/cxx/ast_decoder.cc b/src/parser/cxx/ast_decoder.cc index 2f3e69d8..bb3d522c 100644 --- a/src/parser/cxx/ast_decoder.cc +++ b/src/parser/cxx/ast_decoder.cc @@ -47,6 +47,27 @@ auto ASTDecoder::operator()(std::span bytes) -> bool { return true; } +auto ASTDecoder::decodeNestedNameSpecifier(const void* ptr, + io::NestedNameSpecifier type) + -> NestedNameSpecifierAST* { + switch (type) { + case io::NestedNameSpecifier_GlobalNestedNameSpecifier: + return decodeGlobalNestedNameSpecifier( + reinterpret_cast(ptr)); + case io::NestedNameSpecifier_SimpleNestedNameSpecifier: + return decodeSimpleNestedNameSpecifier( + reinterpret_cast(ptr)); + case io::NestedNameSpecifier_DecltypeNestedNameSpecifier: + return decodeDecltypeNestedNameSpecifier( + reinterpret_cast(ptr)); + case io::NestedNameSpecifier_TemplateNestedNameSpecifier: + return decodeTemplateNestedNameSpecifier( + reinterpret_cast(ptr)); + default: + return nullptr; + } // switch +} + auto ASTDecoder::decodeExceptionSpecifier(const void* ptr, io::ExceptionSpecifier type) -> ExceptionSpecifierAST* { @@ -734,29 +755,13 @@ auto ASTDecoder::decodeTypeId(const io::TypeId* node) -> TypeIdAST* { return ast; } -auto ASTDecoder::decodeNestedNameSpecifier(const io::NestedNameSpecifier* node) - -> NestedNameSpecifierAST* { - if (!node) return nullptr; - - auto ast = new (pool_) NestedNameSpecifierAST(); - if (node->name_list()) { - auto* inserter = &ast->nameList; - for (std::size_t i = 0; i < node->name_list()->size(); ++i) { - *inserter = new (pool_) List(decodeName( - node->name_list()->Get(i), io::Name(node->name_list_type()->Get(i)))); - inserter = &(*inserter)->next; - } - } - return ast; -} - auto ASTDecoder::decodeUsingDeclarator(const io::UsingDeclarator* node) -> UsingDeclaratorAST* { if (!node) return nullptr; auto ast = new (pool_) UsingDeclaratorAST(); - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); return ast; } @@ -1083,8 +1088,8 @@ auto ASTDecoder::decodeTypeConstraint(const io::TypeConstraint* node) if (!node) return nullptr; auto ast = new (pool_) TypeConstraintAST(); - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); if (node->template_argument_list()) { auto* inserter = &ast->templateArgumentList; for (std::size_t i = 0; i < node->template_argument_list()->size(); ++i) { @@ -1255,6 +1260,54 @@ auto ASTDecoder::decodeNewPlacement(const io::NewPlacement* node) return ast; } +auto ASTDecoder::decodeGlobalNestedNameSpecifier( + const io::GlobalNestedNameSpecifier* node) + -> GlobalNestedNameSpecifierAST* { + if (!node) return nullptr; + + auto ast = new (pool_) GlobalNestedNameSpecifierAST(); + return ast; +} + +auto ASTDecoder::decodeSimpleNestedNameSpecifier( + const io::SimpleNestedNameSpecifier* node) + -> SimpleNestedNameSpecifierAST* { + if (!node) return nullptr; + + auto ast = new (pool_) SimpleNestedNameSpecifierAST(); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); + if (node->identifier()) { + ast->identifier = + unit_->control()->getIdentifier(node->identifier()->str()); + } + return ast; +} + +auto ASTDecoder::decodeDecltypeNestedNameSpecifier( + const io::DecltypeNestedNameSpecifier* node) + -> DecltypeNestedNameSpecifierAST* { + if (!node) return nullptr; + + auto ast = new (pool_) DecltypeNestedNameSpecifierAST(); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); + ast->decltypeSpecifier = decodeDecltypeSpecifier(node->decltype_specifier()); + return ast; +} + +auto ASTDecoder::decodeTemplateNestedNameSpecifier( + const io::TemplateNestedNameSpecifier* node) + -> TemplateNestedNameSpecifierAST* { + if (!node) return nullptr; + + auto ast = new (pool_) TemplateNestedNameSpecifierAST(); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); + ast->templateName = decodeTemplateName(node->template_name()); + return ast; +} + auto ASTDecoder::decodeThrowExceptionSpecifier( const io::ThrowExceptionSpecifier* node) -> ThrowExceptionSpecifierAST* { if (!node) return nullptr; @@ -1872,8 +1925,8 @@ auto ASTDecoder::decodeTypeRequirement(const io::TypeRequirement* node) if (!node) return nullptr; auto ast = new (pool_) TypeRequirementAST(); - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); return ast; } @@ -2564,8 +2617,8 @@ auto ASTDecoder::decodeOpaqueEnumDeclaration( inserter = &(*inserter)->next; } } - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); ast->enumBase = decodeEnumBase(node->enum_base()); return ast; @@ -2636,8 +2689,8 @@ auto ASTDecoder::decodeNamespaceAliasDefinition( if (!node) return nullptr; auto ast = new (pool_) NamespaceAliasDefinitionAST(); - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); if (node->identifier()) { ast->identifier = @@ -2660,8 +2713,8 @@ auto ASTDecoder::decodeUsingDirective(const io::UsingDirective* node) inserter = &(*inserter)->next; } } - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); return ast; } @@ -2936,8 +2989,7 @@ auto ASTDecoder::decodeDecltypeName(const io::DecltypeName* node) if (!node) return nullptr; auto ast = new (pool_) DecltypeNameAST(); - ast->decltypeSpecifier = decodeSpecifier(node->decltype_specifier(), - node->decltype_specifier_type()); + ast->decltypeSpecifier = decodeDecltypeSpecifier(node->decltype_specifier()); return ast; } @@ -2994,8 +3046,8 @@ auto ASTDecoder::decodeQualifiedName(const io::QualifiedName* node) if (!node) return nullptr; auto ast = new (pool_) QualifiedNameAST(); - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->id = decodeName(node->id(), node->id_type()); return ast; } @@ -3199,8 +3251,8 @@ auto ASTDecoder::decodeElaboratedTypeSpecifier( inserter = &(*inserter)->next; } } - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); ast->classKey = static_cast(node->class_key()); return ast; @@ -3272,8 +3324,8 @@ auto ASTDecoder::decodeEnumSpecifier(const io::EnumSpecifier* node) inserter = &(*inserter)->next; } } - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); ast->enumBase = decodeEnumBase(node->enum_base()); if (node->enumerator_list()) { @@ -3301,8 +3353,8 @@ auto ASTDecoder::decodeClassSpecifier(const io::ClassSpecifier* node) inserter = &(*inserter)->next; } } - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); ast->baseClause = decodeBaseClause(node->base_clause()); if (node->declaration_list()) { @@ -3323,8 +3375,8 @@ auto ASTDecoder::decodeTypenameSpecifier(const io::TypenameSpecifier* node) if (!node) return nullptr; auto ast = new (pool_) TypenameSpecifierAST(); - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); ast->name = decodeName(node->name(), node->name_type()); return ast; } @@ -3429,8 +3481,8 @@ auto ASTDecoder::decodePtrToMemberOperator(const io::PtrToMemberOperator* node) if (!node) return nullptr; auto ast = new (pool_) PtrToMemberOperatorAST(); - ast->nestedNameSpecifier = - decodeNestedNameSpecifier(node->nested_name_specifier()); + ast->nestedNameSpecifier = decodeNestedNameSpecifier( + node->nested_name_specifier(), node->nested_name_specifier_type()); if (node->attribute_list()) { auto* inserter = &ast->attributeList; for (std::size_t i = 0; i < node->attribute_list()->size(); ++i) { diff --git a/src/parser/cxx/ast_encoder.cc b/src/parser/cxx/ast_encoder.cc index 65f693b7..933c47ed 100644 --- a/src/parser/cxx/ast_encoder.cc +++ b/src/parser/cxx/ast_encoder.cc @@ -126,6 +126,19 @@ auto ASTEncoder::encodeSourceLocation(const SourceLocation& loc) return offset.Union(); } +auto ASTEncoder::acceptNestedNameSpecifier(NestedNameSpecifierAST* ast) + -> std::tuple, std::uint32_t> { + if (!ast) return {}; + flatbuffers::Offset<> offset; + std::uint32_t type = 0; + std::swap(offset, offset_); + std::swap(type, type_); + ast->accept(this); + std::swap(offset, offset_); + std::swap(type, type_); + return {offset, type}; +} + auto ASTEncoder::acceptExceptionSpecifier(ExceptionSpecifierAST* ast) -> std::tuple, std::uint32_t> { if (!ast) return {}; @@ -398,40 +411,19 @@ void ASTEncoder::visit(TypeIdAST* ast) { offset_ = builder.Finish().Union(); } -void ASTEncoder::visit(NestedNameSpecifierAST* ast) { - auto scopeLoc = encodeSourceLocation(ast->scopeLoc); - - std::vector> nameListOffsets; - std::vector> nameListTypes; - - for (auto it = ast->nameList; it; it = it->next) { - if (!it->value) continue; - const auto [offset, type] = acceptName(it->value); - nameListOffsets.push_back(offset); - nameListTypes.push_back(type); - } - - auto nameListOffsetsVector = fbb_.CreateVector(nameListOffsets); - auto nameListTypesVector = fbb_.CreateVector(nameListTypes); - - io::NestedNameSpecifier::Builder builder{fbb_}; - builder.add_scope_loc(scopeLoc.o); - builder.add_name_list(nameListOffsetsVector); - builder.add_name_list_type(nameListTypesVector); - - offset_ = builder.Finish().Union(); -} - void ASTEncoder::visit(UsingDeclaratorAST* ast) { auto typenameLoc = encodeSourceLocation(ast->typenameLoc); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); io::UsingDeclarator::Builder builder{fbb_}; builder.add_typename_loc(typenameLoc.o); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); @@ -942,7 +934,8 @@ void ASTEncoder::visit(RequirementBodyAST* ast) { } void ASTEncoder::visit(TypeConstraintAST* ast) { - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); auto identifierLoc = encodeSourceLocation(ast->identifierLoc); @@ -977,7 +970,9 @@ void ASTEncoder::visit(TypeConstraintAST* ast) { } io::TypeConstraint::Builder builder{fbb_}; - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_identifier_loc(identifierLoc.o); builder.add_less_loc(lessLoc.o); builder.add_template_argument_list(templateArgumentListOffsetsVector); @@ -1264,6 +1259,89 @@ void ASTEncoder::visit(NewPlacementAST* ast) { offset_ = builder.Finish().Union(); } +void ASTEncoder::visit(GlobalNestedNameSpecifierAST* ast) { + auto scopeLoc = encodeSourceLocation(ast->scopeLoc); + + io::GlobalNestedNameSpecifier::Builder builder{fbb_}; + builder.add_scope_loc(scopeLoc.o); + + offset_ = builder.Finish().Union(); + type_ = io::NestedNameSpecifier_GlobalNestedNameSpecifier; +} + +void ASTEncoder::visit(SimpleNestedNameSpecifierAST* ast) { + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); + + auto identifierLoc = encodeSourceLocation(ast->identifierLoc); + + flatbuffers::Offset identifier; + if (ast->identifier) { + if (identifiers_.contains(ast->identifier)) { + identifier = identifiers_.at(ast->identifier); + } else { + identifier = fbb_.CreateString(ast->identifier->value()); + identifiers_.emplace(ast->identifier, identifier); + } + } + + auto scopeLoc = encodeSourceLocation(ast->scopeLoc); + + io::SimpleNestedNameSpecifier::Builder builder{fbb_}; + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); + builder.add_identifier_loc(identifierLoc.o); + if (ast->identifier) { + builder.add_identifier(identifier); + } + builder.add_scope_loc(scopeLoc.o); + + offset_ = builder.Finish().Union(); + type_ = io::NestedNameSpecifier_SimpleNestedNameSpecifier; +} + +void ASTEncoder::visit(DecltypeNestedNameSpecifierAST* ast) { + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); + + const auto decltypeSpecifier = accept(ast->decltypeSpecifier); + + auto scopeLoc = encodeSourceLocation(ast->scopeLoc); + + io::DecltypeNestedNameSpecifier::Builder builder{fbb_}; + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); + builder.add_decltype_specifier(decltypeSpecifier.o); + builder.add_scope_loc(scopeLoc.o); + + offset_ = builder.Finish().Union(); + type_ = io::NestedNameSpecifier_DecltypeNestedNameSpecifier; +} + +void ASTEncoder::visit(TemplateNestedNameSpecifierAST* ast) { + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); + + auto templateLoc = encodeSourceLocation(ast->templateLoc); + + const auto templateName = accept(ast->templateName); + + auto scopeLoc = encodeSourceLocation(ast->scopeLoc); + + io::TemplateNestedNameSpecifier::Builder builder{fbb_}; + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); + builder.add_template_loc(templateLoc.o); + builder.add_template_name(templateName.o); + builder.add_scope_loc(scopeLoc.o); + + offset_ = builder.Finish().Union(); + type_ = io::NestedNameSpecifier_TemplateNestedNameSpecifier; +} + void ASTEncoder::visit(ThrowExceptionSpecifierAST* ast) { auto throwLoc = encodeSourceLocation(ast->throwLoc); @@ -2382,7 +2460,8 @@ void ASTEncoder::visit(CompoundRequirementAST* ast) { void ASTEncoder::visit(TypeRequirementAST* ast) { auto typenameLoc = encodeSourceLocation(ast->typenameLoc); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); @@ -2390,7 +2469,9 @@ void ASTEncoder::visit(TypeRequirementAST* ast) { io::TypeRequirement::Builder builder{fbb_}; builder.add_typename_loc(typenameLoc.o); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); builder.add_semicolon_loc(semicolonLoc.o); @@ -3645,7 +3726,8 @@ void ASTEncoder::visit(OpaqueEnumDeclarationAST* ast) { auto attributeListOffsetsVector = fbb_.CreateVector(attributeListOffsets); auto attributeListTypesVector = fbb_.CreateVector(attributeListTypes); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); @@ -3658,7 +3740,9 @@ void ASTEncoder::visit(OpaqueEnumDeclarationAST* ast) { builder.add_class_loc(classLoc.o); builder.add_attribute_list(attributeListOffsetsVector); builder.add_attribute_list_type(attributeListTypesVector); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); builder.add_enum_base(enumBase.o); @@ -3800,7 +3884,8 @@ void ASTEncoder::visit(NamespaceAliasDefinitionAST* ast) { auto equalLoc = encodeSourceLocation(ast->equalLoc); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); @@ -3820,7 +3905,9 @@ void ASTEncoder::visit(NamespaceAliasDefinitionAST* ast) { builder.add_namespace_loc(namespaceLoc.o); builder.add_identifier_loc(identifierLoc.o); builder.add_equal_loc(equalLoc.o); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); builder.add_semicolon_loc(semicolonLoc.o); @@ -3851,7 +3938,8 @@ void ASTEncoder::visit(UsingDirectiveAST* ast) { auto namespaceLoc = encodeSourceLocation(ast->namespaceLoc); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); @@ -3862,7 +3950,9 @@ void ASTEncoder::visit(UsingDirectiveAST* ast) { builder.add_attribute_list_type(attributeListTypesVector); builder.add_using_loc(usingLoc.o); builder.add_namespace_loc(namespaceLoc.o); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); builder.add_semicolon_loc(semicolonLoc.o); @@ -4424,13 +4514,10 @@ void ASTEncoder::visit(DestructorNameAST* ast) { } void ASTEncoder::visit(DecltypeNameAST* ast) { - const auto [decltypeSpecifier, decltypeSpecifierType] = - acceptSpecifier(ast->decltypeSpecifier); + const auto decltypeSpecifier = accept(ast->decltypeSpecifier); io::DecltypeName::Builder builder{fbb_}; - builder.add_decltype_specifier(decltypeSpecifier); - builder.add_decltype_specifier_type( - static_cast(decltypeSpecifierType)); + builder.add_decltype_specifier(decltypeSpecifier.o); offset_ = builder.Finish().Union(); type_ = io::Name_DecltypeName; @@ -4534,14 +4621,17 @@ void ASTEncoder::visit(TemplateNameAST* ast) { } void ASTEncoder::visit(QualifiedNameAST* ast) { - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); auto templateLoc = encodeSourceLocation(ast->templateLoc); const auto [id, idType] = acceptName(ast->id); io::QualifiedName::Builder builder{fbb_}; - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_template_loc(templateLoc.o); builder.add_id(id); builder.add_id_type(static_cast(idType)); @@ -4819,7 +4909,8 @@ void ASTEncoder::visit(ElaboratedTypeSpecifierAST* ast) { auto attributeListOffsetsVector = fbb_.CreateVector(attributeListOffsets); auto attributeListTypesVector = fbb_.CreateVector(attributeListTypes); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); @@ -4827,7 +4918,9 @@ void ASTEncoder::visit(ElaboratedTypeSpecifierAST* ast) { builder.add_class_loc(classLoc.o); builder.add_attribute_list(attributeListOffsetsVector); builder.add_attribute_list_type(attributeListTypesVector); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); builder.add_class_key(static_cast(ast->classKey)); @@ -4938,7 +5031,8 @@ void ASTEncoder::visit(EnumSpecifierAST* ast) { auto attributeListOffsetsVector = fbb_.CreateVector(attributeListOffsets); auto attributeListTypesVector = fbb_.CreateVector(attributeListTypes); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); @@ -4963,7 +5057,9 @@ void ASTEncoder::visit(EnumSpecifierAST* ast) { builder.add_class_loc(classLoc.o); builder.add_attribute_list(attributeListOffsetsVector); builder.add_attribute_list_type(attributeListTypesVector); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); builder.add_enum_base(enumBase.o); @@ -4993,7 +5089,8 @@ void ASTEncoder::visit(ClassSpecifierAST* ast) { auto attributeListOffsetsVector = fbb_.CreateVector(attributeListOffsets); auto attributeListTypesVector = fbb_.CreateVector(attributeListTypes); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); @@ -5022,7 +5119,9 @@ void ASTEncoder::visit(ClassSpecifierAST* ast) { builder.add_class_loc(classLoc.o); builder.add_attribute_list(attributeListOffsetsVector); builder.add_attribute_list_type(attributeListTypesVector); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); builder.add_final_loc(finalLoc.o); @@ -5040,13 +5139,16 @@ void ASTEncoder::visit(ClassSpecifierAST* ast) { void ASTEncoder::visit(TypenameSpecifierAST* ast) { auto typenameLoc = encodeSourceLocation(ast->typenameLoc); - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); const auto [name, nameType] = acceptName(ast->name); io::TypenameSpecifier::Builder builder{fbb_}; builder.add_typename_loc(typenameLoc.o); - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_name(name); builder.add_name_type(static_cast(nameType)); @@ -5214,7 +5316,8 @@ void ASTEncoder::visit(ReferenceOperatorAST* ast) { } void ASTEncoder::visit(PtrToMemberOperatorAST* ast) { - const auto nestedNameSpecifier = accept(ast->nestedNameSpecifier); + const auto [nestedNameSpecifier, nestedNameSpecifierType] = + acceptNestedNameSpecifier(ast->nestedNameSpecifier); auto starLoc = encodeSourceLocation(ast->starLoc); @@ -5246,7 +5349,9 @@ void ASTEncoder::visit(PtrToMemberOperatorAST* ast) { auto cvQualifierListTypesVector = fbb_.CreateVector(cvQualifierListTypes); io::PtrToMemberOperator::Builder builder{fbb_}; - builder.add_nested_name_specifier(nestedNameSpecifier.o); + builder.add_nested_name_specifier(nestedNameSpecifier); + builder.add_nested_name_specifier_type( + static_cast(nestedNameSpecifierType)); builder.add_star_loc(starLoc.o); builder.add_attribute_list(attributeListOffsetsVector); builder.add_attribute_list_type(attributeListTypesVector); diff --git a/src/parser/cxx/ast_fwd.h b/src/parser/cxx/ast_fwd.h index 2274a80d..3afc0fde 100644 --- a/src/parser/cxx/ast_fwd.h +++ b/src/parser/cxx/ast_fwd.h @@ -64,6 +64,7 @@ class FunctionBodyAST; class LambdaCaptureAST; class MemInitializerAST; class NameAST; +class NestedNameSpecifierAST; class NewInitializerAST; class PtrOperatorAST; class RequirementAST; @@ -74,7 +75,6 @@ class UnitAST; // AST class TypeIdAST; -class NestedNameSpecifierAST; class UsingDeclaratorAST; class HandlerAST; class EnumBaseAST; @@ -107,6 +107,12 @@ class AttributeUsingPrefixAST; class DesignatorAST; class NewPlacementAST; +// NestedNameSpecifierAST +class GlobalNestedNameSpecifierAST; +class SimpleNestedNameSpecifierAST; +class DecltypeNestedNameSpecifierAST; +class TemplateNestedNameSpecifierAST; + // ExceptionSpecifierAST class ThrowExceptionSpecifierAST; class NoexceptSpecifierAST; diff --git a/src/parser/cxx/ast_kind.h b/src/parser/cxx/ast_kind.h index b1acb2a4..f03af5d2 100644 --- a/src/parser/cxx/ast_kind.h +++ b/src/parser/cxx/ast_kind.h @@ -26,7 +26,6 @@ enum struct ASTKind { // AST TypeId, - NestedNameSpecifier, UsingDeclarator, Handler, EnumBase, @@ -59,6 +58,12 @@ enum struct ASTKind { Designator, NewPlacement, + // NestedNameSpecifierAST + GlobalNestedNameSpecifier, + SimpleNestedNameSpecifier, + DecltypeNestedNameSpecifier, + TemplateNestedNameSpecifier, + // ExceptionSpecifierAST ThrowExceptionSpecifier, NoexceptSpecifier, diff --git a/src/parser/cxx/ast_slot.cc b/src/parser/cxx/ast_slot.cc index eebfb19a..82735026 100644 --- a/src/parser/cxx/ast_slot.cc +++ b/src/parser/cxx/ast_slot.cc @@ -60,21 +60,6 @@ void ASTSlot::visit(TypeIdAST* ast) { slotCount_ = 2; } -void ASTSlot::visit(NestedNameSpecifierAST* ast) { - switch (slot_) { - case 0: // scopeLoc - value_ = ast->scopeLoc.index(); - slotKind_ = ASTSlotKind::kToken; - break; - case 1: // nameList - value_ = reinterpret_cast(ast->nameList); - slotKind_ = ASTSlotKind::kNodeList; - break; - } // switch - - slotCount_ = 2; -} - void ASTSlot::visit(UsingDeclaratorAST* ast) { switch (slot_) { case 0: // typenameLoc @@ -728,6 +713,82 @@ void ASTSlot::visit(NewPlacementAST* ast) { slotCount_ = 3; } +void ASTSlot::visit(GlobalNestedNameSpecifierAST* ast) { + switch (slot_) { + case 0: // scopeLoc + value_ = ast->scopeLoc.index(); + slotKind_ = ASTSlotKind::kToken; + break; + } // switch + + slotCount_ = 1; +} + +void ASTSlot::visit(SimpleNestedNameSpecifierAST* ast) { + switch (slot_) { + case 0: // nestedNameSpecifier + value_ = reinterpret_cast(ast->nestedNameSpecifier); + slotKind_ = ASTSlotKind::kNode; + break; + case 1: // identifierLoc + value_ = ast->identifierLoc.index(); + slotKind_ = ASTSlotKind::kToken; + break; + case 2: // identifier + value_ = reinterpret_cast(ast->identifier); + slotKind_ = ASTSlotKind::kIdentifierAttribute; + break; + case 3: // scopeLoc + value_ = ast->scopeLoc.index(); + slotKind_ = ASTSlotKind::kToken; + break; + } // switch + + slotCount_ = 4; +} + +void ASTSlot::visit(DecltypeNestedNameSpecifierAST* ast) { + switch (slot_) { + case 0: // nestedNameSpecifier + value_ = reinterpret_cast(ast->nestedNameSpecifier); + slotKind_ = ASTSlotKind::kNode; + break; + case 1: // decltypeSpecifier + value_ = reinterpret_cast(ast->decltypeSpecifier); + slotKind_ = ASTSlotKind::kNode; + break; + case 2: // scopeLoc + value_ = ast->scopeLoc.index(); + slotKind_ = ASTSlotKind::kToken; + break; + } // switch + + slotCount_ = 3; +} + +void ASTSlot::visit(TemplateNestedNameSpecifierAST* ast) { + switch (slot_) { + case 0: // nestedNameSpecifier + value_ = reinterpret_cast(ast->nestedNameSpecifier); + slotKind_ = ASTSlotKind::kNode; + break; + case 1: // templateLoc + value_ = ast->templateLoc.index(); + slotKind_ = ASTSlotKind::kToken; + break; + case 2: // templateName + value_ = reinterpret_cast(ast->templateName); + slotKind_ = ASTSlotKind::kNode; + break; + case 3: // scopeLoc + value_ = ast->scopeLoc.index(); + slotKind_ = ASTSlotKind::kToken; + break; + } // switch + + slotCount_ = 4; +} + void ASTSlot::visit(ThrowExceptionSpecifierAST* ast) { switch (slot_) { case 0: // throwLoc diff --git a/src/parser/cxx/ast_slot.h b/src/parser/cxx/ast_slot.h index b8c0bd94..a373eb31 100644 --- a/src/parser/cxx/ast_slot.h +++ b/src/parser/cxx/ast_slot.h @@ -46,7 +46,6 @@ class ASTSlot final : ASTVisitor { private: void visit(TypeIdAST* ast) override; - void visit(NestedNameSpecifierAST* ast) override; void visit(UsingDeclaratorAST* ast) override; void visit(HandlerAST* ast) override; void visit(EnumBaseAST* ast) override; @@ -79,6 +78,11 @@ class ASTSlot final : ASTVisitor { void visit(DesignatorAST* ast) override; void visit(NewPlacementAST* ast) override; + void visit(GlobalNestedNameSpecifierAST* ast) override; + void visit(SimpleNestedNameSpecifierAST* ast) override; + void visit(DecltypeNestedNameSpecifierAST* ast) override; + void visit(TemplateNestedNameSpecifierAST* ast) override; + void visit(ThrowExceptionSpecifierAST* ast) override; void visit(NoexceptSpecifierAST* ast) override; diff --git a/src/parser/cxx/ast_visitor.h b/src/parser/cxx/ast_visitor.h index 62943bfc..cd1d8234 100644 --- a/src/parser/cxx/ast_visitor.h +++ b/src/parser/cxx/ast_visitor.h @@ -30,7 +30,6 @@ class ASTVisitor { // AST virtual void visit(TypeIdAST* ast) = 0; - virtual void visit(NestedNameSpecifierAST* ast) = 0; virtual void visit(UsingDeclaratorAST* ast) = 0; virtual void visit(HandlerAST* ast) = 0; virtual void visit(EnumBaseAST* ast) = 0; @@ -63,6 +62,12 @@ class ASTVisitor { virtual void visit(DesignatorAST* ast) = 0; virtual void visit(NewPlacementAST* ast) = 0; + // NestedNameSpecifierAST + virtual void visit(GlobalNestedNameSpecifierAST* ast) = 0; + virtual void visit(SimpleNestedNameSpecifierAST* ast) = 0; + virtual void visit(DecltypeNestedNameSpecifierAST* ast) = 0; + virtual void visit(TemplateNestedNameSpecifierAST* ast) = 0; + // ExceptionSpecifierAST virtual void visit(ThrowExceptionSpecifierAST* ast) = 0; virtual void visit(NoexceptSpecifierAST* ast) = 0; diff --git a/src/parser/cxx/default_ast_visitor.cc b/src/parser/cxx/default_ast_visitor.cc index dbf60878..7b8b9405 100644 --- a/src/parser/cxx/default_ast_visitor.cc +++ b/src/parser/cxx/default_ast_visitor.cc @@ -30,10 +30,6 @@ void DefaultASTVisitor::visit(TypeIdAST* ast) { cxx_runtime_error("visit(TypeIdAST): not implemented"); } -void DefaultASTVisitor::visit(NestedNameSpecifierAST* ast) { - cxx_runtime_error("visit(NestedNameSpecifierAST): not implemented"); -} - void DefaultASTVisitor::visit(UsingDeclaratorAST* ast) { cxx_runtime_error("visit(UsingDeclaratorAST): not implemented"); } @@ -158,6 +154,23 @@ void DefaultASTVisitor::visit(NewPlacementAST* ast) { cxx_runtime_error("visit(NewPlacementAST): not implemented"); } +// NestedNameSpecifierAST +void DefaultASTVisitor::visit(GlobalNestedNameSpecifierAST* ast) { + cxx_runtime_error("visit(GlobalNestedNameSpecifierAST): not implemented"); +} + +void DefaultASTVisitor::visit(SimpleNestedNameSpecifierAST* ast) { + cxx_runtime_error("visit(SimpleNestedNameSpecifierAST): not implemented"); +} + +void DefaultASTVisitor::visit(DecltypeNestedNameSpecifierAST* ast) { + cxx_runtime_error("visit(DecltypeNestedNameSpecifierAST): not implemented"); +} + +void DefaultASTVisitor::visit(TemplateNestedNameSpecifierAST* ast) { + cxx_runtime_error("visit(TemplateNestedNameSpecifierAST): not implemented"); +} + // ExceptionSpecifierAST void DefaultASTVisitor::visit(ThrowExceptionSpecifierAST* ast) { cxx_runtime_error("visit(ThrowExceptionSpecifierAST): not implemented"); diff --git a/src/parser/cxx/default_ast_visitor.h b/src/parser/cxx/default_ast_visitor.h index 5f9e11f8..92d7d35f 100644 --- a/src/parser/cxx/default_ast_visitor.h +++ b/src/parser/cxx/default_ast_visitor.h @@ -28,7 +28,6 @@ class DefaultASTVisitor : public ASTVisitor { public: // AST void visit(TypeIdAST* ast) override; - void visit(NestedNameSpecifierAST* ast) override; void visit(UsingDeclaratorAST* ast) override; void visit(HandlerAST* ast) override; void visit(EnumBaseAST* ast) override; @@ -61,6 +60,12 @@ class DefaultASTVisitor : public ASTVisitor { void visit(DesignatorAST* ast) override; void visit(NewPlacementAST* ast) override; + // NestedNameSpecifierAST + void visit(GlobalNestedNameSpecifierAST* ast) override; + void visit(SimpleNestedNameSpecifierAST* ast) override; + void visit(DecltypeNestedNameSpecifierAST* ast) override; + void visit(TemplateNestedNameSpecifierAST* ast) override; + // ExceptionSpecifierAST void visit(ThrowExceptionSpecifierAST* ast) override; void visit(NoexceptSpecifierAST* ast) override; diff --git a/src/parser/cxx/parser.cc b/src/parser/cxx/parser.cc index 39e2f8be..67ed2c49 100644 --- a/src/parser/cxx/parser.cc +++ b/src/parser/cxx/parser.cc @@ -735,7 +735,7 @@ auto Parser::parse_unqualified_id(NameAST*& yyast, bool inRequiresClause) SourceLocation tildeLoc; if (match(TokenKind::T_TILDE, tildeLoc)) { - SpecifierAST* decltypeSpecifier = nullptr; + DecltypeSpecifierAST* decltypeSpecifier = nullptr; if (parse_decltype_specifier(decltypeSpecifier)) { auto decltypeName = new (pool) DecltypeNameAST(); @@ -808,137 +808,122 @@ auto Parser::parse_qualified_id(NameAST*& yyast, bool inRequiresClause) return true; } -auto Parser::parse_start_of_nested_name_specifier(NameAST*& yyast, - SourceLocation& scopeLoc) - -> bool { - yyast = nullptr; +void Parser::parse_optional_nested_name_specifier( + NestedNameSpecifierAST*& yyast) { + LookaheadParser lookahead(this); + if (!parse_nested_name_specifier(yyast)) return; + lookahead.commit(); +} - if (match(TokenKind::T_COLON_COLON, scopeLoc)) return true; +auto Parser::parse_nested_name_specifier(NestedNameSpecifierAST*& yyast) + -> bool { + auto lookat_global_nested_name_specifier = [&] { + if (yyast) return false; - auto lookat_decltype_specifier = [&] { - LookaheadParser lookahead{this}; - SpecifierAST* decltypeSpecifier = nullptr; - if (!parse_decltype_specifier(decltypeSpecifier)) return false; + SourceLocation scopeLoc; if (!match(TokenKind::T_COLON_COLON, scopeLoc)) return false; - lookahead.commit(); - auto ast = new (pool) DecltypeNameAST(); + + auto ast = new (pool) GlobalNestedNameSpecifierAST(); yyast = ast; - ast->decltypeSpecifier = decltypeSpecifier; + ast->scopeLoc = scopeLoc; + return true; }; - auto lookat_simple_template_id = [&] { + auto lookat_decltype_nested_name_specifier = [&] { + if (yyast) return false; + LookaheadParser lookahead{this}; - NameAST* templateId = nullptr; - if (!parse_simple_template_id(templateId)) return false; + + DecltypeSpecifierAST* decltypeSpecifier = nullptr; + if (!parse_decltype_specifier(decltypeSpecifier)) return false; + + SourceLocation scopeLoc; if (!match(TokenKind::T_COLON_COLON, scopeLoc)) return false; - lookahead.commit(); - yyast = templateId; - return true; - }; - if (lookat_decltype_specifier()) return true; - if (lookat_simple_template_id()) return true; + lookahead.commit(); - LookaheadParser lookahead{this}; - NameAST* nameId = nullptr; - if (!parse_name_id(nameId)) return false; - if (!match(TokenKind::T_COLON_COLON, scopeLoc)) return false; - lookahead.commit(); - yyast = nameId; - return true; -} + auto ast = new (pool) DecltypeNestedNameSpecifierAST(); + ast->nestedNameSpecifier = yyast; + yyast = ast; -void Parser::parse_optional_nested_name_specifier( - NestedNameSpecifierAST*& yyast) { - LookaheadParser lookahead(this); - if (!parse_nested_name_specifier(yyast)) return; - lookahead.commit(); -} + ast->decltypeSpecifier = decltypeSpecifier; + ast->scopeLoc = scopeLoc; -auto Parser::parse_nested_name_specifier(NestedNameSpecifierAST*& yyast) - -> bool { - const auto start = currentLocation(); + return true; + }; - auto it = nested_name_specifiers_.find(start); + auto lookat_simple_nested_name_specifier = [&] { + if (!lookat(TokenKind::T_IDENTIFIER, TokenKind::T_COLON_COLON)) + return false; - if (it != nested_name_specifiers_.end()) { - auto [cursor, ast, parsed] = it->second; - rewind(cursor); + auto ast = new (pool) SimpleNestedNameSpecifierAST(); + ast->nestedNameSpecifier = yyast; yyast = ast; - return parsed; - } - struct Context { - Parser* p; - SourceLocation start; - NestedNameSpecifierAST* ast = nullptr; - bool parsed = false; - - explicit Context(Parser* p) : p(p), start(p->currentLocation()) {} + ast->identifierLoc = consumeToken(); + ast->identifier = unit->identifier(ast->identifierLoc); + ast->scopeLoc = consumeToken(); - ~Context() { - p->nested_name_specifiers_.emplace( - start, std::make_tuple(p->currentLocation(), ast, parsed)); - } + return true; }; - Context context(this); - - NameAST* name = nullptr; - SourceLocation scopeLoc; + auto lookat_template_nested_name_specifier = [&] { + LookaheadParser lookahead{this}; - if (!parse_start_of_nested_name_specifier(name, scopeLoc)) return false; + SourceLocation templateLoc; + match(TokenKind::T_TEMPLATE, templateLoc); - auto ast = new (pool) NestedNameSpecifierAST(); - context.ast = ast; - yyast = ast; + NameAST* templateName = nullptr; + if (!parse_simple_template_id(templateName)) return false; - auto nameIt = &ast->nameList; + SourceLocation scopeLoc; + if (!match(TokenKind::T_COLON_COLON, scopeLoc)) return false; - if (!name) { - ast->scopeLoc = scopeLoc; - } else { - *nameIt = new (pool) List(name); - nameIt = &(*nameIt)->next; - } + lookahead.commit(); - LoopParser loop(this); + auto ast = new (pool) TemplateNestedNameSpecifierAST(); + ast->nestedNameSpecifier = yyast; + yyast = ast; - while (true) { - loop.start(); + ast->templateLoc = templateLoc; + ast->templateName = static_cast(templateName); + ast->scopeLoc = scopeLoc; - if (lookat(TokenKind::T_IDENTIFIER, TokenKind::T_COLON_COLON)) { - NameAST* name = nullptr; - (void)parse_name_id(name); + return true; + }; - SourceLocation scopeLoc; + const auto start = currentLocation(); - expect(TokenKind::T_COLON_COLON, scopeLoc); + if (auto it = nested_name_specifiers_.find(start); + it != nested_name_specifiers_.end()) { + auto [cursor, ast, parsed] = it->second; + rewind(cursor); + yyast = ast; + return parsed; + } - *nameIt = new (pool) List(name); - nameIt = &(*nameIt)->next; - } else { - auto lookat_template_id = [&] { - LookaheadParser lookahead{this}; - SourceLocation templateLoc; - const auto hasTemplate = match(TokenKind::T_TEMPLATE, templateLoc); - NameAST* name = nullptr; - if (!parse_simple_template_id(name)) return false; - if (!match(TokenKind::T_COLON_COLON, scopeLoc)) return false; - lookahead.commit(); - *nameIt = new (pool) List(name); - nameIt = &(*nameIt)->next; - return true; - }; + yyast = nullptr; - if (!lookat_template_id()) break; - } + while (true) { + if (lookat_global_nested_name_specifier()) + continue; + else if (lookat_simple_nested_name_specifier()) + continue; + else if (lookat_decltype_nested_name_specifier()) + continue; + else if (lookat_template_nested_name_specifier()) + continue; + else + break; } - context.parsed = true; + const auto parsed = yyast != nullptr; - return true; + nested_name_specifiers_.emplace( + start, std::make_tuple(currentLocation(), yyast, parsed)); + + return parsed; } auto Parser::parse_lambda_expression(ExpressionAST*& yyast) -> bool { @@ -4207,8 +4192,8 @@ auto Parser::parse_simple_type_specifier(SpecifierAST*& yyast, DeclSpecs& specs) if (parse_primitive_type_specifier(yyast, specs)) return true; if (parse_underlying_type_specifier(yyast, specs)) return true; if (parse_atomic_type_specifier(yyast, specs)) return true; - if (parse_decltype_specifier_type_specifier(yyast, specs)) return true; if (parse_named_type_specifier(yyast, specs)) return true; + if (parse_decltype_specifier_type_specifier(yyast, specs)) return true; return false; } @@ -4280,7 +4265,10 @@ auto Parser::parse_decltype_specifier_type_specifier(SpecifierAST*& yyast, DeclSpecs& specs) -> bool { if (specs.has_typespec()) return false; - if (!parse_decltype_specifier(yyast)) return false; + DecltypeSpecifierAST* decltypeSpecifier = nullptr; + if (!parse_decltype_specifier(decltypeSpecifier)) return false; + + yyast = decltypeSpecifier; specs.has_placeholder_typespec = true; @@ -4608,7 +4596,7 @@ auto Parser::parse_decl_specifier_seq_no_typespecs(List*& yyast) return parse_decl_specifier_seq_no_typespecs(yyast, specs); } -auto Parser::parse_decltype_specifier(SpecifierAST*& yyast) -> bool { +auto Parser::parse_decltype_specifier(DecltypeSpecifierAST*& yyast) -> bool { SourceLocation decltypeLoc; if (match(TokenKind::T_DECLTYPE, decltypeLoc)) { @@ -7362,7 +7350,7 @@ auto Parser::parse_class_or_decltype(NameAST*& yyast) -> bool { if (lookat_qualified_name()) return true; - SpecifierAST* decltypeSpecifier = nullptr; + DecltypeSpecifierAST* decltypeSpecifier = nullptr; if (parse_decltype_specifier(decltypeSpecifier)) { auto ast = new (pool) DecltypeNameAST(); diff --git a/src/parser/cxx/parser.h b/src/parser/cxx/parser.h index e65e0a70..629574f3 100644 --- a/src/parser/cxx/parser.h +++ b/src/parser/cxx/parser.h @@ -116,8 +116,6 @@ class Parser final { void parse_optional_nested_name_specifier(NestedNameSpecifierAST*& yyast); [[nodiscard]] auto parse_nested_name_specifier(NestedNameSpecifierAST*& yyast) -> bool; - [[nodiscard]] auto parse_start_of_nested_name_specifier( - NameAST*& yyast, SourceLocation& scopeLoc) -> bool; [[nodiscard]] auto parse_lambda_expression(ExpressionAST*& yyast) -> bool; [[nodiscard]] auto parse_lambda_introducer(LambdaIntroducerAST*& yyast) -> bool; @@ -317,7 +315,8 @@ class Parser final { ElaboratedTypeSpecifierAST*& yyast, DeclSpecs& specs) -> bool; [[nodiscard]] auto parse_elaborated_enum_specifier( ElaboratedTypeSpecifierAST*& yyast, DeclSpecs& specs) -> bool; - [[nodiscard]] auto parse_decltype_specifier(SpecifierAST*& yyast) -> bool; + [[nodiscard]] auto parse_decltype_specifier(DecltypeSpecifierAST*& yyast) + -> bool; [[nodiscard]] auto parse_placeholder_type_specifier(SpecifierAST*& yyast) -> bool; [[nodiscard]] auto parse_init_declarator(InitDeclaratorAST*& yyast, diff --git a/src/parser/cxx/private/ast_decoder.h b/src/parser/cxx/private/ast_decoder.h index 45ca8d51..729d46ff 100644 --- a/src/parser/cxx/private/ast_decoder.h +++ b/src/parser/cxx/private/ast_decoder.h @@ -38,6 +38,8 @@ class ASTDecoder { auto operator()(std::span data) -> bool; private: + auto decodeNestedNameSpecifier(const void* ptr, io::NestedNameSpecifier type) + -> NestedNameSpecifierAST*; auto decodeExceptionSpecifier(const void* ptr, io::ExceptionSpecifier type) -> ExceptionSpecifierAST*; auto decodeExpression(const void* ptr, io::Expression type) -> ExpressionAST*; @@ -74,8 +76,6 @@ class ASTDecoder { -> AttributeTokenAST*; auto decodeTypeId(const io::TypeId* node) -> TypeIdAST*; - auto decodeNestedNameSpecifier(const io::NestedNameSpecifier* node) - -> NestedNameSpecifierAST*; auto decodeUsingDeclarator(const io::UsingDeclarator* node) -> UsingDeclaratorAST*; auto decodeHandler(const io::Handler* node) -> HandlerAST*; @@ -127,6 +127,19 @@ class ASTDecoder { auto decodeDesignator(const io::Designator* node) -> DesignatorAST*; auto decodeNewPlacement(const io::NewPlacement* node) -> NewPlacementAST*; + auto decodeGlobalNestedNameSpecifier( + const io::GlobalNestedNameSpecifier* node) + -> GlobalNestedNameSpecifierAST*; + auto decodeSimpleNestedNameSpecifier( + const io::SimpleNestedNameSpecifier* node) + -> SimpleNestedNameSpecifierAST*; + auto decodeDecltypeNestedNameSpecifier( + const io::DecltypeNestedNameSpecifier* node) + -> DecltypeNestedNameSpecifierAST*; + auto decodeTemplateNestedNameSpecifier( + const io::TemplateNestedNameSpecifier* node) + -> TemplateNestedNameSpecifierAST*; + auto decodeThrowExceptionSpecifier(const io::ThrowExceptionSpecifier* node) -> ThrowExceptionSpecifierAST*; auto decodeNoexceptSpecifier(const io::NoexceptSpecifier* node) diff --git a/src/parser/cxx/private/ast_encoder.h b/src/parser/cxx/private/ast_encoder.h index 571e23d0..0f09fffe 100644 --- a/src/parser/cxx/private/ast_encoder.h +++ b/src/parser/cxx/private/ast_encoder.h @@ -69,6 +69,9 @@ class ASTEncoder : ASTVisitor { auto accept(AST* ast) -> flatbuffers::Offset<>; + auto acceptNestedNameSpecifier(NestedNameSpecifierAST* ast) + -> std::tuple, std::uint32_t>; + auto acceptExceptionSpecifier(ExceptionSpecifierAST* ast) -> std::tuple, std::uint32_t>; @@ -127,7 +130,6 @@ class ASTEncoder : ASTVisitor { -> std::tuple, std::uint32_t>; void visit(TypeIdAST* ast) override; - void visit(NestedNameSpecifierAST* ast) override; void visit(UsingDeclaratorAST* ast) override; void visit(HandlerAST* ast) override; void visit(EnumBaseAST* ast) override; @@ -160,6 +162,11 @@ class ASTEncoder : ASTVisitor { void visit(DesignatorAST* ast) override; void visit(NewPlacementAST* ast) override; + void visit(GlobalNestedNameSpecifierAST* ast) override; + void visit(SimpleNestedNameSpecifierAST* ast) override; + void visit(DecltypeNestedNameSpecifierAST* ast) override; + void visit(TemplateNestedNameSpecifierAST* ast) override; + void visit(ThrowExceptionSpecifierAST* ast) override; void visit(NoexceptSpecifierAST* ast) override; diff --git a/src/parser/cxx/recursive_ast_visitor.cc b/src/parser/cxx/recursive_ast_visitor.cc index 92934f30..8a6140ad 100644 --- a/src/parser/cxx/recursive_ast_visitor.cc +++ b/src/parser/cxx/recursive_ast_visitor.cc @@ -33,13 +33,13 @@ void RecursiveASTVisitor::acceptSpecifier(SpecifierAST* ast) { accept(ast); } void RecursiveASTVisitor::acceptDeclarator(DeclaratorAST* ast) { accept(ast); } -void RecursiveASTVisitor::acceptName(NameAST* ast) { accept(ast); } - void RecursiveASTVisitor::acceptNestedNameSpecifier( NestedNameSpecifierAST* ast) { accept(ast); } +void RecursiveASTVisitor::acceptName(NameAST* ast) { accept(ast); } + void RecursiveASTVisitor::acceptExceptionDeclaration( ExceptionDeclarationAST* ast) { accept(ast); @@ -142,6 +142,14 @@ void RecursiveASTVisitor::acceptAttributeArgumentClause( accept(ast); } +void RecursiveASTVisitor::acceptDecltypeSpecifier(DecltypeSpecifierAST* ast) { + accept(ast); +} + +void RecursiveASTVisitor::acceptTemplateName(TemplateNameAST* ast) { + accept(ast); +} + void RecursiveASTVisitor::acceptDesignator(DesignatorAST* ast) { accept(ast); } void RecursiveASTVisitor::acceptRequirementBody(RequirementBodyAST* ast) { @@ -245,12 +253,6 @@ void RecursiveASTVisitor::visit(TypeIdAST* ast) { acceptDeclarator(ast->declarator); } -void RecursiveASTVisitor::visit(NestedNameSpecifierAST* ast) { - for (auto it = ast->nameList; it; it = it->next) { - acceptName(it->value); - } -} - void RecursiveASTVisitor::visit(UsingDeclaratorAST* ast) { acceptNestedNameSpecifier(ast->nestedNameSpecifier); acceptName(ast->name); @@ -436,6 +438,22 @@ void RecursiveASTVisitor::visit(NewPlacementAST* ast) { } } +void RecursiveASTVisitor::visit(GlobalNestedNameSpecifierAST* ast) {} + +void RecursiveASTVisitor::visit(SimpleNestedNameSpecifierAST* ast) { + acceptNestedNameSpecifier(ast->nestedNameSpecifier); +} + +void RecursiveASTVisitor::visit(DecltypeNestedNameSpecifierAST* ast) { + acceptNestedNameSpecifier(ast->nestedNameSpecifier); + acceptDecltypeSpecifier(ast->decltypeSpecifier); +} + +void RecursiveASTVisitor::visit(TemplateNestedNameSpecifierAST* ast) { + acceptNestedNameSpecifier(ast->nestedNameSpecifier); + acceptTemplateName(ast->templateName); +} + void RecursiveASTVisitor::visit(ThrowExceptionSpecifierAST* ast) {} void RecursiveASTVisitor::visit(NoexceptSpecifierAST* ast) { @@ -1041,7 +1059,7 @@ void RecursiveASTVisitor::visit(SimpleNameAST* ast) {} void RecursiveASTVisitor::visit(DestructorNameAST* ast) { acceptName(ast->id); } void RecursiveASTVisitor::visit(DecltypeNameAST* ast) { - acceptSpecifier(ast->decltypeSpecifier); + acceptDecltypeSpecifier(ast->decltypeSpecifier); } void RecursiveASTVisitor::visit(OperatorNameAST* ast) {} diff --git a/src/parser/cxx/recursive_ast_visitor.h b/src/parser/cxx/recursive_ast_visitor.h index 3acc38f7..ed9244ec 100644 --- a/src/parser/cxx/recursive_ast_visitor.h +++ b/src/parser/cxx/recursive_ast_visitor.h @@ -30,8 +30,8 @@ class RecursiveASTVisitor : public ASTVisitor { virtual void acceptSpecifier(SpecifierAST* ast); virtual void acceptDeclarator(DeclaratorAST* ast); - virtual void acceptName(NameAST* ast); virtual void acceptNestedNameSpecifier(NestedNameSpecifierAST* ast); + virtual void acceptName(NameAST* ast); virtual void acceptExceptionDeclaration(ExceptionDeclarationAST* ast); virtual void acceptCompoundStatement(CompoundStatementAST* ast); virtual void acceptAttributeSpecifier(AttributeSpecifierAST* ast); @@ -59,6 +59,8 @@ class RecursiveASTVisitor : public ASTVisitor { virtual void acceptModulePartition(ModulePartitionAST* ast); virtual void acceptAttributeToken(AttributeTokenAST* ast); virtual void acceptAttributeArgumentClause(AttributeArgumentClauseAST* ast); + virtual void acceptDecltypeSpecifier(DecltypeSpecifierAST* ast); + virtual void acceptTemplateName(TemplateNameAST* ast); virtual void acceptDesignator(DesignatorAST* ast); virtual void acceptRequirementBody(RequirementBodyAST* ast); virtual void acceptLambdaIntroducer(LambdaIntroducerAST* ast); @@ -90,7 +92,6 @@ class RecursiveASTVisitor : public ASTVisitor { virtual void postVisit(AST*) {} void visit(TypeIdAST* ast) override; - void visit(NestedNameSpecifierAST* ast) override; void visit(UsingDeclaratorAST* ast) override; void visit(HandlerAST* ast) override; void visit(EnumBaseAST* ast) override; @@ -123,6 +124,11 @@ class RecursiveASTVisitor : public ASTVisitor { void visit(DesignatorAST* ast) override; void visit(NewPlacementAST* ast) override; + void visit(GlobalNestedNameSpecifierAST* ast) override; + void visit(SimpleNestedNameSpecifierAST* ast) override; + void visit(DecltypeNestedNameSpecifierAST* ast) override; + void visit(TemplateNestedNameSpecifierAST* ast) override; + void visit(ThrowExceptionSpecifierAST* ast) override; void visit(NoexceptSpecifierAST* ast) override;