1d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis//===- unittests/Basic/SourceManagerTest.cpp ------ SourceManager tests ---===// 2d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// 3d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// The LLVM Compiler Infrastructure 4d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// 5d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source 6d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// License. See LICENSE.TXT for details. 7d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// 8d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis//===----------------------------------------------------------------------===// 9d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 10d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h" 11d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 123aeb34f5639ca03ba952bef7239028eaaec33281Douglas Gregor#include "clang/Basic/DiagnosticOptions.h" 131050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Basic/FileManager.h" 14d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h" 15d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 161050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Basic/TargetOptions.h" 17d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 18b0985c86f7f75e780bfeb366afdbee7676c28948Douglas Gregor#include "clang/Lex/HeaderSearchOptions.h" 191050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Lex/ModuleLoader.h" 20d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 2136a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor#include "clang/Lex/PreprocessorOptions.h" 228fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 23ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include "llvm/Config/llvm-config.h" 24d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "gtest/gtest.h" 25d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 26d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisusing namespace llvm; 27d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisusing namespace clang; 28d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 29d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisnamespace { 30d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 31d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// The test fixture. 32d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisclass SourceManagerTest : public ::testing::Test { 33d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisprotected: 34d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceManagerTest() 35d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis : FileMgr(FileMgrOpts), 36d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis DiagID(new DiagnosticIDs()), 378e023611637905629b928915cbda22a90b2432c3Douglas Gregor Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()), 3807f8cf4ec3ffb6668b35e7b864354faa76167209Douglas Gregor SourceMgr(Diags, FileMgr), 3907f8cf4ec3ffb6668b35e7b864354faa76167209Douglas Gregor TargetOpts(new TargetOptions) { 4007f8cf4ec3ffb6668b35e7b864354faa76167209Douglas Gregor TargetOpts->Triple = "x86_64-apple-darwin11.1.0"; 41ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 42d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis } 43d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 44d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis FileSystemOptions FileMgrOpts; 45d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis FileManager FileMgr; 46c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID; 47d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis DiagnosticsEngine Diags; 48d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceManager SourceMgr; 49d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis LangOptions LangOpts; 50ef8225444452a1486bd721f3285301fe84643b00Stephen Hines std::shared_ptr<TargetOptions> TargetOpts; 51c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<TargetInfo> Target; 52d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis}; 53d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 54d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisclass VoidModuleLoader : public ModuleLoader { 556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleLoadResult loadModule(SourceLocation ImportLoc, 566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ModuleIdPath Path, 576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module::NameVisibilityKind Visibility, 586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool IsInclusionDirective) override { 597dff05bf3019995798def5d1066e4282b8578df6Douglas Gregor return ModuleLoadResult(); 60d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis } 611a4191d0697098c424646654784399b839f87bc4NAKAMURA Takumi 626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void makeModuleVisible(Module *Mod, 636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Module::NameVisibilityKind Visibility, 646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceLocation ImportLoc, 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Complain) override { } 666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override 68ef8225444452a1486bd721f3285301fe84643b00Stephen Hines { return nullptr; } 696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override 706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines { return 0; }; 71d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis}; 72d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 73d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios KyrtzidisTEST_F(SourceManagerTest, isBeforeInTranslationUnit) { 74d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis const char *source = 75d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis "#define M(x) [x]\n" 76d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis "M(foo)"; 77d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source); 786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FileID mainFileID = SourceMgr.createFileID(buf); 796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceMgr.setMainFileID(mainFileID); 80d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 81d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis VoidModuleLoader ModLoader; 82ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 83b0985c86f7f75e780bfeb366afdbee7676c28948Douglas Gregor &*Target); 846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr, 856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HeaderInfo, ModLoader, 86ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IILookup =*/nullptr, 876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*OwnsHeaderSearch =*/false); 886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PP.Initialize(*Target); 89d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis PP.EnterMainSourceFile(); 90d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 91d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis std::vector<Token> toks; 92d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis while (1) { 93d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis Token tok; 94d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis PP.Lex(tok); 95d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis if (tok.is(tok::eof)) 96d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis break; 97d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis toks.push_back(tok); 98d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis } 99d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 100d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis // Make sure we got the tokens that we expected. 101d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(3U, toks.size()); 102d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(tok::l_square, toks[0].getKind()); 103d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(tok::identifier, toks[1].getKind()); 104d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(tok::r_square, toks[2].getKind()); 105d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 106d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation lsqrLoc = toks[0].getLocation(); 107d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation idLoc = toks[1].getLocation(); 108d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation rsqrLoc = toks[2].getLocation(); 109d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 110d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation macroExpStartLoc = SourceMgr.translateLineCol(mainFileID, 2, 1); 111d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation macroExpEndLoc = SourceMgr.translateLineCol(mainFileID, 2, 6); 112d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_TRUE(macroExpStartLoc.isFileID()); 113d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_TRUE(macroExpEndLoc.isFileID()); 114d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 11536d592718ff342f762e32cbde73d1113f88cb275Dylan Noblesmith SmallString<32> str; 116d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ("M", PP.getSpelling(macroExpStartLoc, str)); 117d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(")", PP.getSpelling(macroExpEndLoc, str)); 118d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 119d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(lsqrLoc, idLoc)); 120d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, rsqrLoc)); 121d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(macroExpStartLoc, idLoc)); 122d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, macroExpEndLoc)); 123d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis} 124d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 1252e413f977d13d83b5baf7b5e4e93fe7c390959caJordan RoseTEST_F(SourceManagerTest, getColumnNumber) { 1262e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose const char *Source = 1272e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose "int x;\n" 1282e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose "int y;"; 1292e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1302e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source); 1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FileID MainFileID = SourceMgr.createFileID(Buf); 1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceMgr.setMainFileID(MainFileID); 1332e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1342e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose bool Invalid; 1352e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1362e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1372e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, &Invalid)); 1382e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1392e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1402e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1412e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(5U, SourceMgr.getColumnNumber(MainFileID, 4, &Invalid)); 1422e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1432e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1442e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1452e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 7, &Invalid)); 1462e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1472e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1482e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1492e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(5U, SourceMgr.getColumnNumber(MainFileID, 11, &Invalid)); 1502e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1512e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1522e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1532e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(7U, SourceMgr.getColumnNumber(MainFileID, strlen(Source), 1542e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose &Invalid)); 1552e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1562e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1572e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1582e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose SourceMgr.getColumnNumber(MainFileID, strlen(Source)+1, &Invalid); 1592e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(Invalid); 1602e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1612e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose // Test invalid files 1622e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1632e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose SourceMgr.getColumnNumber(FileID(), 0, &Invalid); 1642e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(Invalid); 1652e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1662e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1672e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose SourceMgr.getColumnNumber(FileID(), 1, &Invalid); 1682e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(Invalid); 1692e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1702e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose // Test with no invalid flag. 171ef8225444452a1486bd721f3285301fe84643b00Stephen Hines EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, nullptr)); 1722e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose} 1732e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 174cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis#if defined(LLVM_ON_UNIX) 175cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 176cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios KyrtzidisTEST_F(SourceManagerTest, getMacroArgExpandedLocation) { 177cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const char *header = 178cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#define FM(x,y) x\n"; 179cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 180cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const char *main = 181cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#include \"/test-header.h\"\n" 182cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#define VAL 0\n" 183cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "FM(VAL,0)\n" 184cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "FM(0,VAL)\n" 185cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "FM(FM(0,VAL),0)\n" 186cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#define CONCAT(X, Y) X##Y\n" 187cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "CONCAT(1,1)\n"; 188cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 189cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header); 190cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main); 1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FileID mainFileID = SourceMgr.createFileID(mainBuf); 1926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceMgr.setMainFileID(mainFileID); 193cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 194cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h", 195cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis headerBuf->getBufferSize(), 0); 196cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceMgr.overrideFileContents(headerFile, headerBuf); 197cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 198cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis VoidModuleLoader ModLoader; 199ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 200b0985c86f7f75e780bfeb366afdbee7676c28948Douglas Gregor &*Target); 2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr, 2026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HeaderInfo, ModLoader, 203ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IILookup =*/nullptr, 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*OwnsHeaderSearch =*/false); 2056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PP.Initialize(*Target); 206cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis PP.EnterMainSourceFile(); 207cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 208cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis std::vector<Token> toks; 209cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis while (1) { 210cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis Token tok; 211cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis PP.Lex(tok); 212cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (tok.is(tok::eof)) 213cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis break; 214cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis toks.push_back(tok); 215cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis } 216cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 217cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis // Make sure we got the tokens that we expected. 218cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(4U, toks.size()); 219cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[0].getKind()); 220cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[1].getKind()); 221cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[2].getKind()); 222cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[3].getKind()); 223cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 224cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation defLoc = SourceMgr.translateLineCol(mainFileID, 2, 13); 225cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation loc1 = SourceMgr.translateLineCol(mainFileID, 3, 8); 226cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation loc2 = SourceMgr.translateLineCol(mainFileID, 4, 4); 227cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation loc3 = SourceMgr.translateLineCol(mainFileID, 5, 7); 228cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation defLoc2 = SourceMgr.translateLineCol(mainFileID, 6, 22); 229cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis defLoc = SourceMgr.getMacroArgExpandedLocation(defLoc); 230cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis loc1 = SourceMgr.getMacroArgExpandedLocation(loc1); 231cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis loc2 = SourceMgr.getMacroArgExpandedLocation(loc2); 232cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis loc3 = SourceMgr.getMacroArgExpandedLocation(loc3); 233cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis defLoc2 = SourceMgr.getMacroArgExpandedLocation(defLoc2); 234cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 235cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(defLoc.isFileID()); 236cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(loc1.isFileID()); 237cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc2)); 238cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc3)); 239cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_EQ(loc2, toks[1].getLocation()); 240cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_EQ(loc3, toks[2].getLocation()); 241cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(defLoc2.isFileID()); 242cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis} 243cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 244db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidisnamespace { 245db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 246db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidisstruct MacroAction { 247db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis SourceLocation Loc; 248db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::string Name; 249db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis bool isDefinition; // if false, it is expansion. 250db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 251db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MacroAction(SourceLocation Loc, StringRef Name, bool isDefinition) 252db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis : Loc(Loc), Name(Name), isDefinition(isDefinition) { } 253db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis}; 254db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 255db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidisclass MacroTracker : public PPCallbacks { 256db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::vector<MacroAction> &Macros; 257db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 258db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidispublic: 259db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis explicit MacroTracker(std::vector<MacroAction> &Macros) : Macros(Macros) { } 260db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 261c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis virtual void MacroDefined(const Token &MacroNameTok, 262c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis const MacroDirective *MD) { 263c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis Macros.push_back(MacroAction(MD->getLocation(), 264db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MacroNameTok.getIdentifierInfo()->getName(), 265db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis true)); 266db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis } 267c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, 268dd08a0c178329ec16cb9e494e6880f3991708b93Argyrios Kyrtzidis SourceRange Range, const MacroArgs *Args) { 269db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis Macros.push_back(MacroAction(MacroNameTok.getLocation(), 270db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MacroNameTok.getIdentifierInfo()->getName(), 271db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis false)); 272db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis } 273db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis}; 274db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 275db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis} 276db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 277db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios KyrtzidisTEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) { 278db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis const char *header = 279db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define MACRO_IN_INCLUDE 0\n"; 280db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 281db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis const char *main = 282db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define M(x) x\n" 283db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define INC \"/test-header.h\"\n" 284db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#include M(INC)\n" 285db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define INC2 </test-header.h>\n" 286db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#include M(INC2)\n"; 287db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 288db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header); 289db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main); 2906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SourceMgr.setMainFileID(SourceMgr.createFileID(mainBuf)); 291db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 292db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h", 293db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis headerBuf->getBufferSize(), 0); 294db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis SourceMgr.overrideFileContents(headerFile, headerBuf); 295db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 296db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis VoidModuleLoader ModLoader; 297ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 298b0985c86f7f75e780bfeb366afdbee7676c28948Douglas Gregor &*Target); 2996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr, 3006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HeaderInfo, ModLoader, 301ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /*IILookup =*/nullptr, 3026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /*OwnsHeaderSearch =*/false); 3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PP.Initialize(*Target); 304db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 305db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::vector<MacroAction> Macros; 306db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis PP.addPPCallbacks(new MacroTracker(Macros)); 307db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 308db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis PP.EnterMainSourceFile(); 309db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 310db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::vector<Token> toks; 311db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis while (1) { 312db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis Token tok; 313db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis PP.Lex(tok); 314db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis if (tok.is(tok::eof)) 315db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis break; 316db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis toks.push_back(tok); 317db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis } 318db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 319db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // Make sure we got the tokens that we expected. 320db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ(0U, toks.size()); 321db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 322db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ(9U, Macros.size()); 323db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define M(x) x 324db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[0].isDefinition); 325db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("M", Macros[0].Name); 326db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define INC "/test-header.h" 327db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[1].isDefinition); 328db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC", Macros[1].Name); 329db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // M expansion in #include M(INC) 330db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[2].isDefinition); 331db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("M", Macros[2].Name); 332db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // INC expansion in #include M(INC) 333db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[3].isDefinition); 334db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC", Macros[3].Name); 335db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define MACRO_IN_INCLUDE 0 336db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[4].isDefinition); 337db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("MACRO_IN_INCLUDE", Macros[4].Name); 338db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define INC2 </test-header.h> 339db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[5].isDefinition); 340db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC2", Macros[5].Name); 341db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // M expansion in #include M(INC2) 342db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[6].isDefinition); 343db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("M", Macros[6].Name); 344db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // INC2 expansion in #include M(INC2) 345db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[7].isDefinition); 346db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC2", Macros[7].Name); 347db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define MACRO_IN_INCLUDE 0 348db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[8].isDefinition); 349db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("MACRO_IN_INCLUDE", Macros[8].Name); 350db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 351db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // The INC expansion in #include M(INC) comes before the first 352db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // MACRO_IN_INCLUDE definition of the included file. 353db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[3].Loc, Macros[4].Loc)); 354db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 355db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // The INC2 expansion in #include M(INC2) comes before the second 356db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // MACRO_IN_INCLUDE definition of the included file. 357db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[7].Loc, Macros[8].Loc)); 358db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis} 359db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 360cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis#endif 361cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 362d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis} // anonymous namespace 363