Skip to content

Commit 157f664

Browse files
author
huqizhi
committed
[StructuralEquivalence] improve NTTP and CXXDependentScopeMemberExpr comparison
1 parent 7e5bc71 commit 157f664

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-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: 47 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,23 @@ 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+
T().x;
2631+
}
2632+
)",
2633+
R"(
2634+
template <class T>
2635+
void foo() {
2636+
T().y;
2637+
}
2638+
)",
2639+
Lang_CXX11, cxxDependentScopeMemberExpr());
2640+
EXPECT_FALSE(testStructuralMatch(S));
2641+
}
2642+
25982643
} // end namespace ast_matchers
25992644
} // end namespace clang

0 commit comments

Comments
 (0)