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/FileManager.h" 12d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h" 13d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h" 14d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/TargetOptions.h" 15d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h" 16d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Lex/ModuleLoader.h" 17d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h" 18d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h" 198fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 20cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis#include "llvm/Config/config.h" 21d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 22d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis#include "gtest/gtest.h" 23d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 24d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisusing namespace llvm; 25d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisusing namespace clang; 26d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 27d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisnamespace { 28d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 29d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis// The test fixture. 30d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisclass SourceManagerTest : public ::testing::Test { 31d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisprotected: 32d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceManagerTest() 33d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis : FileMgr(FileMgrOpts), 34d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis DiagID(new DiagnosticIDs()), 35d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis Diags(DiagID, new IgnoringDiagConsumer()), 36d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceMgr(Diags, FileMgr) { 37d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis TargetOpts.Triple = "x86_64-apple-darwin11.1.0"; 38d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts); 39d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis } 40d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 41d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis FileSystemOptions FileMgrOpts; 42d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis FileManager FileMgr; 43c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID; 44d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis DiagnosticsEngine Diags; 45d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceManager SourceMgr; 46d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis LangOptions LangOpts; 47d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis TargetOptions TargetOpts; 48c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith IntrusiveRefCntPtr<TargetInfo> Target; 49d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis}; 50d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 51d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidisclass VoidModuleLoader : public ModuleLoader { 52d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path, 53d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis Module::NameVisibilityKind Visibility, 54d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis bool IsInclusionDirective) { 55d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis return 0; 56d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis } 57d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis}; 58d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 59d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios KyrtzidisTEST_F(SourceManagerTest, isBeforeInTranslationUnit) { 60d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis const char *source = 61d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis "#define M(x) [x]\n" 62d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis "M(foo)"; 63d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source); 64d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(buf); 65d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 66d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis VoidModuleLoader ModLoader; 67dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target); 68d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis Preprocessor PP(Diags, LangOpts, 69d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis Target.getPtr(), 70d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceMgr, HeaderInfo, ModLoader, 71d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis /*IILookup =*/ 0, 72d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis /*OwnsHeaderSearch =*/false, 73d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis /*DelayInitialization =*/ false); 74d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis PP.EnterMainSourceFile(); 75d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 76d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis std::vector<Token> toks; 77d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis while (1) { 78d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis Token tok; 79d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis PP.Lex(tok); 80d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis if (tok.is(tok::eof)) 81d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis break; 82d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis toks.push_back(tok); 83d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis } 84d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 85d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis // Make sure we got the tokens that we expected. 86d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(3U, toks.size()); 87d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(tok::l_square, toks[0].getKind()); 88d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(tok::identifier, toks[1].getKind()); 89d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(tok::r_square, toks[2].getKind()); 90d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 91d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation lsqrLoc = toks[0].getLocation(); 92d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation idLoc = toks[1].getLocation(); 93d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation rsqrLoc = toks[2].getLocation(); 94d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 95d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation macroExpStartLoc = SourceMgr.translateLineCol(mainFileID, 2, 1); 96d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis SourceLocation macroExpEndLoc = SourceMgr.translateLineCol(mainFileID, 2, 6); 97d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_TRUE(macroExpStartLoc.isFileID()); 98d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_TRUE(macroExpEndLoc.isFileID()); 99d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 10036d592718ff342f762e32cbde73d1113f88cb275Dylan Noblesmith SmallString<32> str; 101d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ("M", PP.getSpelling(macroExpStartLoc, str)); 102d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis ASSERT_EQ(")", PP.getSpelling(macroExpEndLoc, str)); 103d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 104d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(lsqrLoc, idLoc)); 105d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, rsqrLoc)); 106d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(macroExpStartLoc, idLoc)); 107d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, macroExpEndLoc)); 108d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis} 109d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis 1102e413f977d13d83b5baf7b5e4e93fe7c390959caJordan RoseTEST_F(SourceManagerTest, getColumnNumber) { 1112e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose const char *Source = 1122e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose "int x;\n" 1132e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose "int y;"; 1142e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1152e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source); 1162e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose FileID MainFileID = SourceMgr.createMainFileIDForMemBuffer(Buf); 1172e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1182e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose bool Invalid; 1192e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1202e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1212e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, &Invalid)); 1222e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1232e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1242e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1252e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(5U, SourceMgr.getColumnNumber(MainFileID, 4, &Invalid)); 1262e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1272e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1282e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1292e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 7, &Invalid)); 1302e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1312e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1322e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1332e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(5U, SourceMgr.getColumnNumber(MainFileID, 11, &Invalid)); 1342e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1352e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1362e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1372e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(7U, SourceMgr.getColumnNumber(MainFileID, strlen(Source), 1382e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose &Invalid)); 1392e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(!Invalid); 1402e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1412e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1422e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose SourceMgr.getColumnNumber(MainFileID, strlen(Source)+1, &Invalid); 1432e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(Invalid); 1442e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1452e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose // Test invalid files 1462e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1472e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose SourceMgr.getColumnNumber(FileID(), 0, &Invalid); 1482e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(Invalid); 1492e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1502e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose Invalid = false; 1512e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose SourceMgr.getColumnNumber(FileID(), 1, &Invalid); 1522e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_TRUE(Invalid); 1532e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 1542e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose // Test with no invalid flag. 1552e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, NULL)); 1562e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose} 1572e413f977d13d83b5baf7b5e4e93fe7c390959caJordan Rose 158cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis#if defined(LLVM_ON_UNIX) 159cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 160cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios KyrtzidisTEST_F(SourceManagerTest, getMacroArgExpandedLocation) { 161cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const char *header = 162cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#define FM(x,y) x\n"; 163cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 164cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const char *main = 165cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#include \"/test-header.h\"\n" 166cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#define VAL 0\n" 167cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "FM(VAL,0)\n" 168cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "FM(0,VAL)\n" 169cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "FM(FM(0,VAL),0)\n" 170cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "#define CONCAT(X, Y) X##Y\n" 171cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis "CONCAT(1,1)\n"; 172cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 173cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header); 174cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main); 175cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(mainBuf); 176cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 177cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h", 178cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis headerBuf->getBufferSize(), 0); 179cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceMgr.overrideFileContents(headerFile, headerBuf); 180cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 181cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis VoidModuleLoader ModLoader; 182dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target); 183cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis Preprocessor PP(Diags, LangOpts, 184cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis Target.getPtr(), 185cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceMgr, HeaderInfo, ModLoader, 186cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis /*IILookup =*/ 0, 187cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis /*OwnsHeaderSearch =*/false, 188cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis /*DelayInitialization =*/ false); 189cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis PP.EnterMainSourceFile(); 190cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 191cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis std::vector<Token> toks; 192cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis while (1) { 193cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis Token tok; 194cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis PP.Lex(tok); 195cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis if (tok.is(tok::eof)) 196cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis break; 197cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis toks.push_back(tok); 198cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis } 199cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 200cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis // Make sure we got the tokens that we expected. 201cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(4U, toks.size()); 202cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[0].getKind()); 203cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[1].getKind()); 204cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[2].getKind()); 205cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[3].getKind()); 206cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 207cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation defLoc = SourceMgr.translateLineCol(mainFileID, 2, 13); 208cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation loc1 = SourceMgr.translateLineCol(mainFileID, 3, 8); 209cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation loc2 = SourceMgr.translateLineCol(mainFileID, 4, 4); 210cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation loc3 = SourceMgr.translateLineCol(mainFileID, 5, 7); 211cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis SourceLocation defLoc2 = SourceMgr.translateLineCol(mainFileID, 6, 22); 212cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis defLoc = SourceMgr.getMacroArgExpandedLocation(defLoc); 213cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis loc1 = SourceMgr.getMacroArgExpandedLocation(loc1); 214cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis loc2 = SourceMgr.getMacroArgExpandedLocation(loc2); 215cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis loc3 = SourceMgr.getMacroArgExpandedLocation(loc3); 216cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis defLoc2 = SourceMgr.getMacroArgExpandedLocation(defLoc2); 217cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 218cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(defLoc.isFileID()); 219cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(loc1.isFileID()); 220cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc2)); 221cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc3)); 222cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_EQ(loc2, toks[1].getLocation()); 223cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_EQ(loc3, toks[2].getLocation()); 224cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis EXPECT_TRUE(defLoc2.isFileID()); 225cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis} 226cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 227db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidisnamespace { 228db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 229db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidisstruct MacroAction { 230db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis SourceLocation Loc; 231db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::string Name; 232db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis bool isDefinition; // if false, it is expansion. 233db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 234db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MacroAction(SourceLocation Loc, StringRef Name, bool isDefinition) 235db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis : Loc(Loc), Name(Name), isDefinition(isDefinition) { } 236db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis}; 237db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 238db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidisclass MacroTracker : public PPCallbacks { 239db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::vector<MacroAction> &Macros; 240db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 241db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidispublic: 242db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis explicit MacroTracker(std::vector<MacroAction> &Macros) : Macros(Macros) { } 243db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 244db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) { 245db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis Macros.push_back(MacroAction(MI->getDefinitionLoc(), 246db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MacroNameTok.getIdentifierInfo()->getName(), 247db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis true)); 248db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis } 249db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI, 250db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis SourceRange Range) { 251db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis Macros.push_back(MacroAction(MacroNameTok.getLocation(), 252db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MacroNameTok.getIdentifierInfo()->getName(), 253db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis false)); 254db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis } 255db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis}; 256db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 257db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis} 258db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 259db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios KyrtzidisTEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) { 260db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis const char *header = 261db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define MACRO_IN_INCLUDE 0\n"; 262db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 263db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis const char *main = 264db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define M(x) x\n" 265db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define INC \"/test-header.h\"\n" 266db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#include M(INC)\n" 267db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#define INC2 </test-header.h>\n" 268db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis "#include M(INC2)\n"; 269db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 270db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header); 271db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main); 272db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis SourceMgr.createMainFileIDForMemBuffer(mainBuf); 273db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 274db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h", 275db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis headerBuf->getBufferSize(), 0); 276db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis SourceMgr.overrideFileContents(headerFile, headerBuf); 277db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 278db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis VoidModuleLoader ModLoader; 279db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target); 280db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis Preprocessor PP(Diags, LangOpts, 281db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis Target.getPtr(), 282db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis SourceMgr, HeaderInfo, ModLoader, 283db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis /*IILookup =*/ 0, 284db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis /*OwnsHeaderSearch =*/false, 285db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis /*DelayInitialization =*/ false); 286db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 287db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::vector<MacroAction> Macros; 288db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis PP.addPPCallbacks(new MacroTracker(Macros)); 289db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 290db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis PP.EnterMainSourceFile(); 291db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 292db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis std::vector<Token> toks; 293db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis while (1) { 294db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis Token tok; 295db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis PP.Lex(tok); 296db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis if (tok.is(tok::eof)) 297db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis break; 298db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis toks.push_back(tok); 299db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis } 300db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 301db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // Make sure we got the tokens that we expected. 302db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ(0U, toks.size()); 303db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 304db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ(9U, Macros.size()); 305db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define M(x) x 306db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[0].isDefinition); 307db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("M", Macros[0].Name); 308db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define INC "/test-header.h" 309db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[1].isDefinition); 310db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC", Macros[1].Name); 311db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // M expansion in #include M(INC) 312db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[2].isDefinition); 313db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("M", Macros[2].Name); 314db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // INC expansion in #include M(INC) 315db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[3].isDefinition); 316db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC", Macros[3].Name); 317db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define MACRO_IN_INCLUDE 0 318db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[4].isDefinition); 319db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("MACRO_IN_INCLUDE", Macros[4].Name); 320db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define INC2 </test-header.h> 321db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[5].isDefinition); 322db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC2", Macros[5].Name); 323db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // M expansion in #include M(INC2) 324db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[6].isDefinition); 325db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("M", Macros[6].Name); 326db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // INC2 expansion in #include M(INC2) 327db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_FALSE(Macros[7].isDefinition); 328db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("INC2", Macros[7].Name); 329db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // #define MACRO_IN_INCLUDE 0 330db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_TRUE(Macros[8].isDefinition); 331db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis ASSERT_EQ("MACRO_IN_INCLUDE", Macros[8].Name); 332db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 333db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // The INC expansion in #include M(INC) comes before the first 334db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // MACRO_IN_INCLUDE definition of the included file. 335db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[3].Loc, Macros[4].Loc)); 336db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 337db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // The INC2 expansion in #include M(INC2) comes before the second 338db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis // MACRO_IN_INCLUDE definition of the included file. 339db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[7].Loc, Macros[8].Loc)); 340db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis} 341db81d38d9cd468a9eeffe8ab092be4d48e43888eArgyrios Kyrtzidis 342cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis#endif 343cee5ec9df479994e4ba27fb65b7ded5bb5a980ebArgyrios Kyrtzidis 344d7711ec430fde5706f85ba6c4b85283a8e743ff7Argyrios Kyrtzidis} // anonymous namespace 345