• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 using namespace llvm;
22 using namespace clang;
23 
24 namespace {
25 
26 class TestASTFrontendAction : public ASTFrontendAction {
27 public:
TestASTFrontendAction(bool enableIncrementalProcessing=false)28   TestASTFrontendAction(bool enableIncrementalProcessing = false)
29     : EnableIncrementalProcessing(enableIncrementalProcessing) { }
30 
31   bool EnableIncrementalProcessing;
32   std::vector<std::string> decl_names;
33 
BeginSourceFileAction(CompilerInstance & ci,StringRef filename)34   virtual bool BeginSourceFileAction(CompilerInstance &ci, StringRef filename) {
35     if (EnableIncrementalProcessing)
36       ci.getPreprocessor().enableIncrementalProcessing();
37 
38     return ASTFrontendAction::BeginSourceFileAction(ci, filename);
39   }
40 
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)41   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
42                                          StringRef InFile) {
43     return new Visitor(decl_names);
44   }
45 
46 private:
47   class Visitor : public ASTConsumer, public RecursiveASTVisitor<Visitor> {
48   public:
Visitor(std::vector<std::string> & decl_names)49     Visitor(std::vector<std::string> &decl_names) : decl_names_(decl_names) {}
50 
HandleTranslationUnit(ASTContext & context)51     virtual void HandleTranslationUnit(ASTContext &context) {
52       TraverseDecl(context.getTranslationUnitDecl());
53     }
54 
VisitNamedDecl(NamedDecl * Decl)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 
TEST(ASTFrontendAction,Sanity)65 TEST(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 
TEST(ASTFrontendAction,IncrementalParsing)84 TEST(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