@@ -140,9 +140,6 @@ void Binder::bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs,
140140 bool isDeclaration) {
141141 const auto _ = ScopeGuard{this };
142142
143- auto className = get_name (control (), ast->unqualifiedId );
144- const auto location = ast->unqualifiedId ->firstSourceLocation ();
145-
146143 if (ast->nestedNameSpecifier ) {
147144 auto parent = ast->nestedNameSpecifier ->symbol ;
148145
@@ -151,32 +148,62 @@ void Binder::bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs,
151148 }
152149 }
153150
154- ClassSymbol* classSymbol = nullptr ;
151+ auto templateId = ast_cast<SimpleTemplateIdAST>(ast-> unqualifiedId ) ;
155152
156- if (scope ()->isClassOrNamespaceScope ()) {
157- for (auto candidate : scope ()->find (className) | views::classes) {
158- classSymbol = candidate;
159- break ;
153+ const Identifier* name = nullptr ;
154+ if (templateId)
155+ name = templateId->identifier ;
156+ else if (auto nameId = ast_cast<NameIdAST>(ast->unqualifiedId ))
157+ name = nameId->identifier ;
158+
159+ const auto location = ast->unqualifiedId ->firstSourceLocation ();
160+
161+ if (ast->classKey == TokenKind::T_CLASS ||
162+ ast->classKey == TokenKind::T_STRUCT ||
163+ ast->classKey == TokenKind::T_UNION) {
164+ auto is_class = [](Symbol* symbol) {
165+ if (symbol->isClass ()) return true ;
166+ return false ;
167+ };
168+
169+ auto candidate =
170+ Lookup{scope ()}.lookup (ast->nestedNameSpecifier , name, is_class);
171+
172+ auto classSymbol = symbol_cast<ClassSymbol>(candidate);
173+
174+ if (classSymbol) {
175+ // validate the resolved class symbol
176+
177+ if (isDeclaration) {
178+ // if the class is already declared, we need to check if the
179+ if (classSymbol->enclosingScope () != declaringScope ()) {
180+ // the class is declared in a different scope
181+ classSymbol = nullptr ;
182+ }
183+ }
160184 }
161- }
162185
163- if (!classSymbol) {
164- const auto isUnion = ast->classKey == TokenKind::T_UNION;
165- classSymbol = control ()->newClassSymbol (scope (), location);
186+ if (!classSymbol) {
187+ const auto isUnion = ast->classKey == TokenKind::T_UNION;
188+ classSymbol = control ()->newClassSymbol (scope (), location);
166189
167- classSymbol->setIsUnion (isUnion);
168- classSymbol->setName (className );
169- classSymbol->setTemplateParameters (currentTemplateParameters ());
170- classSymbol->setTemplateDeclaration (declSpecs.templateHead );
171- declaringScope ()->addSymbol (classSymbol);
190+ classSymbol->setIsUnion (isUnion);
191+ classSymbol->setName (name );
192+ classSymbol->setTemplateParameters (currentTemplateParameters ());
193+ classSymbol->setTemplateDeclaration (declSpecs.templateHead );
194+ declaringScope ()->addSymbol (classSymbol);
172195
173- classSymbol->setDeclaration (ast);
174- }
196+ classSymbol->setDeclaration (ast);
197+ }
175198
176- ast->symbol = classSymbol;
199+ ast->symbol = classSymbol;
200+ }
177201
178202 declSpecs.setTypeSpecifier (ast);
179- declSpecs.setType (ast->symbol ->type ());
203+
204+ if (ast->symbol ) {
205+ declSpecs.setType (ast->symbol ->type ());
206+ }
180207}
181208
182209void Binder::bind (ClassSpecifierAST* ast, DeclSpecs& declSpecs) {
0 commit comments