Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -50,111 +50,236 @@ llvm::MemoryBuffer::getMemBuffer(Code)); } -template -NodeType importNode(ASTUnit *From, ASTUnit *To, ASTImporter &Importer, - NodeType Node) { - ASTContext &ToCtx = To->getASTContext(); +const StringRef DeclToImportID = "declToImport"; +const StringRef DeclToVerifyID = "declToVerify"; - // Add 'From' file to virtual file system so importer can 'find' it - // while importing SourceLocations. It is safe to add same file multiple - // times - it just isn't replaced. - StringRef FromFileName = From->getMainFileName(); - createVirtualFileIfNeeded(To, FromFileName, - From->getBufferForFile(FromFileName)); +// Common base for the different families of ASTImporter tests that are +// parameterized on the compiler options which may result a different AST. E.g. +// -fms-compatibility or -fdelayed-template-parsing. +struct ParameterizedTestsFixture : ::testing::TestWithParam { - auto Imported = Importer.Import(Node); + // Returns the argument vector used for a specific language option, this set + // can be tweaked by the test parameters. + ArgVector getArgVectorForLanguage(Language Lang) const { + ArgVector Args = getBasicRunOptionsForLanguage(Lang); + ArgVector ExtraArgs = GetParam(); + for (const auto &Arg : ExtraArgs) { + Args.push_back(Arg); + } + return Args; + } - // This should dump source locations and assert if some source locations - // were not imported. - SmallString<1024> ImportChecker; - llvm::raw_svector_ostream ToNothing(ImportChecker); - ToCtx.getTranslationUnitDecl()->print(ToNothing); +}; - // This traverses the AST to catch certain bugs like poorly or not - // implemented subtrees. - Imported->dump(ToNothing); +// Base class for those tests which use the family of `testImport` functions. +class TestImportBase : public ParameterizedTestsFixture { - return Imported; -} + template + NodeType importNode(ASTUnit *From, ASTUnit *To, ASTImporter &Importer, + NodeType Node) { + ASTContext &ToCtx = To->getASTContext(); -const StringRef DeclToImportID = "declToImport"; -const StringRef DeclToVerifyID = "declToVerify"; + // Add 'From' file to virtual file system so importer can 'find' it + // while importing SourceLocations. It is safe to add same file multiple + // times - it just isn't replaced. + StringRef FromFileName = From->getMainFileName(); + createVirtualFileIfNeeded(To, FromFileName, + From->getBufferForFile(FromFileName)); -template -testing::AssertionResult -testImport(const std::string &FromCode, const ArgVector &FromArgs, - const std::string &ToCode, const ArgVector &ToArgs, - MatchVerifier &Verifier, - const BindableMatcher &SearchMatcher, - const BindableMatcher &VerificationMatcher) { - const char *const InputFileName = "input.cc"; - const char *const OutputFileName = "output.cc"; + auto Imported = Importer.Import(Node); - std::unique_ptr - FromAST = tooling::buildASTFromCodeWithArgs( - FromCode, FromArgs, InputFileName), - ToAST = tooling::buildASTFromCodeWithArgs(ToCode, ToArgs, OutputFileName); - - ASTContext &FromCtx = FromAST->getASTContext(), - &ToCtx = ToAST->getASTContext(); - - ASTImporter Importer(ToCtx, ToAST->getFileManager(), - FromCtx, FromAST->getFileManager(), false); - - auto FoundNodes = match(SearchMatcher, FromCtx); - if (FoundNodes.size() != 1) - return testing::AssertionFailure() - << "Multiple potential nodes were found!"; - - auto ToImport = selectFirst(DeclToImportID, FoundNodes); - if (!ToImport) - return testing::AssertionFailure() << "Node type mismatch!"; - - // Sanity check: the node being imported should match in the same way as - // the result node. - BindableMatcher WrapperMatcher(VerificationMatcher); - EXPECT_TRUE(Verifier.match(ToImport, WrapperMatcher)); - - auto Imported = importNode(FromAST.get(), ToAST.get(), Importer, ToImport); - if (!Imported) - return testing::AssertionFailure() << "Import failed, nullptr returned!"; - - return Verifier.match(Imported, WrapperMatcher); -} - -template -testing::AssertionResult -testImport(const std::string &FromCode, const ArgVector &FromArgs, - const std::string &ToCode, const ArgVector &ToArgs, - MatchVerifier &Verifier, - const BindableMatcher &VerificationMatcher) { - return testImport( - FromCode, FromArgs, ToCode, ToArgs, Verifier, - translationUnitDecl( - has(namedDecl(hasName(DeclToImportID)).bind(DeclToImportID))), - VerificationMatcher); -} - -/// Test how AST node named "declToImport" located in the translation unit -/// of "FromCode" virtual file is imported to "ToCode" virtual file. -/// The verification is done by running AMatcher over the imported node. -template -void testImport(const std::string &FromCode, Language FromLang, - const std::string &ToCode, Language ToLang, - MatchVerifier &Verifier, - const MatcherType &AMatcher) { - auto RunOptsFrom = getRunOptionsForLanguage(FromLang); - auto RunOptsTo = getRunOptionsForLanguage(ToLang); - for (const auto &FromArgs : RunOptsFrom) - for (const auto &ToArgs : RunOptsTo) - EXPECT_TRUE(testImport(FromCode, FromArgs, ToCode, ToArgs, - Verifier, AMatcher)); -} + // This should dump source locations and assert if some source locations + // were not imported. + SmallString<1024> ImportChecker; + llvm::raw_svector_ostream ToNothing(ImportChecker); + ToCtx.getTranslationUnitDecl()->print(ToNothing); + + // This traverses the AST to catch certain bugs like poorly or not + // implemented subtrees. + Imported->dump(ToNothing); + + return Imported; + } + + template + testing::AssertionResult + testImport(const std::string &FromCode, const ArgVector &FromArgs, + const std::string &ToCode, const ArgVector &ToArgs, + MatchVerifier &Verifier, + const BindableMatcher &SearchMatcher, + const BindableMatcher &VerificationMatcher) { + const char *const InputFileName = "input.cc"; + const char *const OutputFileName = "output.cc"; + + std::unique_ptr FromAST = tooling::buildASTFromCodeWithArgs( + FromCode, FromArgs, InputFileName), + ToAST = tooling::buildASTFromCodeWithArgs( + ToCode, ToArgs, OutputFileName); + + ASTContext &FromCtx = FromAST->getASTContext(), + &ToCtx = ToAST->getASTContext(); + + ASTImporter Importer(ToCtx, ToAST->getFileManager(), FromCtx, + FromAST->getFileManager(), false); + + auto FoundNodes = match(SearchMatcher, FromCtx); + if (FoundNodes.size() != 1) + return testing::AssertionFailure() + << "Multiple potential nodes were found!"; + + auto ToImport = selectFirst(DeclToImportID, FoundNodes); + if (!ToImport) + return testing::AssertionFailure() << "Node type mismatch!"; + + // Sanity check: the node being imported should match in the same way as + // the result node. + BindableMatcher WrapperMatcher(VerificationMatcher); + EXPECT_TRUE(Verifier.match(ToImport, WrapperMatcher)); + + auto Imported = importNode(FromAST.get(), ToAST.get(), Importer, ToImport); + if (!Imported) + return testing::AssertionFailure() << "Import failed, nullptr returned!"; + + return Verifier.match(Imported, WrapperMatcher); + } + + template + testing::AssertionResult + testImport(const std::string &FromCode, const ArgVector &FromArgs, + const std::string &ToCode, const ArgVector &ToArgs, + MatchVerifier &Verifier, + const BindableMatcher &VerificationMatcher) { + return testImport( + FromCode, FromArgs, ToCode, ToArgs, Verifier, + translationUnitDecl( + has(namedDecl(hasName(DeclToImportID)).bind(DeclToImportID))), + VerificationMatcher); + } + +public: + + /// Test how AST node named "declToImport" located in the translation unit + /// of "FromCode" virtual file is imported to "ToCode" virtual file. + /// The verification is done by running AMatcher over the imported node. + template + void testImport(const std::string &FromCode, Language FromLang, + const std::string &ToCode, Language ToLang, + MatchVerifier &Verifier, + const MatcherType &AMatcher) { + ArgVector FromArgs = getArgVectorForLanguage(FromLang), + ToArgs = getArgVectorForLanguage(ToLang); + EXPECT_TRUE( + testImport(FromCode, FromArgs, ToCode, ToArgs, Verifier, AMatcher)); + } + + struct ImportAction { + StringRef FromFilename; + StringRef ToFilename; + // FIXME: Generalize this to support other node kinds. + BindableMatcher ImportPredicate; + + ImportAction(StringRef FromFilename, StringRef ToFilename, + DeclarationMatcher ImportPredicate) + : FromFilename(FromFilename), ToFilename(ToFilename), + ImportPredicate(ImportPredicate) {} + + ImportAction(StringRef FromFilename, StringRef ToFilename, + const std::string &DeclName) + : FromFilename(FromFilename), ToFilename(ToFilename), + ImportPredicate(namedDecl(hasName(DeclName))) {} + }; + + using SingleASTUnit = std::unique_ptr; + using AllASTUnits = StringMap; + + struct CodeEntry { + std::string CodeSample; + Language Lang; + }; + + using CodeFiles = StringMap; + + /// Builds an ASTUnit for one potential compile options set. + SingleASTUnit createASTUnit(StringRef FileName, const CodeEntry &CE) const { + ArgVector Args = getArgVectorForLanguage(CE.Lang); + auto AST = tooling::buildASTFromCodeWithArgs(CE.CodeSample, Args, FileName); + EXPECT_TRUE(AST.get()); + return AST; + } + + /// Test an arbitrary sequence of imports for a set of given in-memory files. + /// The verification is done by running VerificationMatcher against a + /// specified + /// AST node inside of one of given files. + /// \param CodeSamples Map whose key is the file name and the value is the + /// file + /// content. + /// \param ImportActions Sequence of imports. Each import in sequence + /// specifies "from file" and "to file" and a matcher that is used for + /// searching a declaration for import in "from file". + /// \param FileForFinalCheck Name of virtual file for which the final check is + /// applied. + /// \param FinalSelectPredicate Matcher that specifies the AST node in the + /// FileForFinalCheck for which the verification will be done. + /// \param VerificationMatcher Matcher that will be used for verification + /// after + /// all imports in sequence are done. + void testImportSequence(const CodeFiles &CodeSamples, + const std::vector &ImportActions, + StringRef FileForFinalCheck, + BindableMatcher FinalSelectPredicate, + BindableMatcher VerificationMatcher) { + AllASTUnits AllASTs; + using ImporterKey = std::pair; + llvm::DenseMap> Importers; + + auto GenASTsIfNeeded = [this, &AllASTs, &CodeSamples](StringRef Filename) { + if (!AllASTs.count(Filename)) { + auto Found = CodeSamples.find(Filename); + assert(Found != CodeSamples.end() && "Wrong file for import!"); + AllASTs[Filename] = createASTUnit(Filename, Found->getValue()); + } + }; + + for (const ImportAction &Action : ImportActions) { + StringRef FromFile = Action.FromFilename, ToFile = Action.ToFilename; + GenASTsIfNeeded(FromFile); + GenASTsIfNeeded(ToFile); + + ASTUnit *From = AllASTs[FromFile].get(); + ASTUnit *To = AllASTs[ToFile].get(); + + // Create a new importer if needed. + std::unique_ptr &ImporterRef = Importers[{From, To}]; + if (!ImporterRef) + ImporterRef.reset(new ASTImporter( + To->getASTContext(), To->getFileManager(), From->getASTContext(), + From->getFileManager(), false)); + + // Find the declaration and import it. + auto FoundDecl = match(Action.ImportPredicate.bind(DeclToImportID), + From->getASTContext()); + EXPECT_TRUE(FoundDecl.size() == 1); + const Decl *ToImport = selectFirst(DeclToImportID, FoundDecl); + auto Imported = importNode(From, To, *ImporterRef, ToImport); + EXPECT_TRUE(Imported); + } + + // Find the declaration and import it. + auto FoundDecl = match(FinalSelectPredicate.bind(DeclToVerifyID), + AllASTs[FileForFinalCheck]->getASTContext()); + EXPECT_TRUE(FoundDecl.size() == 1); + const Decl *ToVerify = selectFirst(DeclToVerifyID, FoundDecl); + MatchVerifier Verifier; + EXPECT_TRUE( + Verifier.match(ToVerify, BindableMatcher(VerificationMatcher))); + } +}; // This class provides generic methods to write tests which can check internal // attributes of AST nodes like getPreviousDecl(), isVirtual(), etc. Also, // this fixture makes it possible to import from several "From" contexts. -class ASTImporterTestBase : public ::testing::TestWithParam { +class ASTImporterTestBase : public ParameterizedTestsFixture { const char *const InputFileName = "input.cc"; const char *const OutputFileName = "output.cc"; @@ -188,17 +313,6 @@ // We may have several From context but only one To context. std::unique_ptr ToAST; - // Returns the argument vector used for a specific language, this set - // can be tweaked by the test parameters. - ArgVector getArgVectorForLanguage(Language Lang) { - ArgVector Args = getBasicRunOptionsForLanguage(Lang); - ArgVector ExtraArgs = GetParam(); - for (const auto& Arg : ExtraArgs) { - Args.push_back(Arg); - } - return Args; - } - // Creates an AST both for the From and To source code and imports the Decl // of the identifier into the To context. // Must not be called more than once within the same test. @@ -308,124 +422,11 @@ } }; +struct ImportExpr : TestImportBase {}; +struct ImportType : TestImportBase {}; +struct ImportDecl : TestImportBase {}; -struct ImportAction { - StringRef FromFilename; - StringRef ToFilename; - // FIXME: Generalize this to support other node kinds. - BindableMatcher ImportPredicate; - - ImportAction(StringRef FromFilename, StringRef ToFilename, - DeclarationMatcher ImportPredicate) - : FromFilename(FromFilename), ToFilename(ToFilename), - ImportPredicate(ImportPredicate) {} - - ImportAction(StringRef FromFilename, StringRef ToFilename, - const std::string &DeclName) - : FromFilename(FromFilename), ToFilename(ToFilename), - ImportPredicate(namedDecl(hasName(DeclName))) {} -}; - -using SingleASTUnitForAllOpts = std::vector>; -using AllASTUnitsForAllOpts = StringMap; - -struct CodeEntry { - std::string CodeSample; - Language Lang; - - /// Builds N copies of ASTUnits for each potential compile options set - /// for further import actions. N is equal to size of this option set. - SingleASTUnitForAllOpts createASTUnits(StringRef FileName) const { - auto RunOpts = getRunOptionsForLanguage(Lang); - size_t NumOpts = RunOpts.size(); - SingleASTUnitForAllOpts ResultASTs(NumOpts); - for (size_t CompileOpt = 0; CompileOpt < NumOpts; ++CompileOpt) { - auto AST = tooling::buildASTFromCodeWithArgs( - CodeSample, RunOpts[CompileOpt], FileName); - EXPECT_TRUE(AST.get()); - ResultASTs[CompileOpt] = std::move(AST); - } - return ResultASTs; - } -}; - -using CodeFiles = StringMap; - -/// Test an arbitrary sequence of imports for a set of given in-memory files. -/// The verification is done by running VerificationMatcher against a specified -/// AST node inside of one of given files. -/// \param CodeSamples Map whose key is the file name and the value is the file -/// content. -/// \param ImportActions Sequence of imports. Each import in sequence -/// specifies "from file" and "to file" and a matcher that is used for -/// searching a declaration for import in "from file". -/// \param FileForFinalCheck Name of virtual file for which the final check is -/// applied. -/// \param FinalSelectPredicate Matcher that specifies the AST node in the -/// FileForFinalCheck for which the verification will be done. -/// \param VerificationMatcher Matcher that will be used for verification after -/// all imports in sequence are done. -void testImportSequence(const CodeFiles &CodeSamples, - const std::vector &ImportActions, - StringRef FileForFinalCheck, - BindableMatcher FinalSelectPredicate, - BindableMatcher VerificationMatcher) { - AllASTUnitsForAllOpts AllASTUnits; - using ImporterKey = std::pair; - llvm::DenseMap> Importers; - - auto GenASTsIfNeeded = [&AllASTUnits, &CodeSamples](StringRef Filename) { - if (!AllASTUnits.count(Filename)) { - auto Found = CodeSamples.find(Filename); - assert(Found != CodeSamples.end() && "Wrong file for import!"); - AllASTUnits[Filename] = Found->getValue().createASTUnits(Filename); - } - }; - - size_t NumCompileOpts = 0; - for (const ImportAction &Action : ImportActions) { - StringRef FromFile = Action.FromFilename, ToFile = Action.ToFilename; - GenASTsIfNeeded(FromFile); - GenASTsIfNeeded(ToFile); - NumCompileOpts = AllASTUnits[FromFile].size(); - - for (size_t CompileOpt = 0; CompileOpt < NumCompileOpts; ++CompileOpt) { - ASTUnit *From = AllASTUnits[FromFile][CompileOpt].get(); - ASTUnit *To = AllASTUnits[ToFile][CompileOpt].get(); - - // Create a new importer if needed. - std::unique_ptr &ImporterRef = Importers[{From, To}]; - if (!ImporterRef) - ImporterRef.reset(new ASTImporter( - To->getASTContext(), To->getFileManager(), From->getASTContext(), - From->getFileManager(), false)); - - // Find the declaration and import it. - auto FoundDecl = match(Action.ImportPredicate.bind(DeclToImportID), - From->getASTContext()); - EXPECT_TRUE(FoundDecl.size() == 1); - const Decl *ToImport = selectFirst(DeclToImportID, FoundDecl); - auto Imported = importNode(From, To, *ImporterRef, ToImport); - EXPECT_TRUE(Imported); - } - } - - // NOTE: We don't do cross-option import check here due to fast growth of - // potential option sets. - for (size_t CompileOpt = 0; CompileOpt < NumCompileOpts; ++CompileOpt) { - // Find the declaration and import it. - auto FoundDecl = - match(FinalSelectPredicate.bind(DeclToVerifyID), - AllASTUnits[FileForFinalCheck][CompileOpt]->getASTContext()); - EXPECT_TRUE(FoundDecl.size() == 1); - const Decl *ToVerify = selectFirst(DeclToVerifyID, FoundDecl); - MatchVerifier Verifier; - EXPECT_TRUE(Verifier.match(ToVerify, - BindableMatcher(VerificationMatcher))); - } -} - -TEST(ImportExpr, ImportStringLiteral) { +TEST_P(ImportExpr, ImportStringLiteral) { MatchVerifier Verifier; testImport("void declToImport() { \"foo\"; }", Lang_CXX, "", Lang_CXX, Verifier, @@ -456,7 +457,7 @@ asString("const char [7]")))))))); } -TEST(ImportExpr, ImportGNUNullExpr) { +TEST_P(ImportExpr, ImportGNUNullExpr) { MatchVerifier Verifier; testImport("void declToImport() { __null; }", Lang_CXX, "", Lang_CXX, Verifier, @@ -468,7 +469,7 @@ hasType(isInteger()))))))); } -TEST(ImportExpr, ImportCXXNullPtrLiteralExpr) { +TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) { MatchVerifier Verifier; testImport("void declToImport() { nullptr; }", Lang_CXX11, "", Lang_CXX11, Verifier, @@ -480,7 +481,7 @@ } -TEST(ImportExpr, ImportFloatinglLiteralExpr) { +TEST_P(ImportExpr, ImportFloatinglLiteralExpr) { MatchVerifier Verifier; testImport("void declToImport() { 1.0; }", Lang_C, "", Lang_C, Verifier, @@ -502,7 +503,7 @@ hasType(asString("float")))))))); } -TEST(ImportExpr, ImportCompoundLiteralExpr) { +TEST_P(ImportExpr, ImportCompoundLiteralExpr) { MatchVerifier Verifier; testImport("void declToImport() {" " struct s { int x; long y; unsigned z; }; " @@ -526,7 +527,7 @@ )))))))); } -TEST(ImportExpr, ImportCXXThisExpr) { +TEST_P(ImportExpr, ImportCXXThisExpr) { MatchVerifier Verifier; testImport("class declToImport { void f() { this; } };", Lang_CXX, "", Lang_CXX, Verifier, @@ -540,7 +541,7 @@ asString("class declToImport *"))))))))); } -TEST(ImportExpr, ImportAtomicExpr) { +TEST_P(ImportExpr, ImportAtomicExpr) { MatchVerifier Verifier; testImport("void declToImport() { int *ptr; __atomic_load_n(ptr, 1); }", Lang_C, "", Lang_C, Verifier, @@ -551,7 +552,7 @@ has(integerLiteral(equals(1), hasType(asString("int")))))))))); } -TEST(ImportExpr, ImportLabelDeclAndAddrLabelExpr) { +TEST_P(ImportExpr, ImportLabelDeclAndAddrLabelExpr) { MatchVerifier Verifier; testImport( "void declToImport() { loop: goto loop; &&loop; }", Lang_C, "", Lang_C, @@ -567,7 +568,7 @@ return Template && InnerMatcher.matches(*Template, Finder, Builder); } -TEST(ImportExpr, ImportParenListExpr) { +TEST_P(ImportExpr, ImportParenListExpr) { MatchVerifier Verifier; testImport( "template class dummy { void f() { dummy X(*this); } };" @@ -584,7 +585,7 @@ hasUnaryOperand(cxxThisExpr()))))))))))))))))))))))); } -TEST(ImportExpr, ImportSwitch) { +TEST_P(ImportExpr, ImportSwitch) { MatchVerifier Verifier; testImport("void declToImport() { int b; switch (b) { case 1: break; } }", Lang_C, "", Lang_C, Verifier, @@ -592,7 +593,7 @@ has(switchStmt(has(compoundStmt(has(caseStmt()))))))))); } -TEST(ImportExpr, ImportStmtExpr) { +TEST_P(ImportExpr, ImportStmtExpr) { MatchVerifier Verifier; // NOTE: has() ignores implicit casts, using hasDescendant() to match it testImport( @@ -622,7 +623,7 @@ ))))))))))); } -TEST(ImportExpr, ImportConditionalOperator) { +TEST_P(ImportExpr, ImportConditionalOperator) { MatchVerifier Verifier; testImport( "void declToImport() { true ? 1 : -5; }", @@ -639,7 +640,7 @@ ))))))); } -TEST(ImportExpr, ImportBinaryConditionalOperator) { +TEST_P(ImportExpr, ImportBinaryConditionalOperator) { MatchVerifier Verifier; testImport( "void declToImport() { 1 ?: -5; }", Lang_CXX, "", Lang_CXX, Verifier, @@ -663,7 +664,7 @@ )))))); } -TEST(ImportExpr, ImportDesignatedInitExpr) { +TEST_P(ImportExpr, ImportDesignatedInitExpr) { MatchVerifier Verifier; testImport("void declToImport() {" " struct point { double x; double y; };" @@ -706,7 +707,7 @@ } -TEST(ImportExpr, ImportPredefinedExpr) { +TEST_P(ImportExpr, ImportPredefinedExpr) { MatchVerifier Verifier; // __func__ expands as StringLiteral("declToImport") testImport("void declToImport() { __func__; }", @@ -724,7 +725,7 @@ asString("const char [13]")))))))))); } -TEST(ImportExpr, ImportInitListExpr) { +TEST_P(ImportExpr, ImportInitListExpr) { MatchVerifier Verifier; testImport( "void declToImport() {" @@ -761,7 +762,7 @@ const internal::VariadicDynCastAllOfMatcher vaArgExpr; -TEST(ImportExpr, ImportVAArgExpr) { +TEST_P(ImportExpr, ImportVAArgExpr) { MatchVerifier Verifier; testImport("void declToImport(__builtin_va_list list, ...) {" " (void)__builtin_va_arg(list, int); }", @@ -775,7 +776,7 @@ vaArgExpr()))))))); } -TEST(ImportExpr, CXXTemporaryObjectExpr) { +TEST_P(ImportExpr, CXXTemporaryObjectExpr) { MatchVerifier Verifier; testImport("struct C {};" "void declToImport() { C c = C(); }", @@ -786,7 +787,7 @@ has(cxxTemporaryObjectExpr()))))))))))))))))); } -TEST(ImportType, ImportAtomicType) { +TEST_P(ImportType, ImportAtomicType) { MatchVerifier Verifier; testImport("void declToImport() { typedef _Atomic(int) a_int; }", Lang_CXX11, "", Lang_CXX11, Verifier, @@ -800,7 +801,7 @@ has(atomicType()))))))))); } -TEST(ImportDecl, ImportFunctionTemplateDecl) { +TEST_P(ImportDecl, ImportFunctionTemplateDecl) { MatchVerifier Verifier; testImport("template void declToImport() { };", Lang_CXX, "", Lang_CXX, Verifier, functionTemplateDecl()); @@ -809,7 +810,7 @@ const internal::VariadicDynCastAllOfMatcher cxxDependentScopeMemberExpr; -TEST(ImportExpr, ImportCXXDependentScopeMemberExpr) { +TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) { MatchVerifier Verifier; testImport("template struct C { T t; };" "template void declToImport() {" @@ -831,7 +832,7 @@ has(compoundStmt(has(cxxDependentScopeMemberExpr()))))))); } -TEST(ImportType, ImportTypeAliasTemplate) { +TEST_P(ImportType, ImportTypeAliasTemplate) { MatchVerifier Verifier; testImport( "template " @@ -848,7 +849,7 @@ const internal::VariadicDynCastAllOfMatcher varTemplateSpecializationDecl; -TEST(ImportDecl, ImportVarTemplate) { +TEST_P(ImportDecl, ImportVarTemplate) { MatchVerifier Verifier; testImport( "template " @@ -861,7 +862,7 @@ hasName("pi"), unless(varTemplateSpecializationDecl())))))))); } -TEST(ImportType, ImportPackExpansion) { +TEST_P(ImportType, ImportPackExpansion) { MatchVerifier Verifier; testImport("template " "struct dummy {" @@ -885,7 +886,7 @@ DependentTemplateSpecializationType> dependentTemplateSpecializationType; -TEST(ImportType, ImportDependentTemplateSpecialization) { +TEST_P(ImportType, ImportDependentTemplateSpecialization) { MatchVerifier Verifier; testImport("template" "struct A;" @@ -901,7 +902,7 @@ const internal::VariadicDynCastAllOfMatcher sizeOfPackExpr; -TEST(ImportExpr, ImportSizeOfPackExpr) { +TEST_P(ImportExpr, ImportSizeOfPackExpr) { MatchVerifier Verifier; testImport("template " "void declToImport() {" @@ -934,7 +935,7 @@ // will generate TypeTraitExpr <...> 'int' const internal::VariadicDynCastAllOfMatcher typeTraitExpr; -TEST(ImportExpr, ImportTypeTraitExpr) { +TEST_P(ImportExpr, ImportTypeTraitExpr) { MatchVerifier Verifier; testImport("void declToImport() { " " __builtin_types_compatible_p(int, int);" @@ -949,7 +950,7 @@ const internal::VariadicDynCastAllOfMatcher cxxTypeidExpr; -TEST(ImportExpr, ImportCXXTypeidExpr) { +TEST_P(ImportExpr, ImportCXXTypeidExpr) { MatchVerifier Verifier; testImport( "namespace std { class type_info {}; }" @@ -965,7 +966,7 @@ hasName("b"), hasInitializer(hasDescendant(cxxTypeidExpr())))))); } -TEST(ImportExpr, ImportTypeTraitExprValDep) { +TEST_P(ImportExpr, ImportTypeTraitExprValDep) { MatchVerifier Verifier; testImport("template struct declToImport {" " void m() { __is_pod(T); }" @@ -988,7 +989,7 @@ const internal::VariadicDynCastAllOfMatcher cxxPseudoDestructorExpr; -TEST(ImportExpr, ImportCXXPseudoDestructorExpr) { +TEST_P(ImportExpr, ImportCXXPseudoDestructorExpr) { MatchVerifier Verifier; testImport("typedef int T;" "void declToImport(int *p) {" @@ -1000,7 +1001,7 @@ callExpr(has(cxxPseudoDestructorExpr()))))))); } -TEST(ImportDecl, ImportUsingDecl) { +TEST_P(ImportDecl, ImportUsingDecl) { MatchVerifier Verifier; testImport("namespace foo { int bar; }" "void declToImport() { using foo::bar; }", @@ -1027,7 +1028,7 @@ const internal::VariadicDynCastAllOfMatcher usingShadowDecl; -TEST(ImportDecl, ImportUsingShadowDecl) { +TEST_P(ImportDecl, ImportUsingShadowDecl) { MatchVerifier Verifier; testImport("namespace foo { int bar; }" "namespace declToImport { using foo::bar; }", @@ -1035,7 +1036,7 @@ namespaceDecl(has(usingShadowDecl()))); } -TEST(ImportExpr, ImportUnresolvedLookupExpr) { +TEST_P(ImportExpr, ImportUnresolvedLookupExpr) { MatchVerifier Verifier; testImport("template int foo();" "template void declToImport() {" @@ -1048,7 +1049,7 @@ has(compoundStmt(has(unresolvedLookupExpr()))))))); } -TEST(ImportExpr, ImportCXXUnresolvedConstructExpr) { +TEST_P(ImportExpr, ImportCXXUnresolvedConstructExpr) { MatchVerifier Verifier; testImport("template struct C { T t; };" "template void declToImport() {" @@ -1073,7 +1074,7 @@ /// Check that function "declToImport()" (which is the templated function /// for corresponding FunctionTemplateDecl) is not added into DeclContext. /// Same for class template declarations. -TEST(ImportDecl, ImportTemplatedDeclForTemplate) { +TEST_P(ImportDecl, ImportTemplatedDeclForTemplate) { MatchVerifier Verifier; testImport("template void declToImport() { T a = 1; }" "void instantiate() { declToImport(); }", @@ -1087,7 +1088,7 @@ unless(has(cxxRecordDecl(hasName("declToImport")))))))); } -TEST(ImportExpr, CXXOperatorCallExpr) { +TEST_P(ImportExpr, CXXOperatorCallExpr) { MatchVerifier Verifier; testImport("class declToImport {" " void f() { *this = declToImport(); }" @@ -1097,7 +1098,7 @@ has(exprWithCleanups(has(cxxOperatorCallExpr()))))))))); } -TEST(ImportExpr, DependentSizedArrayType) { +TEST_P(ImportExpr, DependentSizedArrayType) { MatchVerifier Verifier; testImport("template class declToImport {" " T data[Size];" @@ -1607,10 +1608,6 @@ .match(ToTU, classTemplateSpecializationDecl())); } -INSTANTIATE_TEST_CASE_P( - ParameterizedTests, ASTImporterTestBase, - ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),); - struct ImportFunctions : ASTImporterTestBase {}; TEST_P(ImportFunctions, @@ -1835,10 +1832,6 @@ EXPECT_TRUE(To->isVirtual()); } -INSTANTIATE_TEST_CASE_P( - ParameterizedTests, ImportFunctions, - ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),); - AST_MATCHER_P(TagDecl, hasTypedefForAnonDecl, Matcher, InnerMatcher) { if (auto *Typedef = Node.getTypedefNameForAnonDecl()) @@ -1846,7 +1839,7 @@ return false; } -TEST(ImportDecl, ImportEnumSequential) { +TEST_P(ImportDecl, ImportEnumSequential) { CodeFiles Samples{{"main.c", {"void foo();" "void moo();" @@ -1888,7 +1881,7 @@ const internal::VariadicDynCastAllOfMatcher dependentScopeDeclRefExpr; -TEST(ImportExpr, DependentScopeDeclRefExpr) { +TEST_P(ImportExpr, DependentScopeDeclRefExpr) { MatchVerifier Verifier; testImport("template struct S { static T foo; };" "template void declToImport() {" @@ -1914,7 +1907,7 @@ const internal::VariadicDynCastAllOfMatcher dependentNameType; -TEST(ImportExpr, DependentNameType) { +TEST_P(ImportExpr, DependentNameType) { MatchVerifier Verifier; testImport("template struct declToImport {" " typedef typename T::type dependent_name;" @@ -1927,7 +1920,7 @@ const internal::VariadicDynCastAllOfMatcher unresolvedMemberExpr; -TEST(ImportExpr, UnresolvedMemberExpr) { +TEST_P(ImportExpr, UnresolvedMemberExpr) { MatchVerifier Verifier; testImport("struct S { template void mem(); };" "template void declToImport() {" @@ -1969,9 +1962,29 @@ EXPECT_FALSE(NS->containsDecl(Spec)); } -INSTANTIATE_TEST_CASE_P( - ParameterizedTests, DeclContextTest, - ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),); +INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest, + ::testing::Values(ArgVector()), ); + +auto DefaultTestValuesForRunOptions = ::testing::Values( + ArgVector(), + ArgVector{"-fdelayed-template-parsing"}, + ArgVector{"-fms-compatibility"}, + ArgVector{"-fdelayed-template-parsing", "-fms-compatibility"}); + +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportExpr, + DefaultTestValuesForRunOptions, ); + +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportType, + DefaultTestValuesForRunOptions, ); + +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportDecl, + DefaultTestValuesForRunOptions, ); + +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterTestBase, + DefaultTestValuesForRunOptions, ); + +INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions, + DefaultTestValuesForRunOptions, ); } // end namespace ast_matchers } // end namespace clang Index: unittests/AST/Language.h =================================================================== --- unittests/AST/Language.h +++ unittests/AST/Language.h @@ -22,7 +22,6 @@ namespace ast_matchers { typedef std::vector ArgVector; -typedef std::vector RunOptions; enum Language { Lang_C, @@ -34,12 +33,7 @@ Lang_OBJCXX }; -inline bool isCXX(Language Lang) { - return Lang == Lang_CXX || Lang == Lang_CXX11 || Lang == Lang_CXX14; -} - ArgVector getBasicRunOptionsForLanguage(Language Lang); -RunOptions getRunOptionsForLanguage(Language Lang); } // end namespace ast_matchers } // end namespace clang Index: unittests/AST/Language.cpp =================================================================== --- unittests/AST/Language.cpp +++ unittests/AST/Language.cpp @@ -42,19 +42,5 @@ return BasicArgs; } -RunOptions getRunOptionsForLanguage(Language Lang) { - ArgVector BasicArgs = getBasicRunOptionsForLanguage(Lang); - - // For C++, test with "-fdelayed-template-parsing" enabled to handle MSVC - // default behaviour. - if (isCXX(Lang)) { - ArgVector ArgsForDelayedTemplateParse = BasicArgs; - ArgsForDelayedTemplateParse.emplace_back("-fdelayed-template-parsing"); - return {BasicArgs, ArgsForDelayedTemplateParse}; - } - - return {BasicArgs}; -} - } // end namespace ast_matchers } // end namespace clang