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"
29 using namespace clang;
30 using namespace SrcMgr;
31 using llvm::MemoryBuffer;
39 delete Buffer.getPointer();
45 return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
51 assert(Buffer.getPointer());
54 if (!Buffer.getPointer())
55 return llvm::MemoryBuffer::MemoryBuffer_Malloc;
57 llvm::MemoryBuffer *buf = Buffer.getPointer();
58 return buf->getBufferKind();
66 return Buffer.getPointer() ? (
unsigned) Buffer.getPointer()->getBufferSize()
71 if (B && B == Buffer.getPointer()) {
72 assert(0 &&
"Replacing with the same buffer");
73 Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
78 delete Buffer.getPointer();
80 Buffer.setInt((B && DoNotFree) ? DoNotFreeFlag : 0);
86 bool *Invalid)
const {
93 return Buffer.getPointer();
110 if (!BufferOrError) {
111 StringRef FillStr(
"<<<MISSING SOURCE FILE>>>\n");
112 Buffer.setPointer(MemoryBuffer::getNewUninitMemBuffer(
114 char *Ptr =
const_cast<char*
>(Buffer.getPointer()->getBufferStart());
116 Ptr[i] = FillStr[i % FillStr.size()];
121 BufferOrError.getError().message());
123 Diag.
Report(Loc, diag::err_cannot_open_file)
126 Buffer.setInt(Buffer.getInt() | InvalidFlag);
128 if (Invalid) *Invalid =
true;
129 return Buffer.getPointer();
132 Buffer.setPointer(BufferOrError->release());
141 Diag.
Report(Loc, diag::err_file_modified)
144 Buffer.setInt(Buffer.getInt() | InvalidFlag);
145 if (Invalid) *Invalid =
true;
146 return Buffer.getPointer();
152 StringRef BufStr = Buffer.getPointer()->getBuffer();
153 const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr)
154 .StartsWith(
"\xFE\xFF",
"UTF-16 (BE)")
155 .StartsWith(
"\xFF\xFE",
"UTF-16 (LE)")
156 .StartsWith(
"\x00\x00\xFE\xFF",
"UTF-32 (BE)")
157 .StartsWith(
"\xFF\xFE\x00\x00",
"UTF-32 (LE)")
158 .StartsWith(
"\x2B\x2F\x76",
"UTF-7")
159 .StartsWith(
"\xF7\x64\x4C",
"UTF-1")
160 .StartsWith(
"\xDD\x73\x66\x73",
"UTF-EBCDIC")
161 .StartsWith(
"\x0E\xFE\xFF",
"SDSU")
162 .StartsWith(
"\xFB\xEE\x28",
"BOCU-1")
163 .StartsWith(
"\x84\x31\x95\x33",
"GB-18030")
167 Diag.
Report(Loc, diag::err_unsupported_bom)
169 Buffer.setInt(Buffer.getInt() | InvalidFlag);
175 return Buffer.getPointer();
180 FilenameIDs.insert(std::make_pair(Name, FilenamesByID.size()));
182 FilenamesByID.push_back(&*IterBool.first);
183 return IterBool.first->second;
193 int FilenameID,
unsigned EntryExit,
195 std::vector<LineEntry> &Entries = LineEntries[FID];
199 if (FilenameID == -1 && !Entries.empty())
200 FilenameID = Entries.back().FilenameID;
202 assert((Entries.empty() || Entries.back().FileOffset <
Offset) &&
203 "Adding line entries out of order!");
205 unsigned IncludeOffset = 0;
206 if (EntryExit == 0) {
207 IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
208 }
else if (EntryExit == 1) {
209 IncludeOffset = Offset-1;
210 }
else if (EntryExit == 2) {
211 assert(!Entries.empty() && Entries.back().IncludeOffset &&
212 "PPDirectives should have caught case when popping empty include stack");
217 FindNearestLineEntry(FID, Entries.back().IncludeOffset))
218 IncludeOffset = PrevEntry->IncludeOffset;
221 Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, FileKind,
230 const std::vector<LineEntry> &Entries = LineEntries[FID];
231 assert(!Entries.empty() &&
"No #line entries for this FID after all!");
235 if (Entries.back().FileOffset <=
Offset)
236 return &Entries.back();
239 std::vector<LineEntry>::const_iterator
I =
240 std::upper_bound(Entries.begin(), Entries.end(),
Offset);
241 if (I == Entries.begin())
return nullptr;
248 const std::vector<LineEntry> &Entries) {
249 LineEntries[FID] = Entries;
255 return getLineTable().getLineTableFilenameID(Name);
262 int FilenameID,
bool IsFileEntry,
265 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
267 bool Invalid =
false;
268 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
269 if (!Entry.
isFile() || Invalid)
277 (void) getLineTable();
279 unsigned EntryExit = 0;
285 LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
286 EntryExit, FileKind);
300 bool UserFilesAreVolatile)
301 : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(
true),
302 UserFilesAreVolatile(UserFilesAreVolatile), FilesAreTransient(
false),
303 ExternalSLocEntries(nullptr), LineTable(nullptr), NumLinearScans(0),
315 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
316 if (MemBufferInfos[i]) {
317 MemBufferInfos[i]->~ContentCache();
318 ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
321 for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
322 I = FileInfos.begin(),
E = FileInfos.end();
I !=
E; ++
I) {
324 I->second->~ContentCache();
325 ContentCacheAlloc.Deallocate(
I->second);
332 LocalSLocEntryTable.clear();
333 LoadedSLocEntryTable.clear();
334 SLocEntryLoaded.clear();
335 LastLineNoFileIDQuery =
FileID();
336 LastLineNoContentCache =
nullptr;
337 LastFileIDLookup =
FileID();
344 CurrentLoadedOffset = MaxLoadedOffset;
349 assert(MainFileID.
isInvalid() &&
"expected uninitialized SourceManager");
354 Clone->ContentsEntry =
Cache->ContentsEntry;
355 Clone->BufferOverridden =
Cache->BufferOverridden;
356 Clone->IsSystemFile =
Cache->IsSystemFile;
357 Clone->IsTransient =
Cache->IsTransient;
358 Clone->replaceBuffer(
Cache->getRawBuffer(),
true);
363 for (
unsigned I = 0, N = Old.LoadedSLocEntryTable.size();
I != N; ++
I)
364 if (!Old.SLocEntryLoaded[
I])
365 Old.loadSLocEntry(
I,
nullptr);
368 for (
auto &
FileInfo : Old.FileInfos) {
372 Slot = CloneContentCache(
FileInfo.second);
379 SourceManager::getOrCreateContentCache(
const FileEntry *FileEnt,
381 assert(FileEnt &&
"Didn't specify a file entry to use?");
385 if (Entry)
return Entry;
390 if (OverriddenFilesInfo) {
393 llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
394 overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
395 if (overI == OverriddenFilesInfo->OverriddenFiles.end())
398 new (Entry)
ContentCache(OverridenFilesKeepOriginalName ? FileEnt
414 const ContentCache *SourceManager::createMemBufferContentCache(
415 std::unique_ptr<llvm::MemoryBuffer>
Buffer) {
419 MemBufferInfos.push_back(Entry);
425 bool *Invalid)
const {
426 assert(!SLocEntryLoaded[Index]);
427 if (ExternalSLocEntries->
ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
431 if (!SLocEntryLoaded[Index]) {
433 LoadedSLocEntryTable[Index] = SLocEntry::get(0,
435 getFakeContentCacheForRecovery(),
440 return LoadedSLocEntryTable[Index];
443 std::pair<int, unsigned>
445 unsigned TotalSize) {
446 assert(ExternalSLocEntries &&
"Don't have an external sloc source");
448 if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
449 return std::make_pair(0, 0);
450 LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
451 SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
452 CurrentLoadedOffset -= TotalSize;
453 int ID = LoadedSLocEntryTable.size();
454 return std::make_pair(-ID - 1, CurrentLoadedOffset);
459 llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery()
const {
460 if (!FakeBufferForRecovery)
461 FakeBufferForRecovery =
462 llvm::MemoryBuffer::getMemBuffer(
"<<<INVALID BUFFER>>");
464 return FakeBufferForRecovery.get();
470 SourceManager::getFakeContentCacheForRecovery()
const {
471 if (!FakeContentCacheForRecovery) {
472 FakeContentCacheForRecovery = llvm::make_unique<SrcMgr::ContentCache>();
473 FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
476 return FakeContentCacheForRecovery.get();
481 FileID SourceManager::getPreviousFileID(
FileID FID)
const {
492 }
else if (
unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
496 return FileID::get(ID-1);
509 }
else if (ID+1 >= -1) {
513 return FileID::get(ID+1);
526 int LoadedID,
unsigned LoadedOffset) {
528 assert(LoadedID != -1 &&
"Loading sentinel FileID");
529 unsigned Index =
unsigned(-LoadedID) - 2;
530 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
531 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
532 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
533 FileInfo::get(IncludePos, File, FileCharacter));
534 SLocEntryLoaded[Index] =
true;
535 return FileID::get(LoadedID);
537 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
538 FileInfo::get(IncludePos, File,
540 unsigned FileSize = File->
getSize();
541 assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
542 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
543 "Ran out of source locations!");
546 NextLocalOffset += FileSize + 1;
550 FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
551 return LastFileIDLookup = FID;
557 unsigned TokLength) {
558 ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
560 return createExpansionLocImpl(Info, TokLength);
569 unsigned LoadedOffset) {
572 return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
576 SourceManager::createExpansionLocImpl(
const ExpansionInfo &Info,
579 unsigned LoadedOffset) {
581 assert(LoadedID != -1 &&
"Loading sentinel FileID");
582 unsigned Index =
unsigned(-LoadedID) - 2;
583 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
584 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
585 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
586 SLocEntryLoaded[Index] =
true;
587 return SourceLocation::getMacroLoc(LoadedOffset);
589 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
590 assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
591 NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
592 "Ran out of source locations!");
594 NextLocalOffset += TokLength + 1;
595 return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
601 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
606 llvm::MemoryBuffer *Buffer,
609 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
614 getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
620 "Different sizes, use the FileManager to create a virtual file with "
622 assert(FileInfos.count(SourceFile) == 0 &&
623 "This function should be called at the initialization stage, before "
624 "any parsing occurs.");
625 getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
636 assert(OverriddenFilesInfo);
637 OverriddenFilesInfo->OverriddenFiles.erase(File);
638 OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
647 bool MyInvalid =
false;
649 if (!SLoc.
isFile() || MyInvalid) {
652 return "<<<<<INVALID SOURCE LOCATION>>>>>";
658 *Invalid = MyInvalid;
661 return "<<<<<INVALID SOURCE LOCATION>>>>>";
663 return Buf->getBuffer();
675 FileID SourceManager::getFileIDSlow(
unsigned SLocOffset)
const {
677 return FileID::get(0);
681 if (SLocOffset < NextLocalOffset)
682 return getFileIDLocal(SLocOffset);
683 return getFileIDLoaded(SLocOffset);
690 FileID SourceManager::getFileIDLocal(
unsigned SLocOffset)
const {
691 assert(SLocOffset < NextLocalOffset &&
"Bad function choice");
706 if (LastFileIDLookup.ID < 0 ||
707 LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
709 I = LocalSLocEntryTable.end();
712 I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
717 unsigned NumProbes = 0;
721 FileID Res = FileID::get(
int(I - LocalSLocEntryTable.begin()));
726 LastFileIDLookup = Res;
727 NumLinearScans += NumProbes+1;
730 if (++NumProbes == 8)
736 unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
740 unsigned LessIndex = 0;
743 bool Invalid =
false;
744 unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
747 return FileID::get(0);
753 if (MidOffset > SLocOffset) {
754 GreaterIndex = MiddleIndex;
761 if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
762 FileID Res = FileID::get(MiddleIndex);
766 if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
767 LastFileIDLookup = Res;
768 NumBinaryProbes += NumProbes;
773 LessIndex = MiddleIndex;
781 FileID SourceManager::getFileIDLoaded(
unsigned SLocOffset)
const {
783 if (SLocOffset < CurrentLoadedOffset) {
784 assert(0 &&
"Invalid SLocOffset or bad function choice");
793 int LastID = LastFileIDLookup.ID;
794 if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
797 I = (-LastID - 2) + 1;
800 for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++
I) {
804 FileID Res = FileID::get(-
int(I) - 2);
807 LastFileIDLookup = Res;
808 NumLinearScans += NumProbes + 1;
816 unsigned GreaterIndex =
I;
817 unsigned LessIndex = LoadedSLocEntryTable.size();
821 unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
830 if (GreaterIndex == MiddleIndex) {
831 assert(0 &&
"binary search missed the entry");
834 GreaterIndex = MiddleIndex;
838 if (isOffsetInFileID(FileID::get(-
int(MiddleIndex) - 2), SLocOffset)) {
839 FileID Res = FileID::get(-
int(MiddleIndex) - 2);
841 LastFileIDLookup = Res;
842 NumBinaryProbes += NumProbes;
847 if (LessIndex == MiddleIndex) {
848 assert(0 &&
"binary search missed the entry");
851 LessIndex = MiddleIndex;
890 std::pair<FileID, unsigned>
891 SourceManager::getDecomposedExpansionLocSlowCase(
905 return std::make_pair(FID, Offset);
908 std::pair<FileID, unsigned>
910 unsigned Offset)
const {
923 return std::make_pair(FID, Offset);
940 std::pair<SourceLocation,SourceLocation>
942 assert(Loc.
isMacroID() &&
"Not a macro expansion loc!");
949 std::pair<SourceLocation,SourceLocation>
951 if (Loc.
isFileID())
return std::make_pair(Loc, Loc);
953 std::pair<SourceLocation,SourceLocation> Res =
958 while (!Res.first.isFileID())
960 while (!Res.second.isFileID())
991 if (DecompLoc.second > 0)
994 bool Invalid =
false;
1005 FileID PrevFID = getPreviousFileID(DecompLoc.first);
1017 *MacroBegin = ExpLoc;
1030 bool Invalid =
false;
1040 FileID NextFID = getNextFileID(FID);
1065 bool *Invalid)
const {
1071 bool CharDataInvalid =
false;
1073 if (CharDataInvalid || !Entry.
isFile()) {
1077 return "<<<<INVALID BUFFER>>>>";
1082 *Invalid = CharDataInvalid;
1083 return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
1090 bool *Invalid)
const {
1091 bool MyInvalid =
false;
1092 llvm::MemoryBuffer *MemBuf =
getBuffer(FID, &MyInvalid);
1094 *Invalid = MyInvalid;
1100 if (FilePos > MemBuf->getBufferSize()) {
1106 const char *Buf = MemBuf->getBufferStart();
1109 if (LastLineNoFileIDQuery == FID &&
1111 LastLineNoResult < LastLineNoContentCache->NumLines) {
1113 unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1114 unsigned LineEnd = SourceLineCache[LastLineNoResult];
1115 if (FilePos >= LineStart && FilePos < LineEnd) {
1120 if (FilePos + 1 == LineEnd && FilePos > LineStart) {
1121 if (Buf[FilePos - 1] ==
'\r' || Buf[FilePos - 1] ==
'\n')
1124 return FilePos - LineStart + 1;
1128 unsigned LineStart = FilePos;
1129 while (LineStart && Buf[LineStart-1] !=
'\n' && Buf[LineStart-1] !=
'\r')
1131 return FilePos-LineStart+1;
1136 template<
typename LocType>
1138 bool MyInvalid = Loc.isInvalid();
1140 *Invalid = MyInvalid;
1145 bool *Invalid)
const {
1152 bool *Invalid)
const {
1159 bool *Invalid)
const {
1169 static LLVM_ATTRIBUTE_NOINLINE
void
1171 llvm::BumpPtrAllocator &Alloc,
1174 llvm::BumpPtrAllocator &Alloc,
1186 LineOffsets.push_back(0);
1188 const unsigned char *Buf = (
const unsigned char *)Buffer->getBufferStart();
1189 const unsigned char *
End = (
const unsigned char *)Buffer->getBufferEnd();
1193 const unsigned char *NextBuf = (
const unsigned char *)Buf;
1203 while (((
uintptr_t)NextBuf & 0xF) != 0) {
1204 if (*NextBuf ==
'\n' || *NextBuf ==
'\r' || *NextBuf ==
'\0')
1205 goto FoundSpecialChar;
1210 while (NextBuf+16 <= End) {
1211 const __m128i Chunk = *(
const __m128i*)NextBuf;
1218 NextBuf += llvm::countTrailingZeros(Mask);
1219 goto FoundSpecialChar;
1225 while (*NextBuf !=
'\n' && *NextBuf !=
'\r' && *NextBuf !=
'\0')
1231 Offs += NextBuf-Buf;
1234 if (Buf[0] ==
'\n' || Buf[0] ==
'\r') {
1236 if ((Buf[1] ==
'\n' || Buf[1] ==
'\r') && Buf[0] != Buf[1]) {
1242 LineOffsets.push_back(Offs);
1245 if (Buf == End)
break;
1255 std::copy(LineOffsets.begin(), LineOffsets.end(), FI->
SourceLineCache);
1263 bool *Invalid)
const {
1271 if (LastLineNoFileIDQuery == FID)
1272 Content = LastLineNoContentCache;
1274 bool MyInvalid =
false;
1276 if (MyInvalid || !Entry.
isFile()) {
1288 bool MyInvalid =
false;
1291 *Invalid = MyInvalid;
1300 unsigned *SourceLineCacheStart = SourceLineCache;
1301 unsigned *SourceLineCacheEnd = SourceLineCache + Content->
NumLines;
1303 unsigned QueriedFilePos = FilePos+1;
1318 if (LastLineNoFileIDQuery == FID) {
1319 if (QueriedFilePos >= LastLineNoFilePos) {
1321 SourceLineCache = SourceLineCache+LastLineNoResult-1;
1327 if (SourceLineCache+5 < SourceLineCacheEnd) {
1328 if (SourceLineCache[5] > QueriedFilePos)
1329 SourceLineCacheEnd = SourceLineCache+5;
1330 else if (SourceLineCache+10 < SourceLineCacheEnd) {
1331 if (SourceLineCache[10] > QueriedFilePos)
1332 SourceLineCacheEnd = SourceLineCache+10;
1333 else if (SourceLineCache+20 < SourceLineCacheEnd) {
1334 if (SourceLineCache[20] > QueriedFilePos)
1335 SourceLineCacheEnd = SourceLineCache+20;
1340 if (LastLineNoResult < Content->NumLines)
1341 SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1346 = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1347 unsigned LineNo = Pos-SourceLineCacheStart;
1349 LastLineNoFileIDQuery = FID;
1350 LastLineNoContentCache = Content;
1351 LastLineNoFilePos = QueriedFilePos;
1352 LastLineNoResult = LineNo;
1357 bool *Invalid)
const {
1363 bool *Invalid)
const {
1369 bool *Invalid)
const {
1385 assert(Loc.
isValid() &&
"Can't get file characteristic of invalid loc!");
1387 bool Invalid =
false;
1389 if (Invalid || !SEntry.
isFile())
1399 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1415 bool *Invalid)
const {
1416 if (
isInvalid(Loc, Invalid))
return "<invalid loc>";
1430 bool UseLineDirectives)
const {
1436 bool Invalid =
false;
1438 if (Invalid || !Entry.
isFile())
1451 Filename = C->
getBuffer(Diag, *
this)->getBufferIdentifier();
1453 unsigned LineNo =
getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1456 unsigned ColNo =
getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1465 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1470 if (Entry->FilenameID != -1)
1471 Filename = LineTable->
getFilename(Entry->FilenameID);
1477 unsigned MarkerLineNo =
getLineNumber(LocInfo.first, Entry->FileOffset);
1478 LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1483 if (Entry->IncludeOffset) {
1490 return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc);
1506 bool Invalid =
false;
1508 if (Invalid || !Entry.
isFile())
1517 if (Entry->IncludeOffset)
1525 bool Invalid =
false;
1531 unsigned NextOffset;
1534 else if (ID+1 == -1)
1535 NextOffset = MaxLoadedOffset;
1539 return NextOffset - Entry.
getOffset() - 1;
1555 llvm::sys::fs::UniqueID
ID;
1556 if (llvm::sys::fs::getUniqueID(File->
getName(),
ID))
1568 unsigned Col)
const {
1569 assert(SourceFile &&
"Null source file!");
1570 assert(Line && Col &&
"Line and column should start from 1!");
1581 assert(SourceFile &&
"Null source file!");
1591 bool Invalid =
false;
1599 if (!MainContentCache) {
1601 }
else if (MainContentCache->
OrigEntry == SourceFile) {
1602 FirstFID = MainFileID;
1607 SourceFileName = llvm::sys::path::filename(SourceFile->
getName());
1608 if (*SourceFileName == llvm::sys::path::filename(MainFile->
getName())) {
1610 if (SourceFileUID) {
1613 if (*SourceFileUID == *MainFileUID) {
1614 FirstFID = MainFileID;
1615 SourceFile = MainFile;
1628 bool Invalid =
false;
1636 FirstFID = FileID::get(I);
1647 FirstFID = FileID::get(-
int(I) - 2);
1659 (SourceFileName = llvm::sys::path::filename(SourceFile->
getName()))) &&
1661 bool Invalid =
false;
1675 *SourceFileName == llvm::sys::path::filename(Entry->
getName())) {
1678 if (*SourceFileUID == *EntryUID) {
1679 FirstFID = FileID::get(I);
1697 unsigned Col)
const {
1700 assert(Line && Col &&
"Line and column should start from 1!");
1705 bool Invalid =
false;
1715 if (Line == 1 && Col == 1)
1726 bool MyInvalid =
false;
1733 unsigned Size = Content->
getBuffer(Diag, *
this)->getBufferSize();
1739 llvm::MemoryBuffer *Buffer = Content->
getBuffer(Diag, *
this);
1741 const char *Buf = Buffer->getBufferStart() + FilePos;
1742 unsigned BufLength = Buffer->getBufferSize() - FilePos;
1749 while (i < BufLength-1 && i < Col-1 && Buf[i] !=
'\n' && Buf[i] !=
'\r')
1761 void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
1775 }
else if (ID == -1) {
1779 bool Invalid =
false;
1792 if (Entry.
getFile().NumCreatedFIDs)
1793 ID += Entry.
getFile().NumCreatedFIDs - 1;
1807 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1809 SourceLocation::getMacroLoc(Entry.
getOffset()),
1814 void SourceManager::associateFileChunkWithMacroArgExp(
1815 MacroArgsMap &MacroArgsCache,
1819 unsigned ExpansionLength)
const {
1821 unsigned SpellBeginOffs = SpellLoc.getOffset();
1822 unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
1830 unsigned SpellRelativeOffs;
1834 unsigned SpellFIDBeginOffs = Entry.
getOffset();
1836 unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1839 unsigned CurrSpellLength;
1840 if (SpellFIDEndOffs < SpellEndOffs)
1841 CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1843 CurrSpellLength = ExpansionLength;
1844 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1846 ExpansionLoc, CurrSpellLength);
1849 if (SpellFIDEndOffs >= SpellEndOffs)
1853 unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1855 ExpansionLength -= advance;
1857 SpellRelativeOffs = 0;
1868 unsigned EndOffs = BeginOffs + ExpansionLength;
1887 MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1890 MacroArgsCache[BeginOffs] = ExpansionLoc;
1891 MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1914 std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
1915 if (!MacroArgsCache) {
1916 MacroArgsCache = llvm::make_unique<MacroArgsMap>();
1917 computeMacroArgsCache(*MacroArgsCache, FID);
1920 assert(!MacroArgsCache->empty());
1921 MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1924 unsigned MacroArgBeginOffs = I->first;
1926 if (MacroArgExpandedLoc.
isValid())
1932 std::pair<FileID, unsigned>
1935 return std::make_pair(
FileID(), 0);
1939 typedef std::pair<FileID, unsigned> DecompTy;
1940 typedef llvm::DenseMap<FileID, DecompTy>
MapTy;
1941 std::pair<MapTy::iterator, bool>
1942 InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy()));
1943 DecompTy &DecompLoc = InsertOp.first->second;
1944 if (!InsertOp.second)
1948 bool Invalid =
false;
1970 if (UpperLoc.first.isInvalid())
1984 enum { MagicCacheSize = 300 };
1985 IsBeforeInTUCacheKey Key(LFID, RFID);
1991 if (IBTUCache.size() < MagicCacheSize)
1992 return IBTUCache[Key];
1995 InBeforeInTUCache::iterator I = IBTUCache.find(Key);
1996 if (I != IBTUCache.end())
2000 return IBTUCacheOverflow;
2008 assert(LHS.
isValid() && RHS.
isValid() &&
"Passed invalid source location!");
2018 if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
2019 return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
2023 return InSameTU.second;
2028 StringRef LB =
getBuffer(LOffs.first)->getBufferIdentifier();
2029 StringRef RB =
getBuffer(ROffs.first)->getBufferIdentifier();
2030 bool LIsBuiltins = LB ==
"<built-in>";
2031 bool RIsBuiltins = RB ==
"<built-in>";
2033 if (LIsBuiltins || RIsBuiltins) {
2034 if (LIsBuiltins != RIsBuiltins)
2038 return LOffs.first < ROffs.first;
2040 bool LIsAsm = LB ==
"<inline asm>";
2041 bool RIsAsm = RB ==
"<inline asm>";
2043 if (LIsAsm || RIsAsm) {
2044 if (LIsAsm != RIsAsm)
2046 assert(LOffs.first == ROffs.first);
2049 bool LIsScratch = LB ==
"<scratch space>";
2050 bool RIsScratch = RB ==
"<scratch space>";
2052 if (LIsScratch || RIsScratch) {
2053 if (LIsScratch != RIsScratch)
2055 return LOffs.second < ROffs.second;
2057 llvm_unreachable(
"Unsortable locations found");
2061 std::pair<FileID, unsigned> &LOffs,
2062 std::pair<FileID, unsigned> &ROffs)
const {
2064 if (LOffs.first == ROffs.first)
2065 return std::make_pair(
true, LOffs.second < ROffs.second);
2070 getInBeforeInTUCache(LOffs.first, ROffs.first);
2074 if (IsBeforeInTUCache.
isCacheValid(LOffs.first, ROffs.first))
2075 return std::make_pair(
2079 IsBeforeInTUCache.
setQueryFIDs(LOffs.first, ROffs.first,
2080 LOffs.first.ID < ROffs.first.ID);
2087 typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet;
2090 LChain.insert(LOffs);
2095 while((I = LChain.find(ROffs.first)) == LChain.end()) {
2099 if (I != LChain.end())
2104 if (LOffs.first == ROffs.first) {
2105 IsBeforeInTUCache.
setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
2106 return std::make_pair(
2110 IsBeforeInTUCache.
clear();
2111 return std::make_pair(
false,
false);
2115 llvm::errs() <<
"\n*** Source Manager Stats:\n";
2116 llvm::errs() << FileInfos.size() <<
" files mapped, " << MemBufferInfos.size()
2117 <<
" mem buffers mapped.\n";
2118 llvm::errs() << LocalSLocEntryTable.size() <<
" local SLocEntry's allocated ("
2119 << llvm::capacity_in_bytes(LocalSLocEntryTable)
2120 <<
" bytes of capacity), "
2121 << NextLocalOffset <<
"B of Sloc address space used.\n";
2122 llvm::errs() << LoadedSLocEntryTable.size()
2123 <<
" loaded SLocEntries allocated, "
2124 << MaxLoadedOffset - CurrentLoadedOffset
2125 <<
"B of Sloc address space used.\n";
2127 unsigned NumLineNumsComputed = 0;
2128 unsigned NumFileBytesMapped = 0;
2130 NumLineNumsComputed += I->second->SourceLineCache !=
nullptr;
2131 NumFileBytesMapped += I->second->getSizeBytesMapped();
2133 unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2135 llvm::errs() << NumFileBytesMapped <<
" bytes of files mapped, "
2136 << NumLineNumsComputed <<
" files with line #'s computed, "
2137 << NumMacroArgsComputed <<
" files with macro args computed.\n";
2138 llvm::errs() <<
"FileID scans: " << NumLinearScans <<
" linear, "
2139 << NumBinaryProbes <<
" binary.\n";
2143 llvm::raw_ostream &out = llvm::errs();
2147 out <<
"SLocEntry <FileID " << ID <<
"> " << (Entry.isFile() ?
"file" :
"expansion")
2148 <<
" <SourceLocation " << Entry.getOffset() <<
":";
2150 out << *NextStart <<
">\n";
2153 if (Entry.isFile()) {
2154 auto &FI = Entry.getFile();
2155 if (FI.NumCreatedFIDs)
2156 out <<
" covers <FileID " << ID <<
":" << int(ID + FI.NumCreatedFIDs)
2158 if (FI.getIncludeLoc().isValid())
2159 out <<
" included from " << FI.getIncludeLoc().getOffset() <<
"\n";
2160 if (
auto *CC = FI.getContentCache()) {
2161 out <<
" for " << (CC->OrigEntry ? CC->OrigEntry->getName() :
"<none>")
2163 if (CC->BufferOverridden)
2164 out <<
" contents overridden\n";
2165 if (CC->ContentsEntry != CC->OrigEntry) {
2166 out <<
" contents from "
2167 << (CC->ContentsEntry ? CC->ContentsEntry->getName() :
"<none>")
2172 auto &EI = Entry.getExpansion();
2173 out <<
" spelling from " << EI.getSpellingLoc().getOffset() <<
"\n";
2174 out <<
" macro " << (EI.isMacroArgExpansion() ?
"arg" :
"body")
2175 <<
" range <" << EI.getExpansionLocStart().getOffset() <<
":"
2176 << EI.getExpansionLocEnd().getOffset() <<
">\n";
2181 for (
unsigned ID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++
ID) {
2182 DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2183 ID == NumIDs - 1 ? NextLocalOffset
2184 : LocalSLocEntryTable[ID + 1].getOffset());
2188 for (
unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2189 int ID = -(int)Index - 2;
2190 if (SLocEntryLoaded[Index]) {
2191 DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2192 NextStart = LoadedSLocEntryTable[Index].getOffset();
2204 size_t malloc_bytes = 0;
2205 size_t mmap_bytes = 0;
2207 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2208 if (
size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2209 switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2210 case llvm::MemoryBuffer::MemoryBuffer_MMap:
2211 mmap_bytes += sized_mapped;
2213 case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2214 malloc_bytes += sized_mapped;
2222 size_t size = llvm::capacity_in_bytes(MemBufferInfos)
2223 + llvm::capacity_in_bytes(LocalSLocEntryTable)
2224 + llvm::capacity_in_bytes(LoadedSLocEntryTable)
2225 + llvm::capacity_in_bytes(SLocEntryLoaded)
2226 + llvm::capacity_in_bytes(FileInfos);
2228 if (OverriddenFilesInfo)
2229 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...
const FileEntry * OrigEntry
Reference to the file entry representing this ContentCache.
StringRef getFilename(unsigned ID) const
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. ...
unsigned getSizeBytesMapped() const
Returns the number of bytes actually mapped for this ContentCache.
Defines the SourceManager interface.
unsigned getNextLocalOffset() const
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
unsigned NumLines
The number of lines in this ContentCache.
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.
TypePropertyCache< Private > Cache
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.
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.
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.
llvm::MemoryBuffer * getRawBuffer() const
Get the underlying buffer, returning NULL if the buffer is not yet available.
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.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
unsigned IsTransient
True if this file may be transient, that is, if it might not exist at some later point in time when t...
void setSourceManager(SourceManager *SrcMgr)
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.
Defines the Diagnostic-related interfaces.
StringRef getName() const
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,.
void initializeForReplay(const SourceManager &Old)
Initialize this source manager suitably to replay the compilation described by Old.
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 FileEntry * ContentsEntry
References the file which the contents were actually loaded from.
const SrcMgr::SLocEntry & getLocalSLocEntry(unsigned Index, bool *Invalid=nullptr) const
Get a local SLocEntry. This is exposed for indexing.
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...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
unsigned IsSystemFile
True if this content cache was initially created for a source file considered as a system one...
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
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)
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)
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const
Returns the kind of memory used to back the memory buffer for this content cache. ...
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...
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.
const ContentCache * getContentCache() const
fileinfo_iterator fileinfo_end() const
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.
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
bool shouldFreeBuffer() const
Determine whether the buffer should be freed.
llvm::DenseMap< const FileEntry *, SrcMgr::ContentCache * >::const_iterator fileinfo_iterator
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
void setBuffer(std::unique_ptr< llvm::MemoryBuffer > B)
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...
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.
bool isBufferInvalid() const
Determine whether the buffer itself is invalid.
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)
Copies the values of the most significant bits from each 8-bit element in a 128-bit integer vector of...
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. ...
llvm::MemoryBuffer * getBuffer(DiagnosticsEngine &Diag, const SourceManager &SM, SourceLocation Loc=SourceLocation(), bool *Invalid=nullptr) const
Returns the memory buffer for the associated content.
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.
bool isFileOverridden(const FileEntry *File) const
Returns true if the file contents have been overridden.
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...
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.
unsigned getSize() const
Returns the size of the content encapsulated by this ContentCache.
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.