https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/67522
>From 77224ec6297a4fb9a86f2634f4a0278b49e81625 Mon Sep 17 00:00:00 2001 From: huqizhi <huqi...@feysh.com> Date: Wed, 27 Sep 2023 15:32:10 +0800 Subject: [PATCH] [clang][ASTImporter] fix clash when import `VarTemplateDecl` in record --- clang/lib/AST/ASTImporter.cpp | 5 +- clang/unittests/AST/ASTImporterTest.cpp | 96 ++++++++++++------------- 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index c7c2aecc8b179a4..441c61c16917bea 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -6236,10 +6236,13 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) { // The Decl in the "From" context has a definition, but in the // "To" context we already have a definition. VarTemplateDecl *FoundDef = getTemplateDefinition(FoundTemplate); - if (D->isThisDeclarationADefinition() && FoundDef) + + if ((D->isThisDeclarationADefinition() && FoundDef)) // FIXME Check for ODR error if the two definitions have // different initializers? return Importer.MapImported(D, FoundDef); + if (FoundTemplate->getDeclContext()->isRecord()) + return Importer.MapImported(D, FoundTemplate); FoundByLookup = FoundTemplate; break; diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index c90b5aaeb624306..f2fafaf4329b740 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -4355,58 +4355,6 @@ TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) { EXPECT_TRUE(Imported->getPreviousDecl()); } -TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) { - Decl *ToTU = getToTuDecl( - R"( - template <class T, T U> - class A; - - template <class T, T U> - class A { - public: - template <class P, P Q> - friend class A; - - A(T x) :x(x) {} - - private: - T x; - }; - )", - Lang_CXX11); - - auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match( - ToTU, - classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A"))))); - Decl *FromTU = getTuDecl( - R"( - template <class T, T U> - class A; - - template <class T, T U> - class A { - public: - template <class P, P Q> - friend class A; - - A(T x) : x(x) {} - - private: - T x; - }; - - A<int,3> a1(0); - )", - Lang_CXX11, "input1.cc"); - auto *FromA = FirstDeclMatcher<ClassTemplateDecl>().match( - FromTU, - classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A"))))); - auto *ToA = Import(FromA, Lang_CXX11); - EXPECT_TRUE(ToA); - EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(), - ToA->getTemplatedDecl()->getTypeForDecl()); -} - TEST_P(ImportFriendClasses, ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) { Decl *ToTU = getToTuDecl( @@ -4988,6 +4936,50 @@ TEST_P(ASTImporterOptionSpecificTestBase, } } +TEST_P(ImportFriendClasses, RecordVarTemplateDecl) { + Decl *ToTU = getToTuDecl( + R"( + template <class T> + class A { + public: + template <class U> + struct B { + static U Value; + }; + + template <class W> + static constexpr bool X = !B<W>::Value; + }; + )", + Lang_CXX14); + + auto *Fwd = FirstDeclMatcher<VarTemplateDecl>().match( + ToTU, varTemplateDecl(hasName("X"))); + Decl *FromTU = getTuDecl( + R"( + template <class T> + class A { + public: + template <class U> + struct B { + static U Value; + }; + + template <class W> + static constexpr bool X = !B<W>::Value; + }; + )", + Lang_CXX14, "input1.cc"); + auto *FromA = FirstDeclMatcher<VarTemplateDecl>().match( + FromTU, varTemplateDecl(hasName("X"))); + auto *ToA = Import(FromA, Lang_CXX11); + EXPECT_TRUE(ToA); + EXPECT_EQ(Fwd->getTemplatedDecl(), + ToA->getTemplatedDecl()); + EXPECT_EQ(Fwd->getTemplatedDecl()->getDefinition(), + ToA->getTemplatedDecl()->getDefinition()); +} + TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateParameterDeclContext) { constexpr auto Code = R"( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits