@@ -6385,16 +6385,19 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
6385
6385
6386
6386
ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl (
6387
6387
VarTemplateSpecializationDecl *D) {
6388
- // If this record has a definition in the translation unit we're coming from,
6389
- // but this particular declaration is not that definition, import the
6390
- // definition and map to that.
6391
- VarDecl *Definition = D->getDefinition ();
6392
- if (Definition && Definition != D) {
6393
- if (ExpectedDecl ImportedDefOrErr = import (Definition))
6394
- return Importer.MapImported (D, *ImportedDefOrErr);
6395
- else
6396
- return ImportedDefOrErr.takeError ();
6388
+ // A VarTemplateSpecializationDecl inherits from VarDecl, the import is done
6389
+ // in an analog way (but specialized for this case).
6390
+
6391
+ SmallVector<Decl *, 2 > Redecls = getCanonicalForwardRedeclChain (D);
6392
+ auto RedeclIt = Redecls.begin ();
6393
+ // Import the first part of the decl chain. I.e. import all previous
6394
+ // declarations starting from the canonical decl.
6395
+ for (; RedeclIt != Redecls.end () && *RedeclIt != D; ++RedeclIt) {
6396
+ ExpectedDecl RedeclOrErr = import (*RedeclIt);
6397
+ if (!RedeclOrErr)
6398
+ return RedeclOrErr.takeError ();
6397
6399
}
6400
+ assert (*RedeclIt == D);
6398
6401
6399
6402
VarTemplateDecl *VarTemplate = nullptr ;
6400
6403
if (Error Err = importInto (VarTemplate, D->getSpecializedTemplate ()))
@@ -6422,116 +6425,132 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
6422
6425
6423
6426
// Try to find an existing specialization with these template arguments.
6424
6427
void *InsertPos = nullptr ;
6425
- VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization (
6426
- TemplateArgs, InsertPos);
6427
- if (D2) {
6428
- // We already have a variable template specialization with these template
6429
- // arguments.
6430
-
6431
- // FIXME: Check for specialization vs. instantiation errors.
6432
-
6433
- if (VarDecl *FoundDef = D2->getDefinition ()) {
6434
- if (!D->isThisDeclarationADefinition () ||
6435
- IsStructuralMatch (D, FoundDef)) {
6436
- // The record types structurally match, or the "from" translation
6437
- // unit only had a forward declaration anyway; call it the same
6438
- // variable.
6439
- return Importer.MapImported (D, FoundDef);
6428
+ VarTemplateSpecializationDecl *FoundSpecialization =
6429
+ VarTemplate->findSpecialization (TemplateArgs, InsertPos);
6430
+ if (FoundSpecialization) {
6431
+ if (IsStructuralMatch (D, FoundSpecialization)) {
6432
+ VarDecl *FoundDef = FoundSpecialization->getDefinition ();
6433
+ if (D->getDeclContext ()->isRecord ()) {
6434
+ // In a record, it is allowed only to have one optional declaration and
6435
+ // one definition of the (static or constexpr) variable template.
6436
+ assert (
6437
+ FoundSpecialization->getDeclContext ()->isRecord () &&
6438
+ " Member variable template specialization imported as non-member, "
6439
+ " inconsistent imported AST?" );
6440
+ if (FoundDef)
6441
+ return Importer.MapImported (D, FoundDef);
6442
+ if (!D->isThisDeclarationADefinition ())
6443
+ return Importer.MapImported (D, FoundSpecialization);
6444
+ } else {
6445
+ // If definition is imported and there is already one, map to it.
6446
+ // Otherwise create a new variable and link it to the existing.
6447
+ if (FoundDef && D->isThisDeclarationADefinition ())
6448
+ return Importer.MapImported (D, FoundDef);
6440
6449
}
6450
+ } else {
6451
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
6441
6452
}
6442
- } else {
6443
- TemplateArgumentListInfo ToTAInfo;
6444
- if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo ()) {
6445
- if (Error Err = ImportTemplateArgumentListInfo (*Args, ToTAInfo))
6446
- return std::move (Err);
6447
- }
6453
+ }
6448
6454
6449
- using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
6450
- // Create a new specialization.
6451
- if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) {
6452
- // Import TemplateArgumentListInfo
6453
- TemplateArgumentListInfo ArgInfos;
6454
- const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten ();
6455
- // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
6456
- if (Error Err = ImportTemplateArgumentListInfo (
6457
- *FromTAArgsAsWritten, ArgInfos))
6458
- return std::move (Err);
6455
+ VarTemplateSpecializationDecl *D2 = nullptr ;
6459
6456
6460
- auto ToTPListOrErr = import (FromPartial->getTemplateParameters ());
6461
- if (!ToTPListOrErr)
6462
- return ToTPListOrErr.takeError ();
6457
+ TemplateArgumentListInfo ToTAInfo;
6458
+ if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo ()) {
6459
+ if (Error Err = ImportTemplateArgumentListInfo (*Args, ToTAInfo))
6460
+ return std::move (Err);
6461
+ }
6463
6462
6464
- PartVarSpecDecl *ToPartial;
6465
- if (GetImportedOrCreateDecl (ToPartial, D, Importer.getToContext (), DC,
6466
- *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
6467
- VarTemplate, QualType (), nullptr ,
6468
- D->getStorageClass (), TemplateArgs, ArgInfos))
6469
- return ToPartial;
6463
+ using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
6464
+ // Create a new specialization.
6465
+ if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) {
6466
+ // Import TemplateArgumentListInfo
6467
+ TemplateArgumentListInfo ArgInfos;
6468
+ const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten ();
6469
+ // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
6470
+ if (Error Err =
6471
+ ImportTemplateArgumentListInfo (*FromTAArgsAsWritten, ArgInfos))
6472
+ return std::move (Err);
6470
6473
6471
- if (Expected<PartVarSpecDecl *> ToInstOrErr = import (
6472
- FromPartial->getInstantiatedFromMember ()))
6473
- ToPartial->setInstantiatedFromMember (*ToInstOrErr);
6474
- else
6475
- return ToInstOrErr.takeError ();
6476
-
6477
- if (FromPartial->isMemberSpecialization ())
6478
- ToPartial->setMemberSpecialization ();
6479
-
6480
- D2 = ToPartial;
6481
-
6482
- // FIXME: Use this update if VarTemplatePartialSpecializationDecl is fixed
6483
- // to adopt template parameters.
6484
- // updateLookupTableForTemplateParameters(**ToTPListOrErr);
6485
- } else { // Full specialization
6486
- if (GetImportedOrCreateDecl (D2, D, Importer.getToContext (), DC,
6487
- *BeginLocOrErr, *IdLocOrErr, VarTemplate,
6488
- QualType (), nullptr , D->getStorageClass (),
6489
- TemplateArgs))
6490
- return D2;
6491
- }
6474
+ auto ToTPListOrErr = import (FromPartial->getTemplateParameters ());
6475
+ if (!ToTPListOrErr)
6476
+ return ToTPListOrErr.takeError ();
6492
6477
6493
- QualType T;
6494
- if (Error Err = importInto (T, D->getType ()))
6495
- return std::move (Err);
6496
- D2->setType (T);
6478
+ PartVarSpecDecl *ToPartial;
6479
+ if (GetImportedOrCreateDecl (ToPartial, D, Importer.getToContext (), DC,
6480
+ *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
6481
+ VarTemplate, QualType (), nullptr ,
6482
+ D->getStorageClass (), TemplateArgs, ArgInfos))
6483
+ return ToPartial;
6497
6484
6498
- auto TInfoOrErr = import (D->getTypeSourceInfo ());
6499
- if (!TInfoOrErr)
6500
- return TInfoOrErr.takeError ();
6501
- D2->setTypeSourceInfo (*TInfoOrErr);
6485
+ if (Expected<PartVarSpecDecl *> ToInstOrErr =
6486
+ import (FromPartial->getInstantiatedFromMember ()))
6487
+ ToPartial->setInstantiatedFromMember (*ToInstOrErr);
6488
+ else
6489
+ return ToInstOrErr.takeError ();
6502
6490
6503
- if (D->getPointOfInstantiation ().isValid ()) {
6504
- if (ExpectedSLoc POIOrErr = import (D->getPointOfInstantiation ()))
6505
- D2->setPointOfInstantiation (*POIOrErr);
6506
- else
6507
- return POIOrErr.takeError ();
6508
- }
6491
+ if (FromPartial->isMemberSpecialization ())
6492
+ ToPartial->setMemberSpecialization ();
6493
+
6494
+ D2 = ToPartial;
6509
6495
6510
- D2->setSpecializationKind (D->getSpecializationKind ());
6511
- D2->setTemplateArgsInfo (ToTAInfo);
6496
+ // FIXME: Use this update if VarTemplatePartialSpecializationDecl is fixed
6497
+ // to adopt template parameters.
6498
+ // updateLookupTableForTemplateParameters(**ToTPListOrErr);
6499
+ } else { // Full specialization
6500
+ if (GetImportedOrCreateDecl (D2, D, Importer.getToContext (), DC,
6501
+ *BeginLocOrErr, *IdLocOrErr, VarTemplate,
6502
+ QualType (), nullptr , D->getStorageClass (),
6503
+ TemplateArgs))
6504
+ return D2;
6505
+ }
6512
6506
6513
- // Add this specialization to the class template.
6514
- VarTemplate->AddSpecialization (D2, InsertPos);
6507
+ QualType T;
6508
+ if (Error Err = importInto (T, D->getType ()))
6509
+ return std::move (Err);
6510
+ D2->setType (T);
6515
6511
6516
- // Import the qualifier, if any.
6517
- if (auto LocOrErr = import (D->getQualifierLoc ()))
6518
- D2->setQualifierInfo (*LocOrErr);
6512
+ auto TInfoOrErr = import (D->getTypeSourceInfo ());
6513
+ if (!TInfoOrErr)
6514
+ return TInfoOrErr.takeError ();
6515
+ D2->setTypeSourceInfo (*TInfoOrErr);
6516
+
6517
+ if (D->getPointOfInstantiation ().isValid ()) {
6518
+ if (ExpectedSLoc POIOrErr = import (D->getPointOfInstantiation ()))
6519
+ D2->setPointOfInstantiation (*POIOrErr);
6519
6520
else
6520
- return LocOrErr.takeError ();
6521
+ return POIOrErr.takeError ();
6522
+ }
6521
6523
6522
- if (D->isConstexpr ())
6523
- D2->setConstexpr ( true );
6524
+ D2-> setSpecializationKind (D->getSpecializationKind ());
6525
+ D2->setTemplateArgsInfo (ToTAInfo );
6524
6526
6525
- // Add the specialization to this context.
6526
- D2->setLexicalDeclContext (LexicalDC);
6527
- LexicalDC->addDeclInternal (D2);
6527
+ if (auto LocOrErr = import (D->getQualifierLoc ()))
6528
+ D2->setQualifierInfo (*LocOrErr);
6529
+ else
6530
+ return LocOrErr.takeError ();
6528
6531
6529
- D2->setAccess (D->getAccess ());
6530
- }
6532
+ if (D->isConstexpr ())
6533
+ D2->setConstexpr (true );
6534
+
6535
+ D2->setAccess (D->getAccess ());
6531
6536
6532
6537
if (Error Err = ImportInitializer (D, D2))
6533
6538
return std::move (Err);
6534
6539
6540
+ if (FoundSpecialization)
6541
+ D2->setPreviousDecl (FoundSpecialization->getMostRecentDecl ());
6542
+
6543
+ VarTemplate->AddSpecialization (D2, InsertPos);
6544
+
6545
+ addDeclToContexts (D, D2);
6546
+
6547
+ // Import the rest of the chain. I.e. import all subsequent declarations.
6548
+ for (++RedeclIt; RedeclIt != Redecls.end (); ++RedeclIt) {
6549
+ ExpectedDecl RedeclOrErr = import (*RedeclIt);
6550
+ if (!RedeclOrErr)
6551
+ return RedeclOrErr.takeError ();
6552
+ }
6553
+
6535
6554
return D2;
6536
6555
}
6537
6556
0 commit comments