https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/76226
>From 08a2bb64e19fe244361cb58a1e8eed64a2c1f0cd Mon Sep 17 00:00:00 2001 From: huqizhi <huqi...@feysh.com> Date: Fri, 22 Dec 2023 17:56:32 +0800 Subject: [PATCH] [clang][ASTImporter][StructuralEquivalence] improve StructuralEquivalence on recordType --- clang/lib/AST/ASTStructuralEquivalence.cpp | 15 ++++++++++--- .../AST/StructuralEquivalenceTest.cpp | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index 6bb4bf14b873d7..7c04c09bb80874 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -1107,11 +1107,20 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, } case Type::Record: - case Type::Enum: - if (!IsStructurallyEquivalent(Context, cast<TagType>(T1)->getDecl(), - cast<TagType>(T2)->getDecl())) + case Type::Enum: { + auto *D1 = cast<TagType>(T1)->getDecl(); + auto *D2 = cast<TagType>(T2)->getDecl(); + if (!IsStructurallyEquivalent(Context, D1, D2)) + return false; + auto *D1Spec = + dyn_cast_or_null<ClassTemplateSpecializationDecl>(D1->getDeclContext()); + auto *D2Spec = + dyn_cast_or_null<ClassTemplateSpecializationDecl>(D2->getDeclContext()); + if (nullptr != D1Spec && nullptr != D2Spec && + !IsStructurallyEquivalent(Context, D1Spec, D2Spec)) return false; break; + } case Type::TemplateTypeParm: { const auto *Parm1 = cast<TemplateTypeParmType>(T1); diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp index 44d950cfe758f1..b54d149152e105 100644 --- a/clang/unittests/AST/StructuralEquivalenceTest.cpp +++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp @@ -1024,6 +1024,28 @@ TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextInNamespace) { EXPECT_TRUE(testStructuralMatch(Decls)); } +TEST_F(StructuralEquivalenceRecordContextTest, RecordWithinTemplateClass) { + std::string Code = + R"( + template <typename T> struct O { + struct M {}; + }; + )"; + auto t = makeDecls<VarDecl>(Code + R"( + typedef O<int>::M MT1; + MT1 A; + )", + Code + R"( + namespace { + struct I {}; + } // namespace + typedef O<I>::M MT2; + MT2 A; + )", + Lang_CXX11, varDecl(hasName("A"))); + EXPECT_FALSE(testStructuralMatch(t)); +} + TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) { auto Decls = makeNamedDecls( R"( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits