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