[clang] [clang][ASTImporter][StructuralEquivalence] improve StructuralEquivalence on recordType (PR #76226)

Qizhi Hu via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 22 18:17:22 PST 2023


https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/76226

>From 9a8cea81eba77eef914089e3cffd96e863aac36f Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at 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"(



More information about the cfe-commits mailing list