[clang] [StructuralEquivalence] improve NTTP and CXXDependentScopeMemberExpr comparison (PR #95190)

Qizhi Hu via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 11 18:56:59 PDT 2024


https://github.com/jcsxky created https://github.com/llvm/llvm-project/pull/95190

improve `ASTStructuralEquivalenceTest`:

1. compare the depth and index of NTTP
2. provide comparison of `CXXDependentScopeMemberExpr` to `StmtCompare`.

>From 644c6e8499285e5b3ab17193ec63eed051dae583 Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at feysh.com>
Date: Wed, 12 Jun 2024 09:47:16 +0800
Subject: [PATCH] [StructuralEquivalence] improve NTTP and
 CXXDependentScopeMemberExpr comparison

---
 clang/lib/AST/ASTStructuralEquivalence.cpp    | 14 ++++-
 .../AST/StructuralEquivalenceTest.cpp         | 52 ++++++++++++++++++-
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index d56bf21b459e0..37555c324282f 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -348,6 +348,15 @@ class StmtComparer {
     return true;
   }
 
+  bool IsStmtEquivalent(const CXXDependentScopeMemberExpr *E1,
+                        const CXXDependentScopeMemberExpr *E2) {
+    if (!IsStructurallyEquivalent(Context, E1->getMember(), E2->getMember())) {
+      return false;
+    }
+    return IsStructurallyEquivalent(Context, E1->getBaseType(),
+                                    E2->getBaseType());
+  }
+
   bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr *E1,
                         const UnaryExprOrTypeTraitExpr *E2) {
     if (E1->getKind() != E2->getKind())
@@ -1997,7 +2006,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
     }
     return false;
   }
-
+  if (!Context.IgnoreTemplateParmDepth && D1->getDepth() != D2->getDepth())
+    return false;
+  if (D1->getIndex() != D2->getIndex())
+    return false;
   // Check types.
   if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
     if (Context.Complain) {
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 91dd717d7b25e..55b2580bfce3b 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -1877,6 +1877,34 @@ TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
   EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
 }
 
+TEST_F(StructuralEquivalenceCacheTest,
+       NonTypeTemplateParmWithDifferentPositionNoEq) {
+  auto TU = makeTuDecls(
+      R"(
+      template<int T>
+      struct A {
+        template<int U>
+        void foo() {}
+      };
+      )",
+      R"(
+      template<int U>
+      struct A {
+        template<int V, int T>
+        void foo() {}
+      };
+      )",
+      Lang_CXX03);
+
+  StructuralEquivalenceContext Ctx(
+      get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
+      NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
+
+  auto NTTP = findDeclPair<NonTypeTemplateParmDecl>(
+      TU, nonTypeTemplateParmDecl(hasName("T")));
+  EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
+}
+
 TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
   auto TU = makeTuDecls(
       R"(
@@ -2441,8 +2469,7 @@ TEST_F(StructuralEquivalenceStmtTest, NonTypeTemplateParm) {
       void foo(A<T, y>);
       )",
       Lang_CXX11);
-  // FIXME: These should not match,
-  EXPECT_TRUE(testStructuralMatch(t));
+  EXPECT_FALSE(testStructuralMatch(t));
 }
 
 TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
@@ -2595,5 +2622,26 @@ TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDependentScopeMemberExpr>
+    cxxDependentScopeMemberExpr;
+
+TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
+  auto S = makeStmts(
+      R"(
+      template <class T>
+      void foo() {
+        T().x;
+      }
+      )",
+      R"(
+      template <class T>
+      void foo() {
+        T().y;
+      }
+      )",
+      Lang_CXX11, cxxDependentScopeMemberExpr());
+  EXPECT_FALSE(testStructuralMatch(S));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang



More information about the cfe-commits mailing list