Home | History | Annotate | Download | only in Frontend
      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:
     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 
     46 private:
     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 
     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 
     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