[clang] [clang][ASTImporter] Improve import of variable template specializations. (PR #78284)
Shafik Yaghmour via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 31 18:00:53 PST 2024
=?utf-8?q?Balázs_Kéri?= <balazs.keri at ericsson.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/78284 at github.com>
================
@@ -6397,116 +6400,132 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
// Try to find an existing specialization with these template arguments.
void *InsertPos = nullptr;
- VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
- TemplateArgs, InsertPos);
- if (D2) {
- // We already have a variable template specialization with these template
- // arguments.
-
- // FIXME: Check for specialization vs. instantiation errors.
-
- if (VarDecl *FoundDef = D2->getDefinition()) {
- if (!D->isThisDeclarationADefinition() ||
- IsStructuralMatch(D, FoundDef)) {
- // The record types structurally match, or the "from" translation
- // unit only had a forward declaration anyway; call it the same
- // variable.
- return Importer.MapImported(D, FoundDef);
+ VarTemplateSpecializationDecl *FoundSpecialization =
+ VarTemplate->findSpecialization(TemplateArgs, InsertPos);
+ if (FoundSpecialization) {
+ if (IsStructuralMatch(D, FoundSpecialization)) {
+ VarDecl *FoundDef = FoundSpecialization->getDefinition();
+ if (D->getDeclContext()->isRecord()) {
+ // In a record, it is allowed only to have one optional declaration and
+ // one definition of the (static or constexpr) variable template.
+ assert(
+ FoundSpecialization->getDeclContext()->isRecord() &&
+ "Member variable template specialization imported as non-member, "
+ "inconsistent imported AST?");
+ if (FoundDef)
+ return Importer.MapImported(D, FoundDef);
+ if (!D->isThisDeclarationADefinition())
+ return Importer.MapImported(D, FoundSpecialization);
+ } else {
+ // If definition is imported and there is already one, map to it.
+ // Otherwise create a new variable and link it to the existing.
+ if (FoundDef && D->isThisDeclarationADefinition())
+ return Importer.MapImported(D, FoundDef);
}
+ } else {
+ return make_error<ASTImportError>(ASTImportError::NameConflict);
}
- } else {
- TemplateArgumentListInfo ToTAInfo;
- if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) {
- if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo))
- return std::move(Err);
- }
+ }
- using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
- // Create a new specialization.
- if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) {
- // Import TemplateArgumentListInfo
- TemplateArgumentListInfo ArgInfos;
- const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
- // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
- if (Error Err = ImportTemplateArgumentListInfo(
- *FromTAArgsAsWritten, ArgInfos))
- return std::move(Err);
+ VarTemplateSpecializationDecl *D2 = nullptr;
- auto ToTPListOrErr = import(FromPartial->getTemplateParameters());
- if (!ToTPListOrErr)
- return ToTPListOrErr.takeError();
+ TemplateArgumentListInfo ToTAInfo;
+ if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) {
+ if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo))
+ return std::move(Err);
+ }
- PartVarSpecDecl *ToPartial;
- if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
- *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
- VarTemplate, QualType(), nullptr,
- D->getStorageClass(), TemplateArgs, ArgInfos))
- return ToPartial;
+ using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
+ // Create a new specialization.
+ if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) {
+ // Import TemplateArgumentListInfo
+ TemplateArgumentListInfo ArgInfos;
+ const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
+ // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
+ if (Error Err =
+ ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos))
+ return std::move(Err);
- if (Expected<PartVarSpecDecl *> ToInstOrErr = import(
- FromPartial->getInstantiatedFromMember()))
- ToPartial->setInstantiatedFromMember(*ToInstOrErr);
- else
- return ToInstOrErr.takeError();
-
- if (FromPartial->isMemberSpecialization())
- ToPartial->setMemberSpecialization();
-
- D2 = ToPartial;
-
- // FIXME: Use this update if VarTemplatePartialSpecializationDecl is fixed
- // to adopt template parameters.
- // updateLookupTableForTemplateParameters(**ToTPListOrErr);
- } else { // Full specialization
- if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC,
- *BeginLocOrErr, *IdLocOrErr, VarTemplate,
- QualType(), nullptr, D->getStorageClass(),
- TemplateArgs))
- return D2;
- }
+ auto ToTPListOrErr = import(FromPartial->getTemplateParameters());
+ if (!ToTPListOrErr)
+ return ToTPListOrErr.takeError();
- QualType T;
- if (Error Err = importInto(T, D->getType()))
- return std::move(Err);
- D2->setType(T);
+ PartVarSpecDecl *ToPartial;
+ if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
+ *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
+ VarTemplate, QualType(), nullptr,
+ D->getStorageClass(), TemplateArgs, ArgInfos))
+ return ToPartial;
- auto TInfoOrErr = import(D->getTypeSourceInfo());
- if (!TInfoOrErr)
- return TInfoOrErr.takeError();
- D2->setTypeSourceInfo(*TInfoOrErr);
+ if (Expected<PartVarSpecDecl *> ToInstOrErr =
+ import(FromPartial->getInstantiatedFromMember()))
+ ToPartial->setInstantiatedFromMember(*ToInstOrErr);
+ else
+ return ToInstOrErr.takeError();
- if (D->getPointOfInstantiation().isValid()) {
- if (ExpectedSLoc POIOrErr = import(D->getPointOfInstantiation()))
- D2->setPointOfInstantiation(*POIOrErr);
- else
- return POIOrErr.takeError();
- }
+ if (FromPartial->isMemberSpecialization())
+ ToPartial->setMemberSpecialization();
+
+ D2 = ToPartial;
- D2->setSpecializationKind(D->getSpecializationKind());
- D2->setTemplateArgsInfo(ToTAInfo);
+ // FIXME: Use this update if VarTemplatePartialSpecializationDecl is fixed
+ // to adopt template parameters.
+ // updateLookupTableForTemplateParameters(**ToTPListOrErr);
+ } else { // Full specialization
+ if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC,
+ *BeginLocOrErr, *IdLocOrErr, VarTemplate,
+ QualType(), nullptr, D->getStorageClass(),
----------------
shafik wrote:
Same comment as above
https://github.com/llvm/llvm-project/pull/78284
More information about the cfe-commits
mailing list