@@ -6658,43 +6658,69 @@ auto Parser::parse_elaborated_type_specifier_helper(
66586658 ast->classKey = unit->tokenKind (classLoc);
66596659 ast->isTemplateIntroduced = isTemplateIntroduced;
66606660
6661- const auto loc = currentLocation ();
6662-
6663- if (lookat (TokenKind::T_IDENTIFIER, TokenKind::T_LESS)) {
6664- if (SimpleTemplateIdAST* templateId = nullptr ; parse_simple_template_id (
6665- templateId, nestedNameSpecifier, isTemplateIntroduced)) {
6666- ast->unqualifiedId = templateId;
6667- } else {
6668- parse_error (loc, " expected a template-id" );
6669- }
6670- } else if (NameIdAST* nameId = nullptr ; parse_name_id (nameId)) {
6671- ast->unqualifiedId = nameId;
6661+ if (!parse_simple_template_or_name_id (ast->unqualifiedId ,
6662+ ast->nestedNameSpecifier ,
6663+ ast->isTemplateIntroduced )) {
6664+ parse_error (" expected a name" );
6665+ return false ;
6666+ }
66726667
6673- auto symbol = Lookup{scope_}(nestedNameSpecifier, nameId-> identifier );
6668+ const auto loc = ast-> unqualifiedId -> firstSourceLocation ( );
66746669
6675- if (ast->classKey == TokenKind::T_CLASS ||
6676- ast->classKey == TokenKind::T_STRUCT ||
6677- ast->classKey == TokenKind::T_UNION) {
6678- for (auto symbol : SymbolChainView (symbol) | views::classes) {
6679- ast->symbol = symbol;
6680- specs.type = symbol->type ();
6681- break ;
6682- }
6683- } else if (ast->classKey == TokenKind::T_ENUM) {
6684- for (auto symbol :
6685- SymbolChainView (symbol) | views::enum_or_scoped_enums) {
6686- ast->symbol = symbol;
6687- specs.type = symbol->type ();
6688- break ;
6689- }
6690- }
6691- } else {
6692- parse_error (loc, " expected a name" );
6670+ if (isClassKey (ast->classKey )) {
6671+ finish_elaborated_class_specifier (ast, templateDeclarations);
6672+ return true ;
66936673 }
66946674
66956675 return true ;
66966676}
66976677
6678+ void Parser::finish_elaborated_class_specifier (
6679+ ElaboratedTypeSpecifierAST* elab,
6680+ const std::vector<TemplateDeclarationAST*>& templateDeclarations) {
6681+ auto className = getIdentifier (elab->unqualifiedId );
6682+
6683+ if (elab->nestedNameSpecifier ) {
6684+ auto parent = getClassOrNamespace (elab->nestedNameSpecifier );
6685+ ClassSymbol* classSymbol = findClass (parent, className);
6686+ elab->symbol = classSymbol;
6687+ return ;
6688+ }
6689+
6690+ const auto isForwardClassDeclaration = lookat (TokenKind::T_SEMICOLON);
6691+
6692+ auto declaringScope = currentDeclaringScope ();
6693+ if (!declaringScope) {
6694+ cxx_runtime_error (" no declaring scope" );
6695+ }
6696+
6697+ auto parent = declaringScope->owner ();
6698+
6699+ if (isForwardClassDeclaration && !parent->isClassOrNamespace ()) {
6700+ parent = currentNamespace ();
6701+ }
6702+
6703+ if (auto classSymbol = findClass (parent, className)) {
6704+ elab->symbol = classSymbol;
6705+ return ;
6706+ }
6707+
6708+ const auto isUnion = elab->classKey == TokenKind::T_UNION;
6709+
6710+ // create a forward declaration
6711+ auto classSymbol = control_->newClassSymbol (
6712+ parent->scope (), elab->unqualifiedId ->firstSourceLocation ());
6713+ classSymbol->setName (className);
6714+ classSymbol->setIsUnion (isUnion);
6715+
6716+ auto templateParameters =
6717+ symbol_cast<TemplateParametersSymbol>(scope_->owner ());
6718+
6719+ classSymbol->setTemplateParameters (templateParameters);
6720+
6721+ std::invoke (DeclareSymbol{this , parent->scope ()}, classSymbol);
6722+ }
6723+
66986724auto Parser::parse_elaborated_enum_specifier (ElaboratedTypeSpecifierAST*& yyast,
66996725 DeclSpecs& specs) -> bool {
67006726 SourceLocation enumLoc;
@@ -9207,87 +9233,67 @@ auto Parser::parse_class_head(ClassHead& classHead) -> bool {
92079233
92089234 parse_optional_attribute_specifier_seq (classHead.attributeList );
92099235
9210- auto is_class_declaration = false ;
9236+ bool isClassDeclaration = false ;
9237+ bool isForwardClassDeclaration = false ;
92119238
92129239 if (parse_class_head_name (classHead.nestedNameSpecifier , classHead.name )) {
92139240 if (parse_class_virt_specifier (classHead.finalLoc )) {
9214- is_class_declaration = true ;
9241+ isClassDeclaration = true ;
92159242 }
92169243 }
92179244
9218- if (LA ().isOneOf (TokenKind::T_COLON, TokenKind::T_LBRACE)) {
9219- is_class_declaration = true ;
9245+ if (!isClassDeclaration) {
9246+ isClassDeclaration = LA ().isOneOf (TokenKind::T_COLON, TokenKind::T_LBRACE);
9247+ }
9248+
9249+ if (!isClassDeclaration) {
9250+ return false ;
92209251 }
92219252
9222- auto is_template_declaration = !classHead.templateDeclarations .empty ();
9253+ auto isTemplateDeclaration = !classHead.templateDeclarations .empty ();
92239254
9224- if (is_class_declaration && is_template_declaration &&
9225- !classHead.nestedNameSpecifier ) {
9255+ if (isTemplateDeclaration) {
92269256 mark_maybe_template_name (classHead.name );
92279257 }
92289258
9229- if (classHead.nestedNameSpecifier ) {
9230- auto enclosingSymbol = classHead.nestedNameSpecifier ->symbol ;
9231- if (!enclosingSymbol) {
9232- if (config_.checkTypes ) {
9233- parse_error (classHead.nestedNameSpecifier ->firstSourceLocation (),
9234- " unresolved nested name specifier" );
9235- }
9236- } else {
9237- Scope* enclosingScope = nullptr ;
9259+ auto templateId = ast_cast<SimpleTemplateIdAST>(classHead.name );
92389260
9239- if (auto alias = symbol_cast<TypeAliasSymbol>(enclosingSymbol)) {
9240- if (auto classTy = type_cast<ClassType>(alias->type ())) {
9241- enclosingScope = classTy->symbol ()->scope ();
9242- }
9243- } else if (auto enclosingClass =
9244- symbol_cast<ClassSymbol>(enclosingSymbol)) {
9245- enclosingScope = enclosingClass->scope ();
9246- } else if (auto enclosingNamespace =
9247- symbol_cast<NamespaceSymbol>(enclosingSymbol)) {
9248- enclosingScope = enclosingNamespace->scope ();
9249- }
9261+ const Identifier* identifier = getIdentifier (classHead.name );
92509262
9251- if (enclosingScope) {
9252- setScope (enclosingScope);
9253- } else if (config_.checkTypes ) {
9254- parse_error (classHead.nestedNameSpecifier ->firstSourceLocation (),
9255- " unresolved nested name specifier" );
9256- }
9257- }
9258- }
9263+ SourceLocation location = currentLocation ();
92599264
9260- const Identifier* identifier = nullptr ;
9261- SourceLocation location;
9262- bool isTemplateSpecialization = false ;
9263- if (const auto simpleName = ast_cast<NameIdAST>(classHead.name )) {
9264- location = simpleName->identifierLoc ;
9265- identifier = simpleName->identifier ;
9266- } else if (const auto t = ast_cast<SimpleTemplateIdAST>(classHead.name )) {
9267- location = t->firstSourceLocation ();
9268- isTemplateSpecialization = true ;
9269- identifier = t->identifier ;
9270- } else {
9271- location = currentLocation ();
9265+ if (classHead.name ) {
9266+ location = classHead.name ->firstSourceLocation ();
92729267 }
92739268
92749269 ClassSymbol* classSymbol = nullptr ;
92759270
92769271 if (identifier) {
9277- if (!is_class_declaration && !lookat (TokenKind::T_SEMICOLON)) {
9278- auto symbol = symbol_cast<ClassSymbol>(Lookup{scope_}(identifier));
9279- classSymbol = symbol;
9280- } else if (!isTemplateSpecialization) {
9281- for (auto previousClass : scope_->find (identifier) | views::classes) {
9282- if (previousClass->isComplete ()) {
9283- parse_error (classHead.name ->firstSourceLocation (),
9284- " class name already declared" );
9285- } else {
9286- classSymbol = previousClass;
9272+ ScopedSymbol* parent = nullptr ;
9273+
9274+ if (classHead.nestedNameSpecifier ) {
9275+ if (auto ns = symbol_cast<NamespaceSymbol>(
9276+ classHead.nestedNameSpecifier ->symbol )) {
9277+ parent = ns;
9278+ } else if (auto cls = symbol_cast<ClassSymbol>(
9279+ classHead.nestedNameSpecifier ->symbol )) {
9280+ parent = cls;
9281+ } else {
9282+ if (config_.checkTypes ) {
9283+ parse_error (classHead.nestedNameSpecifier ->firstSourceLocation (),
9284+ " expected a namespace or class" );
92879285 }
9288- break ;
92899286 }
92909287 }
9288+
9289+ if (!parent) {
9290+ parent = currentClassOrNamespace ();
9291+ }
9292+
9293+ for (auto candidate : parent->scope ()->find (identifier) | views::classes) {
9294+ classSymbol = candidate;
9295+ break ;
9296+ }
92919297 }
92929298
92939299 if (!classSymbol) {
@@ -9296,6 +9302,8 @@ auto Parser::parse_class_head(ClassHead& classHead) -> bool {
92969302 classSymbol->setName (identifier);
92979303
92989304 std::invoke (DeclareSymbol{this , scope_}, classSymbol);
9305+ } else {
9306+ classSymbol->setLocation (location);
92999307 }
93009308
93019309 classHead.symbol = classSymbol;
@@ -11253,6 +11261,36 @@ void Parser::setScope(Scope* scope) { scope_ = scope; }
1125311261
1125411262void Parser::setScope (ScopedSymbol* symbol) { setScope (symbol->scope ()); }
1125511263
11264+ auto Parser::currentClassOrNamespace () const -> ScopedSymbol* {
11265+ for (auto scope = scope_; scope; scope = scope->parent ()) {
11266+ if (auto ns = symbol_cast<NamespaceSymbol>(scope->owner ())) {
11267+ return ns;
11268+ }
11269+
11270+ if (auto cls = symbol_cast<ClassSymbol>(scope->owner ())) {
11271+ return cls;
11272+ }
11273+ }
11274+
11275+ return nullptr ;
11276+ }
11277+
11278+ auto Parser::currentNamespace () const -> NamespaceSymbol* {
11279+ for (auto scope = scope_; scope; scope = scope->parent ()) {
11280+ if (auto ns = symbol_cast<NamespaceSymbol>(scope->owner ())) {
11281+ return ns;
11282+ }
11283+ }
11284+
11285+ return nullptr ;
11286+ }
11287+
11288+ auto Parser::currentDeclaringScope () const -> Scope* {
11289+ auto scope = scope_;
11290+ while (scope && scope->isTransparent ()) scope = scope->parent ();
11291+ return scope;
11292+ }
11293+
1125611294void Parser::completeFunctionDefinition (FunctionDefinitionAST* ast) {
1125711295 if (!ast->functionBody ) return ;
1125811296
@@ -11307,10 +11345,58 @@ void Parser::completeFunctionDefinition(FunctionDefinitionAST* ast) {
1130711345 rewind (saved);
1130811346}
1130911347
11348+ auto Parser::isClassKey (TokenKind tk) const -> bool {
11349+ return tk == TokenKind::T_CLASS || tk == TokenKind::T_STRUCT ||
11350+ tk == TokenKind::T_UNION;
11351+ }
11352+
11353+ auto Parser::findClass (ScopedSymbol* parent, const Identifier* className) const
11354+ -> ClassSymbol* {
11355+ if (!parent) return nullptr ;
11356+
11357+ return findClass (parent->scope (), className);
11358+ }
11359+
11360+ auto Parser::findClass (Scope* scope, const Identifier* className) const
11361+ -> ClassSymbol* {
11362+ if (!scope) return nullptr ;
11363+
11364+ for (auto candidate : scope->find (className) | views::classes) {
11365+ return candidate;
11366+ }
11367+
11368+ return nullptr ;
11369+ }
11370+
11371+ auto Parser::getClassOrNamespace (
11372+ NestedNameSpecifierAST* nestedNameSpecifier) const -> ScopedSymbol* {
11373+ if (auto ns = symbol_cast<NamespaceSymbol>(nestedNameSpecifier->symbol ))
11374+ return ns;
11375+
11376+ if (auto classSymbol = symbol_cast<ClassSymbol>(nestedNameSpecifier->symbol ))
11377+ return classSymbol;
11378+
11379+ return nullptr ;
11380+ }
11381+
1131011382auto Parser::convertName (UnqualifiedIdAST* id) -> const Name* {
1131111383 if (!id) return nullptr ;
1131211384 return visit (ConvertToName{control_}, id);
1131311385}
11386+
11387+ auto Parser::getIdentifier (UnqualifiedIdAST* unqualifiedId)
11388+ -> const Identifier* {
11389+ if (auto nameId = ast_cast<NameIdAST>(unqualifiedId)) {
11390+ return nameId->identifier ;
11391+ }
11392+
11393+ if (auto templateId = ast_cast<SimpleTemplateIdAST>(unqualifiedId)) {
11394+ return templateId->identifier ;
11395+ }
11396+
11397+ return nullptr ;
11398+ }
11399+
1131411400auto Parser::getFunction (Scope* scope, const Name* name, const Type* type)
1131511401 -> FunctionSymbol* {
1131611402 for (auto candidate : scope->find (name)) {
0 commit comments