18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/Support/Capacity.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/MemoryBuffer.h"
24 #include "llvm/Support/Path.h"
25 #include "llvm/Support/raw_ostream.h"
30 using namespace clang;
31 using namespace SrcMgr;
32 using llvm::MemoryBuffer;
38 ContentCache::~ContentCache() {
39 if (shouldFreeBuffer())
40 delete Buffer.getPointer();
45 unsigned ContentCache::getSizeBytesMapped()
const {
46 return Buffer.getPointer() ?
Buffer.getPointer()->getBufferSize() : 0;
51 llvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind()
const {
52 assert(
Buffer.getPointer());
56 return llvm::MemoryBuffer::MemoryBuffer_Malloc;
58 llvm::MemoryBuffer *buf =
Buffer.getPointer();
59 return buf->getBufferKind();
66 unsigned ContentCache::getSize()
const {
68 : (
unsigned) ContentsEntry->getSize();
71 void ContentCache::replaceBuffer(llvm::MemoryBuffer *B,
bool DoNotFree) {
72 if (B && B ==
Buffer.getPointer()) {
73 assert(0 &&
"Replacing with the same buffer");
74 Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
78 if (shouldFreeBuffer())
79 delete Buffer.getPointer();
81 Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
87 bool *Invalid)
const {
90 if (
Buffer.getPointer() || !ContentsEntry) {
92 *Invalid = isBufferInvalid();
94 return Buffer.getPointer();
111 if (!BufferOrError) {
112 StringRef FillStr(
"<<<MISSING SOURCE FILE>>>\n");
113 Buffer.setPointer(MemoryBuffer::getNewUninitMemBuffer(
114 ContentsEntry->getSize(),
"<invalid>").release());
115 char *Ptr =
const_cast<char*
>(
Buffer.getPointer()->getBufferStart());
116 for (
unsigned i = 0, e = ContentsEntry->getSize(); i != e; ++i)
117 Ptr[i] = FillStr[i % FillStr.size()];
121 ContentsEntry->getName(),
122 BufferOrError.getError().message());
124 Diag.
Report(Loc, diag::err_cannot_open_file)
125 << ContentsEntry->getName() << BufferOrError.getError().message();
129 if (Invalid) *Invalid =
true;
130 return Buffer.getPointer();
133 Buffer.setPointer(BufferOrError->release());
137 if (getRawBuffer()->getBufferSize() != (
size_t)ContentsEntry->getSize()) {
140 ContentsEntry->getName());
142 Diag.
Report(Loc, diag::err_file_modified)
143 << ContentsEntry->getName();
146 if (Invalid) *Invalid =
true;
147 return Buffer.getPointer();
153 StringRef BufStr =
Buffer.getPointer()->getBuffer();
154 const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr)
155 .StartsWith(
"\xFE\xFF",
"UTF-16 (BE)")
156 .StartsWith(
"\xFF\xFE",
"UTF-16 (LE)")
157 .StartsWith(
"\x00\x00\xFE\xFF",
"UTF-32 (BE)")
158 .StartsWith(
"\xFF\xFE\x00\x00",
"UTF-32 (LE)")
159 .StartsWith(
"\x2B\x2F\x76",
"UTF-7")
160 .StartsWith(
"\xF7\x64\x4C",
"UTF-1")
161 .StartsWith(
"\xDD\x73\x66\x73",
"UTF-EBCDIC")
162 .StartsWith(
"\x0E\xFE\xFF",
"SDSU")
163 .StartsWith(
"\xFB\xEE\x28",
"BOCU-1")
164 .StartsWith(
"\x84\x31\x95\x33",
"GB-18030")
168 Diag.
Report(Loc, diag::err_unsupported_bom)
169 << InvalidBOM << ContentsEntry->getName();
174 *Invalid = isBufferInvalid();
176 return Buffer.getPointer();
181 FilenameIDs.insert(std::make_pair(Name, FilenamesByID.size()));
183 FilenamesByID.push_back(&*IterBool.first);
184 return IterBool.first->second;
191 unsigned LineNo,
int FilenameID) {
192 std::vector<LineEntry> &Entries = LineEntries[FID];
194 assert((Entries.empty() || Entries.back().FileOffset <
Offset) &&
195 "Adding line entries out of order!");
198 unsigned IncludeOffset = 0;
200 if (!Entries.empty()) {
203 if (FilenameID == -1)
204 FilenameID = Entries.back().FilenameID;
208 Kind = Entries.back().FileKind;
209 IncludeOffset = Entries.back().IncludeOffset;
212 Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, Kind,
222 unsigned LineNo,
int FilenameID,
225 assert(FilenameID != -1 &&
"Unspecified filename should use other accessor");
227 std::vector<LineEntry> &Entries = LineEntries[FID];
229 assert((Entries.empty() || Entries.back().FileOffset <
Offset) &&
230 "Adding line entries out of order!");
232 unsigned IncludeOffset = 0;
233 if (EntryExit == 0) {
234 IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
235 }
else if (EntryExit == 1) {
236 IncludeOffset = Offset-1;
237 }
else if (EntryExit == 2) {
238 assert(!Entries.empty() && Entries.back().IncludeOffset &&
239 "PPDirectives should have caught case when popping empty include stack");
244 FindNearestLineEntry(FID, Entries.back().IncludeOffset))
245 IncludeOffset = PrevEntry->IncludeOffset;
248 Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, FileKind,
257 const std::vector<LineEntry> &Entries = LineEntries[FID];
258 assert(!Entries.empty() &&
"No #line entries for this FID after all!");
262 if (Entries.back().FileOffset <=
Offset)
263 return &Entries.back();
266 std::vector<LineEntry>::const_iterator
I =
267 std::upper_bound(Entries.begin(), Entries.end(),
Offset);
268 if (I == Entries.begin())
return nullptr;
275 const std::vector<LineEntry> &Entries) {
276 LineEntries[FID] = Entries;
282 return getLineTable().getLineTableFilenameID(Name);
291 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
293 bool Invalid =
false;
294 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
295 if (!Entry.
isFile() || Invalid)
303 getLineTable().AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID);
308 int FilenameID,
bool IsFileEntry,
309 bool IsFileExit,
bool IsSystemHeader,
310 bool IsExternCHeader) {
313 if (FilenameID == -1) {
314 assert(!IsFileEntry && !IsFileExit && !IsSystemHeader && !IsExternCHeader &&
315 "Can't set flags without setting the filename!");
316 return AddLineNote(Loc, LineNo, FilenameID);
319 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
321 bool Invalid =
false;
322 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
323 if (!Entry.
isFile() || Invalid)
331 (void) getLineTable();
336 else if (IsSystemHeader)
341 unsigned EntryExit = 0;
347 LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
348 EntryExit, FileKind);
362 bool UserFilesAreVolatile)
363 : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(
true),
364 UserFilesAreVolatile(UserFilesAreVolatile), FilesAreTransient(
false),
365 ExternalSLocEntries(nullptr), LineTable(nullptr), NumLinearScans(0),
377 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
378 if (MemBufferInfos[i]) {
379 MemBufferInfos[i]->~ContentCache();
380 ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
384 I = FileInfos.begin(),
E = FileInfos.end();
I !=
E; ++
I) {
386 I->second->~ContentCache();
387 ContentCacheAlloc.Deallocate(
I->second);
391 llvm::DeleteContainerSeconds(MacroArgsCacheMap);
396 LocalSLocEntryTable.clear();
397 LoadedSLocEntryTable.clear();
398 SLocEntryLoaded.clear();
399 LastLineNoFileIDQuery =
FileID();
400 LastLineNoContentCache =
nullptr;
401 LastFileIDLookup =
FileID();
408 CurrentLoadedOffset = MaxLoadedOffset;
415 SourceManager::getOrCreateContentCache(
const FileEntry *FileEnt,
417 assert(FileEnt &&
"Didn't specify a file entry to use?");
420 ContentCache *&Entry = FileInfos[FileEnt];
421 if (Entry)
return Entry;
424 Entry = ContentCacheAlloc.Allocate<ContentCache>();
426 if (OverriddenFilesInfo) {
430 overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
431 if (overI == OverriddenFilesInfo->OverriddenFiles.end())
432 new (Entry) ContentCache(FileEnt);
434 new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt
438 new (Entry) ContentCache(FileEnt);
441 Entry->IsSystemFile = isSystemFile;
442 Entry->IsTransient = FilesAreTransient;
450 const ContentCache *SourceManager::createMemBufferContentCache(
451 std::unique_ptr<llvm::MemoryBuffer>
Buffer) {
453 ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>();
454 new (Entry) ContentCache();
455 MemBufferInfos.push_back(Entry);
456 Entry->setBuffer(std::move(Buffer));
461 bool *Invalid)
const {
462 assert(!SLocEntryLoaded[Index]);
463 if (ExternalSLocEntries->
ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
467 if (!SLocEntryLoaded[Index]) {
469 LoadedSLocEntryTable[Index] = SLocEntry::get(0,
471 getFakeContentCacheForRecovery(),
476 return LoadedSLocEntryTable[Index];
479 std::pair<int, unsigned>
481 unsigned TotalSize) {
482 assert(ExternalSLocEntries &&
"Don't have an external sloc source");
484 if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
485 return std::make_pair(0, 0);
486 LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
487 SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
488 CurrentLoadedOffset -= TotalSize;
489 int ID = LoadedSLocEntryTable.size();
490 return std::make_pair(-ID - 1, CurrentLoadedOffset);
495 llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery()
const {
496 if (!FakeBufferForRecovery)
497 FakeBufferForRecovery =
498 llvm::MemoryBuffer::getMemBuffer(
"<<<INVALID BUFFER>>");
500 return FakeBufferForRecovery.get();
505 const SrcMgr::ContentCache *
506 SourceManager::getFakeContentCacheForRecovery()
const {
507 if (!FakeContentCacheForRecovery) {
508 FakeContentCacheForRecovery = llvm::make_unique<SrcMgr::ContentCache>();
509 FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
512 return FakeContentCacheForRecovery.get();
517 FileID SourceManager::getPreviousFileID(
FileID FID)
const {
528 }
else if (
unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
532 return FileID::get(ID-1);
545 }
else if (ID+1 >= -1) {
549 return FileID::get(ID+1);
562 int LoadedID,
unsigned LoadedOffset) {
564 assert(LoadedID != -1 &&
"Loading sentinel FileID");
565 unsigned Index =
unsigned(-LoadedID) - 2;
566 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
567 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
568 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
569 FileInfo::get(IncludePos, File, FileCharacter));
570 SLocEntryLoaded[Index] =
true;
571 return FileID::get(LoadedID);
573 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
574 FileInfo::get(IncludePos, File,
576 unsigned FileSize = File->getSize();
577 assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
578 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
579 "Ran out of source locations!");
582 NextLocalOffset += FileSize + 1;
586 FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
587 return LastFileIDLookup = FID;
593 unsigned TokLength) {
594 ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
596 return createExpansionLocImpl(Info, TokLength);
605 unsigned LoadedOffset) {
608 return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
612 SourceManager::createExpansionLocImpl(
const ExpansionInfo &Info,
615 unsigned LoadedOffset) {
617 assert(LoadedID != -1 &&
"Loading sentinel FileID");
618 unsigned Index =
unsigned(-LoadedID) - 2;
619 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
620 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
621 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
622 SLocEntryLoaded[Index] =
true;
623 return SourceLocation::getMacroLoc(LoadedOffset);
625 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
626 assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
627 NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
628 "Ran out of source locations!");
630 NextLocalOffset += TokLength + 1;
631 return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
636 const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
637 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
642 llvm::MemoryBuffer *Buffer,
644 const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
645 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
647 const_cast<SrcMgr::ContentCache *
>(IR)->replaceBuffer(Buffer, DoNotFree);
648 const_cast<SrcMgr::ContentCache *
>(IR)->BufferOverridden =
true;
650 getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
656 "Different sizes, use the FileManager to create a virtual file with "
658 assert(FileInfos.count(SourceFile) == 0 &&
659 "This function should be called at the initialization stage, before "
660 "any parsing occurs.");
661 getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
668 const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
669 const_cast<SrcMgr::ContentCache *
>(IR)->replaceBuffer(
nullptr);
670 const_cast<SrcMgr::ContentCache *
>(IR)->ContentsEntry = IR->OrigEntry;
672 assert(OverriddenFilesInfo);
673 OverriddenFilesInfo->OverriddenFiles.erase(File);
674 OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
678 const SrcMgr::ContentCache *CC = getOrCreateContentCache(File);
679 const_cast<SrcMgr::ContentCache *
>(CC)->IsTransient =
true;
683 bool MyInvalid =
false;
685 if (!SLoc.
isFile() || MyInvalid) {
688 return "<<<<<INVALID SOURCE LOCATION>>>>>";
694 *Invalid = MyInvalid;
697 return "<<<<<INVALID SOURCE LOCATION>>>>>";
699 return Buf->getBuffer();
711 FileID SourceManager::getFileIDSlow(
unsigned SLocOffset)
const {
713 return FileID::get(0);
717 if (SLocOffset < NextLocalOffset)
718 return getFileIDLocal(SLocOffset);
719 return getFileIDLoaded(SLocOffset);
726 FileID SourceManager::getFileIDLocal(
unsigned SLocOffset)
const {
727 assert(SLocOffset < NextLocalOffset &&
"Bad function choice");
742 if (LastFileIDLookup.ID < 0 ||
743 LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
745 I = LocalSLocEntryTable.end();
748 I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
753 unsigned NumProbes = 0;
757 FileID Res = FileID::get(
int(I - LocalSLocEntryTable.begin()));
762 LastFileIDLookup = Res;
763 NumLinearScans += NumProbes+1;
766 if (++NumProbes == 8)
772 unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
776 unsigned LessIndex = 0;
779 bool Invalid =
false;
780 unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
783 return FileID::get(0);
789 if (MidOffset > SLocOffset) {
790 GreaterIndex = MiddleIndex;
797 if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
798 FileID Res = FileID::get(MiddleIndex);
802 if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
803 LastFileIDLookup = Res;
804 NumBinaryProbes += NumProbes;
809 LessIndex = MiddleIndex;
817 FileID SourceManager::getFileIDLoaded(
unsigned SLocOffset)
const {
819 if (SLocOffset < CurrentLoadedOffset) {
820 assert(0 &&
"Invalid SLocOffset or bad function choice");
829 int LastID = LastFileIDLookup.ID;
830 if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
833 I = (-LastID - 2) + 1;
836 for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++
I) {
840 FileID Res = FileID::get(-
int(I) - 2);
843 LastFileIDLookup = Res;
844 NumLinearScans += NumProbes + 1;
852 unsigned GreaterIndex =
I;
853 unsigned LessIndex = LoadedSLocEntryTable.size();
857 unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
866 if (GreaterIndex == MiddleIndex) {
867 assert(0 &&
"binary search missed the entry");
870 GreaterIndex = MiddleIndex;
874 if (isOffsetInFileID(FileID::get(-
int(MiddleIndex) - 2), SLocOffset)) {
875 FileID Res = FileID::get(-
int(MiddleIndex) - 2);
877 LastFileIDLookup = Res;
878 NumBinaryProbes += NumProbes;
883 if (LessIndex == MiddleIndex) {
884 assert(0 &&
"binary search missed the entry");
887 LessIndex = MiddleIndex;
926 std::pair<FileID, unsigned>
927 SourceManager::getDecomposedExpansionLocSlowCase(
941 return std::make_pair(FID, Offset);
944 std::pair<FileID, unsigned>
946 unsigned Offset)
const {
959 return std::make_pair(FID, Offset);
976 std::pair<SourceLocation,SourceLocation>
978 assert(Loc.
isMacroID() &&
"Not a macro expansion loc!");
985 std::pair<SourceLocation,SourceLocation>
987 if (Loc.
isFileID())
return std::make_pair(Loc, Loc);
989 std::pair<SourceLocation,SourceLocation> Res =
994 while (!Res.first.isFileID())
996 while (!Res.second.isFileID())
1027 if (DecompLoc.second > 0)
1030 bool Invalid =
false;
1041 FileID PrevFID = getPreviousFileID(DecompLoc.first);
1053 *MacroBegin = ExpLoc;
1066 bool Invalid =
false;
1076 FileID NextFID = getNextFileID(FID);
1101 bool *Invalid)
const {
1107 bool CharDataInvalid =
false;
1109 if (CharDataInvalid || !Entry.
isFile()) {
1113 return "<<<<INVALID BUFFER>>>>";
1118 *Invalid = CharDataInvalid;
1119 return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
1126 bool *Invalid)
const {
1127 bool MyInvalid =
false;
1128 llvm::MemoryBuffer *MemBuf =
getBuffer(FID, &MyInvalid);
1130 *Invalid = MyInvalid;
1136 if (FilePos > MemBuf->getBufferSize()) {
1144 if (LastLineNoFileIDQuery == FID &&
1145 LastLineNoContentCache->SourceLineCache !=
nullptr &&
1146 LastLineNoResult < LastLineNoContentCache->NumLines) {
1147 unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache;
1148 unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1149 unsigned LineEnd = SourceLineCache[LastLineNoResult];
1150 if (FilePos >= LineStart && FilePos < LineEnd)
1151 return FilePos - LineStart + 1;
1154 const char *Buf = MemBuf->getBufferStart();
1155 unsigned LineStart = FilePos;
1156 while (LineStart && Buf[LineStart-1] !=
'\n' && Buf[LineStart-1] !=
'\r')
1158 return FilePos-LineStart+1;
1163 template<
typename LocType>
1165 bool MyInvalid = Loc.isInvalid();
1167 *Invalid = MyInvalid;
1172 bool *Invalid)
const {
1179 bool *Invalid)
const {
1186 bool *Invalid)
const {
1196 static LLVM_ATTRIBUTE_NOINLINE
void
1198 llvm::BumpPtrAllocator &Alloc,
1201 llvm::BumpPtrAllocator &Alloc,
1204 MemoryBuffer *Buffer = FI->getBuffer(Diag, SM,
SourceLocation(), &Invalid);
1213 LineOffsets.push_back(0);
1215 const unsigned char *Buf = (
const unsigned char *)Buffer->getBufferStart();
1216 const unsigned char *
End = (
const unsigned char *)Buffer->getBufferEnd();
1220 const unsigned char *NextBuf = (
const unsigned char *)Buf;
1230 while (((
uintptr_t)NextBuf & 0xF) != 0) {
1231 if (*NextBuf ==
'\n' || *NextBuf ==
'\r' || *NextBuf ==
'\0')
1232 goto FoundSpecialChar;
1237 while (NextBuf+16 <= End) {
1238 const __m128i Chunk = *(
const __m128i*)NextBuf;
1245 NextBuf += llvm::countTrailingZeros(Mask);
1246 goto FoundSpecialChar;
1252 while (*NextBuf !=
'\n' && *NextBuf !=
'\r' && *NextBuf !=
'\0')
1258 Offs += NextBuf-Buf;
1261 if (Buf[0] ==
'\n' || Buf[0] ==
'\r') {
1263 if ((Buf[1] ==
'\n' || Buf[1] ==
'\r') && Buf[0] != Buf[1]) {
1269 LineOffsets.push_back(Offs);
1272 if (Buf == End)
break;
1280 FI->NumLines = LineOffsets.size();
1281 FI->SourceLineCache = Alloc.Allocate<
unsigned>(LineOffsets.size());
1282 std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
1290 bool *Invalid)
const {
1297 ContentCache *Content;
1298 if (LastLineNoFileIDQuery == FID)
1299 Content = LastLineNoContentCache;
1301 bool MyInvalid =
false;
1303 if (MyInvalid || !Entry.
isFile()) {
1314 if (!Content->SourceLineCache) {
1315 bool MyInvalid =
false;
1318 *Invalid = MyInvalid;
1326 unsigned *SourceLineCache = Content->SourceLineCache;
1327 unsigned *SourceLineCacheStart = SourceLineCache;
1328 unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;
1330 unsigned QueriedFilePos = FilePos+1;
1345 if (LastLineNoFileIDQuery == FID) {
1346 if (QueriedFilePos >= LastLineNoFilePos) {
1348 SourceLineCache = SourceLineCache+LastLineNoResult-1;
1354 if (SourceLineCache+5 < SourceLineCacheEnd) {
1355 if (SourceLineCache[5] > QueriedFilePos)
1356 SourceLineCacheEnd = SourceLineCache+5;
1357 else if (SourceLineCache+10 < SourceLineCacheEnd) {
1358 if (SourceLineCache[10] > QueriedFilePos)
1359 SourceLineCacheEnd = SourceLineCache+10;
1360 else if (SourceLineCache+20 < SourceLineCacheEnd) {
1361 if (SourceLineCache[20] > QueriedFilePos)
1362 SourceLineCacheEnd = SourceLineCache+20;
1367 if (LastLineNoResult < Content->NumLines)
1368 SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1373 = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1374 unsigned LineNo = Pos-SourceLineCacheStart;
1376 LastLineNoFileIDQuery = FID;
1377 LastLineNoContentCache = Content;
1378 LastLineNoFilePos = QueriedFilePos;
1379 LastLineNoResult = LineNo;
1384 bool *Invalid)
const {
1390 bool *Invalid)
const {
1396 bool *Invalid)
const {
1412 assert(Loc.
isValid() &&
"Can't get file characteristic of invalid loc!");
1414 bool Invalid =
false;
1416 if (Invalid || !SEntry.
isFile())
1426 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1442 bool *Invalid)
const {
1443 if (
isInvalid(Loc, Invalid))
return "<invalid loc>";
1457 bool UseLineDirectives)
const {
1463 bool Invalid =
false;
1465 if (Invalid || !Entry.
isFile())
1476 Filename = C->OrigEntry->getName();
1478 Filename = C->getBuffer(Diag, *
this)->getBufferIdentifier();
1480 unsigned LineNo =
getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1483 unsigned ColNo =
getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1492 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1497 if (Entry->FilenameID != -1)
1498 Filename = LineTable->
getFilename(Entry->FilenameID);
1504 unsigned MarkerLineNo =
getLineNumber(LocInfo.first, Entry->FileOffset);
1505 LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1510 if (Entry->IncludeOffset) {
1517 return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
1533 bool Invalid =
false;
1535 if (Invalid || !Entry.
isFile())
1544 if (Entry->IncludeOffset)
1552 bool Invalid =
false;
1558 unsigned NextOffset;
1561 else if (ID+1 == -1)
1562 NextOffset = MaxLoadedOffset;
1566 return NextOffset - Entry.
getOffset() - 1;
1582 llvm::sys::fs::UniqueID
ID;
1583 if (llvm::sys::fs::getUniqueID(File->
getName(),
ID))
1595 unsigned Col)
const {
1596 assert(SourceFile &&
"Null source file!");
1597 assert(Line && Col &&
"Line and column should start from 1!");
1608 assert(SourceFile &&
"Null source file!");
1618 bool Invalid =
false;
1624 const ContentCache *MainContentCache
1626 if (!MainContentCache) {
1628 }
else if (MainContentCache->OrigEntry == SourceFile) {
1629 FirstFID = MainFileID;
1633 const FileEntry *MainFile = MainContentCache->OrigEntry;
1634 SourceFileName = llvm::sys::path::filename(SourceFile->
getName());
1635 if (*SourceFileName == llvm::sys::path::filename(MainFile->
getName())) {
1637 if (SourceFileUID) {
1640 if (*SourceFileUID == *MainFileUID) {
1641 FirstFID = MainFileID;
1642 SourceFile = MainFile;
1655 bool Invalid =
false;
1663 FirstFID = FileID::get(I);
1674 FirstFID = FileID::get(-
int(I) - 2);
1686 (SourceFileName = llvm::sys::path::filename(SourceFile->
getName()))) &&
1688 bool Invalid =
false;
1697 const ContentCache *FileContentCache
1699 const FileEntry *Entry = FileContentCache ? FileContentCache->OrigEntry
1702 *SourceFileName == llvm::sys::path::filename(Entry->
getName())) {
1705 if (*SourceFileUID == *EntryUID) {
1706 FirstFID = FileID::get(I);
1724 unsigned Col)
const {
1727 assert(Line && Col &&
"Line and column should start from 1!");
1732 bool Invalid =
false;
1742 if (Line == 1 && Col == 1)
1745 ContentCache *Content
1752 if (!Content->SourceLineCache) {
1753 bool MyInvalid =
false;
1759 if (Line > Content->NumLines) {
1760 unsigned Size = Content->getBuffer(Diag, *
this)->getBufferSize();
1766 llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *
this);
1767 unsigned FilePos = Content->SourceLineCache[Line - 1];
1768 const char *Buf = Buffer->getBufferStart() + FilePos;
1769 unsigned BufLength = Buffer->getBufferSize() - FilePos;
1776 while (i < BufLength-1 && i < Col-1 && Buf[i] !=
'\n' && Buf[i] !=
'\r')
1788 void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr,
1793 CachePtr =
new MacroArgsMap();
1794 MacroArgsMap &MacroArgsCache = *CachePtr;
1805 }
else if (ID == -1) {
1809 bool Invalid =
false;
1822 if (Entry.
getFile().NumCreatedFIDs)
1823 ID += Entry.
getFile().NumCreatedFIDs - 1;
1837 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1839 SourceLocation::getMacroLoc(Entry.
getOffset()),
1844 void SourceManager::associateFileChunkWithMacroArgExp(
1845 MacroArgsMap &MacroArgsCache,
1849 unsigned ExpansionLength)
const {
1851 unsigned SpellBeginOffs = SpellLoc.getOffset();
1852 unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
1860 unsigned SpellRelativeOffs;
1864 unsigned SpellFIDBeginOffs = Entry.
getOffset();
1866 unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1869 unsigned CurrSpellLength;
1870 if (SpellFIDEndOffs < SpellEndOffs)
1871 CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1873 CurrSpellLength = ExpansionLength;
1874 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1876 ExpansionLoc, CurrSpellLength);
1879 if (SpellFIDEndOffs >= SpellEndOffs)
1883 unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1885 ExpansionLength -= advance;
1887 SpellRelativeOffs = 0;
1898 unsigned EndOffs = BeginOffs + ExpansionLength;
1920 MacroArgsCache[BeginOffs] = ExpansionLoc;
1921 MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1944 MacroArgsMap *&MacroArgsCache = MacroArgsCacheMap[FID];
1945 if (!MacroArgsCache)
1946 computeMacroArgsCache(MacroArgsCache, FID);
1948 assert(!MacroArgsCache->empty());
1952 unsigned MacroArgBeginOffs = I->first;
1954 if (MacroArgExpandedLoc.
isValid())
1960 std::pair<FileID, unsigned>
1963 return std::make_pair(
FileID(), 0);
1967 typedef std::pair<FileID, unsigned> DecompTy;
1968 typedef llvm::DenseMap<FileID, DecompTy>
MapTy;
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];
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();
2050 if (LOffs.first == ROffs.first)
2051 return LOffs.second < ROffs.second;
2056 getInBeforeInTUCache(LOffs.first, ROffs.first);
2060 if (IsBeforeInTUCache.
isCacheValid(LOffs.first, ROffs.first))
2064 IsBeforeInTUCache.
setQueryFIDs(LOffs.first, ROffs.first,
2065 LOffs.first.ID < ROffs.first.ID);
2072 typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet;
2075 LChain.insert(LOffs);
2080 while((I = LChain.find(ROffs.first)) == LChain.end()) {
2084 if (I != LChain.end())
2089 if (LOffs.first == ROffs.first) {
2090 IsBeforeInTUCache.
setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
2098 IsBeforeInTUCache.
clear();
2099 const char *LB =
getBuffer(LOffs.first)->getBufferIdentifier();
2100 const char *RB =
getBuffer(ROffs.first)->getBufferIdentifier();
2101 bool LIsBuiltins = strcmp(
"<built-in>", LB) == 0;
2102 bool RIsBuiltins = strcmp(
"<built-in>", RB) == 0;
2104 if (LIsBuiltins || RIsBuiltins) {
2105 if (LIsBuiltins != RIsBuiltins)
2109 return LOffs.first < ROffs.first;
2111 bool LIsAsm = strcmp(
"<inline asm>", LB) == 0;
2112 bool RIsAsm = strcmp(
"<inline asm>", RB) == 0;
2114 if (LIsAsm || RIsAsm) {
2115 if (LIsAsm != RIsAsm)
2117 assert(LOffs.first == ROffs.first);
2120 bool LIsScratch = strcmp(
"<scratch space>", LB) == 0;
2121 bool RIsScratch = strcmp(
"<scratch space>", RB) == 0;
2123 if (LIsScratch || RIsScratch) {
2124 if (LIsScratch != RIsScratch)
2126 return LOffs.second < ROffs.second;
2128 llvm_unreachable(
"Unsortable locations found");
2132 llvm::errs() <<
"\n*** Source Manager Stats:\n";
2133 llvm::errs() << FileInfos.size() <<
" files mapped, " << MemBufferInfos.size()
2134 <<
" mem buffers mapped.\n";
2135 llvm::errs() << LocalSLocEntryTable.size() <<
" local SLocEntry's allocated ("
2136 << llvm::capacity_in_bytes(LocalSLocEntryTable)
2137 <<
" bytes of capacity), "
2138 << NextLocalOffset <<
"B of Sloc address space used.\n";
2139 llvm::errs() << LoadedSLocEntryTable.size()
2140 <<
" loaded SLocEntries allocated, "
2141 << MaxLoadedOffset - CurrentLoadedOffset
2142 <<
"B of Sloc address space used.\n";
2144 unsigned NumLineNumsComputed = 0;
2145 unsigned NumFileBytesMapped = 0;
2147 NumLineNumsComputed += I->second->SourceLineCache !=
nullptr;
2148 NumFileBytesMapped += I->second->getSizeBytesMapped();
2150 unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2152 llvm::errs() << NumFileBytesMapped <<
" bytes of files mapped, "
2153 << NumLineNumsComputed <<
" files with line #'s computed, "
2154 << NumMacroArgsComputed <<
" files with macro args computed.\n";
2155 llvm::errs() <<
"FileID scans: " << NumLinearScans <<
" linear, "
2156 << NumBinaryProbes <<
" binary.\n";
2160 llvm::raw_ostream &out = llvm::errs();
2164 out <<
"SLocEntry <FileID " << ID <<
"> " << (Entry.isFile() ?
"file" :
"expansion")
2165 <<
" <SourceLocation " << Entry.getOffset() <<
":";
2167 out << *NextStart <<
">\n";
2170 if (Entry.isFile()) {
2171 auto &FI = Entry.getFile();
2172 if (FI.NumCreatedFIDs)
2173 out <<
" covers <FileID " << ID <<
":" << int(ID + FI.NumCreatedFIDs)
2175 if (FI.getIncludeLoc().isValid())
2176 out <<
" included from " << FI.getIncludeLoc().getOffset() <<
"\n";
2177 if (
auto *CC = FI.getContentCache()) {
2178 out <<
" for " << (CC->OrigEntry ? CC->OrigEntry->getName() :
"<none>")
2180 if (CC->BufferOverridden)
2181 out <<
" contents overridden\n";
2182 if (CC->ContentsEntry != CC->OrigEntry) {
2183 out <<
" contents from "
2184 << (CC->ContentsEntry ? CC->ContentsEntry->getName() :
"<none>")
2189 auto &EI = Entry.getExpansion();
2190 out <<
" spelling from " << EI.getSpellingLoc().getOffset() <<
"\n";
2191 out <<
" macro " << (EI.isMacroArgExpansion() ?
"arg" :
"body")
2192 <<
" range <" << EI.getExpansionLocStart().getOffset() <<
":"
2193 << EI.getExpansionLocEnd().getOffset() <<
">\n";
2198 for (
unsigned ID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++
ID) {
2199 DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2200 ID == NumIDs - 1 ? NextLocalOffset
2201 : LocalSLocEntryTable[ID + 1].getOffset());
2205 for (
unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2206 int ID = -(int)Index - 2;
2207 if (SLocEntryLoaded[Index]) {
2208 DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2209 NextStart = LoadedSLocEntryTable[Index].getOffset();
2221 size_t malloc_bytes = 0;
2222 size_t mmap_bytes = 0;
2224 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2225 if (
size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2226 switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2227 case llvm::MemoryBuffer::MemoryBuffer_MMap:
2228 mmap_bytes += sized_mapped;
2230 case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2231 malloc_bytes += sized_mapped;
2239 size_t size = llvm::capacity_in_bytes(MemBufferInfos)
2240 + llvm::capacity_in_bytes(LocalSLocEntryTable)
2241 + llvm::capacity_in_bytes(LoadedSLocEntryTable)
2242 + llvm::capacity_in_bytes(SLocEntryLoaded)
2243 + llvm::capacity_in_bytes(FileInfos);
2245 if (OverriddenFilesInfo)
2246 size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
bool hasLineDirectives() const
Return true if this FileID has #line directives in it.
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
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.
This is a discriminated union of FileInfo and ExpansionInfo.
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...
unsigned getColumn() const
Return the presumed column number of this location.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Implements support for file system lookup, file system caching, and directory search management...
unsigned local_sloc_entry_size() const
Get the number of local SLocEntries we have.
__SIZE_TYPE__ size_t
The unsigned integer type of the result of the sizeof operator.
Defines the clang::FileManager interface and associated types.
SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID. ...
Defines the SourceManager interface.
unsigned getNextLocalOffset() const
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer...
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded...
const ExpansionInfo & getExpansion() const
std::unique_ptr< llvm::MemoryBuffer > Buffer
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID)
Set up a new query.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID)
Add a line note to the line table for the FileID and offset specified by Loc.
llvm::DenseMap< Stmt *, Stmt * > MapTy
fileinfo_iterator fileinfo_begin() const
void setCommonLoc(FileID commonFID, unsigned lCommonOffset, unsigned rCommonOffset)
SourceLocation getIncludeLoc() const
CharacteristicKind getFileCharacteristic() const
Return whether this is a system header or not.
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.
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.
void disableFileContentsOverride(const FileEntry *File)
Disable overridding the contents of a file, previously enabled with overrideFileContents.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
std::pair< SourceLocation, SourceLocation > getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
bool isDiagnosticInFlight() const
Determine whethere there is already a diagnostic in flight.
const LineEntry * FindNearestLineEntry(FileID FID, unsigned Offset)
Find the line entry nearest to FID that is before it.
bool isFileOverridden(const FileEntry *File)
Returns true if the file contents have been overridden.
void setSourceManager(SourceManager *SrcMgr)
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
std::pair< FileID, unsigned > getDecomposedSpellingLoc(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.
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body. ...
Concrete class used by the front-end to report problems and issues.
unsigned getLine() const
Return the presumed line number of this location.
SourceLocation translateFileLineCol(const FileEntry *SourceFile, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
detail::InMemoryDirectory::const_iterator I
SrcMgr::CharacteristicKind FileKind
Set the 0 if no flags, 1 if a system header,.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
bool isMacroBodyExpansion() const
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
virtual ~ExternalSLocEntrySource()
SourceLocation translateLineCol(FileID FID, unsigned Line, unsigned Col) const
Get the source location in FID for the given line:col.
void setFileIsTransient(const FileEntry *SourceFile)
Specify that a file is transient.
size_t getDataStructureSizes() const
Return the amount of memory used for various side tables and data structures in the SourceManager...
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...
SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const
If Loc points inside a function macro argument, the returned location will be the macro location in w...
static Optional< llvm::sys::fs::UniqueID > getActualFileUID(const FileEntry *File)
Retrieve the inode for the given file entry, if possible.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
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.
FileManager & getFileManager() const
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 SrcMgr::SLocEntry & getLocalSLocEntry(unsigned Index, bool *Invalid=nullptr) const
Get a local SLocEntry. This is exposed for indexing.
const char * getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
static LineEntry get(unsigned Offs, unsigned Line, int Filename, SrcMgr::CharacteristicKind FileKind, unsigned IncludeOffset)
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
Represents an unpacked "presumed" location which can be presented to the user.
SourceLocation createExpansionLoc(SourceLocation Loc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned TokLength, int LoadedID=0, unsigned LoadedOffset=0)
Return a new SourceLocation that encodes the fact that a token from SpellingLoc should actually be re...
SourceLocation getExpansionLocEnd() const
unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Return the column # for the specified file position.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
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 isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
Information about a FileID, basically just the logical file that it represents and include stack info...
const char * getName() const
Encodes a location in the source.
const TemplateArgument * iterator
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned getOffset() const
Cached information about one file (either on disk or in the virtual file system). ...
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 getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
llvm::MemoryBuffer * getMemoryBufferForFile(const FileEntry *File, bool *Invalid=nullptr)
Retrieve the memory buffer associated with the given file.
bool isCacheValid(FileID LHS, FileID RHS) const
Return true if the currently cached values match up with the specified LHS/RHS query.
const FileInfo & getFile() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
MemoryBufferSizes getMemoryBufferSizes() const
Return the amount of memory used by memory buffers, breaking down by heap-backed versus mmap'ed memor...
static bool isInvalid(LocType Loc, bool *Invalid)
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...
const char * getFilename(unsigned ID) const
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc, SourceLocation *MacroBegin=nullptr) const
Returns true if the given MacroID location points at the beginning of the immediate macro expansion...
std::pair< SourceLocation, SourceLocation > getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
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.
void AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, int FilenameID)
AddLineNote - Add a line note to the line table that indicates that there is a #line at the specified...
const ContentCache * getContentCache() const
fileinfo_iterator fileinfo_end() const
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
detail::InMemoryDirectory::const_iterator E
SourceLocation getExpansionLocStart() const
llvm::DenseMap< const FileEntry *, SrcMgr::ContentCache * >::const_iterator fileinfo_iterator
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
Defines the Diagnostic-related interfaces.
bool userFilesAreVolatile() const
True if non-system source files should be treated as volatile (likely to change while trying to use t...
bool isMacroArgExpansion() const
Holds the cache used by isBeforeInTranslationUnit.
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...
static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_or_si128(__m128i __a, __m128i __b)
Performs a bitwise OR of two 128-bit integer vectors.
void PrintStats() const
Print statistics to stderr.
LineTableInfo & getLineTable()
Retrieve the stored line table.
static __inline__ int __DEFAULT_FN_ATTRS _mm_movemask_epi8(__m128i __a)
unsigned loaded_sloc_entry_size() const
Get the number of loaded SLocEntries we have.
SourceLocation getLocForStartOfFile(FileID FID) const
Return the source location corresponding to the first byte of the specified file. ...
std::pair< SourceLocation, SourceLocation > getExpansionLocRange() const
const SrcMgr::SLocEntry & getLoadedSLocEntry(unsigned Index, bool *Invalid=nullptr) const
Get a loaded SLocEntry. This is exposed for indexing.
std::pair< FileID, unsigned > getDecomposedIncludedLoc(FileID FID) const
Returns the "included/expanded in" decomposed location of the given FileID.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
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...
SourceLocation getSpellingLoc() const
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.