forked from OSchip/llvm-project
Revert "[clang][AST] Check context of record in structural equivalence."
Revert commit 6b96b2a0bf
because Windows
test failure.
This commit is contained in:
parent
c0e3bb4d4b
commit
8804d08e99
|
@ -1347,42 +1347,6 @@ IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context,
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Determine if context of a class is equivalent.
|
||||
static bool IsRecordContextStructurallyEquivalent(RecordDecl *D1,
|
||||
RecordDecl *D2) {
|
||||
// The context should be completely equal, including anonymous and inline
|
||||
// namespaces.
|
||||
// We compare objects as part of full translation units, not subtrees of
|
||||
// translation units.
|
||||
DeclContext *DC1 = D1->getDeclContext()->getNonTransparentContext();
|
||||
DeclContext *DC2 = D2->getDeclContext()->getNonTransparentContext();
|
||||
while (true) {
|
||||
// Special case: We allow a struct defined in a function to be equivalent
|
||||
// with a similar struct defined outside of a function.
|
||||
if ((DC1->isFunctionOrMethod() && DC2->isTranslationUnit()) ||
|
||||
(DC2->isFunctionOrMethod() && DC1->isTranslationUnit()))
|
||||
return true;
|
||||
|
||||
if (DC1->getDeclKind() != DC2->getDeclKind())
|
||||
return false;
|
||||
if (DC1->isTranslationUnit())
|
||||
break;
|
||||
if (DC1->isInlineNamespace() != DC2->isInlineNamespace())
|
||||
return false;
|
||||
if (const auto *ND1 = dyn_cast<NamedDecl>(DC1)) {
|
||||
const auto *ND2 = cast<NamedDecl>(DC2);
|
||||
if (!DC1->isInlineNamespace() &&
|
||||
!IsStructurallyEquivalent(ND1->getIdentifier(), ND2->getIdentifier()))
|
||||
return false;
|
||||
}
|
||||
|
||||
DC1 = DC1->getParent()->getNonTransparentContext();
|
||||
DC2 = DC2->getParent()->getNonTransparentContext();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Determine structural equivalence of two records.
|
||||
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
RecordDecl *D1, RecordDecl *D2) {
|
||||
|
@ -1422,12 +1386,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
|||
}
|
||||
}
|
||||
|
||||
// If the records occur in different context (namespace), these should be
|
||||
// different. This is specially important if the definition of one or both
|
||||
// records is missing.
|
||||
if (!IsRecordContextStructurallyEquivalent(D1, D2))
|
||||
return false;
|
||||
|
||||
// If both declarations are class template specializations, we know
|
||||
// the ODR applies, so check the template and template arguments.
|
||||
const auto *Spec1 = dyn_cast<ClassTemplateSpecializationDecl>(D1);
|
||||
|
|
|
@ -929,136 +929,6 @@ TEST_F(StructuralEquivalenceTest, ExplicitBoolSame) {
|
|||
EXPECT_TRUE(testStructuralMatch(First, Second));
|
||||
}
|
||||
|
||||
struct StructuralEquivalenceRecordContextTest : StructuralEquivalenceTest {};
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsNamed) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("class X;", "namespace N { class X; }",
|
||||
Lang_CXX03, cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsNamed) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("namespace A { class X; }",
|
||||
"namespace B { class X; }", Lang_CXX03,
|
||||
cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsNamed) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("namespace { class X; }",
|
||||
"namespace N { class X; }", Lang_CXX03,
|
||||
cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNoVsAnon) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("class X;", "namespace { class X; }",
|
||||
Lang_CXX03, cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnon) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("namespace { class X; }",
|
||||
"namespace { class X; }", Lang_CXX03,
|
||||
cxxRecordDecl());
|
||||
EXPECT_TRUE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceAnonVsAnonAnon) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("namespace { class X; }",
|
||||
"namespace { namespace { class X; } }",
|
||||
Lang_CXX03, cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest,
|
||||
NamespaceNamedNamedVsNamedNamed) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>(
|
||||
"namespace A { namespace N { class X; } }",
|
||||
"namespace B { namespace N { class X; } }", Lang_CXX03, cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceNamedVsInline) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>(
|
||||
"namespace A { namespace A { class X; } }",
|
||||
"namespace A { inline namespace A { class X; } }", Lang_CXX17,
|
||||
cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineVsInline) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>(
|
||||
"namespace A { inline namespace A { class X; } }",
|
||||
"namespace A { inline namespace B { class X; } }", Lang_CXX17,
|
||||
cxxRecordDecl());
|
||||
EXPECT_TRUE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, NamespaceInlineTopLevel) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("inline namespace A { class X; } }",
|
||||
"inline namespace B { class X; } }",
|
||||
Lang_CXX17, cxxRecordDecl());
|
||||
EXPECT_TRUE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, TransparentContext) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("extern \"C\" { class X; }", "class X;",
|
||||
Lang_CXX03, cxxRecordDecl());
|
||||
EXPECT_TRUE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextNE) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>("extern \"C\" { class X; }",
|
||||
"namespace { class X; }", Lang_CXX03,
|
||||
cxxRecordDecl());
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, TransparentContextInNamespace) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>(
|
||||
"extern \"C\" { namespace N { class X; } }",
|
||||
"namespace N { extern \"C\" { class X; } }", Lang_CXX03, cxxRecordDecl());
|
||||
EXPECT_TRUE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTest, NamespaceOfRecordMember) {
|
||||
auto Decls = makeDecls<CXXRecordDecl>(
|
||||
R"(
|
||||
class X;
|
||||
class Y { X* x; };
|
||||
)",
|
||||
R"(
|
||||
namespace N { class X; }
|
||||
class Y { N::X* x; };
|
||||
)",
|
||||
Lang_CXX03, cxxRecordDecl(hasName("Y")));
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototype) {
|
||||
auto Decls = makeDecls<FunctionDecl>(
|
||||
"struct Param { int a; }; void f(struct Param *p);",
|
||||
"void f(struct Param { int a; } *p);", Lang_C89,
|
||||
functionDecl(hasName("f")));
|
||||
EXPECT_TRUE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTest, StructDefinitionInPrototypeDifferentName) {
|
||||
auto Decls = makeDecls<FunctionDecl>(
|
||||
"struct Param1 { int a; }; void f(struct Param1 *p);",
|
||||
"void f(struct Param2 { int a; } *p);", Lang_C89,
|
||||
functionDecl(hasName("f")));
|
||||
EXPECT_FALSE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceRecordContextTest, RecordInsideFunction) {
|
||||
auto Decls = makeDecls<RecordDecl>("struct Param { int a; };",
|
||||
"void f() { struct Param { int a; }; }",
|
||||
Lang_C89, recordDecl(hasName("Param")));
|
||||
EXPECT_TRUE(testStructuralMatch(Decls));
|
||||
}
|
||||
|
||||
struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
|
||||
|
||||
TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) {
|
||||
|
|
Loading…
Reference in New Issue