diff options
Diffstat (limited to 'clang/unittests/AST/ASTImporterTest.cpp')
-rw-r--r-- | clang/unittests/AST/ASTImporterTest.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 41a041f101e..215dc10a398 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -4738,6 +4738,93 @@ TEST_P(ErrorHandlingTest, ErrorHappensAfterNodeIsCreatedAndLinked) { EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); } +// An error should be set for a class if we cannot import one member. +TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) { + TranslationUnitDecl *FromTU = getTuDecl( + std::string(R"( + class X { + void f() { )") + ErroneousStmt + R"( } // This member has the error + // during import. + void ok(); // The error should not prevent importing this. + }; // An error will be set for X too. + )", + Lang_CXX); + auto *FromX = FirstDeclMatcher<CXXRecordDecl>().match( + FromTU, cxxRecordDecl(hasName("X"))); + CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX); + + // An error is set for X. + EXPECT_FALSE(ImportedX); + ASTImporter *Importer = findFromTU(FromX)->Importer.get(); + Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); + ASSERT_TRUE(OptErr); + EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); + + // An error is set for f(). + auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match( + FromTU, cxxMethodDecl(hasName("f"))); + OptErr = Importer->getImportDeclErrorIfAny(FromF); + ASSERT_TRUE(OptErr); + EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); + // And any subsequent import should fail. + CXXMethodDecl *ImportedF = Import(FromF, Lang_CXX); + EXPECT_FALSE(ImportedF); + + // There is no error set for ok(). + auto *FromOK = FirstDeclMatcher<CXXMethodDecl>().match( + FromTU, cxxMethodDecl(hasName("ok"))); + OptErr = Importer->getImportDeclErrorIfAny(FromOK); + EXPECT_FALSE(OptErr); + // And we should be able to import. + CXXMethodDecl *ImportedOK = Import(FromOK, Lang_CXX); + EXPECT_TRUE(ImportedOK); + + // Unwary clients may access X even if the error is set, so, at least make + // sure the class is set to be complete. + CXXRecordDecl *ToX = cast<CXXRecordDecl>(ImportedOK->getDeclContext()); + EXPECT_TRUE(ToX->isCompleteDefinition()); +} + +TEST_P(ErrorHandlingTest, ErrorIsNotPropagatedFromMemberToNamespace) { + TranslationUnitDecl *FromTU = getTuDecl( + std::string(R"( + namespace X { + void f() { )") + ErroneousStmt + R"( } // This member has the error + // during import. + void ok(); // The error should not prevent importing this. + }; // An error will be set for X too. + )", + Lang_CXX); + auto *FromX = FirstDeclMatcher<NamespaceDecl>().match( + FromTU, namespaceDecl(hasName("X"))); + NamespaceDecl *ImportedX = Import(FromX, Lang_CXX); + + // There is no error set for X. + EXPECT_TRUE(ImportedX); + ASTImporter *Importer = findFromTU(FromX)->Importer.get(); + Optional<ImportError> OptErr = Importer->getImportDeclErrorIfAny(FromX); + ASSERT_FALSE(OptErr); + + // An error is set for f(). + auto *FromF = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + OptErr = Importer->getImportDeclErrorIfAny(FromF); + ASSERT_TRUE(OptErr); + EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct); + // And any subsequent import should fail. + FunctionDecl *ImportedF = Import(FromF, Lang_CXX); + EXPECT_FALSE(ImportedF); + + // There is no error set for ok(). + auto *FromOK = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("ok"))); + OptErr = Importer->getImportDeclErrorIfAny(FromOK); + EXPECT_FALSE(OptErr); + // And we should be able to import. + FunctionDecl *ImportedOK = Import(FromOK, Lang_CXX); + EXPECT_TRUE(ImportedOK); +} + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ErrorHandlingTest, DefaultTestValuesForRunOptions, ); |