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