;
48using namespaceSrcMgr;
49usingllvm::MemoryBuffer;
51#define DEBUG_TYPE "source-manager" 55STATISTIC(MaxUsedSLocBytes,
"Maximum number of bytes used by source locations " 56 "(both loaded and local).");
65 returnBuffer ? Buffer->getBufferSize() : 0;
71 if(Buffer ==
nullptr) {
72assert(0 &&
"Buffer should never be null");
73 returnllvm::MemoryBuffer::MemoryBuffer_Malloc;
75 returnBuffer->getBufferKind();
83 returnBuffer ? (
unsigned)Buffer->getBufferSize()
91 const char*InvalidBOM =
92llvm::StringSwitch<const char *>(BufStr)
93.StartsWith(llvm::StringLiteral::withInnerNUL(
"\x00\x00\xFE\xFF"),
95.StartsWith(llvm::StringLiteral::withInnerNUL(
"\xFF\xFE\x00\x00"),
97.StartsWith(
"\xFE\xFF",
"UTF-16 (BE)")
98.StartsWith(
"\xFF\xFE",
"UTF-16 (LE)")
99.StartsWith(
"\x2B\x2F\x76",
"UTF-7")
100.StartsWith(
"\xF7\x64\x4C",
"UTF-1")
101.StartsWith(
"\xDD\x73\x66\x73",
"UTF-EBCDIC")
102.StartsWith(
"\x0E\xFE\xFF",
"SCSU")
103.StartsWith(
"\xFB\xEE\x28",
"BOCU-1")
104.StartsWith(
"\x84\x31\x95\x33",
"GB-18030")
110std::optional<llvm::MemoryBufferRef>
118 returnBuffer->getMemBufferRef();
133 if(!BufferOrError) {
134 Diag.Report(
Loc, diag::err_cannot_open_file)
140Buffer = std::move(*BufferOrError);
151 if(Buffer->getBufferSize() >= std::numeric_limits<unsigned>::max()) {
173StringRef BufStr = Buffer->getBuffer();
177 Diag.Report(
Loc, diag::err_unsupported_bom)
184 returnBuffer->getMemBufferRef();
188 autoIterBool = FilenameIDs.try_emplace(Name, FilenamesByID.size());
190FilenamesByID.push_back(&*IterBool.first);
191 returnIterBool.first->second;
201 intFilenameID,
unsignedEntryExit,
203std::vector<LineEntry> &Entries = LineEntries[FID];
205assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
206 "Adding line entries out of order!");
208 unsignedIncludeOffset = 0;
209 if(EntryExit == 1) {
211IncludeOffset = Offset-1;
213 const auto*PrevEntry = Entries.empty() ? nullptr : &Entries.back();
214 if(EntryExit == 2) {
216assert(PrevEntry && PrevEntry->IncludeOffset &&
217 "PPDirectives should have caught case when popping empty include " 219PrevEntry = FindNearestLineEntry(FID, PrevEntry->IncludeOffset);
222IncludeOffset = PrevEntry->IncludeOffset;
223 if(FilenameID == -1) {
226FilenameID = PrevEntry->FilenameID;
231Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, FileKind,
239 conststd::vector<LineEntry> &Entries = LineEntries[FID];
240assert(!Entries.empty() &&
"No #line entries for this FID after all!");
244 if(Entries.back().FileOffset <= Offset)
245 return&Entries.back();
248std::vector<LineEntry>::const_iterator I = llvm::upper_bound(Entries, Offset);
249 if(I == Entries.begin())
257 conststd::vector<LineEntry> &Entries) {
258LineEntries[FID] = Entries;
263 returngetLineTable().getLineTableFilenameID(Name);
270 intFilenameID,
boolIsFileEntry,
273std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(
Loc);
285(void) getLineTable();
287 unsignedEntryExit = 0;
293LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
294EntryExit, FileKind);
308 boolUserFilesAreVolatile)
309:
Diag(
Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) {
318 for(
unsignedi = 0, e = MemBufferInfos.size(); i != e; ++i) {
319 if(MemBufferInfos[i]) {
320MemBufferInfos[i]->~ContentCache();
321ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
324 for(
autoI = FileInfos.begin(),
E= FileInfos.end(); I !=
E; ++I) {
326I->second->~ContentCache();
327ContentCacheAlloc.Deallocate(I->second);
334LocalSLocEntryTable.clear();
335LoadedSLocEntryTable.clear();
336SLocEntryLoaded.clear();
337SLocEntryOffsetLoaded.clear();
338LastLineNoFileIDQuery =
FileID();
339LastLineNoContentCache =
nullptr;
340LastFileIDLookup =
FileID();
342IncludedLocMap.clear();
348CurrentLoadedOffset = MaxLoadedOffset;
353assert(MainFileID.
isValid() &&
"expected initialized SourceManager");
355 returnFE->getUID() == SourceFile.
getUID();
360assert(MainFileID.
isInvalid() &&
"expected uninitialized SourceManager");
365Clone->ContentsEntry =
Cache->ContentsEntry;
366Clone->BufferOverridden =
Cache->BufferOverridden;
367Clone->IsFileVolatile =
Cache->IsFileVolatile;
368Clone->IsTransient =
Cache->IsTransient;
369Clone->setUnownedBuffer(
Cache->getBufferIfLoaded());
374 for(
unsignedI = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
375 if(!Old.SLocEntryLoaded[I])
376Old.loadSLocEntry(I,
nullptr);
379 for(
auto&
FileInfo: Old.FileInfos) {
383Slot = CloneContentCache(
FileInfo.second);
397 if(OverriddenFilesInfo) {
400 autooverI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
401 if(overI == OverriddenFilesInfo->OverriddenFiles.end())
404 new(Entry)
ContentCache(OverridenFilesKeepOriginalName ? FileEnt
420ContentCache&SourceManager::createMemBufferContentCache(
421std::unique_ptr<llvm::MemoryBuffer> Buffer) {
425MemBufferInfos.push_back(Entry);
436assert(!SLocEntryLoaded[Index]);
437 if(ExternalSLocEntries->
ReadSLocEntry(-(
static_cast<int>(Index) + 2))) {
441 if(!SLocEntryLoaded[Index]) {
443 if(!FakeSLocEntryForRecovery)
444FakeSLocEntryForRecovery = std::make_unique<SLocEntry>(
SLocEntry::get(
447 return*FakeSLocEntryForRecovery;
451 returnLoadedSLocEntryTable[Index];
454std::pair<int, SourceLocation::UIntTy>
457assert(ExternalSLocEntries &&
"Don't have an external sloc source");
459 if(CurrentLoadedOffset < TotalSize ||
460CurrentLoadedOffset - TotalSize < NextLocalOffset) {
461 returnstd::make_pair(0, 0);
463LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
464SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
465SLocEntryOffsetLoaded.resize(LoadedSLocEntryTable.size());
466CurrentLoadedOffset -= TotalSize;
467updateSlocUsageStats();
468 intBaseID = -
int(LoadedSLocEntryTable.size()) - 1;
469LoadedSLocEntryAllocBegin.push_back(FileID::get(BaseID));
470 returnstd::make_pair(BaseID, CurrentLoadedOffset);
475llvm::MemoryBufferRef SourceManager::getFakeBufferForRecovery()
const{
476 if(!FakeBufferForRecovery)
477FakeBufferForRecovery =
478llvm::MemoryBuffer::getMemBuffer(
"<<<INVALID BUFFER>>");
480 return*FakeBufferForRecovery;
486 if(!FakeContentCacheForRecovery) {
487FakeContentCacheForRecovery = std::make_unique<SrcMgr::ContentCache>();
488FakeContentCacheForRecovery->setUnownedBuffer(getFakeBufferForRecovery());
490 return*FakeContentCacheForRecovery;
495FileIDSourceManager::getPreviousFileID(
FileIDFID)
const{
506}
else if(
unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
510 returnFileID::get(ID-1);
523}
else if(ID+1 >= -1) {
527 returnFileID::get(ID+1);
549 returncreateFileIDImpl(IR, SourceFile.
getName(), IncludePos, FileCharacter,
550LoadedID, LoadedOffset);
562StringRef Name = Buffer->getBufferIdentifier();
563 returncreateFileIDImpl(createMemBufferContentCache(std::move(Buffer)), Name,
564IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
576 return createFileID(llvm::MemoryBuffer::getMemBuffer(Buffer), FileCharacter,
577LoadedID, LoadedOffset, IncludeLoc);
593llvm::ErrorOr<bool> NeedConversion =
594llvm::needzOSConversion(
Filename.str().c_str());
595 returnNeedConversion && *NeedConversion;
610assert(LoadedID != -1 &&
"Loading sentinel FileID");
611 unsignedIndex =
unsigned(-LoadedID) - 2;
612assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
613assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
616SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] =
true;
617 returnFileID::get(LoadedID);
619 unsignedFileSize =
File.getSize();
621 if(NeedConversion) {
624 if(std::optional<llvm::MemoryBufferRef> Buffer =
626 unsignedBufSize = Buffer->getBufferSize();
627 if(BufSize > FileSize) {
628 if(
File.ContentsEntry.has_value())
629 File.ContentsEntry->updateFileEntryBufferSize(BufSize);
634 if(!(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
635NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) {
636Diag.
Report(IncludePos, diag::err_sloc_space_too_large);
640LocalSLocEntryTable.push_back(
645NextLocalOffset += FileSize + 1;
646updateSlocUsageStats();
650 FileIDFID = FileID::get(LocalSLocEntryTable.size()-1);
651 returnLastFileIDLookup = FID;
658 returncreateExpansionLocImpl(Info, Length);
664 boolExpansionIsTokenRange,
intLoadedID,
667SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange);
668 returncreateExpansionLocImpl(Info, Length, LoadedID, LoadedOffset);
675 "token spans multiple files");
676 returncreateExpansionLocImpl(
678TokenEnd.getOffset() - TokenStart.getOffset());
682SourceManager::createExpansionLocImpl(
const ExpansionInfo&Info,
683 unsignedLength,
intLoadedID,
686assert(LoadedID != -1 &&
"Loading sentinel FileID");
687 unsignedIndex =
unsigned(-LoadedID) - 2;
688assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
689assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
690LoadedSLocEntryTable[Index] =
SLocEntry::get(LoadedOffset, Info);
691SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] =
true;
692 returnSourceLocation::getMacroLoc(LoadedOffset);
694LocalSLocEntryTable.push_back(
SLocEntry::get(NextLocalOffset, Info));
695 if(NextLocalOffset + Length + 1 <= NextLocalOffset ||
696NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
697Diag.
Report(diag::err_sloc_space_too_large);
703llvm::report_fatal_error(
"ran out of source locations");
706NextLocalOffset += Length + 1;
707updateSlocUsageStats();
708 returnSourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));
711std::optional<llvm::MemoryBufferRef>
718 FileEntryRefSourceFile, std::unique_ptr<llvm::MemoryBuffer> Buffer) {
724getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
730 "Different sizes, use the FileManager to create a virtual file with " 731 "the correct size");
732assert(FileInfos.find_as(SourceFile) == FileInfos.end() &&
733 "This function should be called at the initialization stage, before " 734 "any parsing occurs.");
736 autoPair = getOverriddenFilesInfo().OverriddenFiles.insert(
737std::make_pair(SourceFile, NewFile));
739Pair.first->second = NewFile;
751(void)getOrCreateContentCache(*BypassFile);
759std::optional<StringRef>
762 if(Entry->getFile().getContentCache().
OrigEntry)
763 returnEntry->getFile().getName();
771 returnB ? *B :
"<<<<<INVALID SOURCE LOCATION>>>>>";
774std::optional<StringRef>
785 returnB->getBuffer();
800 returnFileID::get(0);
804 if(SLocOffset < NextLocalOffset)
805 returngetFileIDLocal(SLocOffset);
806 returngetFileIDLoaded(SLocOffset);
814assert(SLocOffset < NextLocalOffset &&
"Bad function choice");
831 unsignedLessIndex = 0;
833 unsignedGreaterIndex = LocalSLocEntryTable.size();
834 if(LastFileIDLookup.ID >= 0) {
836 if(LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset)
837LessIndex = LastFileIDLookup.ID;
839GreaterIndex = LastFileIDLookup.ID;
843 unsignedNumProbes = 0;
846assert(GreaterIndex < LocalSLocEntryTable.size());
847 if(LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) {
848 FileIDRes = FileID::get(
int(GreaterIndex));
850LastFileIDLookup = Res;
851NumLinearScans += NumProbes+1;
854 if(++NumProbes == 8)
860 unsignedMiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
868 if(MidOffset > SLocOffset) {
869GreaterIndex = MiddleIndex;
874 if(MiddleIndex + 1 == LocalSLocEntryTable.size() ||
876 FileIDRes = FileID::get(MiddleIndex);
879LastFileIDLookup = Res;
880NumBinaryProbes += NumProbes;
885LessIndex = MiddleIndex;
894 if(SLocOffset < CurrentLoadedOffset) {
895assert(0 &&
"Invalid SLocOffset or bad function choice");
899 returnFileID::get(ExternalSLocEntries->
getSLocEntryID(SLocOffset));
937std::pair<FileID, unsigned>
938SourceManager::getDecomposedExpansionLocSlowCase(
945 Loc=
E->getExpansion().getExpansionLocStart();
949Offset =
Loc.getOffset()-
E->getOffset();
952 returnstd::make_pair(FID, Offset);
955std::pair<FileID, unsigned>
957 unsignedOffset)
const{
962 Loc=
E->getExpansion().getSpellingLoc();
967Offset =
Loc.getOffset()-
E->getOffset();
970 returnstd::make_pair(FID, Offset);
995assert(
Loc.
isMacroID() &&
"Not a macro expansion loc!");
1052 if(DecompLoc.second > 0)
1066 FileIDPrevFID = getPreviousFileID(DecompLoc.first);
1078*MacroBegin = ExpLoc;
1101 FileIDNextFID = getNextFileID(FID);
1131 boolCharDataInvalid =
false;
1133 if(CharDataInvalid || !Entry.
isFile()) {
1137 return "<<<<INVALID BUFFER>>>>";
1139std::optional<llvm::MemoryBufferRef> Buffer =
1144 returnBuffer ? Buffer->getBufferStart() + LocInfo.second
1145:
"<<<<INVALID BUFFER>>>>";
1160 if(FilePos > MemBuf->getBufferSize()) {
1166 const char*Buf = MemBuf->getBufferStart();
1169 if(LastLineNoFileIDQuery == FID && LastLineNoContentCache->
SourceLineCache&&
1170LastLineNoResult < LastLineNoContentCache->SourceLineCache.
size()) {
1171 const unsigned*SourceLineCache =
1173 unsignedLineStart = SourceLineCache[LastLineNoResult - 1];
1174 unsignedLineEnd = SourceLineCache[LastLineNoResult];
1175 if(FilePos >= LineStart && FilePos < LineEnd) {
1180 if(FilePos + 1 == LineEnd && FilePos > LineStart) {
1181 if(Buf[FilePos - 1] ==
'\r'|| Buf[FilePos - 1] ==
'\n')
1184 returnFilePos - LineStart + 1;
1188 unsignedLineStart = FilePos;
1189 while(LineStart && Buf[LineStart-1] !=
'\n'&& Buf[LineStart-1] !=
'\r')
1191 returnFilePos-LineStart+1;
1196template<
typenameLocType>
1232 return((x - ~
static_cast<T>(0) / 255 * (n + 1)) & ~x &
1233((x & ~
static_cast<T>(0) / 255 * 127) +
1234(~
static_cast<T>(0) / 255 * (127 - (m - 1))))) &
1235~static_cast<T>(0) / 255 * 128;
1239llvm::BumpPtrAllocator &Alloc) {
1246LineOffsets.push_back(0);
1248 const unsigned char*Start = (
const unsigned char*)Buffer.getBufferStart();
1249 const unsigned char*End = (
const unsigned char*)Buffer.getBufferEnd();
1250 const unsigned char*Buf = Start;
1256 if((
unsigned long)(End - Start) >
sizeof(Word)) {
1258Word = llvm::support::endian::read64(Buf, llvm::endianness::little);
1262Buf +=
sizeof(Word);
1270 unsignedN = llvm::countr_zero(Mask) - 7;
1273 unsigned charByte = Word;
1277 if(*Buf ==
'\n') {
1282LineOffsets.push_back(Buf - Start);
1284}
while(Buf < End -
sizeof(Word) - 1);
1289 if(*Buf ==
'\n') {
1290LineOffsets.push_back(Buf - Start + 1);
1291}
else if(*Buf ==
'\r') {
1293 if(Buf + 1 < End && Buf[1] ==
'\n') {
1296LineOffsets.push_back(Buf - Start + 1);
1305llvm::BumpPtrAllocator &Alloc)
1306: Storage(Alloc.Allocate<
unsigned>(LineOffsets.size() + 1)) {
1307Storage[0] = LineOffsets.size();
1308std::copy(LineOffsets.begin(), LineOffsets.end(), Storage + 1);
1324 if(LastLineNoFileIDQuery == FID)
1325Content = LastLineNoContentCache;
1327 boolMyInvalid =
false;
1328 const SLocEntry&Entry = getSLocEntry(FID, &MyInvalid);
1329 if(MyInvalid || !Entry.
isFile()) {
1341std::optional<llvm::MemoryBufferRef> Buffer =
1356 const unsigned*SourceLineCacheStart = SourceLineCache;
1359 unsignedQueriedFilePos = FilePos+1;
1374 if(LastLineNoFileIDQuery == FID) {
1375 if(QueriedFilePos >= LastLineNoFilePos) {
1377SourceLineCache = SourceLineCache+LastLineNoResult-1;
1383 if(SourceLineCache+5 < SourceLineCacheEnd) {
1384 if(SourceLineCache[5] > QueriedFilePos)
1385SourceLineCacheEnd = SourceLineCache+5;
1386 else if(SourceLineCache+10 < SourceLineCacheEnd) {
1387 if(SourceLineCache[10] > QueriedFilePos)
1388SourceLineCacheEnd = SourceLineCache+10;
1389 else if(SourceLineCache+20 < SourceLineCacheEnd) {
1390 if(SourceLineCache[20] > QueriedFilePos)
1391SourceLineCacheEnd = SourceLineCache+20;
1396 if(LastLineNoResult < Content->SourceLineCache.size())
1397SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1401 const unsigned*Pos =
1402std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1403 unsignedLineNo = Pos-SourceLineCacheStart;
1405LastLineNoFileIDQuery = FID;
1406LastLineNoContentCache = Content;
1407LastLineNoFilePos = QueriedFilePos;
1408LastLineNoResult = LineNo;
1415std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(
Loc);
1416 returngetLineNumber(LocInfo.first, LocInfo.second);
1421std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(
Loc);
1422 returngetLineNumber(LocInfo.first, LocInfo.second);
1441assert(
Loc.
isValid() &&
"Can't get file characteristic of invalid loc!");
1442std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(
Loc);
1443 const SLocEntry*SEntry = getSLocEntryForFile(LocInfo.first);
1454assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1457LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second);
1473 autoB = getBufferOrNone(getFileID(
Loc));
1476 returnB ? B->getBufferIdentifier() :
"<invalid buffer>";
1487 boolUseLineDirectives)
const{
1491std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(
Loc);
1504 FileIDFID = LocInfo.first;
1508 else if(
autoBuffer =
C->getBufferOrNone(
Diag, getFileManager()))
1509 Filename= Buffer->getBufferIdentifier();
1511 unsignedLineNo = getLineNumber(LocInfo.first, LocInfo.second, &
Invalid);
1514 unsignedColNo = getColumnNumber(LocInfo.first, LocInfo.second, &
Invalid);
1523assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1526LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) {
1528 if(Entry->FilenameID != -1) {
1529 Filename= LineTable->getFilename(Entry->FilenameID);
1532FID = FileID::get(0);
1539 unsignedMarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset);
1540LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1545 if(Entry->IncludeOffset) {
1546IncludeLoc = getLocForStartOfFile(LocInfo.first);
1566std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(
Loc);
1568 const SLocEntry*Entry = getSLocEntryForFile(LocInfo.first);
1577LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second))
1578 if(Entry->IncludeOffset)
1593 if((ID > 0 &&
unsigned(ID+1) == local_sloc_entry_size()))
1594NextOffset = getNextLocalOffset();
1595 else if(ID+1 == -1)
1596NextOffset = MaxLoadedOffset;
1598NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset();
1600 returnNextOffset - Entry.
getOffset() - 1;
1613 unsignedCol)
const{
1614assert(SourceFile &&
"Null source file!");
1615assert(
Line&& Col &&
"Line and column should start from 1!");
1617 FileIDFirstFID = translateFile(SourceFile);
1618 returntranslateLineCol(FirstFID,
Line, Col);
1626assert(SourceFile &&
"Null source file!");
1630 if(MainFileID.isValid()) {
1636 if(MainSLoc.
isFile()) {
1644 for(
unsignedI = 0, N = local_sloc_entry_size(); I != N; ++I) {
1645 const SLocEntry&SLoc = getLocalSLocEntry(I);
1648 returnFileID::get(I);
1652 for(
unsignedI = 0, N = loaded_sloc_entry_size(); I != N; ++I) {
1653 const SLocEntry&SLoc = getLoadedSLocEntry(I);
1656 returnFileID::get(-
int(I) - 2);
1666 unsignedCol)
const{
1669assert(
Line&& Col &&
"Line and column should start from 1!");
1684 if(
Line== 1 && Col == 1)
1691std::optional<llvm::MemoryBufferRef> Buffer =
1700 unsignedSize = Buffer->getBufferSize();
1707 const char*Buf = Buffer->getBufferStart() + FilePos;
1708 unsignedBufLength = Buffer->getBufferSize() - FilePos;
1715 while(i < BufLength-1 && i < Col-1 && Buf[i] !=
'\n'&& Buf[i] !=
'\r')
1727voidSourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
1739 if(
unsigned(ID) >= local_sloc_entry_size())
1741}
else if(ID == -1) {
1756 boolIncludedInFID =
1757(IncludeLoc.
isValid() && isInFileID(IncludeLoc, FID)) ||
1761(FID == MainFileID && Entry.
getFile().
getName() ==
"<built-in>");
1762 if(IncludedInFID) {
1765 if(Entry.
getFile().NumCreatedFIDs)
1766ID += Entry.
getFile().NumCreatedFIDs - 1
;
1786associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1788SourceLocation::getMacroLoc(Entry.
getOffset()),
1789getFileIDSize(FileID::get(ID)));
1793voidSourceManager::associateFileChunkWithMacroArgExp(
1794MacroArgsMap &MacroArgsCache,
1798 unsignedExpansionLength)
const{
1809 unsignedSpellRelativeOffs;
1810std::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc);
1812 const SLocEntry&Entry = getSLocEntry(SpellFID);
1814 unsignedSpellFIDSize = getFileIDSize(SpellFID);
1818 unsignedCurrSpellLength;
1819 if(SpellFIDEndOffs < SpellEndOffs)
1820CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1822CurrSpellLength = ExpansionLength;
1823associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1825ExpansionLoc, CurrSpellLength);
1828 if(SpellFIDEndOffs >= SpellEndOffs)
1832 unsigned advance= SpellFIDSize - SpellRelativeOffs + 1;
1836SpellRelativeOffs = 0;
1843 if(!isInFileID(SpellLoc, FID, &BeginOffs))
1846 unsignedEndOffs = BeginOffs + ExpansionLength;
1865MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1868MacroArgsCache[BeginOffs] = ExpansionLoc;
1869MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1872voidSourceManager::updateSlocUsageStats()
const{
1874NextLocalOffset + (MaxLoadedOffset - CurrentLoadedOffset);
1875MaxUsedSLocBytes.updateMax(UsedBytes);
1894std::tie(FID, Offset) = getDecomposedLoc(
Loc);
1898std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
1899 if(!MacroArgsCache) {
1900MacroArgsCache = std::make_unique<MacroArgsMap>();
1901computeMacroArgsCache(*MacroArgsCache, FID);
1904assert(!MacroArgsCache->empty());
1905MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1908 if(I == MacroArgsCache->begin())
1915 if(MacroArgExpandedLoc.
isValid())
1921std::pair<FileID, unsigned>
1924 returnstd::make_pair(
FileID(), 0);
1928 usingDecompTy = std::pair<FileID, unsigned>;
1929 autoInsertOp = IncludedLocMap.try_emplace(FID);
1930DecompTy &DecompLoc = InsertOp.first->second;
1931 if(!InsertOp.second)
1945DecompLoc = getDecomposedLoc(UpperLoc);
1951assert(isLoadedSourceLocation(
Loc) &&
1952 "Must be a source location in a loaded PCH/Module file");
1954 auto[FID, Ignore] = getDecomposedLoc(
Loc);
1960llvm::lower_bound(LoadedSLocEntryAllocBegin, FID, std::greater<FileID>{});
1963 "The failure to find the first FileID of a " 1964 "loaded AST from a loaded source location was unexpected.");
1969 conststd::pair<FileID, unsigned> &LOffs,
1970 conststd::pair<FileID, unsigned> &ROffs)
const{
1972 if(isLoadedFileID(LOffs.first) != isLoadedFileID(ROffs.first))
1975 if(isLoadedFileID(LOffs.first) && isLoadedFileID(ROffs.first)) {
1976 autoFindSLocEntryAlloc = [
this](
FileIDFID) {
1979 returnllvm::lower_bound(LoadedSLocEntryAllocBegin, FID,
1980std::greater<FileID>{});
1984 if(FindSLocEntryAlloc(LOffs.first) != FindSLocEntryAlloc(ROffs.first))
1998std::pair<FileID, unsigned> UpperLoc =
SM.getDecomposedIncludedLoc(
Loc.first);
1999 if(UpperLoc.first.isInvalid() ||
2000!
SM.isInTheSameTranslationUnitImpl(UpperLoc,
Loc))
2015 enum{ MagicCacheSize = 300 };
2016IsBeforeInTUCacheKey Key(LFID, RFID);
2022 if(IBTUCache.size() < MagicCacheSize)
2023 returnIBTUCache.try_emplace(Key, LFID, RFID).first->second;
2026InBeforeInTUCache::iterator I = IBTUCache.find(Key);
2027 if(I != IBTUCache.end())
2031IBTUCacheOverflow.setQueryFIDs(LFID, RFID);
2032 returnIBTUCacheOverflow;
2040assert(LHS.
isValid() && RHS.
isValid() &&
"Passed invalid source location!");
2044std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
2045std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
2050 if(LOffs.first.isInvalid() || ROffs.first.isInvalid())
2051 returnLOffs.first.isInvalid() && !ROffs.first.isInvalid();
2053std::pair<bool, bool> InSameTU = isInTheSameTranslationUnit(LOffs, ROffs);
2055 returnInSameTU.second;
2057 returnLOffs.first < ROffs.first;
2061std::pair<FileID, unsigned> &LOffs,
2062std::pair<FileID, unsigned> &ROffs)
const{
2064 if(!isInTheSameTranslationUnitImpl(LOffs, ROffs))
2065 returnstd::make_pair(
false,
false);
2068 if(LOffs.first == ROffs.first)
2069 returnstd::make_pair(
true, LOffs.second < ROffs.second);
2074getInBeforeInTUCache(LOffs.first, ROffs.first);
2079 returnstd::make_pair(
2080 true, IsBeforeInTUCache.
getCachedResult(LOffs.second, ROffs.second));
2089std::pair<FileID, unsigned> DecomposedLoc;
2092llvm::SmallDenseMap<FileID, Entry, 16> LChain;
2096LChain.try_emplace(LOffs.first, Entry{LOffs, LChild});
2099 if(LOffs.first == ROffs.first)
2101LChild = LOffs.first;
2106 autoLIt = LChain.find(ROffs.first);
2107 if(LIt != LChain.end()) {
2109LOffs = LIt->second.DecomposedLoc;
2110LChild = LIt->second.ChildFID;
2119 unsignedLChildID = LChild.ID;
2120 unsignedRChildID = RChild.ID;
2121assert(((LOffs.second != ROffs.second) ||
2122(LChildID == 0 || RChildID == 0) ||
2123isInSameSLocAddrSpace(getComposedLoc(LChild, 0),
2124getComposedLoc(RChild, 0),
nullptr)) &&
2125 "Mixed local/loaded FileIDs with same include location?");
2126IsBeforeInTUCache.
setCommonLoc(LOffs.first, LOffs.second, ROffs.second,
2127LChildID < RChildID);
2128 returnstd::make_pair(
2129 true, IsBeforeInTUCache.
getCachedResult(LOffs.second, ROffs.second));
2131RChild = ROffs.first;
2137StringRef LB = getBufferOrFake(LOffs.first).getBufferIdentifier();
2138StringRef RB = getBufferOrFake(ROffs.first).getBufferIdentifier();
2140 boolLIsBuiltins = LB ==
"<built-in>";
2141 boolRIsBuiltins = RB ==
"<built-in>";
2143 if(LIsBuiltins || RIsBuiltins) {
2144 if(LIsBuiltins != RIsBuiltins)
2145 returnstd::make_pair(
true, LIsBuiltins);
2148 returnstd::make_pair(
true, LOffs.first < ROffs.first);
2151 boolLIsAsm = LB ==
"<inline asm>";
2152 boolRIsAsm = RB ==
"<inline asm>";
2154 if(LIsAsm || RIsAsm) {
2155 if(LIsAsm != RIsAsm)
2156 returnstd::make_pair(
true, RIsAsm);
2157assert(LOffs.first == ROffs.first);
2158 returnstd::make_pair(
true,
false);
2161 boolLIsScratch = LB ==
"<scratch space>";
2162 boolRIsScratch = RB ==
"<scratch space>";
2164 if(LIsScratch || RIsScratch) {
2165 if(LIsScratch != RIsScratch)
2166 returnstd::make_pair(
true, LIsScratch);
2167 returnstd::make_pair(
true, LOffs.second < ROffs.second);
2170llvm_unreachable(
"Unsortable locations found");
2174llvm::errs() <<
"\n*** Source Manager Stats:\n";
2175llvm::errs() << FileInfos.size() <<
" files mapped, "<< MemBufferInfos.size()
2176<<
" mem buffers mapped.\n";
2177llvm::errs() << LocalSLocEntryTable.size() <<
" local SLocEntries allocated (" 2178<< llvm::capacity_in_bytes(LocalSLocEntryTable)
2179<<
" bytes of capacity), "<< NextLocalOffset
2180<<
"B of SLoc address space used.\n";
2181llvm::errs() << LoadedSLocEntryTable.size()
2182<<
" loaded SLocEntries allocated (" 2183<< llvm::capacity_in_bytes(LoadedSLocEntryTable)
2184<<
" bytes of capacity), " 2185<< MaxLoadedOffset - CurrentLoadedOffset
2186<<
"B of SLoc address space used.\n";
2188 unsignedNumLineNumsComputed = 0;
2189 unsignedNumFileBytesMapped = 0;
2191NumLineNumsComputed +=
bool(I->second->SourceLineCache);
2192NumFileBytesMapped += I->second->getSizeBytesMapped();
2194 unsignedNumMacroArgsComputed = MacroArgsCacheMap.size();
2196llvm::errs() << NumFileBytesMapped <<
" bytes of files mapped, " 2197<< NumLineNumsComputed <<
" files with line #'s computed, " 2198<< NumMacroArgsComputed <<
" files with macro args computed.\n";
2199llvm::errs() <<
"FileID scans: "<< NumLinearScans <<
" linear, " 2200<< NumBinaryProbes <<
" binary.\n";
2204llvm::raw_ostream &out = llvm::errs();
2207std::optional<SourceLocation::UIntTy> NextStart) {
2208out <<
"SLocEntry <FileID "<< ID <<
"> "<< (Entry.isFile() ?
"file":
"expansion")
2209<<
" <SourceLocation "<< Entry.getOffset() <<
":";
2211out << *NextStart <<
">\n";
2214 if(Entry.isFile()) {
2215 auto&FI = Entry.getFile();
2216 if(FI.NumCreatedFIDs)
2217out <<
" covers <FileID "<< ID <<
":"<<
int(ID + FI.NumCreatedFIDs)
2219 if(FI.getIncludeLoc().isValid())
2220out <<
" included from "<< FI.getIncludeLoc().getOffset() <<
"\n";
2221 auto&CC = FI.getContentCache();
2222out <<
" for "<< (CC.OrigEntry ? CC.OrigEntry->getName() :
"<none>")
2224 if(CC.BufferOverridden)
2225out <<
" contents overridden\n";
2226 if(CC.ContentsEntry != CC.OrigEntry) {
2227out <<
" contents from " 2228<< (CC.ContentsEntry ? CC.ContentsEntry->getName() :
"<none>")
2232 auto&EI = Entry.getExpansion();
2233out <<
" spelling from "<< EI.getSpellingLoc().getOffset() <<
"\n";
2234out <<
" macro "<< (EI.isMacroArgExpansion() ?
"arg":
"body")
2235<<
" range <"<< EI.getExpansionLocStart().getOffset() <<
":" 2236<< EI.getExpansionLocEnd().getOffset() <<
">\n";
2241 for(
unsignedID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++ID) {
2242DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2243ID == NumIDs - 1 ? NextLocalOffset
2244: LocalSLocEntryTable[ID + 1].getOffset());
2247std::optional<SourceLocation::UIntTy> NextStart;
2248 for(
unsignedIndex = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2249 intID = -(
int)Index - 2;
2250 if(SLocEntryLoaded[Index]) {
2251DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2252NextStart = LoadedSLocEntryTable[Index].getOffset();
2254NextStart = std::nullopt;
2265 unsignedInclusions = 0;
2267uint64_t DirectSize = 0;
2269uint64_t TotalSize = 0;
2271 usingUsageMap = llvm::MapVector<const FileEntry*, Info>;
2274uint64_t CountedSize = 0;
2276 autoAddUsageForFileID = [&](
FileIDID) {
2279 unsignedSize = getFileIDSize(ID) + 1;
2284 FileIDFileLocID = getFileID(FileStart);
2285 const FileEntry*Entry = getFileEntryForID(FileLocID);
2287Info &EntryInfo = Usage[Entry];
2288 if(EntryInfo.Loc.isInvalid())
2289EntryInfo.Loc = FileStart;
2290 if(ID == FileLocID) {
2291++EntryInfo.Inclusions;
2292EntryInfo.DirectSize += Size;
2294EntryInfo.TotalSize += Size;
2295CountedSize += Size;
2299 for(
size_tIndex = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2300AddUsageForFileID(FileID::get(-2 - Index));
2303 for(
size_tIndex = 0; Index != LocalSLocEntryTable.size(); ++Index) {
2304AddUsageForFileID(FileID::get(Index));
2309 autoSortedUsage = Usage.takeVector();
2310 autoCmp = [](
constUsageMap::value_type &A,
constUsageMap::value_type &B) {
2311 returnA.second.TotalSize > B.second.TotalSize ||
2312(A.second.TotalSize == B.second.TotalSize &&
2313A.second.Loc < B.second.Loc);
2315 autoSortedEnd = SortedUsage.end();
2316 if(MaxNotes && SortedUsage.size() > *MaxNotes) {
2317SortedEnd = SortedUsage.begin() + *MaxNotes;
2318std::nth_element(SortedUsage.begin(), SortedEnd, SortedUsage.end(), Cmp);
2320std::sort(SortedUsage.begin(), SortedEnd, Cmp);
2323uint64_t LocalUsage = NextLocalOffset;
2324uint64_t LoadedUsage = MaxLoadedOffset - CurrentLoadedOffset;
2325 intUsagePercent =
static_cast<int>(100.0 *
double(LocalUsage + LoadedUsage) /
2327 Diag.Report(diag::note_total_sloc_usage)
2328<< LocalUsage << LoadedUsage << (LocalUsage + LoadedUsage)
2332uint64_t ReportedSize = 0;
2334llvm::make_range(SortedUsage.begin(), SortedEnd)) {
2335 Diag.Report(
FileInfo.Loc, diag::note_file_sloc_usage)
2338ReportedSize +=
FileInfo.TotalSize;
2342 if(ReportedSize != CountedSize) {
2343 Diag.Report(diag::note_file_misc_sloc_usage)
2344<< (SortedUsage.end() - SortedEnd) << CountedSize - ReportedSize;
2353 size_tmalloc_bytes = 0;
2354 size_tmmap_bytes = 0;
2356 for(
unsignedi = 0, e = MemBufferInfos.size(); i != e; ++i)
2357 if(
size_tsized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2358 switch(MemBufferInfos[i]->getMemoryBufferKind()) {
2359 casellvm::MemoryBuffer::MemoryBuffer_MMap:
2360mmap_bytes += sized_mapped;
2362 casellvm::MemoryBuffer::MemoryBuffer_Malloc:
2363malloc_bytes += sized_mapped;
2371 size_tsize = llvm::capacity_in_bytes(MemBufferInfos) +
2372llvm::capacity_in_bytes(LocalSLocEntryTable) +
2373llvm::capacity_in_bytes(LoadedSLocEntryTable) +
2374llvm::capacity_in_bytes(SLocEntryLoaded) +
2375llvm::capacity_in_bytes(FileInfos);
2377 if(OverriddenFilesInfo)
2378size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
2384StringRef Content) {
2388 newllvm::vfs::InMemoryFileSystem);
2389InMemoryFileSystem->addFile(
2391llvm::MemoryBuffer::getMemBuffer(Content,
FileName,
2399Diagnostics = std::make_unique<DiagnosticsEngine>(
2402SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr);
2406assert(ID.isValid());
2407SourceMgr->setMainFileID(ID);
Defines the Diagnostic-related interfaces.
Defines the clang::FileManager interface and associated types.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
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.
static ParseState advance(ParseState S, size_t N)
Defines the clang::SourceLocation class and associated facilities.
Defines implementation details of the clang::SourceManager class.
static constexpr T likelyhasbetween(T x, unsigned char m, unsigned char n)
static bool MoveUpTranslationUnitIncludeHierarchy(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...
static bool isInvalid(LocType Loc, bool *Invalid)
STATISTIC(MaxUsedSLocBytes, "Maximum number of bytes used by source locations " "(both loaded and local).")
bool needConversion(StringRef Filename)
Helper function to determine if an input file requires conversion.
Defines the SourceManager interface.
Represents a character-granular source range.
void setEnd(SourceLocation e)
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
SourceLocation getBegin() const
void setTokenRange(bool TR)
Used for handling and querying diagnostic IDs.
Options for controlling the compiler diagnostics engine.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
void setSourceManager(SourceManager *SrcMgr)
virtual int getSLocEntryID(SourceLocation::UIntTy SLocOffset)=0
Get the index ID for the loaded SourceLocation offset.
virtual ~ExternalSLocEntrySource()
virtual bool ReadSLocEntry(int ID)=0
Read the source location entry with index ID, which will always be less than -1.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
Cached information about one file (either on disk or in the virtual file system).
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Implements support for file system lookup, file system caching, and directory search management.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt, bool IsText=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
OptionalFileEntryRef getBypassFile(FileEntryRef VFE)
Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual file entry,...
Keeps track of options that affect how file operations are performed.
Holds the cache used by isBeforeInTranslationUnit.
void setCommonLoc(FileID commonFID, unsigned lCommonOffset, unsigned rCommonOffset, bool LParentBeforeRParent)
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.
bool isCacheValid() const
Return true if the currently cached values match up with the specified LHS/RHS query.
Used to hold and unique data used to represent #line information.
const LineEntry * FindNearestLineEntry(FileID FID, unsigned Offset)
Find the line entry nearest to FID that is before it.
unsigned getLineTableFilenameID(StringRef Str)
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 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...
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
unsigned getLine() const
Return the presumed line number of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
SourceManagerForFile(StringRef FileName, StringRef Content)
Creates SourceManager and necessary dependencies (e.g.
This class handles loading and caching of source files into memory.
std::optional< StringRef > getNonBuiltinFilenameForID(FileID FID) const
Returns the filename for the provided FileID, unless it's a built-in buffer that's not represented by...
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
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...
unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Return the column # for the specified file position.
void noteSLocAddressSpaceUsage(DiagnosticsEngine &Diag, std::optional< unsigned > MaxNotes=32) const
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
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.
SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, bool UserFilesAreVolatile=false)
SourceLocation createTokenSplitLoc(SourceLocation SpellingLoc, SourceLocation TokenStart, SourceLocation TokenEnd)
Return a new SourceLocation that encodes that the token starting at TokenStart ends prematurely at To...
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
MemoryBufferSizes getMemoryBufferSizes() const
Return the amount of memory used by memory buffers, breaking down by heap-backed versus mmap'ed memor...
void setFileIsTransient(FileEntryRef SourceFile)
Specify that a file is transient.
bool isFileOverridden(const FileEntry *File) const
Returns true if the file contents have been overridden.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
SourceLocation translateLineCol(FileID FID, unsigned Line, unsigned Col) const
Get the source location in FID for the given line:col.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
std::optional< StringRef > getBufferDataOrNone(FileID FID) const
Return a StringRef to the source buffer data for the specified FileID, returning std::nullopt if inva...
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
void PrintStats() const
Print statistics to stderr.
FileID getUniqueLoadedASTFileID(SourceLocation Loc) const
bool isMainFile(const FileEntry &SourceFile)
Returns true when the given FileEntry corresponds to the main file.
size_t getDataStructureSizes() const
Return the amount of memory used for various side tables and data structures in the SourceManager.
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
bool isInTheSameTranslationUnitImpl(const std::pair< FileID, unsigned > &LOffs, const std::pair< FileID, unsigned > &ROffs) const
Determines whether the two decomposed source location is in the same TU.
const SrcMgr::SLocEntry & getLocalSLocEntry(unsigned Index) const
Get a local SLocEntry. This is exposed for indexing.
OptionalFileEntryRef bypassFileContentsOverride(FileEntryRef File)
Bypass the overridden contents of a file.
FileManager & getFileManager() const
unsigned local_sloc_entry_size() const
Get the number of local SLocEntries we have.
std::optional< StringRef > getBufferDataIfLoaded(FileID FID) const
Return a StringRef to the source buffer data for the specified FileID, returning std::nullopt if it's...
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
std::pair< int, SourceLocation::UIntTy > AllocateLoadedSLocEntries(unsigned NumSLocEntries, SourceLocation::UIntTy TotalSize)
Allocate a number of loaded SLocEntries, which will be actually loaded on demand from the external so...
void overrideFileContents(FileEntryRef SourceFile, const llvm::MemoryBufferRef &Buffer)
Override the contents of the given source file by providing an already-allocated buffer.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
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.
llvm::DenseMap< FileEntryRef, SrcMgr::ContentCache * >::const_iterator fileinfo_iterator
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
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...
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
void initializeForReplay(const SourceManager &Old)
Initialize this source manager suitably to replay the compilation described by Old.
FileID getOrCreateFileID(FileEntryRef SourceFile, SrcMgr::CharacteristicKind FileCharacter)
Get the FileID for SourceFile if it exists.
SourceLocation translateFileLineCol(const FileEntry *SourceFile, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::pair< FileID, unsigned > getDecomposedSpellingLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc, SourceLocation *MacroBegin=nullptr) const
Returns true if the given MacroID location points at the beginning of the immediate macro expansion.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
SourceLocation createExpansionLoc(SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned Length, bool ExpansionIsTokenRange=true, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Creates an expansion SLocEntry for a macro use.
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
std::pair< FileID, unsigned > getDecomposedIncludedLoc(FileID FID) const
Returns the "included/expanded in" decomposed location of the given FileID.
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const
If Loc points inside a function macro argument, the returned location will be the macro location in w...
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
LineTableInfo & getLineTable()
Retrieve the stored line table.
SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
SourceLocation createMacroArgExpansionLoc(SourceLocation SpellingLoc, SourceLocation ExpansionLoc, unsigned Length)
Creates an expansion SLocEntry for the substitution of an argument into a function-like macro's body.
A trivial tuple used to represent a source range.
One instance of this struct is kept for every file loaded or used.
void setBuffer(std::unique_ptr< llvm::MemoryBuffer > B)
Set the buffer.
std::optional< StringRef > getBufferDataIfLoaded() const
Return a StringRef to the source buffer data, only if it has already been loaded.
OptionalFileEntryRef ContentsEntry
References the file which the contents were actually loaded from.
unsigned getSizeBytesMapped() const
Returns the number of bytes actually mapped for this ContentCache.
unsigned IsTransient
True if this file may be transient, that is, if it might not exist at some later point in time when t...
unsigned getSize() const
Returns the size of the content encapsulated by this ContentCache.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const
Returns the kind of memory used to back the memory buffer for this content cache.
unsigned IsFileVolatile
True if this content cache was initially created for a source file considered to be volatile (likely ...
LineOffsetMapping SourceLineCache
A bump pointer allocated array of offsets for each source line.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, SourceLocation Loc=SourceLocation()) const
Returns the memory buffer for the associated content.
static const char * getInvalidBOM(StringRef BufStr)
unsigned BufferOverridden
Indicates whether the buffer itself was provided to override the actual file contents.
OptionalFileEntryRef OrigEntry
Reference to the file entry representing this ContentCache.
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded,...
SourceLocation getExpansionLocStart() const
static ExpansionInfo create(SourceLocation SpellingLoc, SourceLocation Start, SourceLocation End, bool ExpansionIsTokenRange=true)
Return a ExpansionInfo for an expansion.
bool isMacroBodyExpansion() const
SourceLocation getSpellingLoc() const
CharSourceRange getExpansionLocRange() const
bool isMacroArgExpansion() const
static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc, SourceLocation ExpansionLoc)
Return a special ExpansionInfo for the expansion of a macro argument into a function-like macro's bod...
static ExpansionInfo createForTokenSplit(SourceLocation SpellingLoc, SourceLocation Start, SourceLocation End)
Return a special ExpansionInfo representing a token that ends prematurely.
SourceLocation getExpansionLocEnd() const
Information about a FileID, basically just the logical file that it represents and include stack info...
const ContentCache & getContentCache() const
CharacteristicKind getFileCharacteristic() const
Return whether this is a system header or not.
static FileInfo get(SourceLocation IL, ContentCache &Con, CharacteristicKind FileCharacter, StringRef Filename)
Return a FileInfo object.
bool hasLineDirectives() const
Return true if this FileID has #line directives in it.
void setHasLineDirectives()
Set the flag that indicates that this FileID has line table entries associated with it.
SourceLocation getIncludeLoc() const
StringRef getName() const
Returns the name of the file that was used when the file was loaded from the underlying file system.
Mapping of line offsets into a source file.
const unsigned * begin() const
LineOffsetMapping()=default
const unsigned * end() const
static LineOffsetMapping get(llvm::MemoryBufferRef Buffer, llvm::BumpPtrAllocator &Alloc)
This is a discriminated union of FileInfo and ExpansionInfo.
SourceLocation::UIntTy getOffset() const
static SLocEntry get(SourceLocation::UIntTy Offset, const FileInfo &FI)
const FileInfo & getFile() const
const ExpansionInfo & getExpansion() const
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
SrcMgr::CharacteristicKind FileKind
Set the 0 if no flags, 1 if a system header,.
static LineEntry get(unsigned Offs, unsigned Line, int Filename, SrcMgr::CharacteristicKind FileKind, unsigned IncludeOffset)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4