diff options
author | Balazs Keri <1.int32@gmail.com> | 2018-07-16 12:16:39 +0000 |
---|---|---|
committer | Balazs Keri <1.int32@gmail.com> | 2018-07-16 12:16:39 +0000 |
commit | 1d20cc20f672ed7eb5f94584905ba6e902f669eb (patch) | |
tree | 14466e68ad4d6a6dfe5335af45864b9e38dfbd98 /clang/unittests/AST/ASTImporterTest.cpp | |
parent | c3d8002c2e1b41a05095f6a0f2e720fa9bb63c00 (diff) | |
download | bcm5719-llvm-1d20cc20f672ed7eb5f94584905ba6e902f669eb.tar.gz bcm5719-llvm-1d20cc20f672ed7eb5f94584905ba6e902f669eb.zip |
[ASTImporter] Import implicit methods of existing class.
Summary:
When an already existing class is encountered during import,
check if it has implicit methods that are missing in the existing one,
and import these.
The to-be-imported code may use the same class in different way than the
existing (before the import) code. This may result in that there are
implicit methods that are not generated for the existing code.
Reviewers: a.sidorin, a_sidorin
Reviewed By: a_sidorin
Subscribers: a_sidorin, martong, cfe-commits
Differential Revision: https://reviews.llvm.org/D49245
llvm-svn: 337162
Diffstat (limited to 'clang/unittests/AST/ASTImporterTest.cpp')
-rw-r--r-- | clang/unittests/AST/ASTImporterTest.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index cd8254c0a04..8aff6b5df9a 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -2343,6 +2343,117 @@ TEST_P(ImportExpr, UnresolvedMemberExpr) { compoundStmt(has(callExpr(has(unresolvedMemberExpr()))))))))); } +class ImportImplicitMethods : public ASTImporterTestBase { +public: + static constexpr auto DefaultCode = R"( + struct A { int x; }; + void f() { + A a; + A a1(a); + A a2(A{}); + a = a1; + a = A{}; + a.~A(); + })"; + + template <typename MatcherType> + void testImportOf( + const MatcherType &MethodMatcher, const char *Code = DefaultCode) { + test(MethodMatcher, Code, /*ExpectedCount=*/1u); + } + + template <typename MatcherType> + void testNoImportOf( + const MatcherType &MethodMatcher, const char *Code = DefaultCode) { + test(MethodMatcher, Code, /*ExpectedCount=*/0u); + } + +private: + template <typename MatcherType> + void test(const MatcherType &MethodMatcher, + const char *Code, unsigned int ExpectedCount) { + auto ClassMatcher = cxxRecordDecl(unless(isImplicit())); + + Decl *ToTU = getToTuDecl(Code, Lang_CXX11); + auto *ToClass = FirstDeclMatcher<CXXRecordDecl>().match( + ToTU, ClassMatcher); + + ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 1); + + { + CXXMethodDecl *Method = + FirstDeclMatcher<CXXMethodDecl>().match(ToClass, MethodMatcher); + ToClass->removeDecl(Method); + } + + ASSERT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), 0); + + Decl *ImportedClass = nullptr; + { + Decl *FromTU = getTuDecl(Code, Lang_CXX11, "input1.cc"); + auto *FromClass = FirstDeclMatcher<CXXRecordDecl>().match( + FromTU, ClassMatcher); + ImportedClass = Import(FromClass, Lang_CXX11); + } + + EXPECT_EQ(ToClass, ImportedClass); + EXPECT_EQ(DeclCounter<CXXMethodDecl>().match(ToClass, MethodMatcher), + ExpectedCount); + } +}; + +TEST_P(ImportImplicitMethods, DefaultConstructor) { + testImportOf(cxxConstructorDecl(isDefaultConstructor())); +} + +TEST_P(ImportImplicitMethods, CopyConstructor) { + testImportOf(cxxConstructorDecl(isCopyConstructor())); +} + +TEST_P(ImportImplicitMethods, MoveConstructor) { + testImportOf(cxxConstructorDecl(isMoveConstructor())); +} + +TEST_P(ImportImplicitMethods, Destructor) { + testImportOf(cxxDestructorDecl()); +} + +TEST_P(ImportImplicitMethods, CopyAssignment) { + testImportOf(cxxMethodDecl(isCopyAssignmentOperator())); +} + +TEST_P(ImportImplicitMethods, MoveAssignment) { + testImportOf(cxxMethodDecl(isMoveAssignmentOperator())); +} + +TEST_P(ImportImplicitMethods, DoNotImportUserProvided) { + auto Code = R"( + struct A { A() { int x; } }; + )"; + testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); +} + +TEST_P(ImportImplicitMethods, DoNotImportDefault) { + auto Code = R"( + struct A { A() = default; }; + )"; + testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); +} + +TEST_P(ImportImplicitMethods, DoNotImportDeleted) { + auto Code = R"( + struct A { A() = delete; }; + )"; + testNoImportOf(cxxConstructorDecl(isDefaultConstructor()), Code); +} + +TEST_P(ImportImplicitMethods, DoNotImportOtherMethod) { + auto Code = R"( + struct A { void f() { } }; + )"; + testNoImportOf(cxxMethodDecl(hasName("f")), Code); +} + TEST_P(ASTImporterTestBase, ImportOfEquivalentRecord) { Decl *ToR1; { |