Author: martong Date: Thu Aug 9 05:36:25 2018 New Revision: 339336 URL: http://llvm.org/viewvc/llvm-project?rev=339336&view=rev Log: Fix structural inequivalency of forward EnumDecl
Summary: Currently we consider one forward declared RecordDecl and another with a definition equal. We have to do the same in case of enums. Reviewers: a_sidorin, r.stahl, xazax.hun Subscribers: rnkovacs, dkrupp, cfe-commits Differential Revision: https://reviews.llvm.org/D50444 Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=339336&r1=339335&r2=339336&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original) +++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Thu Aug 9 05:36:25 2018 @@ -1178,6 +1178,14 @@ static bool IsStructurallyEquivalent(Str /// Determine structural equivalence of two enums. static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, EnumDecl *D1, EnumDecl *D2) { + + // Compare the definitions of these two enums. If either or both are + // incomplete (i.e. forward declared), we assume that they are equivalent. + D1 = D1->getDefinition(); + D2 = D2->getDefinition(); + if (!D1 || !D2) + return true; + EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(), EC2End = D2->enumerator_end(); for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(), Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=339336&r1=339335&r2=339336&view=diff ============================================================================== --- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original) +++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Thu Aug 9 05:36:25 2018 @@ -642,6 +642,32 @@ TEST_F(StructuralEquivalenceRecordTest, 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( "struct A{ }; struct B{ }; void foo(A a, A b);", @@ -650,5 +676,33 @@ TEST_F(StructuralEquivalenceTest, Compar 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits