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