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