1//===- unittests/Frontend/FrontendActionTest.cpp - FrontendAction 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/Frontend/FrontendAction.h" 11#include "clang/AST/ASTConsumer.h" 12#include "clang/AST/ASTContext.h" 13#include "clang/AST/RecursiveASTVisitor.h" 14#include "clang/Frontend/CompilerInstance.h" 15#include "clang/Frontend/CompilerInvocation.h" 16#include "clang/Lex/Preprocessor.h" 17#include "llvm/ADT/Triple.h" 18#include "llvm/Support/MemoryBuffer.h" 19#include "gtest/gtest.h" 20 21using namespace llvm; 22using namespace clang; 23 24namespace { 25 26class TestASTFrontendAction : public ASTFrontendAction { 27public: 28 TestASTFrontendAction(bool enableIncrementalProcessing = false) 29 : EnableIncrementalProcessing(enableIncrementalProcessing) { } 30 31 bool EnableIncrementalProcessing; 32 std::vector<std::string> decl_names; 33 34 virtual bool BeginSourceFileAction(CompilerInstance &ci, StringRef filename) { 35 if (EnableIncrementalProcessing) 36 ci.getPreprocessor().enableIncrementalProcessing(); 37 38 return ASTFrontendAction::BeginSourceFileAction(ci, filename); 39 } 40 41 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 42 StringRef InFile) { 43 return new Visitor(decl_names); 44 } 45 46private: 47 class Visitor : public ASTConsumer, public RecursiveASTVisitor<Visitor> { 48 public: 49 Visitor(std::vector<std::string> &decl_names) : decl_names_(decl_names) {} 50 51 virtual void HandleTranslationUnit(ASTContext &context) { 52 TraverseDecl(context.getTranslationUnitDecl()); 53 } 54 55 virtual bool VisitNamedDecl(NamedDecl *Decl) { 56 decl_names_.push_back(Decl->getQualifiedNameAsString()); 57 return true; 58 } 59 60 private: 61 std::vector<std::string> &decl_names_; 62 }; 63}; 64 65TEST(ASTFrontendAction, Sanity) { 66 CompilerInvocation *invocation = new CompilerInvocation; 67 invocation->getPreprocessorOpts().addRemappedFile( 68 "test.cc", MemoryBuffer::getMemBuffer("int main() { float x; }")); 69 invocation->getFrontendOpts().Inputs.push_back(FrontendInputFile("test.cc", 70 IK_CXX)); 71 invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly; 72 invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu"; 73 CompilerInstance compiler; 74 compiler.setInvocation(invocation); 75 compiler.createDiagnostics(); 76 77 TestASTFrontendAction test_action; 78 ASSERT_TRUE(compiler.ExecuteAction(test_action)); 79 ASSERT_EQ(2U, test_action.decl_names.size()); 80 EXPECT_EQ("main", test_action.decl_names[0]); 81 EXPECT_EQ("x", test_action.decl_names[1]); 82} 83 84TEST(ASTFrontendAction, IncrementalParsing) { 85 CompilerInvocation *invocation = new CompilerInvocation; 86 invocation->getPreprocessorOpts().addRemappedFile( 87 "test.cc", MemoryBuffer::getMemBuffer("int main() { float x; }")); 88 invocation->getFrontendOpts().Inputs.push_back(FrontendInputFile("test.cc", 89 IK_CXX)); 90 invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly; 91 invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu"; 92 CompilerInstance compiler; 93 compiler.setInvocation(invocation); 94 compiler.createDiagnostics(); 95 96 TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true); 97 ASSERT_TRUE(compiler.ExecuteAction(test_action)); 98 ASSERT_EQ(2U, test_action.decl_names.size()); 99 EXPECT_EQ("main", test_action.decl_names[0]); 100 EXPECT_EQ("x", test_action.decl_names[1]); 101} 102 103} // anonymous namespace 104