Home | History | Annotate | Download | only in Lex
      1 //===- unittests/Lex/PreprocessingRecordTest.cpp - PreprocessingRecord 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/Basic/SourceManager.h"
     11 #include "clang/Basic/FileManager.h"
     12 #include "clang/Basic/Diagnostic.h"
     13 #include "clang/Basic/LangOptions.h"
     14 #include "clang/Basic/TargetOptions.h"
     15 #include "clang/Basic/TargetInfo.h"
     16 #include "clang/Lex/ModuleLoader.h"
     17 #include "clang/Lex/HeaderSearch.h"
     18 #include "clang/Lex/Preprocessor.h"
     19 #include "clang/Lex/PreprocessingRecord.h"
     20 #include "llvm/Config/config.h"
     21 
     22 #include "gtest/gtest.h"
     23 
     24 using namespace llvm;
     25 using namespace clang;
     26 
     27 namespace {
     28 
     29 // The test fixture.
     30 class PreprocessingRecordTest : public ::testing::Test {
     31 protected:
     32   PreprocessingRecordTest()
     33     : FileMgr(FileMgrOpts),
     34       DiagID(new DiagnosticIDs()),
     35       Diags(DiagID, new IgnoringDiagConsumer()),
     36       SourceMgr(Diags, FileMgr) {
     37     TargetOpts.Triple = "x86_64-apple-darwin11.1.0";
     38     Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
     39   }
     40 
     41   FileSystemOptions FileMgrOpts;
     42   FileManager FileMgr;
     43   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
     44   DiagnosticsEngine Diags;
     45   SourceManager SourceMgr;
     46   LangOptions LangOpts;
     47   TargetOptions TargetOpts;
     48   IntrusiveRefCntPtr<TargetInfo> Target;
     49 };
     50 
     51 class VoidModuleLoader : public ModuleLoader {
     52   virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
     53                              Module::NameVisibilityKind Visibility,
     54                              bool IsInclusionDirective) {
     55     return 0;
     56   }
     57 };
     58 
     59 TEST_F(PreprocessingRecordTest, PPRecAPI) {
     60   const char *source =
     61       "0 1\n"
     62       "#if 1\n"
     63       "2\n"
     64       "#ifndef BB\n"
     65       "3 4\n"
     66       "#else\n"
     67       "#endif\n"
     68       "5\n"
     69       "#endif\n"
     70       "6\n"
     71       "#if 1\n"
     72       "7\n"
     73       "#if 1\n"
     74       "#endif\n"
     75       "8\n"
     76       "#endif\n"
     77       "9\n";
     78 
     79   MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
     80   SourceMgr.createMainFileIDForMemBuffer(buf);
     81 
     82   VoidModuleLoader ModLoader;
     83   HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, Target.getPtr());
     84   Preprocessor PP(Diags, LangOpts,
     85                   Target.getPtr(),
     86                   SourceMgr, HeaderInfo, ModLoader,
     87                   /*IILookup =*/ 0,
     88                   /*OwnsHeaderSearch =*/false,
     89                   /*DelayInitialization =*/ false);
     90   PP.createPreprocessingRecord(true);
     91   PP.EnterMainSourceFile();
     92 
     93   std::vector<Token> toks;
     94   while (1) {
     95     Token tok;
     96     PP.Lex(tok);
     97     if (tok.is(tok::eof))
     98       break;
     99     toks.push_back(tok);
    100   }
    101 
    102   // Make sure we got the tokens that we expected.
    103   ASSERT_EQ(10U, toks.size());
    104 
    105   PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
    106   EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective(
    107                     SourceRange(toks[0].getLocation(), toks[1].getLocation())));
    108   EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective(
    109                     SourceRange(toks[0].getLocation(), toks[2].getLocation())));
    110   EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective(
    111                     SourceRange(toks[3].getLocation(), toks[4].getLocation())));
    112   EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective(
    113                     SourceRange(toks[1].getLocation(), toks[5].getLocation())));
    114   EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective(
    115                     SourceRange(toks[2].getLocation(), toks[6].getLocation())));
    116   EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective(
    117                     SourceRange(toks[2].getLocation(), toks[5].getLocation())));
    118   EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective(
    119                     SourceRange(toks[0].getLocation(), toks[6].getLocation())));
    120   EXPECT_TRUE(PPRec.rangeIntersectsConditionalDirective(
    121                     SourceRange(toks[2].getLocation(), toks[8].getLocation())));
    122   EXPECT_FALSE(PPRec.rangeIntersectsConditionalDirective(
    123                     SourceRange(toks[0].getLocation(), toks[9].getLocation())));
    124 
    125   EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion(
    126                     toks[0].getLocation(), toks[2].getLocation()));
    127   EXPECT_FALSE(PPRec.areInDifferentConditionalDirectiveRegion(
    128                     toks[3].getLocation(), toks[4].getLocation()));
    129   EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion(
    130                     toks[1].getLocation(), toks[5].getLocation()));
    131   EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion(
    132                     toks[2].getLocation(), toks[0].getLocation()));
    133   EXPECT_FALSE(PPRec.areInDifferentConditionalDirectiveRegion(
    134                     toks[4].getLocation(), toks[3].getLocation()));
    135   EXPECT_TRUE(PPRec.areInDifferentConditionalDirectiveRegion(
    136                     toks[5].getLocation(), toks[1].getLocation()));
    137 }
    138 
    139 } // anonymous namespace
    140