[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:37:20 PST 2023
https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/76226
>From be62fb62934052db668eea57a9ff241fcd06cd2c 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