19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/Optional.h" 21 #include "llvm/ADT/None.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/Support/Allocator.h" 27 #include "llvm/Support/Capacity.h" 28 #include "llvm/Support/Compiler.h" 29 #include "llvm/Support/ErrorHandling.h" 30 #include "llvm/Support/FileSystem.h" 31 #include "llvm/Support/MathExtras.h" 32 #include "llvm/Support/MemoryBuffer.h" 33 #include "llvm/Support/Path.h" 34 #include "llvm/Support/raw_ostream.h" 44 using namespace clang;
45 using namespace SrcMgr;
46 using llvm::MemoryBuffer;
54 delete Buffer.getPointer();
60 return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
66 assert(Buffer.getPointer());
69 if (!Buffer.getPointer())
70 return llvm::MemoryBuffer::MemoryBuffer_Malloc;
72 const llvm::MemoryBuffer *buf = Buffer.getPointer();
73 return buf->getBufferKind();
81 return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize()
86 if (B && B == Buffer.getPointer()) {
87 assert(0 &&
"Replacing with the same buffer");
88 Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
93 delete Buffer.getPointer();
95 Buffer.setInt((B && DoNotFree) ? DoNotFreeFlag : 0);
102 const char *InvalidBOM =
103 llvm::StringSwitch<const char *>(BufStr)
104 .StartsWith(llvm::StringLiteral::withInnerNUL(
"\x00\x00\xFE\xFF"),
106 .StartsWith(llvm::StringLiteral::withInnerNUL(
"\xFF\xFE\x00\x00"),
108 .StartsWith(
"\xFE\xFF",
"UTF-16 (BE)")
109 .StartsWith(
"\xFF\xFE",
"UTF-16 (LE)")
110 .StartsWith(
"\x2B\x2F\x76",
"UTF-7")
111 .StartsWith(
"\xF7\x64\x4C",
"UTF-1")
112 .StartsWith(
"\xDD\x73\x66\x73",
"UTF-EBCDIC")
113 .StartsWith(
"\x0E\xFE\xFF",
"SCSU")
114 .StartsWith(
"\xFB\xEE\x28",
"BOCU-1")
115 .StartsWith(
"\x84\x31\x95\x33",
"GB-18030")
124 bool *Invalid)
const {
131 return Buffer.getPointer();
152 Diag.
Report(Loc, diag::err_file_too_large)
155 Buffer.setInt(Buffer.getInt() | InvalidFlag);
156 if (Invalid) *Invalid =
true;
157 return Buffer.getPointer();
172 if (!BufferOrError) {
173 StringRef FillStr(
"<<<MISSING SOURCE FILE>>>\n");
174 auto BackupBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
176 char *Ptr = BackupBuffer->getBufferStart();
178 Ptr[i] = FillStr[i % FillStr.size()];
179 Buffer.setPointer(BackupBuffer.release());
184 BufferOrError.getError().message());
186 Diag.
Report(Loc, diag::err_cannot_open_file)
189 Buffer.setInt(Buffer.getInt() | InvalidFlag);
191 if (Invalid) *Invalid =
true;
192 return Buffer.getPointer();
195 Buffer.setPointer(BufferOrError->release());
204 Diag.
Report(Loc, diag::err_file_modified)
207 Buffer.setInt(Buffer.getInt() | InvalidFlag);
208 if (Invalid) *Invalid =
true;
209 return Buffer.getPointer();
215 StringRef BufStr = Buffer.getPointer()->getBuffer();
219 Diag.
Report(Loc, diag::err_unsupported_bom)
221 Buffer.setInt(Buffer.getInt() | InvalidFlag);
227 return Buffer.getPointer();
231 auto IterBool = FilenameIDs.try_emplace(Name, FilenamesByID.size());
233 FilenamesByID.push_back(&*IterBool.first);
234 return IterBool.first->second;
244 int FilenameID,
unsigned EntryExit,
246 std::vector<LineEntry> &Entries = LineEntries[FID];
250 if (FilenameID == -1 && !Entries.empty())
251 FilenameID = Entries.back().FilenameID;
253 assert((Entries.empty() || Entries.back().FileOffset <
Offset) &&
254 "Adding line entries out of order!");
256 unsigned IncludeOffset = 0;
257 if (EntryExit == 0) {
258 IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
259 }
else if (EntryExit == 1) {
260 IncludeOffset = Offset-1;
261 }
else if (EntryExit == 2) {
262 assert(!Entries.empty() && Entries.back().IncludeOffset &&
263 "PPDirectives should have caught case when popping empty include stack");
268 FindNearestLineEntry(FID, Entries.back().IncludeOffset))
269 IncludeOffset = PrevEntry->IncludeOffset;
272 Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, FileKind,
280 const std::vector<LineEntry> &Entries = LineEntries[FID];
281 assert(!Entries.empty() &&
"No #line entries for this FID after all!");
285 if (Entries.back().FileOffset <=
Offset)
286 return &Entries.back();
289 std::vector<LineEntry>::const_iterator I = llvm::upper_bound(Entries, Offset);
290 if (I == Entries.begin())
298 const std::vector<LineEntry> &Entries) {
299 LineEntries[FID] = Entries;
304 return getLineTable().getLineTableFilenameID(Name);
311 int FilenameID,
bool IsFileEntry,
314 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
316 bool Invalid =
false;
317 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
318 if (!Entry.
isFile() || Invalid)
326 (void) getLineTable();
328 unsigned EntryExit = 0;
334 LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
335 EntryExit, FileKind);
349 bool UserFilesAreVolatile)
350 : Diag(Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) {
359 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
360 if (MemBufferInfos[i]) {
361 MemBufferInfos[i]->~ContentCache();
362 ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
365 for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
366 I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
368 I->second->~ContentCache();
369 ContentCacheAlloc.Deallocate(I->second);
376 LocalSLocEntryTable.clear();
377 LoadedSLocEntryTable.clear();
378 SLocEntryLoaded.clear();
379 LastLineNoFileIDQuery =
FileID();
380 LastLineNoContentCache =
nullptr;
381 LastFileIDLookup =
FileID();
388 CurrentLoadedOffset = MaxLoadedOffset;
393 assert(MainFileID.
isInvalid() &&
"expected uninitialized SourceManager");
398 Clone->ContentsEntry =
Cache->ContentsEntry;
399 Clone->BufferOverridden =
Cache->BufferOverridden;
400 Clone->IsFileVolatile =
Cache->IsFileVolatile;
401 Clone->IsTransient =
Cache->IsTransient;
402 Clone->replaceBuffer(
Cache->getRawBuffer(),
true);
407 for (
unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
408 if (!Old.SLocEntryLoaded[I])
409 Old.loadSLocEntry(I,
nullptr);
412 for (
auto &
FileInfo : Old.FileInfos) {
416 Slot = CloneContentCache(
FileInfo.second);
423 SourceManager::getOrCreateContentCache(
const FileEntry *FileEnt,
425 assert(FileEnt &&
"Didn't specify a file entry to use?");
429 if (Entry)
return Entry;
434 if (OverriddenFilesInfo) {
437 llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
438 overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
439 if (overI == OverriddenFilesInfo->OverriddenFiles.end())
442 new (Entry)
ContentCache(OverridenFilesKeepOriginalName ? FileEnt
458 SourceManager::createMemBufferContentCache(
const llvm::MemoryBuffer *Buffer,
463 MemBufferInfos.push_back(Entry);
469 bool *Invalid)
const {
470 assert(!SLocEntryLoaded[Index]);
471 if (ExternalSLocEntries->
ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
475 if (!SLocEntryLoaded[Index]) {
477 LoadedSLocEntryTable[Index] = SLocEntry::get(
478 0, FileInfo::get(
SourceLocation(), getFakeContentCacheForRecovery(),
483 return LoadedSLocEntryTable[Index];
486 std::pair<int, unsigned>
488 unsigned TotalSize) {
489 assert(ExternalSLocEntries &&
"Don't have an external sloc source");
491 if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
492 return std::make_pair(0, 0);
493 LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
494 SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
495 CurrentLoadedOffset -= TotalSize;
496 int ID = LoadedSLocEntryTable.size();
497 return std::make_pair(-ID - 1, CurrentLoadedOffset);
502 llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery()
const {
503 if (!FakeBufferForRecovery)
504 FakeBufferForRecovery =
505 llvm::MemoryBuffer::getMemBuffer(
"<<<INVALID BUFFER>>");
507 return FakeBufferForRecovery.get();
513 SourceManager::getFakeContentCacheForRecovery()
const {
514 if (!FakeContentCacheForRecovery) {
515 FakeContentCacheForRecovery = std::make_unique<SrcMgr::ContentCache>();
516 FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
519 return FakeContentCacheForRecovery.get();
524 FileID SourceManager::getPreviousFileID(
FileID FID)
const {
535 }
else if (
unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
539 return FileID::get(ID-1);
552 }
else if (ID+1 >= -1) {
556 return FileID::get(ID+1);
569 int LoadedID,
unsigned LoadedOffset) {
571 assert(LoadedID != -1 &&
"Loading sentinel FileID");
572 unsigned Index = unsigned(-LoadedID) - 2;
573 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
574 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
575 LoadedSLocEntryTable[Index] = SLocEntry::get(
576 LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter,
Filename));
577 SLocEntryLoaded[Index] =
true;
578 return FileID::get(LoadedID);
580 LocalSLocEntryTable.push_back(
581 SLocEntry::get(NextLocalOffset,
582 FileInfo::get(IncludePos, File, FileCharacter,
Filename)));
583 unsigned FileSize = File->
getSize();
584 assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
585 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
586 "Ran out of source locations!");
589 NextLocalOffset += FileSize + 1;
593 FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
594 return LastFileIDLookup = FID;
600 unsigned TokLength) {
601 ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
603 return createExpansionLocImpl(Info, TokLength);
611 bool ExpansionIsTokenRange,
613 unsigned LoadedOffset) {
615 SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange);
616 return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
623 "token spans multiple files");
624 return createExpansionLocImpl(
625 ExpansionInfo::createForTokenSplit(Spelling, TokenStart, TokenEnd),
626 TokenEnd.getOffset() - TokenStart.getOffset());
630 SourceManager::createExpansionLocImpl(
const ExpansionInfo &Info,
633 unsigned LoadedOffset) {
635 assert(LoadedID != -1 &&
"Loading sentinel FileID");
636 unsigned Index = unsigned(-LoadedID) - 2;
637 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
638 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
639 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
640 SLocEntryLoaded[Index] =
true;
641 return SourceLocation::getMacroLoc(LoadedOffset);
643 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
644 assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
645 NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
646 "Ran out of source locations!");
648 NextLocalOffset += TokLength + 1;
649 return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
652 const llvm::MemoryBuffer *
655 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
660 llvm::MemoryBuffer *Buffer,
663 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
668 getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
674 "Different sizes, use the FileManager to create a virtual file with " 676 assert(FileInfos.count(SourceFile) == 0 &&
677 "This function should be called at the initialization stage, before " 678 "any parsing occurs.");
679 getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
692 const FileEntry *FE = &BypassFile->getFileEntry();
693 (void)getOrCreateContentCache(FE);
703 bool MyInvalid =
false;
705 if (!SLoc.
isFile() || MyInvalid) {
708 return "<<<<<INVALID SOURCE LOCATION>>>>>";
714 *Invalid = MyInvalid;
717 return "<<<<<INVALID SOURCE LOCATION>>>>>";
719 return Buf->getBuffer();
731 FileID SourceManager::getFileIDSlow(
unsigned SLocOffset)
const {
733 return FileID::get(0);
737 if (SLocOffset < NextLocalOffset)
738 return getFileIDLocal(SLocOffset);
739 return getFileIDLoaded(SLocOffset);
746 FileID SourceManager::getFileIDLocal(
unsigned SLocOffset)
const {
747 assert(SLocOffset < NextLocalOffset &&
"Bad function choice");
762 if (LastFileIDLookup.ID < 0 ||
763 LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
765 I = LocalSLocEntryTable.end();
768 I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
773 unsigned NumProbes = 0;
777 FileID Res = FileID::get(
int(I - LocalSLocEntryTable.begin()));
782 LastFileIDLookup = Res;
783 NumLinearScans += NumProbes+1;
786 if (++NumProbes == 8)
792 unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
796 unsigned LessIndex = 0;
799 bool Invalid =
false;
800 unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
803 return FileID::get(0);
809 if (MidOffset > SLocOffset) {
810 GreaterIndex = MiddleIndex;
817 if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
818 FileID Res = FileID::get(MiddleIndex);
822 if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
823 LastFileIDLookup = Res;
824 NumBinaryProbes += NumProbes;
829 LessIndex = MiddleIndex;
837 FileID SourceManager::getFileIDLoaded(
unsigned SLocOffset)
const {
839 if (SLocOffset < CurrentLoadedOffset) {
840 assert(0 &&
"Invalid SLocOffset or bad function choice");
849 int LastID = LastFileIDLookup.ID;
850 if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
853 I = (-LastID - 2) + 1;
856 for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) {
860 FileID Res = FileID::get(-
int(I) - 2);
863 LastFileIDLookup = Res;
864 NumLinearScans += NumProbes + 1;
872 unsigned GreaterIndex = I;
873 unsigned LessIndex = LoadedSLocEntryTable.size();
877 unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
886 if (GreaterIndex == MiddleIndex) {
887 assert(0 &&
"binary search missed the entry");
890 GreaterIndex = MiddleIndex;
894 if (isOffsetInFileID(FileID::get(-
int(MiddleIndex) - 2), SLocOffset)) {
895 FileID Res = FileID::get(-
int(MiddleIndex) - 2);
897 LastFileIDLookup = Res;
898 NumBinaryProbes += NumProbes;
903 if (LessIndex == MiddleIndex) {
904 assert(0 &&
"binary search missed the entry");
907 LessIndex = MiddleIndex;
946 std::pair<FileID, unsigned>
947 SourceManager::getDecomposedExpansionLocSlowCase(
961 return std::make_pair(FID, Offset);
964 std::pair<FileID, unsigned>
979 return std::make_pair(FID, Offset);
997 assert(Loc.
isMacroID() &&
"Not a macro expansion loc!");
1054 if (DecompLoc.second > 0)
1057 bool Invalid =
false;
1068 FileID PrevFID = getPreviousFileID(DecompLoc.first);
1080 *MacroBegin = ExpLoc;
1093 bool Invalid =
false;
1103 FileID NextFID = getNextFileID(FID);
1127 bool *Invalid)
const {
1133 bool CharDataInvalid =
false;
1135 if (CharDataInvalid || !Entry.
isFile()) {
1139 return "<<<<INVALID BUFFER>>>>";
1141 const llvm::MemoryBuffer *Buffer =
1145 *Invalid = CharDataInvalid;
1146 return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
1152 bool *Invalid)
const {
1153 bool MyInvalid =
false;
1154 const llvm::MemoryBuffer *MemBuf =
getBuffer(FID, &MyInvalid);
1156 *Invalid = MyInvalid;
1162 if (FilePos > MemBuf->getBufferSize()) {
1168 const char *Buf = MemBuf->getBufferStart();
1171 if (LastLineNoFileIDQuery == FID &&
1173 LastLineNoResult < LastLineNoContentCache->NumLines) {
1175 unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1176 unsigned LineEnd = SourceLineCache[LastLineNoResult];
1177 if (FilePos >= LineStart && FilePos < LineEnd) {
1182 if (FilePos + 1 == LineEnd && FilePos > LineStart) {
1183 if (Buf[FilePos - 1] ==
'\r' || Buf[FilePos - 1] ==
'\n')
1186 return FilePos - LineStart + 1;
1190 unsigned LineStart = FilePos;
1191 while (LineStart && Buf[LineStart-1] !=
'\n' && Buf[LineStart-1] !=
'\r')
1193 return FilePos-LineStart+1;
1198 template<
typename LocType>
1200 bool MyInvalid = Loc.isInvalid();
1202 *Invalid = MyInvalid;
1207 bool *Invalid)
const {
1214 bool *Invalid)
const {
1221 bool *Invalid)
const {
1228 #include <emmintrin.h> 1231 static LLVM_ATTRIBUTE_NOINLINE
void 1233 llvm::BumpPtrAllocator &Alloc,
1236 llvm::BumpPtrAllocator &Alloc,
1239 const MemoryBuffer *Buffer =
1249 LineOffsets.push_back(0);
1251 const unsigned char *Buf = (
const unsigned char *)Buffer->getBufferStart();
1252 const unsigned char *
End = (
const unsigned char *)Buffer->getBufferEnd();
1255 while (I < BufLen) {
1256 if (Buf[I] ==
'\n') {
1257 LineOffsets.push_back(I + 1);
1258 }
else if (Buf[I] ==
'\r') {
1260 if (I + 1 < BufLen && Buf[I + 1] ==
'\n')
1262 LineOffsets.push_back(I + 1);
1270 std::copy(LineOffsets.begin(), LineOffsets.end(), FI->
SourceLineCache);
1278 bool *Invalid)
const {
1286 if (LastLineNoFileIDQuery == FID)
1287 Content = LastLineNoContentCache;
1289 bool MyInvalid =
false;
1291 if (MyInvalid || !Entry.
isFile()) {
1303 bool MyInvalid =
false;
1306 *Invalid = MyInvalid;
1315 unsigned *SourceLineCacheStart = SourceLineCache;
1316 unsigned *SourceLineCacheEnd = SourceLineCache + Content->
NumLines;
1318 unsigned QueriedFilePos = FilePos+1;
1333 if (LastLineNoFileIDQuery == FID) {
1334 if (QueriedFilePos >= LastLineNoFilePos) {
1336 SourceLineCache = SourceLineCache+LastLineNoResult-1;
1342 if (SourceLineCache+5 < SourceLineCacheEnd) {
1343 if (SourceLineCache[5] > QueriedFilePos)
1344 SourceLineCacheEnd = SourceLineCache+5;
1345 else if (SourceLineCache+10 < SourceLineCacheEnd) {
1346 if (SourceLineCache[10] > QueriedFilePos)
1347 SourceLineCacheEnd = SourceLineCache+10;
1348 else if (SourceLineCache+20 < SourceLineCacheEnd) {
1349 if (SourceLineCache[20] > QueriedFilePos)
1350 SourceLineCacheEnd = SourceLineCache+20;
1355 if (LastLineNoResult < Content->NumLines)
1356 SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1361 = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1362 unsigned LineNo = Pos-SourceLineCacheStart;
1364 LastLineNoFileIDQuery = FID;
1365 LastLineNoContentCache = Content;
1366 LastLineNoFilePos = QueriedFilePos;
1367 LastLineNoResult = LineNo;
1372 bool *Invalid)
const {
1378 bool *Invalid)
const {
1384 bool *Invalid)
const {
1400 assert(Loc.
isValid() &&
"Can't get file characteristic of invalid loc!");
1402 bool Invalid =
false;
1404 if (Invalid || !SEntry.
isFile())
1414 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1417 LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second);
1430 bool *Invalid)
const {
1431 if (
isInvalid(Loc, Invalid))
return "<invalid loc>";
1444 bool UseLineDirectives)
const {
1450 bool Invalid =
false;
1452 if (Invalid || !Entry.
isFile())
1461 FileID FID = LocInfo.first;
1468 unsigned LineNo =
getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1471 unsigned ColNo =
getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1480 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1483 LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) {
1485 if (Entry->FilenameID != -1) {
1486 Filename = LineTable->getFilename(Entry->FilenameID);
1489 FID = FileID::get(0);
1496 unsigned MarkerLineNo =
getLineNumber(LocInfo.first, Entry->FileOffset);
1497 LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1502 if (Entry->IncludeOffset) {
1509 return PresumedLoc(Filename.data(), FID, LineNo, ColNo, IncludeLoc);
1525 bool Invalid =
false;
1527 if (Invalid || !Entry.
isFile())
1535 LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second))
1536 if (Entry->IncludeOffset)
1544 bool Invalid =
false;
1550 unsigned NextOffset;
1553 else if (ID+1 == -1)
1554 NextOffset = MaxLoadedOffset;
1558 return NextOffset - Entry.
getOffset() - 1;
1571 unsigned Col)
const {
1572 assert(SourceFile &&
"Null source file!");
1573 assert(Line && Col &&
"Line and column should start from 1!");
1584 assert(SourceFile &&
"Null source file!");
1589 bool Invalid =
false;
1597 if (MainContentCache && MainContentCache->
OrigEntry == SourceFile)
1605 bool Invalid =
false;
1612 return FileID::get(I);
1620 return FileID::get(-
int(I) - 2);
1630 unsigned Col)
const {
1633 assert(Line && Col &&
"Line and column should start from 1!");
1638 bool Invalid =
false;
1648 if (Line == 1 && Col == 1)
1659 bool MyInvalid =
false;
1674 const char *Buf = Buffer->getBufferStart() + FilePos;
1675 unsigned BufLength = Buffer->getBufferSize() - FilePos;
1682 while (i < BufLength-1 && i < Col-1 && Buf[i] !=
'\n' && Buf[i] !=
'\r')
1694 void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
1708 }
else if (ID == -1) {
1712 bool Invalid =
false;
1725 if (Entry.
getFile().NumCreatedFIDs)
1726 ID += Entry.
getFile().NumCreatedFIDs - 1;
1740 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1742 SourceLocation::getMacroLoc(Entry.
getOffset()),
1747 void SourceManager::associateFileChunkWithMacroArgExp(
1748 MacroArgsMap &MacroArgsCache,
1752 unsigned ExpansionLength)
const {
1754 unsigned SpellBeginOffs = SpellLoc.getOffset();
1755 unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
1763 unsigned SpellRelativeOffs;
1767 unsigned SpellFIDBeginOffs = Entry.
getOffset();
1769 unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1772 unsigned CurrSpellLength;
1773 if (SpellFIDEndOffs < SpellEndOffs)
1774 CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1776 CurrSpellLength = ExpansionLength;
1777 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1779 ExpansionLoc, CurrSpellLength);
1782 if (SpellFIDEndOffs >= SpellEndOffs)
1786 unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1788 ExpansionLength -= advance;
1790 SpellRelativeOffs = 0;
1800 unsigned EndOffs = BeginOffs + ExpansionLength;
1819 MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1822 MacroArgsCache[BeginOffs] = ExpansionLoc;
1823 MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1846 std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
1847 if (!MacroArgsCache) {
1848 MacroArgsCache = std::make_unique<MacroArgsMap>();
1849 computeMacroArgsCache(*MacroArgsCache, FID);
1852 assert(!MacroArgsCache->empty());
1853 MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1856 unsigned MacroArgBeginOffs = I->first;
1858 if (MacroArgExpandedLoc.
isValid())
1864 std::pair<FileID, unsigned>
1867 return std::make_pair(
FileID(), 0);
1871 using DecompTy = std::pair<FileID, unsigned>;
1872 auto InsertOp = IncludedLocMap.try_emplace(FID);
1873 DecompTy &DecompLoc = InsertOp.first->second;
1874 if (!InsertOp.second)
1878 bool Invalid =
false;
1900 if (UpperLoc.first.isInvalid())
1914 enum { MagicCacheSize = 300 };
1915 IsBeforeInTUCacheKey Key(LFID, RFID);
1921 if (IBTUCache.size() < MagicCacheSize)
1922 return IBTUCache[Key];
1925 InBeforeInTUCache::iterator I = IBTUCache.find(Key);
1926 if (I != IBTUCache.end())
1930 return IBTUCacheOverflow;
1938 assert(LHS.
isValid() && RHS.
isValid() &&
"Passed invalid source location!");
1948 if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
1949 return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
1953 return InSameTU.second;
1958 StringRef LB =
getBuffer(LOffs.first)->getBufferIdentifier();
1959 StringRef RB =
getBuffer(ROffs.first)->getBufferIdentifier();
1960 bool LIsBuiltins = LB ==
"<built-in>";
1961 bool RIsBuiltins = RB ==
"<built-in>";
1963 if (LIsBuiltins || RIsBuiltins) {
1964 if (LIsBuiltins != RIsBuiltins)
1968 return LOffs.first < ROffs.first;
1970 bool LIsAsm = LB ==
"<inline asm>";
1971 bool RIsAsm = RB ==
"<inline asm>";
1973 if (LIsAsm || RIsAsm) {
1974 if (LIsAsm != RIsAsm)
1976 assert(LOffs.first == ROffs.first);
1979 bool LIsScratch = LB ==
"<scratch space>";
1980 bool RIsScratch = RB ==
"<scratch space>";
1982 if (LIsScratch || RIsScratch) {
1983 if (LIsScratch != RIsScratch)
1985 return LOffs.second < ROffs.second;
1987 llvm_unreachable(
"Unsortable locations found");
1991 std::pair<FileID, unsigned> &LOffs,
1992 std::pair<FileID, unsigned> &ROffs)
const {
1994 if (LOffs.first == ROffs.first)
1995 return std::make_pair(
true, LOffs.second < ROffs.second);
2000 getInBeforeInTUCache(LOffs.first, ROffs.first);
2004 if (IsBeforeInTUCache.
isCacheValid(LOffs.first, ROffs.first))
2005 return std::make_pair(
2009 IsBeforeInTUCache.
setQueryFIDs(LOffs.first, ROffs.first,
2010 LOffs.first.ID < ROffs.first.ID);
2017 using LocSet = llvm::SmallDenseMap<FileID, unsigned, 16>;
2020 LChain.insert(LOffs);
2025 while((I = LChain.find(ROffs.first)) == LChain.end()) {
2029 if (I != LChain.end())
2034 if (LOffs.first == ROffs.first) {
2035 IsBeforeInTUCache.
setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
2036 return std::make_pair(
2040 IsBeforeInTUCache.
clear();
2041 return std::make_pair(
false,
false);
2045 llvm::errs() <<
"\n*** Source Manager Stats:\n";
2046 llvm::errs() << FileInfos.size() <<
" files mapped, " << MemBufferInfos.size()
2047 <<
" mem buffers mapped.\n";
2048 llvm::errs() << LocalSLocEntryTable.size() <<
" local SLocEntry's allocated (" 2049 << llvm::capacity_in_bytes(LocalSLocEntryTable)
2050 <<
" bytes of capacity), " 2051 << NextLocalOffset <<
"B of Sloc address space used.\n";
2052 llvm::errs() << LoadedSLocEntryTable.size()
2053 <<
" loaded SLocEntries allocated, " 2054 << MaxLoadedOffset - CurrentLoadedOffset
2055 <<
"B of Sloc address space used.\n";
2057 unsigned NumLineNumsComputed = 0;
2058 unsigned NumFileBytesMapped = 0;
2060 NumLineNumsComputed += I->second->SourceLineCache !=
nullptr;
2061 NumFileBytesMapped += I->second->getSizeBytesMapped();
2063 unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2065 llvm::errs() << NumFileBytesMapped <<
" bytes of files mapped, " 2066 << NumLineNumsComputed <<
" files with line #'s computed, " 2067 << NumMacroArgsComputed <<
" files with macro args computed.\n";
2068 llvm::errs() <<
"FileID scans: " << NumLinearScans <<
" linear, " 2069 << NumBinaryProbes <<
" binary.\n";
2073 llvm::raw_ostream &out = llvm::errs();
2077 out <<
"SLocEntry <FileID " << ID <<
"> " << (Entry.isFile() ?
"file" :
"expansion")
2078 <<
" <SourceLocation " << Entry.getOffset() <<
":";
2080 out << *NextStart <<
">\n";
2083 if (Entry.isFile()) {
2084 auto &FI = Entry.getFile();
2085 if (FI.NumCreatedFIDs)
2086 out <<
" covers <FileID " << ID <<
":" << int(ID + FI.NumCreatedFIDs)
2088 if (FI.getIncludeLoc().isValid())
2089 out <<
" included from " << FI.getIncludeLoc().getOffset() <<
"\n";
2090 if (
auto *CC = FI.getContentCache()) {
2091 out <<
" for " << (CC->OrigEntry ? CC->OrigEntry->getName() :
"<none>")
2093 if (CC->BufferOverridden)
2094 out <<
" contents overridden\n";
2095 if (CC->ContentsEntry != CC->OrigEntry) {
2096 out <<
" contents from " 2097 << (CC->ContentsEntry ? CC->ContentsEntry->getName() :
"<none>")
2102 auto &EI = Entry.getExpansion();
2103 out <<
" spelling from " << EI.getSpellingLoc().getOffset() <<
"\n";
2104 out <<
" macro " << (EI.isMacroArgExpansion() ?
"arg" :
"body")
2105 <<
" range <" << EI.getExpansionLocStart().getOffset() <<
":" 2106 << EI.getExpansionLocEnd().getOffset() <<
">\n";
2111 for (
unsigned ID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++
ID) {
2112 DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2113 ID == NumIDs - 1 ? NextLocalOffset
2114 : LocalSLocEntryTable[ID + 1].getOffset());
2118 for (
unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2119 int ID = -(int)Index - 2;
2120 if (SLocEntryLoaded[Index]) {
2121 DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2122 NextStart = LoadedSLocEntryTable[Index].getOffset();
2134 size_t malloc_bytes = 0;
2135 size_t mmap_bytes = 0;
2137 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2138 if (
size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2139 switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2140 case llvm::MemoryBuffer::MemoryBuffer_MMap:
2141 mmap_bytes += sized_mapped;
2143 case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2144 malloc_bytes += sized_mapped;
2152 size_t size = llvm::capacity_in_bytes(MemBufferInfos)
2153 + llvm::capacity_in_bytes(LocalSLocEntryTable)
2154 + llvm::capacity_in_bytes(LoadedSLocEntryTable)
2155 + llvm::capacity_in_bytes(SLocEntryLoaded)
2156 + llvm::capacity_in_bytes(FileInfos);
2158 if (OverriddenFilesInfo)
2159 size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
2165 StringRef Content) {
2169 new llvm::vfs::InMemoryFileSystem);
2170 InMemoryFileSystem->addFile(
2172 llvm::MemoryBuffer::getMemBuffer(Content, FileName,
2180 Diagnostics = std::make_unique<DiagnosticsEngine>(
2183 SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr);
2186 assert(ID.isValid());
2187 SourceMgr->setMainFileID(ID);
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
const FileEntry * OrigEntry
Reference to the file entry representing this ContentCache.
unsigned IsFileVolatile
True if this content cache was initially created for a source file considered to be volatile (likely ...
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
This is a discriminated union of FileInfo and ExpansionInfo.
const SrcMgr::SLocEntry & getLoadedSLocEntry(unsigned Index, bool *Invalid=nullptr) const
Get a loaded SLocEntry. This is exposed for indexing.
static bool MoveUpIncludeHierarchy(std::pair< FileID, unsigned > &Loc, const SourceManager &SM)
Given a decomposed source location, move it up the include/expansion stack to the parent source locat...
Implements support for file system lookup, file system caching, and directory search management...
SourceLocation getSpellingLoc() const
Defines the clang::FileManager interface and associated types.
void setBegin(SourceLocation b)
TypePropertyCache< Private > Cache
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
Defines the SourceManager interface.
fileinfo_iterator fileinfo_end() const
unsigned NumLines
The number of lines in this ContentCache.
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isCacheValid(FileID LHS, FileID RHS) const
Return true if the currently cached values match up with the specified LHS/RHS query.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Return the column # for the specified file position.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID)
Set up a new query.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
void setCommonLoc(FileID commonFID, unsigned lCommonOffset, unsigned rCommonOffset)
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
virtual bool ReadSLocEntry(int ID)=0
Read the source location entry with index ID, which will always be less than -1.
unsigned getLineTableFilenameID(StringRef Str)
unsigned getNextLocalOffset() const
static LLVM_ATTRIBUTE_NOINLINE void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, llvm::BumpPtrAllocator &Alloc, const SourceManager &SM, bool &Invalid)
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Used to hold and unique data used to represent #line information.
bool hasLineDirectives() const
Return true if this FileID has #line directives in it.
MemoryBufferSizes getMemoryBufferSizes() const
Return the amount of memory used by memory buffers, breaking down by heap-backed versus mmap'ed memor...
FileManager & getFileManager() const
SourceLocation getBegin() const
SourceLocation translateFileLineCol(const FileEntry *SourceFile, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
One instance of this struct is kept for every file loaded or used.
const LineEntry * FindNearestLineEntry(FileID FID, unsigned Offset)
Find the line entry nearest to FID that is before it.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
__DEVICE__ int max(int __a, int __b)
unsigned IsTransient
True if this file may be transient, that is, if it might not exist at some later point in time when t...
void setSourceManager(SourceManager *SrcMgr)
const llvm::MemoryBuffer * getRawBuffer() const
Get the underlying buffer, returning NULL if the buffer is not yet available.
bool isAtEndOfImmediateMacroExpansion(SourceLocation Loc, SourceLocation *MacroEnd=nullptr) const
Returns true if the given MacroID location points at the character end of the immediate macro expansi...
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
const FileInfo & getFile() const
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
bool isFileOverridden(const FileEntry *File) const
Returns true if the file contents have been overridden.
Concrete class used by the front-end to report problems and issues.
bool isDiagnosticInFlight() const
Determine whethere there is already a diagnostic in flight.
void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1="", StringRef Arg2="", StringRef Arg3="")
Set the "delayed" diagnostic that will be emitted once the current diagnostic completes.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Defines the Diagnostic-related interfaces.
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body. ...
void setTokenRange(bool TR)
SourceLocation getIncludeLoc() const
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
bool isMacroArgExpansion() const
unsigned getSize() const
Returns the size of the content encapsulated by this ContentCache.
unsigned getSizeBytesMapped() const
Returns the number of bytes actually mapped for this ContentCache.
SrcMgr::CharacteristicKind FileKind
Set the 0 if no flags, 1 if a system header,.
void initializeForReplay(const SourceManager &Old)
Initialize this source manager suitably to replay the compilation described by Old.
bool isBufferInvalid() const
Determine whether the buffer itself is invalid.
unsigned local_sloc_entry_size() const
Get the number of local SLocEntries we have.
std::pair< FileID, unsigned > getDecomposedIncludedLoc(FileID FID) const
Returns the "included/expanded in" decomposed location of the given FileID.
virtual ~ExternalSLocEntrySource()
void setFileIsTransient(const FileEntry *SourceFile)
Specify that a file is transient.
bool isInFileID(SourceLocation Loc, FileID FID, unsigned *RelativeOffset=nullptr) const
Given a specific FileID, returns true if Loc is inside that FileID chunk and sets relative offset (of...
CharacteristicKind getFileCharacteristic() const
Return whether this is a system header or not.
SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
Represents a character-granular source range.
const AnnotatedLine * Line
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, unsigned LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
Defines implementation details of the clang::SourceManager class.
unsigned getLine() const
Return the presumed line number of this location.
SourceLocation createMacroArgExpansionLoc(SourceLocation Loc, SourceLocation ExpansionLoc, unsigned TokLength)
Return a new SourceLocation that encodes the fact that a token from SpellingLoc should actually be re...
const FileEntry * ContentsEntry
References the file which the contents were actually loaded from.
static LineEntry get(unsigned Offs, unsigned Line, int Filename, SrcMgr::CharacteristicKind FileKind, unsigned IncludeOffset)
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
void setEnd(SourceLocation e)
bool shouldFreeBuffer() const
Determine whether the buffer should be freed.
size_t getDataStructureSizes() const
Return the amount of memory used for various side tables and data structures in the SourceManager...
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
static const char * getInvalidBOM(StringRef BufStr)
Represents an unpacked "presumed" location which can be presented to the user.
fileinfo_iterator fileinfo_begin() const
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
const ExpansionInfo & getExpansion() const
unsigned getOffset() const
void AddEntry(FileID FID, const std::vector< LineEntry > &Entries)
Add a new line entry that has already been encoded into the internal representation of the line table...
void overrideFileContents(const FileEntry *SourceFile, llvm::MemoryBuffer *Buffer, bool DoNotFree)
Override the contents of the given source file by providing an already-allocated buffer.
bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc, SourceLocation *MacroBegin=nullptr) const
Returns true if the given MacroID location points at the beginning of the immediate macro expansion...
SourceLocation getExpansionLocEnd() const
Information about a FileID, basically just the logical file that it represents and include stack info...
const ContentCache * getContentCache() const
unsigned getColumn() const
Return the presumed column number of this location.
std::pair< FileID, unsigned > getDecomposedSpellingLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Encodes a location in the source.
StringRef getName() const
SourceLocation createExpansionLoc(SourceLocation Loc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned TokLength, bool ExpansionIsTokenRange=true, int LoadedID=0, unsigned LoadedOffset=0)
Return a new SourceLocation that encodes the fact that a token from SpellingLoc should actually be re...
Options for controlling the compiler diagnostics engine.
bool getCachedResult(unsigned LOffset, unsigned ROffset) const
If the cache is valid, compute the result given the specified offsets in the LHS/RHS FileID's...
Cached information about one file (either on disk or in the virtual file system). ...
const SrcMgr::SLocEntry & getLocalSLocEntry(unsigned Index, bool *Invalid=nullptr) const
Get a local SLocEntry. This is exposed for indexing.
std::pair< bool, bool > isInTheSameTranslationUnit(std::pair< FileID, unsigned > &LOffs, std::pair< FileID, unsigned > &ROffs) const
Determines whether the two decomposed source location is in the same translation unit.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
unsigned * SourceLineCache
A bump pointer allocated array of offsets for each source line.
SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, bool UserFilesAreVolatile=false)
llvm::DenseMap< const FileEntry *, SrcMgr::ContentCache * >::const_iterator fileinfo_iterator
SourceLocation getExpansionLocStart() const
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
const FileEntry * bypassFileContentsOverride(const FileEntry &File)
Bypass the overridden contents of a file.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const
Returns the kind of memory used to back the memory buffer for this content cache. ...
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
const llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
bool isMacroBodyExpansion() const
static bool isInvalid(LocType Loc, bool *Invalid)
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree=false)
Replace the existing buffer (which will be deleted) with the given buffer.
const llvm::MemoryBuffer * getMemoryBufferForFile(const FileEntry *File, bool *Invalid=nullptr)
Retrieve the memory buffer associated with the given file.
void PrintStats() const
Print statistics to stderr.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Used for handling and querying diagnostic IDs.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table for the FileID and offset specified by Loc.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const
If Loc points inside a function macro argument, the returned location will be the macro location in w...
SourceLocation translateLineCol(FileID FID, unsigned Line, unsigned Col) const
Get the source location in FID for the given line:col.
llvm::ErrorOr< const FileEntry * > getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
Holds the cache used by isBeforeInTranslationUnit.
SourceManagerForFile(StringRef FileName, StringRef Content)
Creates SourceManager and necessary depdencies (e.g.
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
std::pair< int, unsigned > AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize)
Allocate a number of loaded SLocEntries, which will be actually loaded on demand from the external so...
SourceLocation getEnd() const
unsigned loaded_sloc_entry_size() const
Get the number of loaded SLocEntries we have.
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
Keeps track of options that affect how file operations are performed.
llvm::Optional< FileEntryRef > getBypassFile(FileEntryRef VFE)
Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual file entry, to access the real file.
Defines the clang::SourceLocation class and associated facilities.
SourceLocation createTokenSplitLoc(SourceLocation SpellingLoc, SourceLocation TokenStart, SourceLocation TokenEnd)
Return a new SourceLocation that encodes that the token starting at TokenStart ends prematurely at To...
LineTableInfo & getLineTable()
Retrieve the stored line table.
CharSourceRange getExpansionLocRange() const
A trivial tuple used to represent a source range.
void AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, int FilenameID, unsigned EntryExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table that indicates that there is a #line or GNU line marker at the spec...
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const FileEntry *Entry, bool isVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
This class handles loading and caching of source files into memory.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const llvm::MemoryBuffer * getBuffer(DiagnosticsEngine &Diag, FileManager &FM, SourceLocation Loc=SourceLocation(), bool *Invalid=nullptr) const
Returns the memory buffer for the associated content.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const