https://github.com/antangelo updated https://github.com/llvm/llvm-project/pull/123875
>From ff55e99b39e2e60859a93db5a479ac2128761e30 Mon Sep 17 00:00:00 2001 From: antangelo <cont...@antangelo.com> Date: Tue, 21 Jan 2025 22:53:39 -0500 Subject: [PATCH 1/2] [clang] Track source deduction guide for alias template deduction guides For deduction guides generated from alias template CTAD, store the deduction guide they were originated from. The source kind is also maintained for future expansion in CTAD from inherited constructors. This tracking is required to determine whether an alias template already has a deduction guide corresponding to some deduction guide on the original template, in order to support deduction guides for the alias from deduction guides declared after the initial usage. --- clang/include/clang/AST/DeclCXX.h | 45 +++++++++++++++++-- clang/lib/AST/ASTImporter.cpp | 8 ++-- clang/lib/AST/DeclCXX.cpp | 13 +++--- clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 8 +++- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 +- clang/lib/Serialization/ASTReaderDecl.cpp | 4 ++ clang/lib/Serialization/ASTWriterDecl.cpp | 3 ++ clang/unittests/AST/ASTImporterTest.cpp | 22 +++++++++ 8 files changed, 93 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index fa3f4ec98eb369..79fd403c2718c8 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1967,17 +1967,29 @@ class ExplicitSpecifier { class CXXDeductionGuideDecl : public FunctionDecl { void anchor() override; +public: + // Represents the relationship between this deduction guide and the + // deduction guide that it was generated from (or lack thereof). + // See the SourceDeductionGuide member for more details. + enum class SourceDeductionGuideKind : uint8_t { + None, + Alias, + }; + private: CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor, DeductionCandidate Kind, - Expr *TrailingRequiresClause) + Expr *TrailingRequiresClause, + const CXXDeductionGuideDecl *GeneratedFrom, + SourceDeductionGuideKind SourceKind) : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo, SC_None, false, false, ConstexprSpecKind::Unspecified, TrailingRequiresClause), - Ctor(Ctor), ExplicitSpec(ES) { + Ctor(Ctor), ExplicitSpec(ES), + SourceDeductionGuide(GeneratedFrom, SourceKind) { if (EndLocation.isValid()) setRangeEnd(EndLocation); setDeductionCandidateKind(Kind); @@ -1985,6 +1997,12 @@ class CXXDeductionGuideDecl : public FunctionDecl { CXXConstructorDecl *Ctor; ExplicitSpecifier ExplicitSpec; + // The deduction guide, if any, that this deduction guide was generated from, + // in the case of alias template deduction. The SourceDeductionGuideKind + // member indicates which of these sources applies, or is None otherwise. + llvm::PointerIntPair<const CXXDeductionGuideDecl *, 2, + SourceDeductionGuideKind> + SourceDeductionGuide; void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } public: @@ -1997,7 +2015,9 @@ class CXXDeductionGuideDecl : public FunctionDecl { TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal, - Expr *TrailingRequiresClause = nullptr); + Expr *TrailingRequiresClause = nullptr, + const CXXDeductionGuideDecl *SourceDG = nullptr, + SourceDeductionGuideKind SK = SourceDeductionGuideKind::None); static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); @@ -2017,6 +2037,25 @@ class CXXDeductionGuideDecl : public FunctionDecl { /// this is an implicit deduction guide. CXXConstructorDecl *getCorrespondingConstructor() const { return Ctor; } + /// Get the deduction guide from which this deduction guide was generated, + /// if it was generated as part of alias template deduction or from an + /// inherited constructor. + const CXXDeductionGuideDecl *getSourceDeductionGuide() const { + return SourceDeductionGuide.getPointer(); + } + + void setSourceDeductionGuide(CXXDeductionGuideDecl *DG) { + SourceDeductionGuide.setPointer(DG); + } + + SourceDeductionGuideKind getSourceDeductionGuideKind() const { + return SourceDeductionGuide.getInt(); + } + + void setSourceDeductionGuideKind(SourceDeductionGuideKind SK) { + SourceDeductionGuide.setInt(SK); + } + void setDeductionCandidateKind(DeductionCandidate K) { FunctionDeclBits.DeductionCandidateKind = static_cast<unsigned char>(K); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 0669aa1b809c34..0a643f8092ed3c 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3999,14 +3999,16 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { importExplicitSpecifier(Err, Guide->getExplicitSpecifier()); CXXConstructorDecl *Ctor = importChecked(Err, Guide->getCorrespondingConstructor()); + const CXXDeductionGuideDecl *SourceDG = + importChecked(Err, Guide->getSourceDeductionGuide()); if (Err) return std::move(Err); if (GetImportedOrCreateDecl<CXXDeductionGuideDecl>( ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, ESpec, - NameInfo, T, TInfo, ToEndLoc, Ctor)) + NameInfo, T, TInfo, ToEndLoc, Ctor, + Guide->getDeductionCandidateKind(), TrailingRequiresClause, + SourceDG, Guide->getSourceDeductionGuideKind())) return ToFunction; - cast<CXXDeductionGuideDecl>(ToFunction) - ->setDeductionCandidateKind(Guide->getDeductionCandidateKind()); } else { if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 44f45898fb483d..8cac403712ae95 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2290,10 +2290,12 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor, - DeductionCandidate Kind, Expr *TrailingRequiresClause) { - return new (C, DC) - CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T, TInfo, - EndLocation, Ctor, Kind, TrailingRequiresClause); + DeductionCandidate Kind, Expr *TrailingRequiresClause, + const CXXDeductionGuideDecl *GeneratedFrom, + SourceDeductionGuideKind SourceKind) { + return new (C, DC) CXXDeductionGuideDecl( + C, DC, StartLoc, ES, NameInfo, T, TInfo, EndLocation, Ctor, Kind, + TrailingRequiresClause, GeneratedFrom, SourceKind); } CXXDeductionGuideDecl * @@ -2301,7 +2303,8 @@ CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) CXXDeductionGuideDecl( C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), QualType(), nullptr, SourceLocation(), nullptr, - DeductionCandidate::Normal, nullptr); + DeductionCandidate::Normal, nullptr, + /*GeneratedFrom=*/nullptr, SourceDeductionGuideKind::None); } RequiresExprBodyDecl *RequiresExprBodyDecl::Create( diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 5f813ba3a597a3..00e588499a044c 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -1135,8 +1135,12 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(), AliasTemplate->getEndLoc(), F->isImplicit())); - cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl()) - ->setDeductionCandidateKind(GG->getDeductionCandidateKind()); + auto *DGuide = cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl()); + DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind()); + DGuide->setSourceDeductionGuide( + cast<CXXDeductionGuideDecl>(F->getTemplatedDecl())); + DGuide->setSourceDeductionGuideKind( + CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias); return Result; } return nullptr; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 6a2331e59477a2..1a637710c99b72 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2264,7 +2264,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( SemaRef.Context, DC, D->getInnerLocStart(), InstantiatedExplicitSpecifier, NameInfo, T, TInfo, D->getSourceRange().getEnd(), DGuide->getCorrespondingConstructor(), - DGuide->getDeductionCandidateKind(), TrailingRequiresClause); + DGuide->getDeductionCandidateKind(), TrailingRequiresClause, + DGuide->getSourceDeductionGuide(), + DGuide->getSourceDeductionGuideKind()); Function->setAccess(D->getAccess()); } else { Function = FunctionDecl::Create( diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index de834285fa76b2..3526419b9d3bf4 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2285,6 +2285,10 @@ void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { VisitFunctionDecl(D); D->setDeductionCandidateKind( static_cast<DeductionCandidate>(Record.readInt())); + D->setSourceDeductionGuide(readDeclAs<CXXDeductionGuideDecl>()); + D->setSourceDeductionGuideKind( + static_cast<CXXDeductionGuideDecl::SourceDeductionGuideKind>( + Record.readInt())); } void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 30b28057f4c10f..e9417395ab3bc6 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -831,6 +831,9 @@ void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { Record.AddDeclRef(D->Ctor); VisitFunctionDecl(D); Record.push_back(static_cast<unsigned char>(D->getDeductionCandidateKind())); + Record.AddDeclRef(D->getSourceDeductionGuide()); + Record.push_back( + static_cast<unsigned char>(D->getSourceDeductionGuideKind())); Code = serialization::DECL_CXX_DEDUCTION_GUIDE; } diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 791248e7a394f1..2fc23556196e1a 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -8105,6 +8105,7 @@ TEST_P(ImportFunctions, CTADImplicit) { auto *ToD = Import(FromD, Lang_CXX17); ASSERT_TRUE(ToD); EXPECT_EQ(ToD->getDeductionCandidateKind(), DeductionCandidate::Copy); + EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr); // Check that the deduced class template is also imported. EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull( FromD->getDeducedTemplate())); @@ -8129,6 +8130,7 @@ TEST_P(ImportFunctions, CTADUserDefinedExplicit) { ASSERT_TRUE(ToD); EXPECT_FALSE(FromD->isImplicit()); EXPECT_TRUE(ToD->isExplicit()); + EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr); } TEST_P(ImportFunctions, CTADWithLocalTypedef) { @@ -8147,6 +8149,26 @@ TEST_P(ImportFunctions, CTADWithLocalTypedef) { ASSERT_TRUE(ToD); } +TEST_P(ImportFunctions, CTADAliasTemplate) { + Decl *TU = getTuDecl( + R"( + template <typename T> struct A { + A(T); + }; + template<typename T> + using B = A<T>; + B b{(int)0}; + )", + Lang_CXX20, "input.cc"); + auto *FromD = FirstDeclMatcher<CXXDeductionGuideDecl>().match( + TU, cxxDeductionGuideDecl(hasParameter(0, hasType(asString("int"))))); + auto *ToD = Import(FromD, Lang_CXX20); + ASSERT_TRUE(ToD); + EXPECT_TRUE(ToD->getSourceDeductionGuideKind() == + CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias); + EXPECT_TRUE(ToD->getSourceDeductionGuide()); +} + TEST_P(ImportFunctions, ParmVarDeclDeclContext) { constexpr auto FromTUCode = R"( void f(int P); >From 918fef4e66a4a5b3d0a517726ca8c4b7dcb3e120 Mon Sep 17 00:00:00 2001 From: antangelo <cont...@antangelo.com> Date: Sat, 25 Jan 2025 20:57:57 -0500 Subject: [PATCH 2/2] Fix bugprone-argument-comments, add assertions for DG source kind in None case in ASTImporterTest --- clang/lib/AST/DeclCXX.cpp | 7 ++++--- clang/unittests/AST/ASTImporterTest.cpp | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 93a53976210121..a023a9f456a0e4 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2303,9 +2303,10 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( CXXDeductionGuideDecl * CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) CXXDeductionGuideDecl( - C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), - QualType(), nullptr, SourceLocation(), nullptr, - DeductionCandidate::Normal, nullptr, + C, /*DC=*/nullptr, SourceLocation(), ExplicitSpecifier(), + DeclarationNameInfo(), QualType(), /*TInfo=*/nullptr, SourceLocation(), + /*Ctor=*/nullptr, DeductionCandidate::Normal, + /*TrailingRequiresClause=*/nullptr, /*GeneratedFrom=*/nullptr, SourceDeductionGuideKind::None); } diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 2fc23556196e1a..bd8468ad4baeda 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -8106,6 +8106,8 @@ TEST_P(ImportFunctions, CTADImplicit) { ASSERT_TRUE(ToD); EXPECT_EQ(ToD->getDeductionCandidateKind(), DeductionCandidate::Copy); EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr); + EXPECT_EQ(ToD->getSourceDeductionGuideKind(), + CXXDeductionGuideDecl::SourceDeductionGuideKind::None); // Check that the deduced class template is also imported. EXPECT_TRUE(findFromTU(FromD)->Importer->GetAlreadyImportedOrNull( FromD->getDeducedTemplate())); @@ -8131,6 +8133,8 @@ TEST_P(ImportFunctions, CTADUserDefinedExplicit) { EXPECT_FALSE(FromD->isImplicit()); EXPECT_TRUE(ToD->isExplicit()); EXPECT_EQ(ToD->getSourceDeductionGuide(), nullptr); + EXPECT_EQ(ToD->getSourceDeductionGuideKind(), + CXXDeductionGuideDecl::SourceDeductionGuideKind::None); } TEST_P(ImportFunctions, CTADWithLocalTypedef) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits