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/MemoryBufferCache.h" 16 #include "clang/Basic/SourceManager.h" 17 #include "clang/Basic/TargetInfo.h" 18 #include "clang/Basic/TargetOptions.h" 19 #include "clang/Lex/HeaderSearch.h" 20 #include "clang/Lex/HeaderSearchOptions.h" 21 #include "clang/Lex/ModuleLoader.h" 22 #include "clang/Lex/Preprocessor.h" 23 #include "clang/Lex/PreprocessorOptions.h" 24 #include "gtest/gtest.h" 25 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 TEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) { 55 const char *source = 56 "0 1\n" 57 "#if 1\n" 58 "2\n" 59 "#ifndef BB\n" 60 "3 4\n" 61 "#else\n" 62 "#endif\n" 63 "5\n" 64 "#endif\n" 65 "6\n" 66 "#if 1\n" 67 "7\n" 68 "#if 1\n" 69 "#endif\n" 70 "8\n" 71 "#endif\n" 72 "9\n"; 73 74 std::unique_ptr<llvm::MemoryBuffer> Buf = 75 llvm::MemoryBuffer::getMemBuffer(source); 76 SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); 77 78 TrivialModuleLoader ModLoader; 79 MemoryBufferCache PCMCache; 80 HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr, 81 Diags, LangOpts, Target.get()); 82 Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts, 83 SourceMgr, PCMCache, HeaderInfo, ModLoader, 84 /*IILookup =*/nullptr, 85 /*OwnsHeaderSearch =*/false); 86 PP.Initialize(*Target); 87 PPConditionalDirectiveRecord * 88 PPRec = new PPConditionalDirectiveRecord(SourceMgr); 89 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(PPRec)); 90 PP.EnterMainSourceFile(); 91 92 std::vector<Token> toks; 93 while (1) { 94 Token tok; 95 PP.Lex(tok); 96 if (tok.is(tok::eof)) 97 break; 98 toks.push_back(tok); 99 } 100 101 // Make sure we got the tokens that we expected. 102 ASSERT_EQ(10U, toks.size()); 103 104 EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( 105 SourceRange(toks[0].getLocation(), toks[1].getLocation()))); 106 EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( 107 SourceRange(toks[0].getLocation(), toks[2].getLocation()))); 108 EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( 109 SourceRange(toks[3].getLocation(), toks[4].getLocation()))); 110 EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( 111 SourceRange(toks[1].getLocation(), toks[5].getLocation()))); 112 EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( 113 SourceRange(toks[2].getLocation(), toks[6].getLocation()))); 114 EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( 115 SourceRange(toks[2].getLocation(), toks[5].getLocation()))); 116 EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( 117 SourceRange(toks[0].getLocation(), toks[6].getLocation()))); 118 EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective( 119 SourceRange(toks[2].getLocation(), toks[8].getLocation()))); 120 EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective( 121 SourceRange(toks[0].getLocation(), toks[9].getLocation()))); 122 123 EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( 124 toks[0].getLocation(), toks[2].getLocation())); 125 EXPECT_FALSE(PPRec->areInDifferentConditionalDirectiveRegion( 126 toks[3].getLocation(), toks[4].getLocation())); 127 EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( 128 toks[1].getLocation(), toks[5].getLocation())); 129 EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( 130 toks[2].getLocation(), toks[0].getLocation())); 131 EXPECT_FALSE(PPRec->areInDifferentConditionalDirectiveRegion( 132 toks[4].getLocation(), toks[3].getLocation())); 133 EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion( 134 toks[5].getLocation(), toks[1].getLocation())); 135 } 136 137 } // anonymous namespace 138