20 #include "llvm/ADT/DenseMap.h" 21 #include "llvm/ADT/Optional.h" 22 #include "llvm/ADT/None.h" 23 #include "llvm/ADT/STLExtras.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/ADT/StringSwitch.h" 26 #include "llvm/ADT/StringRef.h" 27 #include "llvm/Support/Allocator.h" 28 #include "llvm/Support/Capacity.h" 29 #include "llvm/Support/Compiler.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/FileSystem.h" 32 #include "llvm/Support/MathExtras.h" 33 #include "llvm/Support/MemoryBuffer.h" 34 #include "llvm/Support/Path.h" 35 #include "llvm/Support/raw_ostream.h" 45 using namespace clang;
46 using namespace SrcMgr;
47 using llvm::MemoryBuffer;
55 delete Buffer.getPointer();
61 return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
67 assert(Buffer.getPointer());
70 if (!Buffer.getPointer())
71 return llvm::MemoryBuffer::MemoryBuffer_Malloc;
73 llvm::MemoryBuffer *buf = Buffer.getPointer();
74 return buf->getBufferKind();
82 return Buffer.getPointer() ? (unsigned) Buffer.getPointer()->getBufferSize()
87 if (B && B == Buffer.getPointer()) {
88 assert(0 &&
"Replacing with the same buffer");
89 Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
94 delete Buffer.getPointer();
96 Buffer.setInt((B && DoNotFree) ? DoNotFreeFlag : 0);
102 bool *Invalid)
const {
109 return Buffer.getPointer();
126 if (!BufferOrError) {
127 StringRef FillStr(
"<<<MISSING SOURCE FILE>>>\n");
128 auto BackupBuffer = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
130 char *Ptr = BackupBuffer->getBufferStart();
132 Ptr[i] = FillStr[i % FillStr.size()];
133 Buffer.setPointer(BackupBuffer.release());
138 BufferOrError.getError().message());
140 Diag.
Report(Loc, diag::err_cannot_open_file)
143 Buffer.setInt(Buffer.getInt() | InvalidFlag);
145 if (Invalid) *Invalid =
true;
146 return Buffer.getPointer();
149 Buffer.setPointer(BufferOrError->release());
158 Diag.
Report(Loc, diag::err_file_modified)
161 Buffer.setInt(Buffer.getInt() | InvalidFlag);
162 if (Invalid) *Invalid =
true;
163 return Buffer.getPointer();
169 StringRef BufStr = Buffer.getPointer()->getBuffer();
170 const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr)
171 .StartsWith(
"\xFE\xFF",
"UTF-16 (BE)")
172 .StartsWith(
"\xFF\xFE",
"UTF-16 (LE)")
173 .StartsWith(llvm::StringLiteral::withInnerNUL(
"\x00\x00\xFE\xFF"),
175 .StartsWith(llvm::StringLiteral::withInnerNUL(
"\xFF\xFE\x00\x00"),
177 .StartsWith(
"\x2B\x2F\x76",
"UTF-7")
178 .StartsWith(
"\xF7\x64\x4C",
"UTF-1")
179 .StartsWith(
"\xDD\x73\x66\x73",
"UTF-EBCDIC")
180 .StartsWith(
"\x0E\xFE\xFF",
"SDSU")
181 .StartsWith(
"\xFB\xEE\x28",
"BOCU-1")
182 .StartsWith(
"\x84\x31\x95\x33",
"GB-18030")
186 Diag.
Report(Loc, diag::err_unsupported_bom)
188 Buffer.setInt(Buffer.getInt() | InvalidFlag);
194 return Buffer.getPointer();
198 auto IterBool = FilenameIDs.try_emplace(Name, FilenamesByID.size());
200 FilenamesByID.push_back(&*IterBool.first);
201 return IterBool.first->second;
211 int FilenameID,
unsigned EntryExit,
213 std::vector<LineEntry> &Entries = LineEntries[FID];
217 if (FilenameID == -1 && !Entries.empty())
218 FilenameID = Entries.back().FilenameID;
220 assert((Entries.empty() || Entries.back().FileOffset <
Offset) &&
221 "Adding line entries out of order!");
223 unsigned IncludeOffset = 0;
224 if (EntryExit == 0) {
225 IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
226 }
else if (EntryExit == 1) {
227 IncludeOffset = Offset-1;
228 }
else if (EntryExit == 2) {
229 assert(!Entries.empty() && Entries.back().IncludeOffset &&
230 "PPDirectives should have caught case when popping empty include stack");
235 FindNearestLineEntry(FID, Entries.back().IncludeOffset))
236 IncludeOffset = PrevEntry->IncludeOffset;
239 Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, FileKind,
247 const std::vector<LineEntry> &Entries = LineEntries[FID];
248 assert(!Entries.empty() &&
"No #line entries for this FID after all!");
252 if (Entries.back().FileOffset <=
Offset)
253 return &Entries.back();
256 std::vector<LineEntry>::const_iterator I =
257 std::upper_bound(Entries.begin(), Entries.end(),
Offset);
258 if (I == Entries.begin())
return nullptr;
265 const std::vector<LineEntry> &Entries) {
266 LineEntries[FID] = Entries;
271 return getLineTable().getLineTableFilenameID(Name);
278 int FilenameID,
bool IsFileEntry,
281 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
283 bool Invalid =
false;
284 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
285 if (!Entry.
isFile() || Invalid)
293 (void) getLineTable();
295 unsigned EntryExit = 0;
301 LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
302 EntryExit, FileKind);
316 bool UserFilesAreVolatile)
317 : Diag(Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) {
328 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
329 if (MemBufferInfos[i]) {
330 MemBufferInfos[i]->~ContentCache();
331 ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
334 for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
335 I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
337 I->second->~ContentCache();
338 ContentCacheAlloc.Deallocate(I->second);
345 LocalSLocEntryTable.clear();
346 LoadedSLocEntryTable.clear();
347 SLocEntryLoaded.clear();
348 LastLineNoFileIDQuery =
FileID();
349 LastLineNoContentCache =
nullptr;
350 LastFileIDLookup =
FileID();
357 CurrentLoadedOffset = MaxLoadedOffset;
362 assert(MainFileID.
isInvalid() &&
"expected uninitialized SourceManager");
367 Clone->ContentsEntry =
Cache->ContentsEntry;
368 Clone->BufferOverridden =
Cache->BufferOverridden;
369 Clone->IsSystemFile =
Cache->IsSystemFile;
370 Clone->IsTransient =
Cache->IsTransient;
371 Clone->replaceBuffer(
Cache->getRawBuffer(),
true);
376 for (
unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
377 if (!Old.SLocEntryLoaded[I])
378 Old.loadSLocEntry(I,
nullptr);
381 for (
auto &
FileInfo : Old.FileInfos) {
385 Slot = CloneContentCache(
FileInfo.second);
392 SourceManager::getOrCreateContentCache(
const FileEntry *FileEnt,
394 assert(FileEnt &&
"Didn't specify a file entry to use?");
398 if (Entry)
return Entry;
403 if (OverriddenFilesInfo) {
406 llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
407 overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
408 if (overI == OverriddenFilesInfo->OverriddenFiles.end())
411 new (Entry)
ContentCache(OverridenFilesKeepOriginalName ? FileEnt
427 SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer,
432 MemBufferInfos.push_back(Entry);
438 bool *Invalid)
const {
439 assert(!SLocEntryLoaded[Index]);
440 if (ExternalSLocEntries->
ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
444 if (!SLocEntryLoaded[Index]) {
446 LoadedSLocEntryTable[Index] = SLocEntry::get(0,
448 getFakeContentCacheForRecovery(),
453 return LoadedSLocEntryTable[Index];
456 std::pair<int, unsigned>
458 unsigned TotalSize) {
459 assert(ExternalSLocEntries &&
"Don't have an external sloc source");
461 if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
462 return std::make_pair(0, 0);
463 LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
464 SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
465 CurrentLoadedOffset -= TotalSize;
466 int ID = LoadedSLocEntryTable.size();
467 return std::make_pair(-ID - 1, CurrentLoadedOffset);
472 llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery()
const {
473 if (!FakeBufferForRecovery)
474 FakeBufferForRecovery =
475 llvm::MemoryBuffer::getMemBuffer(
"<<<INVALID BUFFER>>");
477 return FakeBufferForRecovery.get();
483 SourceManager::getFakeContentCacheForRecovery()
const {
484 if (!FakeContentCacheForRecovery) {
485 FakeContentCacheForRecovery = llvm::make_unique<SrcMgr::ContentCache>();
486 FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
489 return FakeContentCacheForRecovery.get();
494 FileID SourceManager::getPreviousFileID(
FileID FID)
const {
505 }
else if (
unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
509 return FileID::get(ID-1);
522 }
else if (ID+1 >= -1) {
526 return FileID::get(ID+1);
539 int LoadedID,
unsigned LoadedOffset) {
541 assert(LoadedID != -1 &&
"Loading sentinel FileID");
542 unsigned Index = unsigned(-LoadedID) - 2;
543 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
544 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
545 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
546 FileInfo::get(IncludePos, File, FileCharacter));
547 SLocEntryLoaded[Index] =
true;
548 return FileID::get(LoadedID);
550 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
551 FileInfo::get(IncludePos, File,
553 unsigned FileSize = File->
getSize();
554 assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
555 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
556 "Ran out of source locations!");
559 NextLocalOffset += FileSize + 1;
563 FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
564 return LastFileIDLookup = FID;
570 unsigned TokLength) {
571 ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
573 return createExpansionLocImpl(Info, TokLength);
581 bool ExpansionIsTokenRange,
583 unsigned LoadedOffset) {
585 SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange);
586 return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
593 "token spans multiple files");
594 return createExpansionLocImpl(
595 ExpansionInfo::createForTokenSplit(Spelling, TokenStart, TokenEnd),
596 TokenEnd.getOffset() - TokenStart.getOffset());
600 SourceManager::createExpansionLocImpl(
const ExpansionInfo &Info,
603 unsigned LoadedOffset) {
605 assert(LoadedID != -1 &&
"Loading sentinel FileID");
606 unsigned Index = unsigned(-LoadedID) - 2;
607 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
608 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
609 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
610 SLocEntryLoaded[Index] =
true;
611 return SourceLocation::getMacroLoc(LoadedOffset);
613 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
614 assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
615 NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
616 "Ran out of source locations!");
618 NextLocalOffset += TokLength + 1;
619 return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
625 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
630 llvm::MemoryBuffer *Buffer,
633 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
638 getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
644 "Different sizes, use the FileManager to create a virtual file with " 646 assert(FileInfos.count(SourceFile) == 0 &&
647 "This function should be called at the initialization stage, before " 648 "any parsing occurs.");
649 getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
660 assert(OverriddenFilesInfo);
661 OverriddenFilesInfo->OverriddenFiles.erase(File);
662 OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
671 bool MyInvalid =
false;
673 if (!SLoc.
isFile() || MyInvalid) {
676 return "<<<<<INVALID SOURCE LOCATION>>>>>";
682 *Invalid = MyInvalid;
685 return "<<<<<INVALID SOURCE LOCATION>>>>>";
687 return Buf->getBuffer();
699 FileID SourceManager::getFileIDSlow(
unsigned SLocOffset)
const {
701 return FileID::get(0);
705 if (SLocOffset < NextLocalOffset)
706 return getFileIDLocal(SLocOffset);
707 return getFileIDLoaded(SLocOffset);
714 FileID SourceManager::getFileIDLocal(
unsigned SLocOffset)
const {
715 assert(SLocOffset < NextLocalOffset &&
"Bad function choice");
730 if (LastFileIDLookup.ID < 0 ||
731 LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
733 I = LocalSLocEntryTable.end();
736 I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
741 unsigned NumProbes = 0;
745 FileID Res = FileID::get(
int(I - LocalSLocEntryTable.begin()));
750 LastFileIDLookup = Res;
751 NumLinearScans += NumProbes+1;
754 if (++NumProbes == 8)
760 unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
764 unsigned LessIndex = 0;
767 bool Invalid =
false;
768 unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
771 return FileID::get(0);
777 if (MidOffset > SLocOffset) {
778 GreaterIndex = MiddleIndex;
785 if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
786 FileID Res = FileID::get(MiddleIndex);
790 if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
791 LastFileIDLookup = Res;
792 NumBinaryProbes += NumProbes;
797 LessIndex = MiddleIndex;
805 FileID SourceManager::getFileIDLoaded(
unsigned SLocOffset)
const {
807 if (SLocOffset < CurrentLoadedOffset) {
808 assert(0 &&
"Invalid SLocOffset or bad function choice");
817 int LastID = LastFileIDLookup.ID;
818 if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
821 I = (-LastID - 2) + 1;
824 for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) {
828 FileID Res = FileID::get(-
int(I) - 2);
831 LastFileIDLookup = Res;
832 NumLinearScans += NumProbes + 1;
840 unsigned GreaterIndex = I;
841 unsigned LessIndex = LoadedSLocEntryTable.size();
845 unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
854 if (GreaterIndex == MiddleIndex) {
855 assert(0 &&
"binary search missed the entry");
858 GreaterIndex = MiddleIndex;
862 if (isOffsetInFileID(FileID::get(-
int(MiddleIndex) - 2), SLocOffset)) {
863 FileID Res = FileID::get(-
int(MiddleIndex) - 2);
865 LastFileIDLookup = Res;
866 NumBinaryProbes += NumProbes;
871 if (LessIndex == MiddleIndex) {
872 assert(0 &&
"binary search missed the entry");
875 LessIndex = MiddleIndex;
914 std::pair<FileID, unsigned>
915 SourceManager::getDecomposedExpansionLocSlowCase(
929 return std::make_pair(FID, Offset);
932 std::pair<FileID, unsigned>
947 return std::make_pair(FID, Offset);
965 assert(Loc.
isMacroID() &&
"Not a macro expansion loc!");
1022 if (DecompLoc.second > 0)
1025 bool Invalid =
false;
1036 FileID PrevFID = getPreviousFileID(DecompLoc.first);
1048 *MacroBegin = ExpLoc;
1061 bool Invalid =
false;
1071 FileID NextFID = getNextFileID(FID);
1095 bool *Invalid)
const {
1101 bool CharDataInvalid =
false;
1103 if (CharDataInvalid || !Entry.
isFile()) {
1107 return "<<<<INVALID BUFFER>>>>";
1112 *Invalid = CharDataInvalid;
1113 return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
1119 bool *Invalid)
const {
1120 bool MyInvalid =
false;
1121 llvm::MemoryBuffer *MemBuf =
getBuffer(FID, &MyInvalid);
1123 *Invalid = MyInvalid;
1129 if (FilePos > MemBuf->getBufferSize()) {
1135 const char *Buf = MemBuf->getBufferStart();
1138 if (LastLineNoFileIDQuery == FID &&
1140 LastLineNoResult < LastLineNoContentCache->NumLines) {
1142 unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1143 unsigned LineEnd = SourceLineCache[LastLineNoResult];
1144 if (FilePos >= LineStart && FilePos < LineEnd) {
1149 if (FilePos + 1 == LineEnd && FilePos > LineStart) {
1150 if (Buf[FilePos - 1] ==
'\r' || Buf[FilePos - 1] ==
'\n')
1153 return FilePos - LineStart + 1;
1157 unsigned LineStart = FilePos;
1158 while (LineStart && Buf[LineStart-1] !=
'\n' && Buf[LineStart-1] !=
'\r')
1160 return FilePos-LineStart+1;
1165 template<
typename LocType>
1167 bool MyInvalid = Loc.isInvalid();
1169 *Invalid = MyInvalid;
1174 bool *Invalid)
const {
1181 bool *Invalid)
const {
1188 bool *Invalid)
const {
1198 static LLVM_ATTRIBUTE_NOINLINE
void 1200 llvm::BumpPtrAllocator &Alloc,
1203 llvm::BumpPtrAllocator &Alloc,
1215 LineOffsets.push_back(0);
1217 const unsigned char *Buf = (
const unsigned char *)Buffer->getBufferStart();
1218 const unsigned char *
End = (
const unsigned char *)Buffer->getBufferEnd();
1222 while (Buf[I] !=
'\n' && Buf[I] !=
'\r' && Buf[I] !=
'\0')
1225 if (Buf[I] ==
'\n' || Buf[I] ==
'\r') {
1227 if (Buf[I] ==
'\r' && Buf[I+1] ==
'\n')
1230 LineOffsets.push_back(I);
1233 if (Buf+I == End)
break;
1241 std::copy(LineOffsets.begin(), LineOffsets.end(), FI->
SourceLineCache);
1249 bool *Invalid)
const {
1257 if (LastLineNoFileIDQuery == FID)
1258 Content = LastLineNoContentCache;
1260 bool MyInvalid =
false;
1262 if (MyInvalid || !Entry.
isFile()) {
1274 bool MyInvalid =
false;
1277 *Invalid = MyInvalid;
1286 unsigned *SourceLineCacheStart = SourceLineCache;
1287 unsigned *SourceLineCacheEnd = SourceLineCache + Content->
NumLines;
1289 unsigned QueriedFilePos = FilePos+1;
1304 if (LastLineNoFileIDQuery == FID) {
1305 if (QueriedFilePos >= LastLineNoFilePos) {
1307 SourceLineCache = SourceLineCache+LastLineNoResult-1;
1313 if (SourceLineCache+5 < SourceLineCacheEnd) {
1314 if (SourceLineCache[5] > QueriedFilePos)
1315 SourceLineCacheEnd = SourceLineCache+5;
1316 else if (SourceLineCache+10 < SourceLineCacheEnd) {
1317 if (SourceLineCache[10] > QueriedFilePos)
1318 SourceLineCacheEnd = SourceLineCache+10;
1319 else if (SourceLineCache+20 < SourceLineCacheEnd) {
1320 if (SourceLineCache[20] > QueriedFilePos)
1321 SourceLineCacheEnd = SourceLineCache+20;
1326 if (LastLineNoResult < Content->NumLines)
1327 SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1332 = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1333 unsigned LineNo = Pos-SourceLineCacheStart;
1335 LastLineNoFileIDQuery = FID;
1336 LastLineNoContentCache = Content;
1337 LastLineNoFilePos = QueriedFilePos;
1338 LastLineNoResult = LineNo;
1343 bool *Invalid)
const {
1349 bool *Invalid)
const {
1355 bool *Invalid)
const {
1371 assert(Loc.
isValid() &&
"Can't get file characteristic of invalid loc!");
1373 bool Invalid =
false;
1375 if (Invalid || !SEntry.
isFile())
1385 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1401 bool *Invalid)
const {
1402 if (
isInvalid(Loc, Invalid))
return "<invalid loc>";
1415 bool UseLineDirectives)
const {
1421 bool Invalid =
false;
1423 if (Invalid || !Entry.
isFile())
1436 Filename = C->
getBuffer(Diag, *
this)->getBufferIdentifier();
1438 unsigned LineNo =
getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1441 unsigned ColNo =
getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1450 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1455 if (Entry->FilenameID != -1)
1456 Filename = LineTable->
getFilename(Entry->FilenameID);
1462 unsigned MarkerLineNo =
getLineNumber(LocInfo.first, Entry->FileOffset);
1463 LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1468 if (Entry->IncludeOffset) {
1475 return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc);
1491 bool Invalid =
false;
1493 if (Invalid || !Entry.
isFile())
1502 if (Entry->IncludeOffset)
1510 bool Invalid =
false;
1516 unsigned NextOffset;
1519 else if (ID+1 == -1)
1520 NextOffset = MaxLoadedOffset;
1524 return NextOffset - Entry.
getOffset() - 1;
1540 llvm::sys::fs::UniqueID
ID;
1541 if (llvm::sys::fs::getUniqueID(File->
getName(),
ID))
1553 unsigned Col)
const {
1554 assert(SourceFile &&
"Null source file!");
1555 assert(Line && Col &&
"Line and column should start from 1!");
1566 assert(SourceFile &&
"Null source file!");
1576 bool Invalid =
false;
1584 if (!MainContentCache) {
1586 }
else if (MainContentCache->
OrigEntry == SourceFile) {
1587 FirstFID = MainFileID;
1592 SourceFileName = llvm::sys::path::filename(SourceFile->
getName());
1593 if (*SourceFileName == llvm::sys::path::filename(MainFile->
getName())) {
1595 if (SourceFileUID) {
1598 if (*SourceFileUID == *MainFileUID) {
1599 FirstFID = MainFileID;
1600 SourceFile = MainFile;
1613 bool Invalid =
false;
1621 FirstFID = FileID::get(I);
1632 FirstFID = FileID::get(-
int(I) - 2);
1644 (SourceFileName = llvm::sys::path::filename(SourceFile->
getName()))) &&
1646 bool Invalid =
false;
1660 *SourceFileName == llvm::sys::path::filename(Entry->
getName())) {
1663 if (*SourceFileUID == *EntryUID) {
1664 FirstFID = FileID::get(I);
1682 unsigned Col)
const {
1685 assert(Line && Col &&
"Line and column should start from 1!");
1690 bool Invalid =
false;
1700 if (Line == 1 && Col == 1)
1711 bool MyInvalid =
false;
1718 unsigned Size = Content->
getBuffer(Diag, *
this)->getBufferSize();
1724 llvm::MemoryBuffer *Buffer = Content->
getBuffer(Diag, *
this);
1726 const char *Buf = Buffer->getBufferStart() + FilePos;
1727 unsigned BufLength = Buffer->getBufferSize() - FilePos;
1734 while (i < BufLength-1 && i < Col-1 && Buf[i] !=
'\n' && Buf[i] !=
'\r')
1746 void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
1760 }
else if (ID == -1) {
1764 bool Invalid =
false;
1777 if (Entry.
getFile().NumCreatedFIDs)
1778 ID += Entry.
getFile().NumCreatedFIDs - 1;
1792 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1794 SourceLocation::getMacroLoc(Entry.
getOffset()),
1799 void SourceManager::associateFileChunkWithMacroArgExp(
1800 MacroArgsMap &MacroArgsCache,
1804 unsigned ExpansionLength)
const {
1806 unsigned SpellBeginOffs = SpellLoc.getOffset();
1807 unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
1815 unsigned SpellRelativeOffs;
1819 unsigned SpellFIDBeginOffs = Entry.
getOffset();
1821 unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1824 unsigned CurrSpellLength;
1825 if (SpellFIDEndOffs < SpellEndOffs)
1826 CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1828 CurrSpellLength = ExpansionLength;
1829 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1831 ExpansionLoc, CurrSpellLength);
1834 if (SpellFIDEndOffs >= SpellEndOffs)
1838 unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1840 ExpansionLength -= advance;
1842 SpellRelativeOffs = 0;
1852 unsigned EndOffs = BeginOffs + ExpansionLength;
1871 MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1874 MacroArgsCache[BeginOffs] = ExpansionLoc;
1875 MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1898 std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
1899 if (!MacroArgsCache) {
1900 MacroArgsCache = llvm::make_unique<MacroArgsMap>();
1901 computeMacroArgsCache(*MacroArgsCache, FID);
1904 assert(!MacroArgsCache->empty());
1905 MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1908 unsigned MacroArgBeginOffs = I->first;
1910 if (MacroArgExpandedLoc.
isValid())
1916 std::pair<FileID, unsigned>
1919 return std::make_pair(
FileID(), 0);
1923 using DecompTy = std::pair<FileID, unsigned>;
1924 auto InsertOp = IncludedLocMap.try_emplace(FID);
1925 DecompTy &DecompLoc = InsertOp.first->second;
1926 if (!InsertOp.second)
1930 bool Invalid =
false;
1952 if (UpperLoc.first.isInvalid())
1966 enum { MagicCacheSize = 300 };
1967 IsBeforeInTUCacheKey Key(LFID, RFID);
1973 if (IBTUCache.size() < MagicCacheSize)
1974 return IBTUCache[Key];
1977 InBeforeInTUCache::iterator I = IBTUCache.find(Key);
1978 if (I != IBTUCache.end())
1982 return IBTUCacheOverflow;
1990 assert(LHS.
isValid() && RHS.
isValid() &&
"Passed invalid source location!");
2000 if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
2001 return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
2005 return InSameTU.second;
2010 StringRef LB =
getBuffer(LOffs.first)->getBufferIdentifier();
2011 StringRef RB =
getBuffer(ROffs.first)->getBufferIdentifier();
2012 bool LIsBuiltins = LB ==
"<built-in>";
2013 bool RIsBuiltins = RB ==
"<built-in>";
2015 if (LIsBuiltins || RIsBuiltins) {
2016 if (LIsBuiltins != RIsBuiltins)
2020 return LOffs.first < ROffs.first;
2022 bool LIsAsm = LB ==
"<inline asm>";
2023 bool RIsAsm = RB ==
"<inline asm>";
2025 if (LIsAsm || RIsAsm) {
2026 if (LIsAsm != RIsAsm)
2028 assert(LOffs.first == ROffs.first);
2031 bool LIsScratch = LB ==
"<scratch space>";
2032 bool RIsScratch = RB ==
"<scratch space>";
2034 if (LIsScratch || RIsScratch) {
2035 if (LIsScratch != RIsScratch)
2037 return LOffs.second < ROffs.second;
2039 llvm_unreachable(
"Unsortable locations found");
2043 std::pair<FileID, unsigned> &LOffs,
2044 std::pair<FileID, unsigned> &ROffs)
const {
2046 if (LOffs.first == ROffs.first)
2047 return std::make_pair(
true, LOffs.second < ROffs.second);
2052 getInBeforeInTUCache(LOffs.first, ROffs.first);
2056 if (IsBeforeInTUCache.
isCacheValid(LOffs.first, ROffs.first))
2057 return std::make_pair(
2061 IsBeforeInTUCache.
setQueryFIDs(LOffs.first, ROffs.first,
2062 LOffs.first.ID < ROffs.first.ID);
2069 using LocSet = llvm::SmallDenseMap<FileID, unsigned, 16>;
2072 LChain.insert(LOffs);
2077 while((I = LChain.find(ROffs.first)) == LChain.end()) {
2081 if (I != LChain.end())
2086 if (LOffs.first == ROffs.first) {
2087 IsBeforeInTUCache.
setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
2088 return std::make_pair(
2092 IsBeforeInTUCache.
clear();
2093 return std::make_pair(
false,
false);
2097 llvm::errs() <<
"\n*** Source Manager Stats:\n";
2098 llvm::errs() << FileInfos.size() <<
" files mapped, " << MemBufferInfos.size()
2099 <<
" mem buffers mapped.\n";
2100 llvm::errs() << LocalSLocEntryTable.size() <<
" local SLocEntry's allocated (" 2101 << llvm::capacity_in_bytes(LocalSLocEntryTable)
2102 <<
" bytes of capacity), " 2103 << NextLocalOffset <<
"B of Sloc address space used.\n";
2104 llvm::errs() << LoadedSLocEntryTable.size()
2105 <<
" loaded SLocEntries allocated, " 2106 << MaxLoadedOffset - CurrentLoadedOffset
2107 <<
"B of Sloc address space used.\n";
2109 unsigned NumLineNumsComputed = 0;
2110 unsigned NumFileBytesMapped = 0;
2112 NumLineNumsComputed += I->second->SourceLineCache !=
nullptr;
2113 NumFileBytesMapped += I->second->getSizeBytesMapped();
2115 unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2117 llvm::errs() << NumFileBytesMapped <<
" bytes of files mapped, " 2118 << NumLineNumsComputed <<
" files with line #'s computed, " 2119 << NumMacroArgsComputed <<
" files with macro args computed.\n";
2120 llvm::errs() <<
"FileID scans: " << NumLinearScans <<
" linear, " 2121 << NumBinaryProbes <<
" binary.\n";
2125 llvm::raw_ostream &out = llvm::errs();
2129 out <<
"SLocEntry <FileID " << ID <<
"> " << (Entry.isFile() ?
"file" :
"expansion")
2130 <<
" <SourceLocation " << Entry.getOffset() <<
":";
2132 out << *NextStart <<
">\n";
2135 if (Entry.isFile()) {
2136 auto &FI = Entry.getFile();
2137 if (FI.NumCreatedFIDs)
2138 out <<
" covers <FileID " << ID <<
":" << int(ID + FI.NumCreatedFIDs)
2140 if (FI.getIncludeLoc().isValid())
2141 out <<
" included from " << FI.getIncludeLoc().getOffset() <<
"\n";
2142 if (
auto *CC = FI.getContentCache()) {
2143 out <<
" for " << (CC->OrigEntry ? CC->OrigEntry->getName() :
"<none>")
2145 if (CC->BufferOverridden)
2146 out <<
" contents overridden\n";
2147 if (CC->ContentsEntry != CC->OrigEntry) {
2148 out <<
" contents from " 2149 << (CC->ContentsEntry ? CC->ContentsEntry->getName() :
"<none>")
2154 auto &EI = Entry.getExpansion();
2155 out <<
" spelling from " << EI.getSpellingLoc().getOffset() <<
"\n";
2156 out <<
" macro " << (EI.isMacroArgExpansion() ?
"arg" :
"body")
2157 <<
" range <" << EI.getExpansionLocStart().getOffset() <<
":" 2158 << EI.getExpansionLocEnd().getOffset() <<
">\n";
2163 for (
unsigned ID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++
ID) {
2164 DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2165 ID == NumIDs - 1 ? NextLocalOffset
2166 : LocalSLocEntryTable[ID + 1].getOffset());
2170 for (
unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2171 int ID = -(int)Index - 2;
2172 if (SLocEntryLoaded[Index]) {
2173 DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2174 NextStart = LoadedSLocEntryTable[Index].getOffset();
2186 size_t malloc_bytes = 0;
2187 size_t mmap_bytes = 0;
2189 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2190 if (
size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2191 switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2192 case llvm::MemoryBuffer::MemoryBuffer_MMap:
2193 mmap_bytes += sized_mapped;
2195 case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2196 malloc_bytes += sized_mapped;
2204 size_t size = llvm::capacity_in_bytes(MemBufferInfos)
2205 + llvm::capacity_in_bytes(LocalSLocEntryTable)
2206 + llvm::capacity_in_bytes(LoadedSLocEntryTable)
2207 + llvm::capacity_in_bytes(SLocEntryLoaded)
2208 + llvm::capacity_in_bytes(FileInfos);
2210 if (OverriddenFilesInfo)
2211 size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
2217 StringRef Content) {
2221 new llvm::vfs::InMemoryFileSystem);
2222 InMemoryFileSystem->addFile(
2224 llvm::MemoryBuffer::getMemBuffer(Content, FileName,
2232 Diagnostics = llvm::make_unique<DiagnosticsEngine>(
2235 SourceMgr = llvm::make_unique<SourceManager>(*Diagnostics, *FileMgr);
2238 assert(ID.isValid());
2239 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.
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
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
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.
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)
void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1="", StringRef Arg2="")
Set the "delayed" diagnostic that will be emitted once the current diagnostic completes.
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...
void disableFileContentsOverride(const FileEntry *File)
Disable overridding the contents of a file, previously enabled with overrideFileContents.
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.
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)
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.
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.
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
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. ...
llvm::MemoryBuffer * getBuffer(DiagnosticsEngine &Diag, const SourceManager &SM, SourceLocation Loc=SourceLocation(), bool *Invalid=nullptr) const
Returns the memory buffer for the associated content.
Represents a character-granular source range.
static Optional< llvm::sys::fs::UniqueID > getActualFileUID(const FileEntry *File)
Retrieve the inode for the given file entry, if possible.
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.
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...
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
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...
unsigned IsSystemFile
True if this content cache was initially created for a source file considered as a system one...
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.
llvm::MemoryBuffer * getMemoryBufferForFile(const FileEntry *File, bool *Invalid=nullptr)
Retrieve the memory buffer associated with the given file.
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree=false)
Replace the existing buffer (which will be deleted) with the given buffer.
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.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const
Returns the kind of memory used to back the memory buffer for this content cache. ...
llvm::MemoryBuffer * getRawBuffer() const
Get the underlying buffer, returning NULL if the buffer is not yet available.
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
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 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.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const FileEntry *Entry, bool isVolatile=false, bool ShouldCloseOpenFile=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
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.
StringRef getFilename(unsigned ID) const
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.
bool userFilesAreVolatile() const
True if non-system source files should be treated as volatile (likely to change while trying to use t...
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...
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.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const