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