1cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===// 2cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 3cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// The LLVM Compiler Infrastructure 4cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 5cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// This file is distributed under the University of Illinois Open Source 6cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// License. See LICENSE.TXT for details. 7cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek// 8cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek//===----------------------------------------------------------------------===// 9cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 10cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/AST/ASTConsumer.h" 11cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/AST/DeclCXX.h" 12cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/AST/DeclGroup.h" 138051db16aa9513333062ab3145f038429f66780fPeter Collingbourne#include "clang/Frontend/ASTUnit.h" 14d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith#include "clang/Frontend/CompilerInstance.h" 15cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/Frontend/FrontendAction.h" 16cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/Frontend/FrontendActions.h" 17cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/Tooling/CompilationDatabase.h" 18cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek#include "clang/Tooling/Tooling.h" 198051db16aa9513333062ab3145f038429f66780fPeter Collingbourne#include "llvm/ADT/STLExtras.h" 20ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include "llvm/Config/llvm-config.h" 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "gtest/gtest.h" 225f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko#include <string> 23cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 24cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace clang { 25cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace tooling { 26cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 27cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace { 28cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek/// Takes an ast consumer and returns it from CreateASTConsumer. This only 29cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek/// works with single translation unit compilations. 30cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekclass TestAction : public clang::ASTFrontendAction { 31cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek public: 32cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek /// Takes ownership of TestConsumer. 33cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek explicit TestAction(clang::ASTConsumer *TestConsumer) 34cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek : TestConsumer(TestConsumer) {} 35cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 36cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek protected: 37cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek virtual clang::ASTConsumer* CreateASTConsumer( 38cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek clang::CompilerInstance& compiler, StringRef dummy) { 39cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek /// TestConsumer will be deleted by the framework calling us. 40cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return TestConsumer; 41cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 42cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 43cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek private: 44cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek clang::ASTConsumer * const TestConsumer; 45cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}; 46cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 47cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekclass FindTopLevelDeclConsumer : public clang::ASTConsumer { 48cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek public: 49cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl) 50cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek : FoundTopLevelDecl(FoundTopLevelDecl) {} 51cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek virtual bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) { 52cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek *FoundTopLevelDecl = true; 53cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return true; 54cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 55cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek private: 56cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool * const FoundTopLevelDecl; 57cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}; 58cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace 59cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 60c5613b26a24a33d7450e3d0bf315c6ccc920ce7bMeador IngeTEST(runToolOnCode, FindsNoTopLevelDeclOnEmptyCode) { 61cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool FoundTopLevelDecl = false; 62cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek EXPECT_TRUE(runToolOnCode( 63cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), "")); 64c5613b26a24a33d7450e3d0bf315c6ccc920ce7bMeador Inge EXPECT_FALSE(FoundTopLevelDecl); 65cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 66cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 67cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimeknamespace { 68cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekclass FindClassDeclXConsumer : public clang::ASTConsumer { 69cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek public: 70cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek FindClassDeclXConsumer(bool *FoundClassDeclX) 71cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek : FoundClassDeclX(FoundClassDeclX) {} 72cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek virtual bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) { 73cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>( 74cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek *GroupRef.begin())) { 75cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek if (Record->getName() == "X") { 76cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek *FoundClassDeclX = true; 77cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 78cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 79cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek return true; 80cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek } 81cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek private: 82cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool *FoundClassDeclX; 83cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}; 848051db16aa9513333062ab3145f038429f66780fPeter Collingbournebool FindClassDeclX(ASTUnit *AST) { 858051db16aa9513333062ab3145f038429f66780fPeter Collingbourne for (std::vector<Decl *>::iterator i = AST->top_level_begin(), 868051db16aa9513333062ab3145f038429f66780fPeter Collingbourne e = AST->top_level_end(); 878051db16aa9513333062ab3145f038429f66780fPeter Collingbourne i != e; ++i) { 888051db16aa9513333062ab3145f038429f66780fPeter Collingbourne if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(*i)) { 898051db16aa9513333062ab3145f038429f66780fPeter Collingbourne if (Record->getName() == "X") { 908051db16aa9513333062ab3145f038429f66780fPeter Collingbourne return true; 918051db16aa9513333062ab3145f038429f66780fPeter Collingbourne } 928051db16aa9513333062ab3145f038429f66780fPeter Collingbourne } 938051db16aa9513333062ab3145f038429f66780fPeter Collingbourne } 948051db16aa9513333062ab3145f038429f66780fPeter Collingbourne return false; 958051db16aa9513333062ab3145f038429f66780fPeter Collingbourne} 96cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace 97cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 98cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(runToolOnCode, FindsClassDecl) { 99cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek bool FoundClassDeclX = false; 100cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek EXPECT_TRUE(runToolOnCode(new TestAction( 101cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek new FindClassDeclXConsumer(&FoundClassDeclX)), "class X;")); 102cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek EXPECT_TRUE(FoundClassDeclX); 103cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 104cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek FoundClassDeclX = false; 105cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek EXPECT_TRUE(runToolOnCode(new TestAction( 106cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek new FindClassDeclXConsumer(&FoundClassDeclX)), "class Y;")); 107cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek EXPECT_FALSE(FoundClassDeclX); 108cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 109cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 1108051db16aa9513333062ab3145f038429f66780fPeter CollingbourneTEST(buildASTFromCode, FindsClassDecl) { 1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::unique_ptr<ASTUnit> AST = buildASTFromCode("class X;"); 1128051db16aa9513333062ab3145f038429f66780fPeter Collingbourne ASSERT_TRUE(AST.get()); 1138051db16aa9513333062ab3145f038429f66780fPeter Collingbourne EXPECT_TRUE(FindClassDeclX(AST.get())); 1148051db16aa9513333062ab3145f038429f66780fPeter Collingbourne 1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AST = buildASTFromCode("class Y;"); 1168051db16aa9513333062ab3145f038429f66780fPeter Collingbourne ASSERT_TRUE(AST.get()); 1178051db16aa9513333062ab3145f038429f66780fPeter Collingbourne EXPECT_FALSE(FindClassDeclX(AST.get())); 1188051db16aa9513333062ab3145f038429f66780fPeter Collingbourne} 1198051db16aa9513333062ab3145f038429f66780fPeter Collingbourne 120cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) { 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<FrontendActionFactory> Factory( 122cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko newFrontendActionFactory<SyntaxOnlyAction>()); 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<FrontendAction> Action(Factory->create()); 124ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_TRUE(Action.get() != nullptr); 125cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 126cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 127cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimekstruct IndependentFrontendActionCreator { 128e6df0ce08fcdf9f906556d98cca96d38ab440bbaManuel Klimek ASTConsumer *newASTConsumer() { 129ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return new FindTopLevelDeclConsumer(nullptr); 130e6df0ce08fcdf9f906556d98cca96d38ab440bbaManuel Klimek } 131cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek}; 132cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 133cb971c6726d16e12ecd2a340941d7f5c06698332Manuel KlimekTEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) { 134cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek IndependentFrontendActionCreator Creator; 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<FrontendActionFactory> Factory( 136cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko newFrontendActionFactory(&Creator)); 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<FrontendAction> Action(Factory->create()); 138ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_TRUE(Action.get() != nullptr); 139cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} 140cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek 1415f60f606093019174a11fcfd3ae36634dc44e8c9Alexander KornienkoTEST(ToolInvocation, TestMapVirtualFile) { 1428051db16aa9513333062ab3145f038429f66780fPeter Collingbourne IntrusiveRefCntPtr<clang::FileManager> Files( 1438051db16aa9513333062ab3145f038429f66780fPeter Collingbourne new clang::FileManager(clang::FileSystemOptions())); 1445f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko std::vector<std::string> Args; 1455f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko Args.push_back("tool-executable"); 1465f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko Args.push_back("-Idef"); 1475f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko Args.push_back("-fsyntax-only"); 1485f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko Args.push_back("test.cpp"); 1498051db16aa9513333062ab3145f038429f66780fPeter Collingbourne clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, 150ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Files.get()); 1515f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko Invocation.mapVirtualFile("test.cpp", "#include <abc>\n"); 1525f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko Invocation.mapVirtualFile("def/abc", "\n"); 1535f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko EXPECT_TRUE(Invocation.run()); 1545f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko} 1555f60f606093019174a11fcfd3ae36634dc44e8c9Alexander Kornienko 156ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel KlimekTEST(ToolInvocation, TestVirtualModulesCompilation) { 157ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek // FIXME: Currently, this only tests that we don't exit with an error if a 158ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek // mapped module.map is found on the include path. In the future, expand this 159ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek // test to run a full modules enabled compilation, so we make sure we can 160ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek // rerun modules compilations with a virtual file system. 1618051db16aa9513333062ab3145f038429f66780fPeter Collingbourne IntrusiveRefCntPtr<clang::FileManager> Files( 1628051db16aa9513333062ab3145f038429f66780fPeter Collingbourne new clang::FileManager(clang::FileSystemOptions())); 163ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek std::vector<std::string> Args; 164ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Args.push_back("tool-executable"); 165ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Args.push_back("-Idef"); 166ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Args.push_back("-fsyntax-only"); 167ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Args.push_back("test.cpp"); 1688051db16aa9513333062ab3145f038429f66780fPeter Collingbourne clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, 169ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Files.get()); 170ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Invocation.mapVirtualFile("test.cpp", "#include <abc>\n"); 171ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Invocation.mapVirtualFile("def/abc", "\n"); 172ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek // Add a module.map file in the include directory of our header, so we trigger 173ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek // the module.map header search logic. 174ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek Invocation.mapVirtualFile("def/module.map", "\n"); 175ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek EXPECT_TRUE(Invocation.run()); 176ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek} 177ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek 1783c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vanestruct VerifyEndCallback : public SourceFileCallbacks { 1793c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane VerifyEndCallback() : BeginCalled(0), EndCalled(0), Matched(false) {} 1805ec9580f68661ffccff07177613b692d0acb4797Edwin Vane virtual bool handleBeginSource(CompilerInstance &CI, 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Filename) override { 1823c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane ++BeginCalled; 1833c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane return true; 1843c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane } 1855ec9580f68661ffccff07177613b692d0acb4797Edwin Vane virtual void handleEndSource() { 1863c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane ++EndCalled; 1879fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek } 1889fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek ASTConsumer *newASTConsumer() { 1899fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek return new FindTopLevelDeclConsumer(&Matched); 1909fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek } 1913c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane unsigned BeginCalled; 1923c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane unsigned EndCalled; 1939fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek bool Matched; 1949fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek}; 1959fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if !defined(LLVM_ON_WIN32) 1973c16e699b2a6926017b5f7a1516dc1be67468713Edwin VaneTEST(newFrontendActionFactory, InjectsSourceFileCallbacks) { 1989fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek VerifyEndCallback EndCallback; 1999fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek 2009fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek FixedCompilationDatabase Compilations("/", std::vector<std::string>()); 2019fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek std::vector<std::string> Sources; 2029fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek Sources.push_back("/a.cc"); 2039fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek Sources.push_back("/b.cc"); 2049fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek ClangTool Tool(Compilations, Sources); 2059fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek 2069fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek Tool.mapVirtualFile("/a.cc", "void a() {}"); 2079fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek Tool.mapVirtualFile("/b.cc", "void b() {}"); 2089fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek 2096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::unique_ptr<FrontendActionFactory> Action( 2106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines newFrontendActionFactory(&EndCallback, &EndCallback)); 2116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tool.run(Action.get()); 2129fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek 2139fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek EXPECT_TRUE(EndCallback.Matched); 2143c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane EXPECT_EQ(2u, EndCallback.BeginCalled); 2153c16e699b2a6926017b5f7a1516dc1be67468713Edwin Vane EXPECT_EQ(2u, EndCallback.EndCalled); 2169fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek} 217d9a2d5bdb747836917c2a5f7e12d075ec6762c77NAKAMURA Takumi#endif 2189fb6b27e6d584ac339363357335f8d6de3a652acManuel Klimek 219d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smithstruct SkipBodyConsumer : public clang::ASTConsumer { 220d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith /// Skip the 'skipMe' function. 221d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith virtual bool shouldSkipFunctionBody(Decl *D) { 222d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith FunctionDecl *F = dyn_cast<FunctionDecl>(D); 223d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith return F && F->getNameAsString() == "skipMe"; 224d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith } 225d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith}; 226d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith 227d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smithstruct SkipBodyAction : public clang::ASTFrontendAction { 228d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith virtual ASTConsumer *CreateASTConsumer(CompilerInstance &Compiler, 229d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith StringRef) { 230d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith Compiler.getFrontendOpts().SkipFunctionBodies = true; 231d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith return new SkipBodyConsumer; 232d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith } 233d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith}; 234d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith 235b8d2441144557c1b20b89b524d7ac54dbfaac0dbHal FinkelTEST(runToolOnCode, TestSkipFunctionBody) { 236d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith EXPECT_TRUE(runToolOnCode(new SkipBodyAction, 237d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith "int skipMe() { an_error_here }")); 238d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith EXPECT_FALSE(runToolOnCode(new SkipBodyAction, 239d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith "int skipMeNot() { an_error_here }")); 240d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith} 241d1bac8d46740eb00085ec816af0829fd75fb4d5cRichard Smith 242651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(runToolOnCodeWithArgs, TestNoDepFile) { 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::SmallString<32> DepFilePath; 244651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ASSERT_FALSE( 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines llvm::sys::fs::createTemporaryFile("depfile", "d", DepFilePath)); 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::vector<std::string> Args; 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.push_back("-MMD"); 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.push_back("-MT"); 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.push_back(DepFilePath.str()); 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.push_back("-MF"); 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Args.push_back(DepFilePath.str()); 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_TRUE(runToolOnCodeWithArgs(new SkipBodyAction, "", Args)); 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(llvm::sys::fs::exists(DepFilePath.str())); 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines EXPECT_FALSE(llvm::sys::fs::remove(DepFilePath.str())); 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 25748b3f0f74da575a66802dc5019b7440914983885Manuel Klimekstruct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster { 25848b3f0f74da575a66802dc5019b7440914983885Manuel Klimek bool &Found; 25948b3f0f74da575a66802dc5019b7440914983885Manuel Klimek bool &Ran; 26048b3f0f74da575a66802dc5019b7440914983885Manuel Klimek 26148b3f0f74da575a66802dc5019b7440914983885Manuel Klimek CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { } 26248b3f0f74da575a66802dc5019b7440914983885Manuel Klimek 26348b3f0f74da575a66802dc5019b7440914983885Manuel Klimek virtual CommandLineArguments 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Adjust(const CommandLineArguments &Args) override { 26548b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Ran = true; 26648b3f0f74da575a66802dc5019b7440914983885Manuel Klimek for (unsigned I = 0, E = Args.size(); I != E; ++I) { 26748b3f0f74da575a66802dc5019b7440914983885Manuel Klimek if (Args[I] == "-fsyntax-only") { 26848b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Found = true; 26948b3f0f74da575a66802dc5019b7440914983885Manuel Klimek break; 27048b3f0f74da575a66802dc5019b7440914983885Manuel Klimek } 27148b3f0f74da575a66802dc5019b7440914983885Manuel Klimek } 27248b3f0f74da575a66802dc5019b7440914983885Manuel Klimek return Args; 27348b3f0f74da575a66802dc5019b7440914983885Manuel Klimek } 27448b3f0f74da575a66802dc5019b7440914983885Manuel Klimek}; 27548b3f0f74da575a66802dc5019b7440914983885Manuel Klimek 27648b3f0f74da575a66802dc5019b7440914983885Manuel KlimekTEST(ClangToolTest, ArgumentAdjusters) { 27748b3f0f74da575a66802dc5019b7440914983885Manuel Klimek FixedCompilationDatabase Compilations("/", std::vector<std::string>()); 27848b3f0f74da575a66802dc5019b7440914983885Manuel Klimek 27948b3f0f74da575a66802dc5019b7440914983885Manuel Klimek ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc")); 28048b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Tool.mapVirtualFile("/a.cc", "void a() {}"); 28148b3f0f74da575a66802dc5019b7440914983885Manuel Klimek 2826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::unique_ptr<FrontendActionFactory> Action( 2836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines newFrontendActionFactory<SyntaxOnlyAction>()); 2846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 28548b3f0f74da575a66802dc5019b7440914983885Manuel Klimek bool Found = false; 28648b3f0f74da575a66802dc5019b7440914983885Manuel Klimek bool Ran = false; 28748b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran)); 2886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tool.run(Action.get()); 28948b3f0f74da575a66802dc5019b7440914983885Manuel Klimek EXPECT_TRUE(Ran); 29048b3f0f74da575a66802dc5019b7440914983885Manuel Klimek EXPECT_TRUE(Found); 29148b3f0f74da575a66802dc5019b7440914983885Manuel Klimek 29248b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Ran = Found = false; 29348b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Tool.clearArgumentsAdjusters(); 29448b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran)); 29548b3f0f74da575a66802dc5019b7440914983885Manuel Klimek Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster()); 2966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tool.run(Action.get()); 29748b3f0f74da575a66802dc5019b7440914983885Manuel Klimek EXPECT_TRUE(Ran); 29848b3f0f74da575a66802dc5019b7440914983885Manuel Klimek EXPECT_FALSE(Found); 29948b3f0f74da575a66802dc5019b7440914983885Manuel Klimek} 30048b3f0f74da575a66802dc5019b7440914983885Manuel Klimek 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#ifndef LLVM_ON_WIN32 3028051db16aa9513333062ab3145f038429f66780fPeter CollingbourneTEST(ClangToolTest, BuildASTs) { 3038051db16aa9513333062ab3145f038429f66780fPeter Collingbourne FixedCompilationDatabase Compilations("/", std::vector<std::string>()); 3048051db16aa9513333062ab3145f038429f66780fPeter Collingbourne 3058051db16aa9513333062ab3145f038429f66780fPeter Collingbourne std::vector<std::string> Sources; 3068051db16aa9513333062ab3145f038429f66780fPeter Collingbourne Sources.push_back("/a.cc"); 3078051db16aa9513333062ab3145f038429f66780fPeter Collingbourne Sources.push_back("/b.cc"); 3088051db16aa9513333062ab3145f038429f66780fPeter Collingbourne ClangTool Tool(Compilations, Sources); 3098051db16aa9513333062ab3145f038429f66780fPeter Collingbourne 3108051db16aa9513333062ab3145f038429f66780fPeter Collingbourne Tool.mapVirtualFile("/a.cc", "void a() {}"); 3118051db16aa9513333062ab3145f038429f66780fPeter Collingbourne Tool.mapVirtualFile("/b.cc", "void b() {}"); 3128051db16aa9513333062ab3145f038429f66780fPeter Collingbourne 3136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::vector<std::unique_ptr<ASTUnit>> ASTs; 3148051db16aa9513333062ab3145f038429f66780fPeter Collingbourne EXPECT_EQ(0, Tool.buildASTs(ASTs)); 3158051db16aa9513333062ab3145f038429f66780fPeter Collingbourne EXPECT_EQ(2u, ASTs.size()); 3168051db16aa9513333062ab3145f038429f66780fPeter Collingbourne} 3178051db16aa9513333062ab3145f038429f66780fPeter Collingbourne 318fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimekstruct TestDiagnosticConsumer : public DiagnosticConsumer { 319fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek TestDiagnosticConsumer() : NumDiagnosticsSeen(0) {} 320fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 321fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek const Diagnostic &Info) { 322fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek ++NumDiagnosticsSeen; 323fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek } 324fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek unsigned NumDiagnosticsSeen; 325fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek}; 326fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek 327fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel KlimekTEST(ClangToolTest, InjectDiagnosticConsumer) { 328fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek FixedCompilationDatabase Compilations("/", std::vector<std::string>()); 329fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc")); 330fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek Tool.mapVirtualFile("/a.cc", "int x = undeclared;"); 331fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek TestDiagnosticConsumer Consumer; 332fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek Tool.setDiagnosticConsumer(&Consumer); 3336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::unique_ptr<FrontendActionFactory> Action( 3346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines newFrontendActionFactory<SyntaxOnlyAction>()); 3356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Tool.run(Action.get()); 336fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen); 337fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek} 338fa8e7d344fc6ac9bf464419cc9cc2743b5036047Manuel Klimek 339cb5a9ecef48756841652f00311215814746e1e3fManuel KlimekTEST(ClangToolTest, InjectDiagnosticConsumerInBuildASTs) { 340cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek FixedCompilationDatabase Compilations("/", std::vector<std::string>()); 341cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc")); 342cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek Tool.mapVirtualFile("/a.cc", "int x = undeclared;"); 343cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek TestDiagnosticConsumer Consumer; 344cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek Tool.setDiagnosticConsumer(&Consumer); 3456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines std::vector<std::unique_ptr<ASTUnit>> ASTs; 346cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek Tool.buildASTs(ASTs); 347cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek EXPECT_EQ(1u, ASTs.size()); 348cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen); 349cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek} 3502ab056f31b83b8f1751d54614138f2e57e480c77NAKAMURA Takumi#endif 351cb5a9ecef48756841652f00311215814746e1e3fManuel Klimek 352cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace tooling 353cb971c6726d16e12ecd2a340941d7f5c06698332Manuel Klimek} // end namespace clang 354