[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 <836744285@qq.com>
This commit is contained in:
Qizhi Hu 2024-06-12 20:04:41 +08:00 committed by GitHub
parent 575e68e571
commit 66a9e26438
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 68 additions and 3 deletions

View File

@ -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) {

View File

@ -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,31 @@ TEST_F(StructuralEquivalenceStmtTest, DeclRefExpr) {
EXPECT_FALSE(testStructuralMatch(t));
}
TEST_F(StructuralEquivalenceCacheTest, CXXDependentScopeMemberExprNoEq) {
auto S = makeStmts(
R"(
template <class T>
void foo() {
(void)T().x;
}
struct A { int x; };
void bar() {
foo<A>();
}
)",
R"(
template <class T>
void foo() {
(void)T().y;
}
struct A { int y; };
void bar() {
foo<A>();
}
)",
Lang_CXX11, cxxDependentScopeMemberExpr());
EXPECT_FALSE(testStructuralMatch(S));
}
} // end namespace ast_matchers
} // end namespace clang