ToolingTest.cpp revision 5f60f606093019174a11fcfd3ae36634dc44e8c9
1//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/AST/ASTConsumer.h"
11#include "clang/AST/DeclCXX.h"
12#include "clang/AST/DeclGroup.h"
13#include "clang/Frontend/FrontendAction.h"
14#include "clang/Frontend/FrontendActions.h"
15#include "clang/Tooling/CompilationDatabase.h"
16#include "clang/Tooling/Tooling.h"
17#include "gtest/gtest.h"
18#include <string>
19
20namespace clang {
21namespace tooling {
22
23namespace {
24/// Takes an ast consumer and returns it from CreateASTConsumer. This only
25/// works with single translation unit compilations.
26class TestAction : public clang::ASTFrontendAction {
27 public:
28  /// Takes ownership of TestConsumer.
29  explicit TestAction(clang::ASTConsumer *TestConsumer)
30      : TestConsumer(TestConsumer) {}
31
32 protected:
33  virtual clang::ASTConsumer* CreateASTConsumer(
34      clang::CompilerInstance& compiler, StringRef dummy) {
35    /// TestConsumer will be deleted by the framework calling us.
36    return TestConsumer;
37  }
38
39 private:
40  clang::ASTConsumer * const TestConsumer;
41};
42
43class FindTopLevelDeclConsumer : public clang::ASTConsumer {
44 public:
45  explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl)
46      : FoundTopLevelDecl(FoundTopLevelDecl) {}
47  virtual bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) {
48    *FoundTopLevelDecl = true;
49    return true;
50  }
51 private:
52  bool * const FoundTopLevelDecl;
53};
54} // end namespace
55
56TEST(runToolOnCode, FindsTopLevelDeclOnEmptyCode) {
57  bool FoundTopLevelDecl = false;
58  EXPECT_TRUE(runToolOnCode(
59      new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
60  EXPECT_TRUE(FoundTopLevelDecl);
61}
62
63namespace {
64class FindClassDeclXConsumer : public clang::ASTConsumer {
65 public:
66  FindClassDeclXConsumer(bool *FoundClassDeclX)
67      : FoundClassDeclX(FoundClassDeclX) {}
68  virtual bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) {
69    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(
70            *GroupRef.begin())) {
71      if (Record->getName() == "X") {
72        *FoundClassDeclX = true;
73      }
74    }
75    return true;
76  }
77 private:
78  bool *FoundClassDeclX;
79};
80} // end namespace
81
82TEST(runToolOnCode, FindsClassDecl) {
83  bool FoundClassDeclX = false;
84  EXPECT_TRUE(runToolOnCode(new TestAction(
85      new FindClassDeclXConsumer(&FoundClassDeclX)), "class X;"));
86  EXPECT_TRUE(FoundClassDeclX);
87
88  FoundClassDeclX = false;
89  EXPECT_TRUE(runToolOnCode(new TestAction(
90      new FindClassDeclXConsumer(&FoundClassDeclX)), "class Y;"));
91  EXPECT_FALSE(FoundClassDeclX);
92}
93
94TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
95  llvm::OwningPtr<FrontendActionFactory> Factory(
96    newFrontendActionFactory<SyntaxOnlyAction>());
97  llvm::OwningPtr<FrontendAction> Action(Factory->create());
98  EXPECT_TRUE(Action.get() != NULL);
99}
100
101struct IndependentFrontendActionCreator {
102  FrontendAction *newFrontendAction() { return new SyntaxOnlyAction; }
103};
104
105TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
106  IndependentFrontendActionCreator Creator;
107  llvm::OwningPtr<FrontendActionFactory> Factory(
108    newFrontendActionFactory(&Creator));
109  llvm::OwningPtr<FrontendAction> Action(Factory->create());
110  EXPECT_TRUE(Action.get() != NULL);
111}
112
113TEST(ToolInvocation, TestMapVirtualFile) {
114  clang::FileManager Files((clang::FileSystemOptions()));
115  std::vector<std::string> Args;
116  Args.push_back("tool-executable");
117  Args.push_back("-Idef");
118  Args.push_back("-fsyntax-only");
119  Args.push_back("test.cpp");
120  clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, &Files);
121  Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
122  Invocation.mapVirtualFile("def/abc", "\n");
123  EXPECT_TRUE(Invocation.run());
124}
125
126} // end namespace tooling
127} // end namespace clang
128