@@ -108,7 +108,7 @@ void Binder::setScope(ScopeSymbol* scope) {
108
108
inTemplate_ = false ;
109
109
110
110
for (auto current = scope_; current; current = current->parent ()) {
111
- if (current->isTemplateParameters ()) {
111
+ if (auto params = current->templateParameters ()) {
112
112
inTemplate_ = true ;
113
113
break ;
114
114
}
@@ -212,7 +212,6 @@ void Binder::bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs,
212
212
213
213
classSymbol->setIsUnion (isUnion);
214
214
classSymbol->setName (name);
215
- classSymbol->setTemplateParameters (currentTemplateParameters ());
216
215
classSymbol->setTemplateDeclaration (declSpecs.templateHead );
217
216
declaringScope ()->addSymbol (classSymbol);
218
217
@@ -230,42 +229,99 @@ void Binder::bind(ElaboratedTypeSpecifierAST* ast, DeclSpecs& declSpecs,
230
229
}
231
230
232
231
void Binder::bind (ClassSpecifierAST* ast, DeclSpecs& declSpecs) {
233
- auto templateParameters = currentTemplateParameters ();
232
+ auto check_optional_nested_name_specifier = [&] {
233
+ if (!ast->nestedNameSpecifier ) return ;
234
234
235
- if (ast->nestedNameSpecifier ) {
236
235
auto parent = ast->nestedNameSpecifier ->symbol ;
237
236
238
- if (parent && parent->isClassOrNamespace ()) {
239
- setScope (static_cast <ScopeSymbol*>(parent));
237
+ if (!parent || !parent->isClassOrNamespace ()) {
238
+ error (ast->nestedNameSpecifier ->firstSourceLocation (),
239
+ " nested name specifier must be a class or namespace" );
240
+ return ;
240
241
}
241
- }
242
242
243
- auto className = get_name (control (), ast->unqualifiedId );
244
- auto templateId = ast_cast<SimpleTemplateIdAST>(ast->unqualifiedId );
245
- if (templateId) {
246
- className = templateId->identifier ;
247
- }
243
+ setScope (static_cast <ScopeSymbol*>(parent));
244
+ };
248
245
249
- auto location = ast->classLoc ;
250
- if (templateId) {
251
- location = templateId->identifierLoc ;
252
- } else if (ast->unqualifiedId ) {
253
- location = ast->unqualifiedId ->firstSourceLocation ();
254
- }
246
+ auto check_template_specialization = [&] {
247
+ auto templateId = ast_cast<SimpleTemplateIdAST>(ast->unqualifiedId );
248
+ if (!templateId) return false ;
255
249
256
- ClassSymbol* primaryTemplate = nullptr ;
250
+ const auto location = templateId-> identifierLoc ;
257
251
258
- if (templateId && scope ()->isTemplateParameters ()) {
259
- for (auto candidate : declaringScope ()->find (className) | views::classes) {
260
- primaryTemplate = candidate;
252
+ ClassSymbol* primaryTemplateSymbol = nullptr ;
253
+
254
+ for (auto candidate :
255
+ declaringScope ()->find (templateId->identifier ) | views::classes) {
256
+ primaryTemplateSymbol = candidate;
261
257
break ;
262
258
}
263
259
264
- if (!primaryTemplate) {
260
+ if (!primaryTemplateSymbol ||
261
+ !primaryTemplateSymbol->templateParameters ()) {
265
262
error (location, std::format (" specialization of undeclared template '{}'" ,
266
263
templateId->identifier ->name ()));
264
+ // return true;
267
265
}
268
- }
266
+
267
+ std::vector<TemplateArgument> templateArguments;
268
+ ClassSymbol* specialization = nullptr ;
269
+
270
+ if (primaryTemplateSymbol) {
271
+ templateArguments = ASTRewriter::make_substitution (
272
+ unit_, primaryTemplateSymbol->templateDeclaration (),
273
+ templateId->templateArgumentList );
274
+
275
+ specialization =
276
+ primaryTemplateSymbol
277
+ ? primaryTemplateSymbol->findSpecialization (templateArguments)
278
+ : nullptr ;
279
+
280
+ if (specialization) {
281
+ error (location, std::format (" redefinition of specialization '{}'" ,
282
+ templateId->identifier ->name ()));
283
+ // return true;
284
+ }
285
+ }
286
+
287
+ const auto isUnion = ast->classKey == TokenKind::T_UNION;
288
+
289
+ auto classSymbol = control ()->newClassSymbol (declaringScope (), location);
290
+ ast->symbol = classSymbol;
291
+
292
+ classSymbol->setIsUnion (isUnion);
293
+ classSymbol->setName (templateId->identifier );
294
+ ast->symbol ->setDeclaration (ast);
295
+ ast->symbol ->setFinal (ast->isFinal );
296
+
297
+ // if (declSpecs.templateHead) {
298
+ // warning(location, "setting template head");
299
+ // ast->symbol->setTemplateDeclaration(declSpecs.templateHead);
300
+ // }
301
+
302
+ declSpecs.setTypeSpecifier (ast);
303
+ declSpecs.setType (ast->symbol ->type ());
304
+
305
+ if (primaryTemplateSymbol) {
306
+ primaryTemplateSymbol->addSpecialization (std::move (templateArguments),
307
+ classSymbol);
308
+ }
309
+
310
+ return true ;
311
+ };
312
+
313
+ check_optional_nested_name_specifier ();
314
+
315
+ if (check_template_specialization ()) return ;
316
+
317
+ // get the component anme
318
+ const Identifier* className = nullptr ;
319
+ if (auto nameId = ast_cast<NameIdAST>(ast->unqualifiedId ))
320
+ className = nameId->identifier ;
321
+
322
+ const auto location = ast->unqualifiedId
323
+ ? ast->unqualifiedId ->firstSourceLocation ()
324
+ : ast->classLoc ;
269
325
270
326
ClassSymbol* classSymbol = nullptr ;
271
327
@@ -277,6 +333,9 @@ void Binder::bind(ClassSpecifierAST* ast, DeclSpecs& declSpecs) {
277
333
}
278
334
279
335
if (classSymbol && classSymbol->isComplete ()) {
336
+ // not a template-id, but a class with the same name already exists
337
+ error (location,
338
+ std::format (" redefinition of class '{}'" , to_string (className)));
280
339
classSymbol = nullptr ;
281
340
}
282
341
@@ -285,29 +344,22 @@ void Binder::bind(ClassSpecifierAST* ast, DeclSpecs& declSpecs) {
285
344
classSymbol = control ()->newClassSymbol (scope (), location);
286
345
classSymbol->setIsUnion (isUnion);
287
346
classSymbol->setName (className);
288
- classSymbol->setTemplateParameters (templateParameters);
289
347
290
- if (!primaryTemplate) {
291
- declaringScope ()->addSymbol (classSymbol);
292
- } else {
293
- std::vector<TemplateArgument> arguments;
294
- // TODO: parse template arguments
295
- primaryTemplate->addSpecialization (arguments, classSymbol);
296
- }
348
+ declaringScope ()->addSymbol (classSymbol);
297
349
}
298
350
299
- classSymbol->setDeclaration (ast);
351
+ ast->symbol = classSymbol;
352
+
353
+ ast->symbol ->setDeclaration (ast);
300
354
301
355
if (declSpecs.templateHead ) {
302
- classSymbol ->setTemplateDeclaration (declSpecs.templateHead );
356
+ ast-> symbol ->setTemplateDeclaration (declSpecs.templateHead );
303
357
}
304
358
305
- classSymbol->setFinal (ast->isFinal );
306
-
307
- ast->symbol = classSymbol;
359
+ ast->symbol ->setFinal (ast->isFinal );
308
360
309
361
declSpecs.setTypeSpecifier (ast);
310
- declSpecs.setType (classSymbol ->type ());
362
+ declSpecs.setType (ast-> symbol ->type ());
311
363
}
312
364
313
365
void Binder::complete (ClassSpecifierAST* ast) {
@@ -417,7 +469,6 @@ auto Binder::declareTypeAlias(SourceLocation identifierLoc, TypeIdAST* typeId,
417
469
symbol->setName (name);
418
470
419
471
if (typeId) symbol->setType (typeId->type );
420
- symbol->setTemplateParameters (currentTemplateParameters ());
421
472
422
473
if (auto classType = type_cast<ClassType>(symbol->type ())) {
423
474
auto classSymbol = classType->symbol ();
@@ -565,7 +616,6 @@ void Binder::bind(ConceptDefinitionAST* ast) {
565
616
566
617
auto symbol = control ()->newConceptSymbol (scope (), ast->identifierLoc );
567
618
symbol->setName (ast->identifier );
568
- symbol->setTemplateParameters (templateParameters);
569
619
570
620
declaringScope ()->addSymbol (symbol);
571
621
}
@@ -708,7 +758,6 @@ auto Binder::declareFunction(DeclaratorAST* declarator, const Decl& decl)
708
758
applySpecifiers (functionSymbol, decl.specs );
709
759
functionSymbol->setName (name);
710
760
functionSymbol->setType (type);
711
- functionSymbol->setTemplateParameters (currentTemplateParameters ());
712
761
713
762
if (isConstructor (functionSymbol)) {
714
763
auto enclosingClass = symbol_cast<ClassSymbol>(scope ());
@@ -775,7 +824,6 @@ auto Binder::declareVariable(DeclaratorAST* declarator, const Decl& decl)
775
824
applySpecifiers (symbol, decl.specs );
776
825
symbol->setName (name);
777
826
symbol->setType (type);
778
- symbol->setTemplateParameters (currentTemplateParameters ());
779
827
declaringScope ()->addSymbol (symbol);
780
828
return symbol;
781
829
}
@@ -890,13 +938,29 @@ auto Binder::resolve(NestedNameSpecifierAST* nestedNameSpecifier,
890
938
}
891
939
892
940
void Binder::bind (IdExpressionAST* ast) {
893
- if (ast->unqualifiedId ) {
894
- auto name = get_name (control (), ast->unqualifiedId );
895
- const Name* componentName = name;
896
- if (auto templateId = name_cast<TemplateId>(name))
897
- componentName = templateId->name ();
898
- ast->symbol = Lookup{scope ()}(ast->nestedNameSpecifier , componentName);
941
+ if (!ast->unqualifiedId ) {
942
+ error (ast->firstSourceLocation (),
943
+ " expected an unqualified identifier in id expression" );
944
+ return ;
899
945
}
946
+
947
+ auto name = get_name (control (), ast->unqualifiedId );
948
+
949
+ const Name* componentName = name;
950
+
951
+ if (auto templateId = name_cast<TemplateId>(name)) {
952
+ componentName = templateId->name ();
953
+ }
954
+
955
+ if (ast->nestedNameSpecifier ) {
956
+ if (!ast->nestedNameSpecifier ->symbol ) {
957
+ error (ast->nestedNameSpecifier ->firstSourceLocation (),
958
+ " nested name specifier must be a class or namespace" );
959
+ return ;
960
+ }
961
+ }
962
+
963
+ ast->symbol = Lookup{scope ()}(ast->nestedNameSpecifier , componentName);
900
964
}
901
965
902
966
auto Binder::getFunction (ScopeSymbol* scope, const Name* name, const Type* type)
0 commit comments