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();
199 FilenameIDs.insert(std::make_pair(Name, FilenamesByID.size()));
201 FilenamesByID.push_back(&*IterBool.first);
202 return IterBool.first->second;
212 int FilenameID,
unsigned EntryExit,
214 std::vector<LineEntry> &Entries = LineEntries[FID];
218 if (FilenameID == -1 && !Entries.empty())
219 FilenameID = Entries.back().FilenameID;
221 assert((Entries.empty() || Entries.back().FileOffset <
Offset) &&
222 "Adding line entries out of order!");
224 unsigned IncludeOffset = 0;
225 if (EntryExit == 0) {
226 IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
227 }
else if (EntryExit == 1) {
228 IncludeOffset = Offset-1;
229 }
else if (EntryExit == 2) {
230 assert(!Entries.empty() && Entries.back().IncludeOffset &&
231 "PPDirectives should have caught case when popping empty include stack");
236 FindNearestLineEntry(FID, Entries.back().IncludeOffset))
237 IncludeOffset = PrevEntry->IncludeOffset;
240 Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, FileKind,
248 const std::vector<LineEntry> &Entries = LineEntries[FID];
249 assert(!Entries.empty() &&
"No #line entries for this FID after all!");
253 if (Entries.back().FileOffset <=
Offset)
254 return &Entries.back();
257 std::vector<LineEntry>::const_iterator I =
258 std::upper_bound(Entries.begin(), Entries.end(),
Offset);
259 if (I == Entries.begin())
return nullptr;
266 const std::vector<LineEntry> &Entries) {
267 LineEntries[FID] = Entries;
272 return getLineTable().getLineTableFilenameID(Name);
279 int FilenameID,
bool IsFileEntry,
282 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
284 bool Invalid =
false;
285 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
286 if (!Entry.
isFile() || Invalid)
294 (void) getLineTable();
296 unsigned EntryExit = 0;
302 LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
303 EntryExit, FileKind);
317 bool UserFilesAreVolatile)
318 : Diag(Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) {
329 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
330 if (MemBufferInfos[i]) {
331 MemBufferInfos[i]->~ContentCache();
332 ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
335 for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
336 I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
338 I->second->~ContentCache();
339 ContentCacheAlloc.Deallocate(I->second);
346 LocalSLocEntryTable.clear();
347 LoadedSLocEntryTable.clear();
348 SLocEntryLoaded.clear();
349 LastLineNoFileIDQuery =
FileID();
350 LastLineNoContentCache =
nullptr;
351 LastFileIDLookup =
FileID();
358 CurrentLoadedOffset = MaxLoadedOffset;
363 assert(MainFileID.
isInvalid() &&
"expected uninitialized SourceManager");
368 Clone->ContentsEntry =
Cache->ContentsEntry;
369 Clone->BufferOverridden =
Cache->BufferOverridden;
370 Clone->IsSystemFile =
Cache->IsSystemFile;
371 Clone->IsTransient =
Cache->IsTransient;
372 Clone->replaceBuffer(
Cache->getRawBuffer(),
true);
377 for (
unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
378 if (!Old.SLocEntryLoaded[I])
379 Old.loadSLocEntry(I,
nullptr);
382 for (
auto &
FileInfo : Old.FileInfos) {
386 Slot = CloneContentCache(
FileInfo.second);
393 SourceManager::getOrCreateContentCache(
const FileEntry *FileEnt,
395 assert(FileEnt &&
"Didn't specify a file entry to use?");
399 if (Entry)
return Entry;
404 if (OverriddenFilesInfo) {
407 llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
408 overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
409 if (overI == OverriddenFilesInfo->OverriddenFiles.end())
412 new (Entry)
ContentCache(OverridenFilesKeepOriginalName ? FileEnt
428 SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer,
433 MemBufferInfos.push_back(Entry);
439 bool *Invalid)
const {
440 assert(!SLocEntryLoaded[Index]);
441 if (ExternalSLocEntries->
ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
445 if (!SLocEntryLoaded[Index]) {
447 LoadedSLocEntryTable[Index] = SLocEntry::get(0,
449 getFakeContentCacheForRecovery(),
454 return LoadedSLocEntryTable[Index];
457 std::pair<int, unsigned>
459 unsigned TotalSize) {
460 assert(ExternalSLocEntries &&
"Don't have an external sloc source");
462 if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
463 return std::make_pair(0, 0);
464 LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
465 SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
466 CurrentLoadedOffset -= TotalSize;
467 int ID = LoadedSLocEntryTable.size();
468 return std::make_pair(-ID - 1, CurrentLoadedOffset);
473 llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery()
const {
474 if (!FakeBufferForRecovery)
475 FakeBufferForRecovery =
476 llvm::MemoryBuffer::getMemBuffer(
"<<<INVALID BUFFER>>");
478 return FakeBufferForRecovery.get();
484 SourceManager::getFakeContentCacheForRecovery()
const {
485 if (!FakeContentCacheForRecovery) {
486 FakeContentCacheForRecovery = llvm::make_unique<SrcMgr::ContentCache>();
487 FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
490 return FakeContentCacheForRecovery.get();
495 FileID SourceManager::getPreviousFileID(
FileID FID)
const {
506 }
else if (
unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
510 return FileID::get(ID-1);
523 }
else if (ID+1 >= -1) {
527 return FileID::get(ID+1);
540 int LoadedID,
unsigned LoadedOffset) {
542 assert(LoadedID != -1 &&
"Loading sentinel FileID");
543 unsigned Index = unsigned(-LoadedID) - 2;
544 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
545 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
546 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
547 FileInfo::get(IncludePos, File, FileCharacter));
548 SLocEntryLoaded[Index] =
true;
549 return FileID::get(LoadedID);
551 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
552 FileInfo::get(IncludePos, File,
554 unsigned FileSize = File->
getSize();
555 assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
556 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
557 "Ran out of source locations!");
560 NextLocalOffset += FileSize + 1;
564 FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
565 return LastFileIDLookup = FID;
571 unsigned TokLength) {
572 ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
574 return createExpansionLocImpl(Info, TokLength);
582 bool ExpansionIsTokenRange,
584 unsigned LoadedOffset) {
586 SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange);
587 return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
594 "token spans multiple files");
595 return createExpansionLocImpl(
596 ExpansionInfo::createForTokenSplit(Spelling, TokenStart, TokenEnd),
597 TokenEnd.getOffset() - TokenStart.getOffset());
601 SourceManager::createExpansionLocImpl(
const ExpansionInfo &Info,
604 unsigned LoadedOffset) {
606 assert(LoadedID != -1 &&
"Loading sentinel FileID");
607 unsigned Index = unsigned(-LoadedID) - 2;
608 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
609 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
610 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
611 SLocEntryLoaded[Index] =
true;
612 return SourceLocation::getMacroLoc(LoadedOffset);
614 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
615 assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
616 NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
617 "Ran out of source locations!");
619 NextLocalOffset += TokLength + 1;
620 return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
626 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
631 llvm::MemoryBuffer *Buffer,
634 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
639 getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
645 "Different sizes, use the FileManager to create a virtual file with " 647 assert(FileInfos.count(SourceFile) == 0 &&
648 "This function should be called at the initialization stage, before " 649 "any parsing occurs.");
650 getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
661 assert(OverriddenFilesInfo);
662 OverriddenFilesInfo->OverriddenFiles.erase(File);
663 OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
672 bool MyInvalid =
false;
674 if (!SLoc.
isFile() || MyInvalid) {
677 return "<<<<<INVALID SOURCE LOCATION>>>>>";
683 *Invalid = MyInvalid;
686 return "<<<<<INVALID SOURCE LOCATION>>>>>";
688 return Buf->getBuffer();
700 FileID SourceManager::getFileIDSlow(
unsigned SLocOffset)
const {
702 return FileID::get(0);
706 if (SLocOffset < NextLocalOffset)
707 return getFileIDLocal(SLocOffset);
708 return getFileIDLoaded(SLocOffset);
715 FileID SourceManager::getFileIDLocal(
unsigned SLocOffset)
const {
716 assert(SLocOffset < NextLocalOffset &&
"Bad function choice");
731 if (LastFileIDLookup.ID < 0 ||
732 LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
734 I = LocalSLocEntryTable.end();
737 I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
742 unsigned NumProbes = 0;
746 FileID Res = FileID::get(
int(I - LocalSLocEntryTable.begin()));
751 LastFileIDLookup = Res;
752 NumLinearScans += NumProbes+1;
755 if (++NumProbes == 8)
761 unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
765 unsigned LessIndex = 0;
768 bool Invalid =
false;
769 unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
772 return FileID::get(0);
778 if (MidOffset > SLocOffset) {
779 GreaterIndex = MiddleIndex;
786 if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
787 FileID Res = FileID::get(MiddleIndex);
791 if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
792 LastFileIDLookup = Res;
793 NumBinaryProbes += NumProbes;
798 LessIndex = MiddleIndex;
806 FileID SourceManager::getFileIDLoaded(
unsigned SLocOffset)
const {
808 if (SLocOffset < CurrentLoadedOffset) {
809 assert(0 &&
"Invalid SLocOffset or bad function choice");
818 int LastID = LastFileIDLookup.ID;
819 if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
822 I = (-LastID - 2) + 1;
825 for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) {
829 FileID Res = FileID::get(-
int(I) - 2);
832 LastFileIDLookup = Res;
833 NumLinearScans += NumProbes + 1;
841 unsigned GreaterIndex = I;
842 unsigned LessIndex = LoadedSLocEntryTable.size();
846 unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
855 if (GreaterIndex == MiddleIndex) {
856 assert(0 &&
"binary search missed the entry");
859 GreaterIndex = MiddleIndex;
863 if (isOffsetInFileID(FileID::get(-
int(MiddleIndex) - 2), SLocOffset)) {
864 FileID Res = FileID::get(-
int(MiddleIndex) - 2);
866 LastFileIDLookup = Res;
867 NumBinaryProbes += NumProbes;
872 if (LessIndex == MiddleIndex) {
873 assert(0 &&
"binary search missed the entry");
876 LessIndex = MiddleIndex;
915 std::pair<FileID, unsigned>
916 SourceManager::getDecomposedExpansionLocSlowCase(
930 return std::make_pair(FID, Offset);
933 std::pair<FileID, unsigned>
948 return std::make_pair(FID, Offset);
966 assert(Loc.
isMacroID() &&
"Not a macro expansion loc!");
1023 if (DecompLoc.second > 0)
1026 bool Invalid =
false;
1037 FileID PrevFID = getPreviousFileID(DecompLoc.first);
1049 *MacroBegin = ExpLoc;
1062 bool Invalid =
false;
1072 FileID NextFID = getNextFileID(FID);
1096 bool *Invalid)
const {
1102 bool CharDataInvalid =
false;
1104 if (CharDataInvalid || !Entry.
isFile()) {
1108 return "<<<<INVALID BUFFER>>>>";
1113 *Invalid = CharDataInvalid;
1114 return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
1120 bool *Invalid)
const {
1121 bool MyInvalid =
false;
1122 llvm::MemoryBuffer *MemBuf =
getBuffer(FID, &MyInvalid);
1124 *Invalid = MyInvalid;
1130 if (FilePos > MemBuf->getBufferSize()) {
1136 const char *Buf = MemBuf->getBufferStart();
1139 if (LastLineNoFileIDQuery == FID &&
1141 LastLineNoResult < LastLineNoContentCache->NumLines) {
1143 unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1144 unsigned LineEnd = SourceLineCache[LastLineNoResult];
1145 if (FilePos >= LineStart && FilePos < LineEnd) {
1150 if (FilePos + 1 == LineEnd && FilePos > LineStart) {
1151 if (Buf[FilePos - 1] ==
'\r' || Buf[FilePos - 1] ==
'\n')
1154 return FilePos - LineStart + 1;
1158 unsigned LineStart = FilePos;
1159 while (LineStart && Buf[LineStart-1] !=
'\n' && Buf[LineStart-1] !=
'\r')
1161 return FilePos-LineStart+1;
1166 template<
typename LocType>
1168 bool MyInvalid = Loc.isInvalid();
1170 *Invalid = MyInvalid;
1175 bool *Invalid)
const {
1182 bool *Invalid)
const {
1189 bool *Invalid)
const {
1199 static LLVM_ATTRIBUTE_NOINLINE
void 1201 llvm::BumpPtrAllocator &Alloc,
1204 llvm::BumpPtrAllocator &Alloc,
1216 LineOffsets.push_back(0);
1218 const unsigned char *Buf = (
const unsigned char *)Buffer->getBufferStart();
1219 const unsigned char *
End = (
const unsigned char *)Buffer->getBufferEnd();
1223 const unsigned char *NextBuf = (
const unsigned char *)Buf;
1233 while (((
uintptr_t)NextBuf & 0xF) != 0) {
1234 if (*NextBuf ==
'\n' || *NextBuf ==
'\r' || *NextBuf ==
'\0')
1235 goto FoundSpecialChar;
1240 while (NextBuf+16 <= End) {
1241 const __m128i Chunk = *(
const __m128i*)NextBuf;
1248 NextBuf += llvm::countTrailingZeros(Mask);
1249 goto FoundSpecialChar;
1255 while (*NextBuf !=
'\n' && *NextBuf !=
'\r' && *NextBuf !=
'\0')
1261 Offs += NextBuf-Buf;
1264 if (Buf[0] ==
'\n' || Buf[0] ==
'\r') {
1266 if ((Buf[1] ==
'\n' || Buf[1] ==
'\r') && Buf[0] != Buf[1]) {
1272 LineOffsets.push_back(Offs);
1275 if (Buf == End)
break;
1285 std::copy(LineOffsets.begin(), LineOffsets.end(), FI->
SourceLineCache);
1293 bool *Invalid)
const {
1301 if (LastLineNoFileIDQuery == FID)
1302 Content = LastLineNoContentCache;
1304 bool MyInvalid =
false;
1306 if (MyInvalid || !Entry.
isFile()) {
1318 bool MyInvalid =
false;
1321 *Invalid = MyInvalid;
1330 unsigned *SourceLineCacheStart = SourceLineCache;
1331 unsigned *SourceLineCacheEnd = SourceLineCache + Content->
NumLines;
1333 unsigned QueriedFilePos = FilePos+1;
1348 if (LastLineNoFileIDQuery == FID) {
1349 if (QueriedFilePos >= LastLineNoFilePos) {
1351 SourceLineCache = SourceLineCache+LastLineNoResult-1;
1357 if (SourceLineCache+5 < SourceLineCacheEnd) {
1358 if (SourceLineCache[5] > QueriedFilePos)
1359 SourceLineCacheEnd = SourceLineCache+5;
1360 else if (SourceLineCache+10 < SourceLineCacheEnd) {
1361 if (SourceLineCache[10] > QueriedFilePos)
1362 SourceLineCacheEnd = SourceLineCache+10;
1363 else if (SourceLineCache+20 < SourceLineCacheEnd) {
1364 if (SourceLineCache[20] > QueriedFilePos)
1365 SourceLineCacheEnd = SourceLineCache+20;
1370 if (LastLineNoResult < Content->NumLines)
1371 SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1376 = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1377 unsigned LineNo = Pos-SourceLineCacheStart;
1379 LastLineNoFileIDQuery = FID;
1380 LastLineNoContentCache = Content;
1381 LastLineNoFilePos = QueriedFilePos;
1382 LastLineNoResult = LineNo;
1387 bool *Invalid)
const {
1393 bool *Invalid)
const {
1399 bool *Invalid)
const {
1415 assert(Loc.
isValid() &&
"Can't get file characteristic of invalid loc!");
1417 bool Invalid =
false;
1419 if (Invalid || !SEntry.
isFile())
1429 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1445 bool *Invalid)
const {
1446 if (
isInvalid(Loc, Invalid))
return "<invalid loc>";
1459 bool UseLineDirectives)
const {
1465 bool Invalid =
false;
1467 if (Invalid || !Entry.
isFile())
1480 Filename = C->
getBuffer(Diag, *
this)->getBufferIdentifier();
1482 unsigned LineNo =
getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1485 unsigned ColNo =
getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1494 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1499 if (Entry->FilenameID != -1)
1500 Filename = LineTable->
getFilename(Entry->FilenameID);
1506 unsigned MarkerLineNo =
getLineNumber(LocInfo.first, Entry->FileOffset);
1507 LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1512 if (Entry->IncludeOffset) {
1519 return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc);
1535 bool Invalid =
false;
1537 if (Invalid || !Entry.
isFile())
1546 if (Entry->IncludeOffset)
1554 bool Invalid =
false;
1560 unsigned NextOffset;
1563 else if (ID+1 == -1)
1564 NextOffset = MaxLoadedOffset;
1568 return NextOffset - Entry.
getOffset() - 1;
1584 llvm::sys::fs::UniqueID
ID;
1585 if (llvm::sys::fs::getUniqueID(File->
getName(),
ID))
1597 unsigned Col)
const {
1598 assert(SourceFile &&
"Null source file!");
1599 assert(Line && Col &&
"Line and column should start from 1!");
1610 assert(SourceFile &&
"Null source file!");
1620 bool Invalid =
false;
1628 if (!MainContentCache) {
1630 }
else if (MainContentCache->
OrigEntry == SourceFile) {
1631 FirstFID = MainFileID;
1636 SourceFileName = llvm::sys::path::filename(SourceFile->
getName());
1637 if (*SourceFileName == llvm::sys::path::filename(MainFile->
getName())) {
1639 if (SourceFileUID) {
1642 if (*SourceFileUID == *MainFileUID) {
1643 FirstFID = MainFileID;
1644 SourceFile = MainFile;
1657 bool Invalid =
false;
1665 FirstFID = FileID::get(I);
1676 FirstFID = FileID::get(-
int(I) - 2);
1688 (SourceFileName = llvm::sys::path::filename(SourceFile->
getName()))) &&
1690 bool Invalid =
false;
1704 *SourceFileName == llvm::sys::path::filename(Entry->
getName())) {
1707 if (*SourceFileUID == *EntryUID) {
1708 FirstFID = FileID::get(I);
1726 unsigned Col)
const {
1729 assert(Line && Col &&
"Line and column should start from 1!");
1734 bool Invalid =
false;
1744 if (Line == 1 && Col == 1)
1755 bool MyInvalid =
false;
1762 unsigned Size = Content->
getBuffer(Diag, *
this)->getBufferSize();
1768 llvm::MemoryBuffer *Buffer = Content->
getBuffer(Diag, *
this);
1770 const char *Buf = Buffer->getBufferStart() + FilePos;
1771 unsigned BufLength = Buffer->getBufferSize() - FilePos;
1778 while (i < BufLength-1 && i < Col-1 && Buf[i] !=
'\n' && Buf[i] !=
'\r')
1790 void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
1804 }
else if (ID == -1) {
1808 bool Invalid =
false;
1821 if (Entry.
getFile().NumCreatedFIDs)
1822 ID += Entry.
getFile().NumCreatedFIDs - 1;
1836 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1838 SourceLocation::getMacroLoc(Entry.
getOffset()),
1843 void SourceManager::associateFileChunkWithMacroArgExp(
1844 MacroArgsMap &MacroArgsCache,
1848 unsigned ExpansionLength)
const {
1850 unsigned SpellBeginOffs = SpellLoc.getOffset();
1851 unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
1859 unsigned SpellRelativeOffs;
1863 unsigned SpellFIDBeginOffs = Entry.
getOffset();
1865 unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1868 unsigned CurrSpellLength;
1869 if (SpellFIDEndOffs < SpellEndOffs)
1870 CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1872 CurrSpellLength = ExpansionLength;
1873 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1875 ExpansionLoc, CurrSpellLength);
1878 if (SpellFIDEndOffs >= SpellEndOffs)
1882 unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1884 ExpansionLength -= advance;
1886 SpellRelativeOffs = 0;
1896 unsigned EndOffs = BeginOffs + ExpansionLength;
1915 MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1918 MacroArgsCache[BeginOffs] = ExpansionLoc;
1919 MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1942 std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
1943 if (!MacroArgsCache) {
1944 MacroArgsCache = llvm::make_unique<MacroArgsMap>();
1945 computeMacroArgsCache(*MacroArgsCache, FID);
1948 assert(!MacroArgsCache->empty());
1949 MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1952 unsigned MacroArgBeginOffs = I->first;
1954 if (MacroArgExpandedLoc.
isValid())
1960 std::pair<FileID, unsigned>
1963 return std::make_pair(
FileID(), 0);
1967 using DecompTy = std::pair<FileID, unsigned>;
1968 using MapTy = llvm::DenseMap<FileID, DecompTy>;
1969 std::pair<MapTy::iterator, bool>
1970 InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy()));
1971 DecompTy &DecompLoc = InsertOp.first->second;
1972 if (!InsertOp.second)
1976 bool Invalid =
false;
1998 if (UpperLoc.first.isInvalid())
2012 enum { MagicCacheSize = 300 };
2013 IsBeforeInTUCacheKey Key(LFID, RFID);
2019 if (IBTUCache.size() < MagicCacheSize)
2020 return IBTUCache[Key];
2023 InBeforeInTUCache::iterator I = IBTUCache.find(Key);
2024 if (I != IBTUCache.end())
2028 return IBTUCacheOverflow;
2036 assert(LHS.
isValid() && RHS.
isValid() &&
"Passed invalid source location!");
2046 if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
2047 return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
2051 return InSameTU.second;
2056 StringRef LB =
getBuffer(LOffs.first)->getBufferIdentifier();
2057 StringRef RB =
getBuffer(ROffs.first)->getBufferIdentifier();
2058 bool LIsBuiltins = LB ==
"<built-in>";
2059 bool RIsBuiltins = RB ==
"<built-in>";
2061 if (LIsBuiltins || RIsBuiltins) {
2062 if (LIsBuiltins != RIsBuiltins)
2066 return LOffs.first < ROffs.first;
2068 bool LIsAsm = LB ==
"<inline asm>";
2069 bool RIsAsm = RB ==
"<inline asm>";
2071 if (LIsAsm || RIsAsm) {
2072 if (LIsAsm != RIsAsm)
2074 assert(LOffs.first == ROffs.first);
2077 bool LIsScratch = LB ==
"<scratch space>";
2078 bool RIsScratch = RB ==
"<scratch space>";
2080 if (LIsScratch || RIsScratch) {
2081 if (LIsScratch != RIsScratch)
2083 return LOffs.second < ROffs.second;
2085 llvm_unreachable(
"Unsortable locations found");
2089 std::pair<FileID, unsigned> &LOffs,
2090 std::pair<FileID, unsigned> &ROffs)
const {
2092 if (LOffs.first == ROffs.first)
2093 return std::make_pair(
true, LOffs.second < ROffs.second);
2098 getInBeforeInTUCache(LOffs.first, ROffs.first);
2102 if (IsBeforeInTUCache.
isCacheValid(LOffs.first, ROffs.first))
2103 return std::make_pair(
2107 IsBeforeInTUCache.
setQueryFIDs(LOffs.first, ROffs.first,
2108 LOffs.first.ID < ROffs.first.ID);
2115 using LocSet = llvm::SmallDenseMap<FileID, unsigned, 16>;
2118 LChain.insert(LOffs);
2123 while((I = LChain.find(ROffs.first)) == LChain.end()) {
2127 if (I != LChain.end())
2132 if (LOffs.first == ROffs.first) {
2133 IsBeforeInTUCache.
setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
2134 return std::make_pair(
2138 IsBeforeInTUCache.
clear();
2139 return std::make_pair(
false,
false);
2143 llvm::errs() <<
"\n*** Source Manager Stats:\n";
2144 llvm::errs() << FileInfos.size() <<
" files mapped, " << MemBufferInfos.size()
2145 <<
" mem buffers mapped.\n";
2146 llvm::errs() << LocalSLocEntryTable.size() <<
" local SLocEntry's allocated (" 2147 << llvm::capacity_in_bytes(LocalSLocEntryTable)
2148 <<
" bytes of capacity), " 2149 << NextLocalOffset <<
"B of Sloc address space used.\n";
2150 llvm::errs() << LoadedSLocEntryTable.size()
2151 <<
" loaded SLocEntries allocated, " 2152 << MaxLoadedOffset - CurrentLoadedOffset
2153 <<
"B of Sloc address space used.\n";
2155 unsigned NumLineNumsComputed = 0;
2156 unsigned NumFileBytesMapped = 0;
2158 NumLineNumsComputed += I->second->SourceLineCache !=
nullptr;
2159 NumFileBytesMapped += I->second->getSizeBytesMapped();
2161 unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2163 llvm::errs() << NumFileBytesMapped <<
" bytes of files mapped, " 2164 << NumLineNumsComputed <<
" files with line #'s computed, " 2165 << NumMacroArgsComputed <<
" files with macro args computed.\n";
2166 llvm::errs() <<
"FileID scans: " << NumLinearScans <<
" linear, " 2167 << NumBinaryProbes <<
" binary.\n";
2171 llvm::raw_ostream &out = llvm::errs();
2175 out <<
"SLocEntry <FileID " << ID <<
"> " << (Entry.isFile() ?
"file" :
"expansion")
2176 <<
" <SourceLocation " << Entry.getOffset() <<
":";
2178 out << *NextStart <<
">\n";
2181 if (Entry.isFile()) {
2182 auto &FI = Entry.getFile();
2183 if (FI.NumCreatedFIDs)
2184 out <<
" covers <FileID " << ID <<
":" << int(ID + FI.NumCreatedFIDs)
2186 if (FI.getIncludeLoc().isValid())
2187 out <<
" included from " << FI.getIncludeLoc().getOffset() <<
"\n";
2188 if (
auto *CC = FI.getContentCache()) {
2189 out <<
" for " << (CC->OrigEntry ? CC->OrigEntry->getName() :
"<none>")
2191 if (CC->BufferOverridden)
2192 out <<
" contents overridden\n";
2193 if (CC->ContentsEntry != CC->OrigEntry) {
2194 out <<
" contents from " 2195 << (CC->ContentsEntry ? CC->ContentsEntry->getName() :
"<none>")
2200 auto &EI = Entry.getExpansion();
2201 out <<
" spelling from " << EI.getSpellingLoc().getOffset() <<
"\n";
2202 out <<
" macro " << (EI.isMacroArgExpansion() ?
"arg" :
"body")
2203 <<
" range <" << EI.getExpansionLocStart().getOffset() <<
":" 2204 << EI.getExpansionLocEnd().getOffset() <<
">\n";
2209 for (
unsigned ID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++
ID) {
2210 DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2211 ID == NumIDs - 1 ? NextLocalOffset
2212 : LocalSLocEntryTable[ID + 1].getOffset());
2216 for (
unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2217 int ID = -(int)Index - 2;
2218 if (SLocEntryLoaded[Index]) {
2219 DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2220 NextStart = LoadedSLocEntryTable[Index].getOffset();
2232 size_t malloc_bytes = 0;
2233 size_t mmap_bytes = 0;
2235 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2236 if (
size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2237 switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2238 case llvm::MemoryBuffer::MemoryBuffer_MMap:
2239 mmap_bytes += sized_mapped;
2241 case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2242 malloc_bytes += sized_mapped;
2250 size_t size = llvm::capacity_in_bytes(MemBufferInfos)
2251 + llvm::capacity_in_bytes(LocalSLocEntryTable)
2252 + llvm::capacity_in_bytes(LoadedSLocEntryTable)
2253 + llvm::capacity_in_bytes(SLocEntryLoaded)
2254 + llvm::capacity_in_bytes(FileInfos);
2256 if (OverriddenFilesInfo)
2257 size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
2263 StringRef Content) {
2268 InMemoryFileSystem->addFile(
2270 llvm::MemoryBuffer::getMemBuffer(Content, FileName,
2278 Diagnostics = llvm::make_unique<DiagnosticsEngine>(
2281 SourceMgr = llvm::make_unique<SourceManager>(*Diagnostics, *FileMgr);
2284 assert(ID.isValid());
2285 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.
llvm::DenseMap< Stmt *, Stmt * > MapTy
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...
An in-memory file system.
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.
static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_set1_epi8(char __b)
Initializes all values in a 128-bit vector of [16 x i8] with the specified 8-bit value.
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
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
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...
static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_or_si128(__m128i __a, __m128i __b)
Performs a bitwise OR of two 128-bit integer vectors.
LineTableInfo & getLineTable()
Retrieve the stored line table.
CharSourceRange getExpansionLocRange() const
static __inline__ int __DEFAULT_FN_ATTRS _mm_movemask_epi8(__m128i __a)
Copies the values of the most significant bits from each 8-bit element in a 128-bit integer vector of...
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.
static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cmpeq_epi8(__m128i __a, __m128i __b)
Compares each of the corresponding 8-bit values of the 128-bit integer vectors for equality...
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const