12403797eSArgyrios Kyrtzidis //===- unittests/Basic/SourceManagerTest.cpp ------ SourceManager tests ---===//
22403797eSArgyrios Kyrtzidis //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62403797eSArgyrios Kyrtzidis //
72403797eSArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
82403797eSArgyrios Kyrtzidis
92403797eSArgyrios Kyrtzidis #include "clang/Basic/SourceManager.h"
102403797eSArgyrios Kyrtzidis #include "clang/Basic/Diagnostic.h"
11edf8e387SDouglas Gregor #include "clang/Basic/DiagnosticOptions.h"
12320d9666SChandler Carruth #include "clang/Basic/FileManager.h"
132403797eSArgyrios Kyrtzidis #include "clang/Basic/LangOptions.h"
142403797eSArgyrios Kyrtzidis #include "clang/Basic/TargetInfo.h"
15320d9666SChandler Carruth #include "clang/Basic/TargetOptions.h"
162403797eSArgyrios Kyrtzidis #include "clang/Lex/HeaderSearch.h"
1740ba1a01SDouglas Gregor #include "clang/Lex/HeaderSearchOptions.h"
18320d9666SChandler Carruth #include "clang/Lex/ModuleLoader.h"
192403797eSArgyrios Kyrtzidis #include "clang/Lex/Preprocessor.h"
201452ff15SDouglas Gregor #include "clang/Lex/PreprocessorOptions.h"
214903802fSBenjamin Kramer #include "llvm/ADT/SmallString.h"
221d257e1dSAlp Toker #include "llvm/Config/llvm-config.h"
23f28972faSJan Korous #include "llvm/Support/Process.h"
242403797eSArgyrios Kyrtzidis #include "gtest/gtest.h"
25f28972faSJan Korous #include <cstddef>
262403797eSArgyrios Kyrtzidis
272403797eSArgyrios Kyrtzidis using namespace clang;
282403797eSArgyrios Kyrtzidis
292403797eSArgyrios Kyrtzidis namespace {
302403797eSArgyrios Kyrtzidis
312403797eSArgyrios Kyrtzidis // The test fixture.
322403797eSArgyrios Kyrtzidis class SourceManagerTest : public ::testing::Test {
332403797eSArgyrios Kyrtzidis protected:
SourceManagerTest()342403797eSArgyrios Kyrtzidis SourceManagerTest()
352403797eSArgyrios Kyrtzidis : FileMgr(FileMgrOpts),
362403797eSArgyrios Kyrtzidis DiagID(new DiagnosticIDs()),
37d8cfd399SDouglas Gregor Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
3844d6361eSDouglas Gregor SourceMgr(Diags, FileMgr),
3944d6361eSDouglas Gregor TargetOpts(new TargetOptions) {
4044d6361eSDouglas Gregor TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
4180758084SAlp Toker Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
422403797eSArgyrios Kyrtzidis }
432403797eSArgyrios Kyrtzidis
442403797eSArgyrios Kyrtzidis FileSystemOptions FileMgrOpts;
452403797eSArgyrios Kyrtzidis FileManager FileMgr;
46c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
472403797eSArgyrios Kyrtzidis DiagnosticsEngine Diags;
482403797eSArgyrios Kyrtzidis SourceManager SourceMgr;
492403797eSArgyrios Kyrtzidis LangOptions LangOpts;
5080758084SAlp Toker std::shared_ptr<TargetOptions> TargetOpts;
51c95d8192SDylan Noblesmith IntrusiveRefCntPtr<TargetInfo> Target;
522403797eSArgyrios Kyrtzidis };
532403797eSArgyrios Kyrtzidis
TEST_F(SourceManagerTest,isInMemoryBuffersNoSourceLocationInfo)54*e881d853STapasweni Pathak TEST_F(SourceManagerTest, isInMemoryBuffersNoSourceLocationInfo) {
55*e881d853STapasweni Pathak // Check for invalid source location for each method
56*e881d853STapasweni Pathak SourceLocation LocEmpty;
57*e881d853STapasweni Pathak bool isWrittenInBuiltInFileFalse = SourceMgr.isWrittenInBuiltinFile(LocEmpty);
58*e881d853STapasweni Pathak bool isWrittenInCommandLineFileFalse =
59*e881d853STapasweni Pathak SourceMgr.isWrittenInCommandLineFile(LocEmpty);
60*e881d853STapasweni Pathak bool isWrittenInScratchSpaceFalse =
61*e881d853STapasweni Pathak SourceMgr.isWrittenInScratchSpace(LocEmpty);
62*e881d853STapasweni Pathak
63*e881d853STapasweni Pathak EXPECT_FALSE(isWrittenInBuiltInFileFalse);
64*e881d853STapasweni Pathak EXPECT_FALSE(isWrittenInCommandLineFileFalse);
65*e881d853STapasweni Pathak EXPECT_FALSE(isWrittenInScratchSpaceFalse);
66*e881d853STapasweni Pathak
67*e881d853STapasweni Pathak // Check for valid source location per filename for each method
68*e881d853STapasweni Pathak const char *Source = "int x";
69*e881d853STapasweni Pathak
70*e881d853STapasweni Pathak std::unique_ptr<llvm::MemoryBuffer> BuiltInBuf =
71*e881d853STapasweni Pathak llvm::MemoryBuffer::getMemBuffer(Source);
72*e881d853STapasweni Pathak const FileEntry *BuiltInFile =
73*e881d853STapasweni Pathak FileMgr.getVirtualFile("<built-in>", BuiltInBuf->getBufferSize(), 0);
74*e881d853STapasweni Pathak SourceMgr.overrideFileContents(BuiltInFile, std::move(BuiltInBuf));
75*e881d853STapasweni Pathak FileID BuiltInFileID =
76*e881d853STapasweni Pathak SourceMgr.getOrCreateFileID(BuiltInFile, SrcMgr::C_User);
77*e881d853STapasweni Pathak SourceMgr.setMainFileID(BuiltInFileID);
78*e881d853STapasweni Pathak SourceLocation LocBuiltIn =
79*e881d853STapasweni Pathak SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
80*e881d853STapasweni Pathak bool isWrittenInBuiltInFileTrue =
81*e881d853STapasweni Pathak SourceMgr.isWrittenInBuiltinFile(LocBuiltIn);
82*e881d853STapasweni Pathak
83*e881d853STapasweni Pathak std::unique_ptr<llvm::MemoryBuffer> CommandLineBuf =
84*e881d853STapasweni Pathak llvm::MemoryBuffer::getMemBuffer(Source);
85*e881d853STapasweni Pathak const FileEntry *CommandLineFile = FileMgr.getVirtualFile(
86*e881d853STapasweni Pathak "<command line>", CommandLineBuf->getBufferSize(), 0);
87*e881d853STapasweni Pathak SourceMgr.overrideFileContents(CommandLineFile, std::move(CommandLineBuf));
88*e881d853STapasweni Pathak FileID CommandLineFileID =
89*e881d853STapasweni Pathak SourceMgr.getOrCreateFileID(CommandLineFile, SrcMgr::C_User);
90*e881d853STapasweni Pathak SourceMgr.setMainFileID(CommandLineFileID);
91*e881d853STapasweni Pathak SourceLocation LocCommandLine =
92*e881d853STapasweni Pathak SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
93*e881d853STapasweni Pathak bool isWrittenInCommandLineFileTrue =
94*e881d853STapasweni Pathak SourceMgr.isWrittenInCommandLineFile(LocCommandLine);
95*e881d853STapasweni Pathak
96*e881d853STapasweni Pathak std::unique_ptr<llvm::MemoryBuffer> ScratchSpaceBuf =
97*e881d853STapasweni Pathak llvm::MemoryBuffer::getMemBuffer(Source);
98*e881d853STapasweni Pathak const FileEntry *ScratchSpaceFile = FileMgr.getVirtualFile(
99*e881d853STapasweni Pathak "<scratch space>", ScratchSpaceBuf->getBufferSize(), 0);
100*e881d853STapasweni Pathak SourceMgr.overrideFileContents(ScratchSpaceFile, std::move(ScratchSpaceBuf));
101*e881d853STapasweni Pathak FileID ScratchSpaceFileID =
102*e881d853STapasweni Pathak SourceMgr.getOrCreateFileID(ScratchSpaceFile, SrcMgr::C_User);
103*e881d853STapasweni Pathak SourceMgr.setMainFileID(ScratchSpaceFileID);
104*e881d853STapasweni Pathak SourceLocation LocScratchSpace =
105*e881d853STapasweni Pathak SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
106*e881d853STapasweni Pathak bool isWrittenInScratchSpaceTrue =
107*e881d853STapasweni Pathak SourceMgr.isWrittenInScratchSpace(LocScratchSpace);
108*e881d853STapasweni Pathak
109*e881d853STapasweni Pathak EXPECT_TRUE(isWrittenInBuiltInFileTrue);
110*e881d853STapasweni Pathak EXPECT_TRUE(isWrittenInCommandLineFileTrue);
111*e881d853STapasweni Pathak EXPECT_TRUE(isWrittenInScratchSpaceTrue);
112*e881d853STapasweni Pathak }
113*e881d853STapasweni Pathak
TEST_F(SourceManagerTest,isInSystemHeader)114*e881d853STapasweni Pathak TEST_F(SourceManagerTest, isInSystemHeader) {
115*e881d853STapasweni Pathak // Check for invalid source location
116*e881d853STapasweni Pathak SourceLocation LocEmpty;
117*e881d853STapasweni Pathak bool isInSystemHeaderFalse = SourceMgr.isInSystemHeader(LocEmpty);
118*e881d853STapasweni Pathak ASSERT_FALSE(isInSystemHeaderFalse);
119*e881d853STapasweni Pathak }
120*e881d853STapasweni Pathak
TEST_F(SourceManagerTest,isBeforeInTranslationUnit)1212403797eSArgyrios Kyrtzidis TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
1222403797eSArgyrios Kyrtzidis const char *source =
1232403797eSArgyrios Kyrtzidis "#define M(x) [x]\n"
1242403797eSArgyrios Kyrtzidis "M(foo)";
125b214cbc7SJames Y Knight std::unique_ptr<llvm::MemoryBuffer> Buf =
126b214cbc7SJames Y Knight llvm::MemoryBuffer::getMemBuffer(source);
12750a5f97eSDavid Blaikie FileID mainFileID = SourceMgr.createFileID(std::move(Buf));
128b671e34cSAlp Toker SourceMgr.setMainFileID(mainFileID);
1292403797eSArgyrios Kyrtzidis
1305d2ed489SRichard Smith TrivialModuleLoader ModLoader;
1319c28cb3fSDavid Blaikie HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
1329c28cb3fSDavid Blaikie Diags, LangOpts, &*Target);
133e3041688SDavid Blaikie Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
1348bef5cd4SDuncan P. N. Exon Smith SourceMgr, HeaderInfo, ModLoader,
135416fa34bSCraig Topper /*IILookup =*/nullptr,
1361ae02f68SAlp Toker /*OwnsHeaderSearch =*/false);
1371ae02f68SAlp Toker PP.Initialize(*Target);
1382403797eSArgyrios Kyrtzidis PP.EnterMainSourceFile();
1392403797eSArgyrios Kyrtzidis
1402403797eSArgyrios Kyrtzidis std::vector<Token> toks;
1412403797eSArgyrios Kyrtzidis while (1) {
1422403797eSArgyrios Kyrtzidis Token tok;
1432403797eSArgyrios Kyrtzidis PP.Lex(tok);
1442403797eSArgyrios Kyrtzidis if (tok.is(tok::eof))
1452403797eSArgyrios Kyrtzidis break;
1462403797eSArgyrios Kyrtzidis toks.push_back(tok);
1472403797eSArgyrios Kyrtzidis }
1482403797eSArgyrios Kyrtzidis
1492403797eSArgyrios Kyrtzidis // Make sure we got the tokens that we expected.
1502403797eSArgyrios Kyrtzidis ASSERT_EQ(3U, toks.size());
1512403797eSArgyrios Kyrtzidis ASSERT_EQ(tok::l_square, toks[0].getKind());
1522403797eSArgyrios Kyrtzidis ASSERT_EQ(tok::identifier, toks[1].getKind());
1532403797eSArgyrios Kyrtzidis ASSERT_EQ(tok::r_square, toks[2].getKind());
1542403797eSArgyrios Kyrtzidis
1552403797eSArgyrios Kyrtzidis SourceLocation lsqrLoc = toks[0].getLocation();
1562403797eSArgyrios Kyrtzidis SourceLocation idLoc = toks[1].getLocation();
1572403797eSArgyrios Kyrtzidis SourceLocation rsqrLoc = toks[2].getLocation();
1582403797eSArgyrios Kyrtzidis
1592403797eSArgyrios Kyrtzidis SourceLocation macroExpStartLoc = SourceMgr.translateLineCol(mainFileID, 2, 1);
1602403797eSArgyrios Kyrtzidis SourceLocation macroExpEndLoc = SourceMgr.translateLineCol(mainFileID, 2, 6);
1612403797eSArgyrios Kyrtzidis ASSERT_TRUE(macroExpStartLoc.isFileID());
1622403797eSArgyrios Kyrtzidis ASSERT_TRUE(macroExpEndLoc.isFileID());
1632403797eSArgyrios Kyrtzidis
164f1a13f29SDylan Noblesmith SmallString<32> str;
1652403797eSArgyrios Kyrtzidis ASSERT_EQ("M", PP.getSpelling(macroExpStartLoc, str));
1662403797eSArgyrios Kyrtzidis ASSERT_EQ(")", PP.getSpelling(macroExpEndLoc, str));
1672403797eSArgyrios Kyrtzidis
1682403797eSArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(lsqrLoc, idLoc));
1692403797eSArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, rsqrLoc));
1702403797eSArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(macroExpStartLoc, idLoc));
1712403797eSArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, macroExpEndLoc));
1722403797eSArgyrios Kyrtzidis }
1732403797eSArgyrios Kyrtzidis
TEST_F(SourceManagerTest,getColumnNumber)1748d63d5b8SJordan Rose TEST_F(SourceManagerTest, getColumnNumber) {
1758d63d5b8SJordan Rose const char *Source =
1768d63d5b8SJordan Rose "int x;\n"
1778d63d5b8SJordan Rose "int y;";
1788d63d5b8SJordan Rose
179b214cbc7SJames Y Knight std::unique_ptr<llvm::MemoryBuffer> Buf =
180b214cbc7SJames Y Knight llvm::MemoryBuffer::getMemBuffer(Source);
18150a5f97eSDavid Blaikie FileID MainFileID = SourceMgr.createFileID(std::move(Buf));
182b671e34cSAlp Toker SourceMgr.setMainFileID(MainFileID);
1838d63d5b8SJordan Rose
1848d63d5b8SJordan Rose bool Invalid;
1858d63d5b8SJordan Rose
1868d63d5b8SJordan Rose Invalid = false;
1878d63d5b8SJordan Rose EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, &Invalid));
1888d63d5b8SJordan Rose EXPECT_TRUE(!Invalid);
1898d63d5b8SJordan Rose
1908d63d5b8SJordan Rose Invalid = false;
1918d63d5b8SJordan Rose EXPECT_EQ(5U, SourceMgr.getColumnNumber(MainFileID, 4, &Invalid));
1928d63d5b8SJordan Rose EXPECT_TRUE(!Invalid);
1938d63d5b8SJordan Rose
1948d63d5b8SJordan Rose Invalid = false;
1958d63d5b8SJordan Rose EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 7, &Invalid));
1968d63d5b8SJordan Rose EXPECT_TRUE(!Invalid);
1978d63d5b8SJordan Rose
1988d63d5b8SJordan Rose Invalid = false;
1998d63d5b8SJordan Rose EXPECT_EQ(5U, SourceMgr.getColumnNumber(MainFileID, 11, &Invalid));
2008d63d5b8SJordan Rose EXPECT_TRUE(!Invalid);
2018d63d5b8SJordan Rose
2028d63d5b8SJordan Rose Invalid = false;
2038d63d5b8SJordan Rose EXPECT_EQ(7U, SourceMgr.getColumnNumber(MainFileID, strlen(Source),
2048d63d5b8SJordan Rose &Invalid));
2058d63d5b8SJordan Rose EXPECT_TRUE(!Invalid);
2068d63d5b8SJordan Rose
2078d63d5b8SJordan Rose Invalid = false;
2088d63d5b8SJordan Rose SourceMgr.getColumnNumber(MainFileID, strlen(Source)+1, &Invalid);
2098d63d5b8SJordan Rose EXPECT_TRUE(Invalid);
2108d63d5b8SJordan Rose
2118d63d5b8SJordan Rose // Test invalid files
2128d63d5b8SJordan Rose Invalid = false;
2138d63d5b8SJordan Rose SourceMgr.getColumnNumber(FileID(), 0, &Invalid);
2148d63d5b8SJordan Rose EXPECT_TRUE(Invalid);
2158d63d5b8SJordan Rose
2168d63d5b8SJordan Rose Invalid = false;
2178d63d5b8SJordan Rose SourceMgr.getColumnNumber(FileID(), 1, &Invalid);
2188d63d5b8SJordan Rose EXPECT_TRUE(Invalid);
2198d63d5b8SJordan Rose
2208d63d5b8SJordan Rose // Test with no invalid flag.
221416fa34bSCraig Topper EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, nullptr));
2228d63d5b8SJordan Rose }
2238d63d5b8SJordan Rose
TEST_F(SourceManagerTest,locationPrintTest)224b8e08860SStephen Kelly TEST_F(SourceManagerTest, locationPrintTest) {
225b8e08860SStephen Kelly const char *header = "#define IDENTITY(x) x\n";
226b8e08860SStephen Kelly
227b8e08860SStephen Kelly const char *Source = "int x;\n"
228b8e08860SStephen Kelly "include \"test-header.h\"\n"
229b8e08860SStephen Kelly "IDENTITY(int y);\n"
230b8e08860SStephen Kelly "int z;";
231b8e08860SStephen Kelly
232b8e08860SStephen Kelly std::unique_ptr<llvm::MemoryBuffer> HeaderBuf =
233b8e08860SStephen Kelly llvm::MemoryBuffer::getMemBuffer(header);
234b8e08860SStephen Kelly std::unique_ptr<llvm::MemoryBuffer> Buf =
235b8e08860SStephen Kelly llvm::MemoryBuffer::getMemBuffer(Source);
236b8e08860SStephen Kelly
237b8e08860SStephen Kelly const FileEntry *SourceFile =
238b8e08860SStephen Kelly FileMgr.getVirtualFile("/mainFile.cpp", Buf->getBufferSize(), 0);
239b8e08860SStephen Kelly SourceMgr.overrideFileContents(SourceFile, std::move(Buf));
240b8e08860SStephen Kelly
241b8e08860SStephen Kelly const FileEntry *HeaderFile =
242b8e08860SStephen Kelly FileMgr.getVirtualFile("/test-header.h", HeaderBuf->getBufferSize(), 0);
243b8e08860SStephen Kelly SourceMgr.overrideFileContents(HeaderFile, std::move(HeaderBuf));
244b8e08860SStephen Kelly
245b8e08860SStephen Kelly FileID MainFileID = SourceMgr.getOrCreateFileID(SourceFile, SrcMgr::C_User);
246b8e08860SStephen Kelly FileID HeaderFileID = SourceMgr.getOrCreateFileID(HeaderFile, SrcMgr::C_User);
247b8e08860SStephen Kelly SourceMgr.setMainFileID(MainFileID);
248b8e08860SStephen Kelly
249b8e08860SStephen Kelly auto BeginLoc = SourceMgr.getLocForStartOfFile(MainFileID);
250b8e08860SStephen Kelly auto EndLoc = SourceMgr.getLocForEndOfFile(MainFileID);
251b8e08860SStephen Kelly
252b8e08860SStephen Kelly auto BeginEOLLoc = SourceMgr.translateLineCol(MainFileID, 1, 7);
253b8e08860SStephen Kelly
254b8e08860SStephen Kelly auto HeaderLoc = SourceMgr.getLocForStartOfFile(HeaderFileID);
255b8e08860SStephen Kelly
256b8e08860SStephen Kelly EXPECT_EQ(BeginLoc.printToString(SourceMgr), "/mainFile.cpp:1:1");
257b8e08860SStephen Kelly EXPECT_EQ(EndLoc.printToString(SourceMgr), "/mainFile.cpp:4:7");
258b8e08860SStephen Kelly
259b8e08860SStephen Kelly EXPECT_EQ(BeginEOLLoc.printToString(SourceMgr), "/mainFile.cpp:1:7");
260b8e08860SStephen Kelly EXPECT_EQ(HeaderLoc.printToString(SourceMgr), "/test-header.h:1:1");
261b8e08860SStephen Kelly
262b8e08860SStephen Kelly EXPECT_EQ(SourceRange(BeginLoc, BeginLoc).printToString(SourceMgr),
263b8e08860SStephen Kelly "</mainFile.cpp:1:1>");
264b8e08860SStephen Kelly EXPECT_EQ(SourceRange(BeginLoc, BeginEOLLoc).printToString(SourceMgr),
265b8e08860SStephen Kelly "</mainFile.cpp:1:1, col:7>");
266b8e08860SStephen Kelly EXPECT_EQ(SourceRange(BeginLoc, EndLoc).printToString(SourceMgr),
267b8e08860SStephen Kelly "</mainFile.cpp:1:1, line:4:7>");
268b8e08860SStephen Kelly EXPECT_EQ(SourceRange(BeginLoc, HeaderLoc).printToString(SourceMgr),
269b8e08860SStephen Kelly "</mainFile.cpp:1:1, /test-header.h:1:1>");
270b8e08860SStephen Kelly }
271b8e08860SStephen Kelly
TEST_F(SourceManagerTest,getInvalidBOM)2728fa5e98fSpaulhoad TEST_F(SourceManagerTest, getInvalidBOM) {
2738fa5e98fSpaulhoad ASSERT_EQ(SrcMgr::ContentCache::getInvalidBOM(""), nullptr);
2748fa5e98fSpaulhoad ASSERT_EQ(SrcMgr::ContentCache::getInvalidBOM("\x00\x00\x00"), nullptr);
2758fa5e98fSpaulhoad ASSERT_EQ(SrcMgr::ContentCache::getInvalidBOM("\xFF\xFF\xFF"), nullptr);
2768fa5e98fSpaulhoad ASSERT_EQ(SrcMgr::ContentCache::getInvalidBOM("#include <iostream>"),
2778fa5e98fSpaulhoad nullptr);
2788fa5e98fSpaulhoad
2798fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
2808fa5e98fSpaulhoad "\xFE\xFF#include <iostream>")),
2818fa5e98fSpaulhoad "UTF-16 (BE)");
2828fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
2838fa5e98fSpaulhoad "\xFF\xFE#include <iostream>")),
2848fa5e98fSpaulhoad "UTF-16 (LE)");
2858fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
2868fa5e98fSpaulhoad "\x2B\x2F\x76#include <iostream>")),
2878fa5e98fSpaulhoad "UTF-7");
2888fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
2898fa5e98fSpaulhoad "\xF7\x64\x4C#include <iostream>")),
2908fa5e98fSpaulhoad "UTF-1");
2918fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
2928fa5e98fSpaulhoad "\xDD\x73\x66\x73#include <iostream>")),
2938fa5e98fSpaulhoad "UTF-EBCDIC");
2948fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
2958fa5e98fSpaulhoad "\x0E\xFE\xFF#include <iostream>")),
2968fa5e98fSpaulhoad "SCSU");
2978fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
2988fa5e98fSpaulhoad "\xFB\xEE\x28#include <iostream>")),
2998fa5e98fSpaulhoad "BOCU-1");
3008fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
3018fa5e98fSpaulhoad "\x84\x31\x95\x33#include <iostream>")),
3028fa5e98fSpaulhoad "GB-18030");
3038fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
3048fa5e98fSpaulhoad llvm::StringLiteral::withInnerNUL(
3058fa5e98fSpaulhoad "\x00\x00\xFE\xFF#include <iostream>"))),
3068fa5e98fSpaulhoad "UTF-32 (BE)");
3078fa5e98fSpaulhoad ASSERT_EQ(StringRef(SrcMgr::ContentCache::getInvalidBOM(
3088fa5e98fSpaulhoad llvm::StringLiteral::withInnerNUL(
3098fa5e98fSpaulhoad "\xFF\xFE\x00\x00#include <iostream>"))),
3108fa5e98fSpaulhoad "UTF-32 (LE)");
3118fa5e98fSpaulhoad }
3128fa5e98fSpaulhoad
313f28972faSJan Korous // Regression test - there was an out of bound access for buffers not terminated by zero.
TEST_F(SourceManagerTest,getLineNumber)314f28972faSJan Korous TEST_F(SourceManagerTest, getLineNumber) {
315f28972faSJan Korous const unsigned pageSize = llvm::sys::Process::getPageSizeEstimate();
316f28972faSJan Korous std::unique_ptr<char[]> source(new char[pageSize]);
317f28972faSJan Korous for(unsigned i = 0; i < pageSize; ++i) {
318f28972faSJan Korous source[i] = 'a';
319f28972faSJan Korous }
320f28972faSJan Korous
321f28972faSJan Korous std::unique_ptr<llvm::MemoryBuffer> Buf =
322f28972faSJan Korous llvm::MemoryBuffer::getMemBuffer(
323f28972faSJan Korous llvm::MemoryBufferRef(
324f28972faSJan Korous llvm::StringRef(source.get(), 3), "whatever"
325f28972faSJan Korous ),
326f28972faSJan Korous false
327f28972faSJan Korous );
328f28972faSJan Korous
329f28972faSJan Korous FileID mainFileID = SourceMgr.createFileID(std::move(Buf));
330f28972faSJan Korous SourceMgr.setMainFileID(mainFileID);
331f28972faSJan Korous
332f28972faSJan Korous ASSERT_NO_FATAL_FAILURE(SourceMgr.getLineNumber(mainFileID, 1, nullptr));
333f28972faSJan Korous }
334f28972faSJan Korous
335e841c901SArgyrios Kyrtzidis #if defined(LLVM_ON_UNIX)
336e841c901SArgyrios Kyrtzidis
TEST_F(SourceManagerTest,getMacroArgExpandedLocation)337e841c901SArgyrios Kyrtzidis TEST_F(SourceManagerTest, getMacroArgExpandedLocation) {
338e841c901SArgyrios Kyrtzidis const char *header =
339e841c901SArgyrios Kyrtzidis "#define FM(x,y) x\n";
340e841c901SArgyrios Kyrtzidis
341e841c901SArgyrios Kyrtzidis const char *main =
342e841c901SArgyrios Kyrtzidis "#include \"/test-header.h\"\n"
343e841c901SArgyrios Kyrtzidis "#define VAL 0\n"
344e841c901SArgyrios Kyrtzidis "FM(VAL,0)\n"
345e841c901SArgyrios Kyrtzidis "FM(0,VAL)\n"
346e841c901SArgyrios Kyrtzidis "FM(FM(0,VAL),0)\n"
347e841c901SArgyrios Kyrtzidis "#define CONCAT(X, Y) X##Y\n"
348e841c901SArgyrios Kyrtzidis "CONCAT(1,1)\n";
349e841c901SArgyrios Kyrtzidis
350b214cbc7SJames Y Knight std::unique_ptr<llvm::MemoryBuffer> HeaderBuf =
351b214cbc7SJames Y Knight llvm::MemoryBuffer::getMemBuffer(header);
352b214cbc7SJames Y Knight std::unique_ptr<llvm::MemoryBuffer> MainBuf =
353b214cbc7SJames Y Knight llvm::MemoryBuffer::getMemBuffer(main);
35450a5f97eSDavid Blaikie FileID mainFileID = SourceMgr.createFileID(std::move(MainBuf));
355b671e34cSAlp Toker SourceMgr.setMainFileID(mainFileID);
356e841c901SArgyrios Kyrtzidis
357e841c901SArgyrios Kyrtzidis const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
358d87f8d76SRafael Espindola HeaderBuf->getBufferSize(), 0);
35949cc3181SDavid Blaikie SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
360e841c901SArgyrios Kyrtzidis
3615d2ed489SRichard Smith TrivialModuleLoader ModLoader;
3629c28cb3fSDavid Blaikie HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
3639c28cb3fSDavid Blaikie Diags, LangOpts, &*Target);
364411a254aSKadir Cetinkaya
365e3041688SDavid Blaikie Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
3668bef5cd4SDuncan P. N. Exon Smith SourceMgr, HeaderInfo, ModLoader,
367416fa34bSCraig Topper /*IILookup =*/nullptr,
3681ae02f68SAlp Toker /*OwnsHeaderSearch =*/false);
369411a254aSKadir Cetinkaya // Ensure we can get expanded locations in presence of implicit includes.
370411a254aSKadir Cetinkaya // These are different than normal includes since predefines buffer doesn't
371411a254aSKadir Cetinkaya // have a valid insertion location.
372411a254aSKadir Cetinkaya PP.setPredefines("#include \"/implicit-header.h\"");
373411a254aSKadir Cetinkaya FileMgr.getVirtualFile("/implicit-header.h", 0, 0);
3741ae02f68SAlp Toker PP.Initialize(*Target);
375e841c901SArgyrios Kyrtzidis PP.EnterMainSourceFile();
376e841c901SArgyrios Kyrtzidis
377e841c901SArgyrios Kyrtzidis std::vector<Token> toks;
378e841c901SArgyrios Kyrtzidis while (1) {
379e841c901SArgyrios Kyrtzidis Token tok;
380e841c901SArgyrios Kyrtzidis PP.Lex(tok);
381e841c901SArgyrios Kyrtzidis if (tok.is(tok::eof))
382e841c901SArgyrios Kyrtzidis break;
383e841c901SArgyrios Kyrtzidis toks.push_back(tok);
384e841c901SArgyrios Kyrtzidis }
385e841c901SArgyrios Kyrtzidis
386e841c901SArgyrios Kyrtzidis // Make sure we got the tokens that we expected.
387e841c901SArgyrios Kyrtzidis ASSERT_EQ(4U, toks.size());
388e841c901SArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[0].getKind());
389e841c901SArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[1].getKind());
390e841c901SArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[2].getKind());
391e841c901SArgyrios Kyrtzidis ASSERT_EQ(tok::numeric_constant, toks[3].getKind());
392e841c901SArgyrios Kyrtzidis
393e841c901SArgyrios Kyrtzidis SourceLocation defLoc = SourceMgr.translateLineCol(mainFileID, 2, 13);
394e841c901SArgyrios Kyrtzidis SourceLocation loc1 = SourceMgr.translateLineCol(mainFileID, 3, 8);
395e841c901SArgyrios Kyrtzidis SourceLocation loc2 = SourceMgr.translateLineCol(mainFileID, 4, 4);
396e841c901SArgyrios Kyrtzidis SourceLocation loc3 = SourceMgr.translateLineCol(mainFileID, 5, 7);
397e841c901SArgyrios Kyrtzidis SourceLocation defLoc2 = SourceMgr.translateLineCol(mainFileID, 6, 22);
398e841c901SArgyrios Kyrtzidis defLoc = SourceMgr.getMacroArgExpandedLocation(defLoc);
399e841c901SArgyrios Kyrtzidis loc1 = SourceMgr.getMacroArgExpandedLocation(loc1);
400e841c901SArgyrios Kyrtzidis loc2 = SourceMgr.getMacroArgExpandedLocation(loc2);
401e841c901SArgyrios Kyrtzidis loc3 = SourceMgr.getMacroArgExpandedLocation(loc3);
402e841c901SArgyrios Kyrtzidis defLoc2 = SourceMgr.getMacroArgExpandedLocation(defLoc2);
403e841c901SArgyrios Kyrtzidis
404e841c901SArgyrios Kyrtzidis EXPECT_TRUE(defLoc.isFileID());
405e841c901SArgyrios Kyrtzidis EXPECT_TRUE(loc1.isFileID());
406e841c901SArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc2));
407e841c901SArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc3));
408e841c901SArgyrios Kyrtzidis EXPECT_EQ(loc2, toks[1].getLocation());
409e841c901SArgyrios Kyrtzidis EXPECT_EQ(loc3, toks[2].getLocation());
410e841c901SArgyrios Kyrtzidis EXPECT_TRUE(defLoc2.isFileID());
411e841c901SArgyrios Kyrtzidis }
412e841c901SArgyrios Kyrtzidis
413a956450eSArgyrios Kyrtzidis namespace {
414a956450eSArgyrios Kyrtzidis
415a956450eSArgyrios Kyrtzidis struct MacroAction {
416349a624aSVedant Kumar enum Kind { kExpansion, kDefinition, kUnDefinition};
417349a624aSVedant Kumar
418a956450eSArgyrios Kyrtzidis SourceLocation Loc;
419a956450eSArgyrios Kyrtzidis std::string Name;
420349a624aSVedant Kumar unsigned MAKind : 3;
421a956450eSArgyrios Kyrtzidis
MacroAction__anon0851c1e30111::__anon0851c1e30211::MacroAction422349a624aSVedant Kumar MacroAction(SourceLocation Loc, StringRef Name, unsigned K)
423adcd0268SBenjamin Kramer : Loc(Loc), Name(std::string(Name)), MAKind(K) {}
424349a624aSVedant Kumar
isExpansion__anon0851c1e30111::__anon0851c1e30211::MacroAction425349a624aSVedant Kumar bool isExpansion() const { return MAKind == kExpansion; }
isDefinition__anon0851c1e30111::__anon0851c1e30211::MacroAction426349a624aSVedant Kumar bool isDefinition() const { return MAKind & kDefinition; }
isUnDefinition__anon0851c1e30111::__anon0851c1e30211::MacroAction427349a624aSVedant Kumar bool isUnDefinition() const { return MAKind & kUnDefinition; }
428a956450eSArgyrios Kyrtzidis };
429a956450eSArgyrios Kyrtzidis
430a956450eSArgyrios Kyrtzidis class MacroTracker : public PPCallbacks {
431a956450eSArgyrios Kyrtzidis std::vector<MacroAction> &Macros;
432a956450eSArgyrios Kyrtzidis
433a956450eSArgyrios Kyrtzidis public:
MacroTracker(std::vector<MacroAction> & Macros)434a956450eSArgyrios Kyrtzidis explicit MacroTracker(std::vector<MacroAction> &Macros) : Macros(Macros) { }
435a956450eSArgyrios Kyrtzidis
MacroDefined(const Token & MacroNameTok,const MacroDirective * MD)43634eb2072SAlexander Kornienko void MacroDefined(const Token &MacroNameTok,
43734eb2072SAlexander Kornienko const MacroDirective *MD) override {
438fead64beSArgyrios Kyrtzidis Macros.push_back(MacroAction(MD->getLocation(),
439a956450eSArgyrios Kyrtzidis MacroNameTok.getIdentifierInfo()->getName(),
440349a624aSVedant Kumar MacroAction::kDefinition));
441349a624aSVedant Kumar }
MacroUndefined(const Token & MacroNameTok,const MacroDefinition & MD,const MacroDirective * UD)442349a624aSVedant Kumar void MacroUndefined(const Token &MacroNameTok,
443349a624aSVedant Kumar const MacroDefinition &MD,
444349a624aSVedant Kumar const MacroDirective *UD) override {
445349a624aSVedant Kumar Macros.push_back(
446349a624aSVedant Kumar MacroAction(UD ? UD->getLocation() : SourceLocation(),
447349a624aSVedant Kumar MacroNameTok.getIdentifierInfo()->getName(),
448349a624aSVedant Kumar UD ? MacroAction::kDefinition | MacroAction::kUnDefinition
449349a624aSVedant Kumar : MacroAction::kUnDefinition));
450a956450eSArgyrios Kyrtzidis }
MacroExpands(const Token & MacroNameTok,const MacroDefinition & MD,SourceRange Range,const MacroArgs * Args)45136bd40dfSRichard Smith void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
45234eb2072SAlexander Kornienko SourceRange Range, const MacroArgs *Args) override {
453a956450eSArgyrios Kyrtzidis Macros.push_back(MacroAction(MacroNameTok.getLocation(),
454a956450eSArgyrios Kyrtzidis MacroNameTok.getIdentifierInfo()->getName(),
455349a624aSVedant Kumar MacroAction::kExpansion));
456a956450eSArgyrios Kyrtzidis }
457a956450eSArgyrios Kyrtzidis };
458a956450eSArgyrios Kyrtzidis
459ab9db510SAlexander Kornienko }
460a956450eSArgyrios Kyrtzidis
TEST_F(SourceManagerTest,isBeforeInTranslationUnitWithMacroInInclude)461a956450eSArgyrios Kyrtzidis TEST_F(SourceManagerTest, isBeforeInTranslationUnitWithMacroInInclude) {
462a956450eSArgyrios Kyrtzidis const char *header =
463349a624aSVedant Kumar "#define MACRO_IN_INCLUDE 0\n"
464349a624aSVedant Kumar "#define MACRO_DEFINED\n"
465349a624aSVedant Kumar "#undef MACRO_DEFINED\n"
466349a624aSVedant Kumar "#undef MACRO_UNDEFINED\n";
467a956450eSArgyrios Kyrtzidis
468a956450eSArgyrios Kyrtzidis const char *main =
469a956450eSArgyrios Kyrtzidis "#define M(x) x\n"
470a956450eSArgyrios Kyrtzidis "#define INC \"/test-header.h\"\n"
471a956450eSArgyrios Kyrtzidis "#include M(INC)\n"
472a956450eSArgyrios Kyrtzidis "#define INC2 </test-header.h>\n"
473a956450eSArgyrios Kyrtzidis "#include M(INC2)\n";
474a956450eSArgyrios Kyrtzidis
475b214cbc7SJames Y Knight std::unique_ptr<llvm::MemoryBuffer> HeaderBuf =
476b214cbc7SJames Y Knight llvm::MemoryBuffer::getMemBuffer(header);
477b214cbc7SJames Y Knight std::unique_ptr<llvm::MemoryBuffer> MainBuf =
478b214cbc7SJames Y Knight llvm::MemoryBuffer::getMemBuffer(main);
47950a5f97eSDavid Blaikie SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(MainBuf)));
480a956450eSArgyrios Kyrtzidis
481a956450eSArgyrios Kyrtzidis const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
482d87f8d76SRafael Espindola HeaderBuf->getBufferSize(), 0);
48349cc3181SDavid Blaikie SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
484a956450eSArgyrios Kyrtzidis
4855d2ed489SRichard Smith TrivialModuleLoader ModLoader;
4869c28cb3fSDavid Blaikie HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
4879c28cb3fSDavid Blaikie Diags, LangOpts, &*Target);
488e3041688SDavid Blaikie Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
4898bef5cd4SDuncan P. N. Exon Smith SourceMgr, HeaderInfo, ModLoader,
490416fa34bSCraig Topper /*IILookup =*/nullptr,
4911ae02f68SAlp Toker /*OwnsHeaderSearch =*/false);
4921ae02f68SAlp Toker PP.Initialize(*Target);
493a956450eSArgyrios Kyrtzidis
494a956450eSArgyrios Kyrtzidis std::vector<MacroAction> Macros;
4952b3d49b6SJonas Devlieghere PP.addPPCallbacks(std::make_unique<MacroTracker>(Macros));
496a956450eSArgyrios Kyrtzidis
497a956450eSArgyrios Kyrtzidis PP.EnterMainSourceFile();
498a956450eSArgyrios Kyrtzidis
499a956450eSArgyrios Kyrtzidis std::vector<Token> toks;
500a956450eSArgyrios Kyrtzidis while (1) {
501a956450eSArgyrios Kyrtzidis Token tok;
502a956450eSArgyrios Kyrtzidis PP.Lex(tok);
503a956450eSArgyrios Kyrtzidis if (tok.is(tok::eof))
504a956450eSArgyrios Kyrtzidis break;
505a956450eSArgyrios Kyrtzidis toks.push_back(tok);
506a956450eSArgyrios Kyrtzidis }
507a956450eSArgyrios Kyrtzidis
508a956450eSArgyrios Kyrtzidis // Make sure we got the tokens that we expected.
509a956450eSArgyrios Kyrtzidis ASSERT_EQ(0U, toks.size());
510a956450eSArgyrios Kyrtzidis
511349a624aSVedant Kumar ASSERT_EQ(15U, Macros.size());
512a956450eSArgyrios Kyrtzidis // #define M(x) x
513349a624aSVedant Kumar ASSERT_TRUE(Macros[0].isDefinition());
514a956450eSArgyrios Kyrtzidis ASSERT_EQ("M", Macros[0].Name);
515a956450eSArgyrios Kyrtzidis // #define INC "/test-header.h"
516349a624aSVedant Kumar ASSERT_TRUE(Macros[1].isDefinition());
517a956450eSArgyrios Kyrtzidis ASSERT_EQ("INC", Macros[1].Name);
518a956450eSArgyrios Kyrtzidis // M expansion in #include M(INC)
519349a624aSVedant Kumar ASSERT_FALSE(Macros[2].isDefinition());
520a956450eSArgyrios Kyrtzidis ASSERT_EQ("M", Macros[2].Name);
521a956450eSArgyrios Kyrtzidis // INC expansion in #include M(INC)
522349a624aSVedant Kumar ASSERT_TRUE(Macros[3].isExpansion());
523a956450eSArgyrios Kyrtzidis ASSERT_EQ("INC", Macros[3].Name);
524a956450eSArgyrios Kyrtzidis // #define MACRO_IN_INCLUDE 0
525349a624aSVedant Kumar ASSERT_TRUE(Macros[4].isDefinition());
526a956450eSArgyrios Kyrtzidis ASSERT_EQ("MACRO_IN_INCLUDE", Macros[4].Name);
527349a624aSVedant Kumar // #define MACRO_DEFINED
528349a624aSVedant Kumar ASSERT_TRUE(Macros[5].isDefinition());
529349a624aSVedant Kumar ASSERT_FALSE(Macros[5].isUnDefinition());
530349a624aSVedant Kumar ASSERT_EQ("MACRO_DEFINED", Macros[5].Name);
531349a624aSVedant Kumar // #undef MACRO_DEFINED
532349a624aSVedant Kumar ASSERT_TRUE(Macros[6].isDefinition());
533349a624aSVedant Kumar ASSERT_TRUE(Macros[6].isUnDefinition());
534349a624aSVedant Kumar ASSERT_EQ("MACRO_DEFINED", Macros[6].Name);
535349a624aSVedant Kumar // #undef MACRO_UNDEFINED
536349a624aSVedant Kumar ASSERT_FALSE(Macros[7].isDefinition());
537349a624aSVedant Kumar ASSERT_TRUE(Macros[7].isUnDefinition());
538349a624aSVedant Kumar ASSERT_EQ("MACRO_UNDEFINED", Macros[7].Name);
539a956450eSArgyrios Kyrtzidis // #define INC2 </test-header.h>
540349a624aSVedant Kumar ASSERT_TRUE(Macros[8].isDefinition());
541349a624aSVedant Kumar ASSERT_EQ("INC2", Macros[8].Name);
542a956450eSArgyrios Kyrtzidis // M expansion in #include M(INC2)
543349a624aSVedant Kumar ASSERT_FALSE(Macros[9].isDefinition());
544349a624aSVedant Kumar ASSERT_EQ("M", Macros[9].Name);
545a956450eSArgyrios Kyrtzidis // INC2 expansion in #include M(INC2)
546349a624aSVedant Kumar ASSERT_TRUE(Macros[10].isExpansion());
547349a624aSVedant Kumar ASSERT_EQ("INC2", Macros[10].Name);
548a956450eSArgyrios Kyrtzidis // #define MACRO_IN_INCLUDE 0
549349a624aSVedant Kumar ASSERT_TRUE(Macros[11].isDefinition());
550349a624aSVedant Kumar ASSERT_EQ("MACRO_IN_INCLUDE", Macros[11].Name);
551a956450eSArgyrios Kyrtzidis
552a956450eSArgyrios Kyrtzidis // The INC expansion in #include M(INC) comes before the first
553a956450eSArgyrios Kyrtzidis // MACRO_IN_INCLUDE definition of the included file.
554a956450eSArgyrios Kyrtzidis EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[3].Loc, Macros[4].Loc));
555a956450eSArgyrios Kyrtzidis
556a956450eSArgyrios Kyrtzidis // The INC2 expansion in #include M(INC2) comes before the second
557a956450eSArgyrios Kyrtzidis // MACRO_IN_INCLUDE definition of the included file.
558349a624aSVedant Kumar EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(Macros[10].Loc, Macros[11].Loc));
559a956450eSArgyrios Kyrtzidis }
560a956450eSArgyrios Kyrtzidis
TEST_F(SourceManagerTest,isMainFile)56111d612acSAlex Lorenz TEST_F(SourceManagerTest, isMainFile) {
56211d612acSAlex Lorenz const char *Source = "int x;";
56311d612acSAlex Lorenz
56411d612acSAlex Lorenz std::unique_ptr<llvm::MemoryBuffer> Buf =
56511d612acSAlex Lorenz llvm::MemoryBuffer::getMemBuffer(Source);
56611d612acSAlex Lorenz const FileEntry *SourceFile =
56711d612acSAlex Lorenz FileMgr.getVirtualFile("mainFile.cpp", Buf->getBufferSize(), 0);
56811d612acSAlex Lorenz SourceMgr.overrideFileContents(SourceFile, std::move(Buf));
56911d612acSAlex Lorenz
57011d612acSAlex Lorenz std::unique_ptr<llvm::MemoryBuffer> Buf2 =
57111d612acSAlex Lorenz llvm::MemoryBuffer::getMemBuffer(Source);
57211d612acSAlex Lorenz const FileEntry *SecondFile =
57311d612acSAlex Lorenz FileMgr.getVirtualFile("file2.cpp", Buf2->getBufferSize(), 0);
57411d612acSAlex Lorenz SourceMgr.overrideFileContents(SecondFile, std::move(Buf2));
57511d612acSAlex Lorenz
57611d612acSAlex Lorenz FileID MainFileID = SourceMgr.getOrCreateFileID(SourceFile, SrcMgr::C_User);
57711d612acSAlex Lorenz SourceMgr.setMainFileID(MainFileID);
57811d612acSAlex Lorenz
579168db924SDuncan P. N. Exon Smith EXPECT_TRUE(SourceMgr.isMainFile(*SourceFile));
580168db924SDuncan P. N. Exon Smith EXPECT_TRUE(SourceMgr.isMainFile(*SourceFile));
581168db924SDuncan P. N. Exon Smith EXPECT_FALSE(SourceMgr.isMainFile(*SecondFile));
58211d612acSAlex Lorenz }
58311d612acSAlex Lorenz
584e841c901SArgyrios Kyrtzidis #endif
585e841c901SArgyrios Kyrtzidis
5862403797eSArgyrios Kyrtzidis } // anonymous namespace
587