Skip to content

Commit 66a9e26

Browse files
authored
[StructuralEquivalence] improve NTTP and CXXDependentScopeMemberExpr comparison (#95190)
improve `ASTStructuralEquivalenceTest`: 1. compare the depth and index of NTTP 2. provide comparison of `CXXDependentScopeMemberExpr` to `StmtCompare`. Co-authored-by: huqizhi <[email protected]>
1 parent 575e68e commit 66a9e26

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

clang/lib/AST/ASTStructuralEquivalence.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,15 @@ class StmtComparer {
348348
return true;
349349
}
350350

351+
bool IsStmtEquivalent(const CXXDependentScopeMemberExpr *E1,
352+
const CXXDependentScopeMemberExpr *E2) {
353+
if (!IsStructurallyEquivalent(Context, E1->getMember(), E2->getMember())) {
354+
return false;
355+
}
356+
return IsStructurallyEquivalent(Context, E1->getBaseType(),
357+
E2->getBaseType());
358+
}
359+
351360
bool IsStmtEquivalent(const UnaryExprOrTypeTraitExpr *E1,
352361
const UnaryExprOrTypeTraitExpr *E2) {
353362
if (E1->getKind() != E2->getKind())
@@ -1997,7 +2006,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
19972006
}
19982007
return false;
19992008
}
2000-
2009+
if (!Context.IgnoreTemplateParmDepth && D1->getDepth() != D2->getDepth())
2010+
return false;
2011+
if (D1->getIndex() != D2->getIndex())
2012+
return false;
20012013
// Check types.
20022014
if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
20032015
if (Context.Complain) {

clang/unittests/AST/StructuralEquivalenceTest.cpp

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,34 @@ TEST_F(StructuralEquivalenceCacheTest, VarDeclWithDifferentStorageClassNoEq) {
18771877
EXPECT_FALSE(Ctx.IsEquivalent(Var.first, Var.second));
18781878
}
18791879

1880+
TEST_F(StructuralEquivalenceCacheTest,
1881+
NonTypeTemplateParmWithDifferentPositionNoEq) {
1882+
auto TU = makeTuDecls(
1883+
R"(
1884+
template<int T>
1885+
struct A {
1886+
template<int U>
1887+
void foo() {}
1888+
};
1889+
)",
1890+
R"(
1891+
template<int U>
1892+
struct A {
1893+
template<int V, int T>
1894+
void foo() {}
1895+
};
1896+
)",
1897+
Lang_CXX03);
1898+
1899+
StructuralEquivalenceContext Ctx(
1900+
get<0>(TU)->getASTContext(), get<1>(TU)->getASTContext(),
1901+
NonEquivalentDecls, StructuralEquivalenceKind::Default, false, false);
1902+
1903+
auto NTTP = findDeclPair<NonTypeTemplateParmDecl>(
1904+
TU, nonTypeTemplateParmDecl(hasName("T")));
1905+
EXPECT_FALSE(Ctx.IsEquivalent(NTTP.first, NTTP.second));
1906+
}
1907+
18801908
TEST_F(StructuralEquivalenceCacheTest, VarDeclWithInitNoEq) {
18811909
auto TU = makeTuDecls(
18821910
R"(
@@ -2441,8 +2469,7 @@ TEST_F(StructuralEquivalenceStmtTest, NonTypeTemplateParm) {
24412469
void foo(A<T, y>);
24422470
)",
24432471
Lang_CXX11);
2444-
// FIXME: These should not match,
2445-
EXPECT_TRUE(testStructuralMatch(t));
2472+
EXPECT_FALSE(testStructuralMatch(t));
24462473
}
24472474

24482475
TEST_F(StructuralEquivalenceStmtTest, UnresolvedLookupDifferentName) {
@@ -2595,5 +2622,31 @@ TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
25952622
EXPECT_FALSE(testStructuralMatch(t));
25962623
}
25972624

2625+
TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
2626+
auto S = makeStmts(
2627+
R"(
2628+
template <class T>
2629+
void foo() {
2630+
(void)T().x;
2631+
}
2632+
struct A { int x; };
2633+
void bar() {
2634+
foo<A>();
2635+
}
2636+
)",
2637+
R"(
2638+
template <class T>
2639+
void foo() {
2640+
(void)T().y;
2641+
}
2642+
struct A { int y; };
2643+
void bar() {
2644+
foo<A>();
2645+
}
2646+
)",
2647+
Lang_CXX11, cxxDependentScopeMemberExpr());
2648+
EXPECT_FALSE(testStructuralMatch(S));
2649+
}
2650+
25982651
} // end namespace ast_matchers
25992652
} // end namespace clang

0 commit comments

Comments
 (0)