summaryrefslogtreecommitdiff
path: root/unittests/AST/StructuralEquivalenceTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/AST/StructuralEquivalenceTest.cpp')
-rw-r--r--unittests/AST/StructuralEquivalenceTest.cpp158
1 files changed, 153 insertions, 5 deletions
diff --git a/unittests/AST/StructuralEquivalenceTest.cpp b/unittests/AST/StructuralEquivalenceTest.cpp
index d5b529c6b6743..cd1f01d4bfc69 100644
--- a/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/unittests/AST/StructuralEquivalenceTest.cpp
@@ -78,11 +78,18 @@ struct StructuralEquivalenceTest : ::testing::Test {
}
bool testStructuralMatch(Decl *D0, Decl *D1) {
- llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls;
- StructuralEquivalenceContext Ctx(
- D0->getASTContext(), D1->getASTContext(), NonEquivalentDecls,
- StructuralEquivalenceKind::Default, false, false);
- return Ctx.IsEquivalent(D0, D1);
+ llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls01;
+ llvm::DenseSet<std::pair<Decl *, Decl *>> NonEquivalentDecls10;
+ StructuralEquivalenceContext Ctx01(
+ D0->getASTContext(), D1->getASTContext(),
+ NonEquivalentDecls01, StructuralEquivalenceKind::Default, false, false);
+ StructuralEquivalenceContext Ctx10(
+ D1->getASTContext(), D0->getASTContext(),
+ NonEquivalentDecls10, StructuralEquivalenceKind::Default, false, false);
+ bool Eq01 = Ctx01.IsEquivalent(D0, D1);
+ bool Eq10 = Ctx10.IsEquivalent(D1, D0);
+ EXPECT_EQ(Eq01, Eq10);
+ return Eq01;
}
bool testStructuralMatch(std::tuple<Decl *, Decl *> t) {
@@ -215,6 +222,14 @@ TEST_F(StructuralEquivalenceTest, WrongOrderOfFieldsInClass) {
struct StructuralEquivalenceFunctionTest : StructuralEquivalenceTest {
};
+TEST_F(StructuralEquivalenceFunctionTest, TemplateVsNonTemplate) {
+ auto t = makeNamedDecls(
+ "void foo();",
+ "template<class T> void foo();",
+ Lang_CXX);
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
auto t = makeNamedDecls("void foo(int&);",
"void foo(const int&);", Lang_CXX);
@@ -582,6 +597,77 @@ TEST_F(StructuralEquivalenceRecordTest, UnnamedRecordsShouldBeInequivalent) {
EXPECT_FALSE(testStructuralMatch(R0, R1));
}
+TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
+ auto t = makeTuDecls(
+ R"(
+ struct X {
+ struct {
+ int a;
+ };
+ struct {
+ int b;
+ };
+ };
+ )",
+ "", Lang_C);
+ auto *TU = get<0>(t);
+ auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
+ TU, indirectFieldDecl(hasName("a")));
+ auto *FA = cast<FieldDecl>(A->chain().front());
+ RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
+ auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
+ TU, indirectFieldDecl(hasName("b")));
+ auto *FB = cast<FieldDecl>(B->chain().front());
+ RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
+
+ ASSERT_NE(RA, RB);
+ EXPECT_TRUE(testStructuralMatch(RA, RA));
+ EXPECT_TRUE(testStructuralMatch(RB, RB));
+ EXPECT_FALSE(testStructuralMatch(RA, RB));
+}
+
+TEST_F(StructuralEquivalenceRecordTest,
+ RecordsAreInequivalentIfOrderOfAnonRecordsIsDifferent) {
+ auto t = makeTuDecls(
+ R"(
+ struct X {
+ struct { int a; };
+ struct { int b; };
+ };
+ )",
+ R"(
+ struct X { // The order is reversed.
+ struct { int b; };
+ struct { int a; };
+ };
+ )",
+ Lang_C);
+
+ auto *TU = get<0>(t);
+ auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
+ TU, indirectFieldDecl(hasName("a")));
+ auto *FA = cast<FieldDecl>(A->chain().front());
+ RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
+
+ auto *TU1 = get<1>(t);
+ auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
+ TU1, indirectFieldDecl(hasName("a")));
+ auto *FA1 = cast<FieldDecl>(A1->chain().front());
+ RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
+
+ RecordDecl *X =
+ FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
+ RecordDecl *X1 =
+ FirstDeclMatcher<RecordDecl>().match(TU1, recordDecl(hasName("X")));
+ ASSERT_NE(X, X1);
+ EXPECT_FALSE(testStructuralMatch(X, X1));
+
+ ASSERT_NE(RA, RA1);
+ EXPECT_TRUE(testStructuralMatch(RA, RA));
+ EXPECT_TRUE(testStructuralMatch(RA1, RA1));
+ EXPECT_FALSE(testStructuralMatch(RA1, RA));
+}
+
TEST_F(StructuralEquivalenceRecordTest,
UnnamedRecordsShouldBeInequivalentEvenIfTheSecondIsBeingDefined) {
auto Code =
@@ -618,6 +704,40 @@ TEST_F(StructuralEquivalenceRecordTest,
EXPECT_FALSE(testStructuralMatch(R0, R1));
}
+TEST_F(StructuralEquivalenceRecordTest, TemplateVsNonTemplate) {
+ auto t = makeDecls<CXXRecordDecl>(
+ "struct A { };",
+ "template<class T> struct A { };",
+ Lang_CXX,
+ cxxRecordDecl(hasName("A")));
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceRecordTest,
+ FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
+ auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceRecordTest,
+ FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
+ auto t =
+ makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceRecordTest,
+ RecordShouldBeEqualWithRecordWhichHasDefinition) {
+ auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
+ Lang_CXX11);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
+ auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
+ Lang_CXX11);
+ EXPECT_FALSE(testStructuralMatch(t));
+}
TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
auto t = makeNamedDecls(
@@ -627,5 +747,33 @@ TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
EXPECT_FALSE(testStructuralMatch(t));
}
+struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
+
+TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
+ auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceEnumTest,
+ FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
+ auto t =
+ makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceEnumTest,
+ EnumShouldBeEqualWithEnumWhichHasDefinition) {
+ auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
+ Lang_CXX11);
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
+ auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
+ Lang_CXX11);
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
+
} // end namespace ast_matchers
} // end namespace clang