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(
"\x00\x00\xFE\xFF",
"UTF-32 (BE)")
174 .StartsWith(
"\xFF\xFE\x00\x00",
"UTF-32 (LE)")
175 .StartsWith(
"\x2B\x2F\x76",
"UTF-7")
176 .StartsWith(
"\xF7\x64\x4C",
"UTF-1")
177 .StartsWith(
"\xDD\x73\x66\x73",
"UTF-EBCDIC")
178 .StartsWith(
"\x0E\xFE\xFF",
"SDSU")
179 .StartsWith(
"\xFB\xEE\x28",
"BOCU-1")
180 .StartsWith(
"\x84\x31\x95\x33",
"GB-18030")
184 Diag.
Report(Loc, diag::err_unsupported_bom)
186 Buffer.setInt(Buffer.getInt() | InvalidFlag);
192 return Buffer.getPointer();
197 FilenameIDs.insert(std::make_pair(Name, FilenamesByID.size()));
199 FilenamesByID.push_back(&*IterBool.first);
200 return IterBool.first->second;
210 int FilenameID,
unsigned EntryExit,
212 std::vector<LineEntry> &Entries = LineEntries[FID];
216 if (FilenameID == -1 && !Entries.empty())
217 FilenameID = Entries.back().FilenameID;
219 assert((Entries.empty() || Entries.back().FileOffset <
Offset) &&
220 "Adding line entries out of order!");
222 unsigned IncludeOffset = 0;
223 if (EntryExit == 0) {
224 IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
225 }
else if (EntryExit == 1) {
226 IncludeOffset = Offset-1;
227 }
else if (EntryExit == 2) {
228 assert(!Entries.empty() && Entries.back().IncludeOffset &&
229 "PPDirectives should have caught case when popping empty include stack");
234 FindNearestLineEntry(FID, Entries.back().IncludeOffset))
235 IncludeOffset = PrevEntry->IncludeOffset;
238 Entries.push_back(
LineEntry::get(Offset, LineNo, FilenameID, FileKind,
246 const std::vector<LineEntry> &Entries = LineEntries[FID];
247 assert(!Entries.empty() &&
"No #line entries for this FID after all!");
251 if (Entries.back().FileOffset <=
Offset)
252 return &Entries.back();
255 std::vector<LineEntry>::const_iterator I =
256 std::upper_bound(Entries.begin(), Entries.end(),
Offset);
257 if (I == Entries.begin())
return nullptr;
264 const std::vector<LineEntry> &Entries) {
265 LineEntries[FID] = Entries;
270 return getLineTable().getLineTableFilenameID(Name);
277 int FilenameID,
bool IsFileEntry,
280 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
282 bool Invalid =
false;
283 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
284 if (!Entry.
isFile() || Invalid)
292 (void) getLineTable();
294 unsigned EntryExit = 0;
300 LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
301 EntryExit, FileKind);
315 bool UserFilesAreVolatile)
316 : Diag(Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) {
327 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
328 if (MemBufferInfos[i]) {
329 MemBufferInfos[i]->~ContentCache();
330 ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
333 for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
334 I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
336 I->second->~ContentCache();
337 ContentCacheAlloc.Deallocate(I->second);
344 LocalSLocEntryTable.clear();
345 LoadedSLocEntryTable.clear();
346 SLocEntryLoaded.clear();
347 LastLineNoFileIDQuery =
FileID();
348 LastLineNoContentCache =
nullptr;
349 LastFileIDLookup =
FileID();
356 CurrentLoadedOffset = MaxLoadedOffset;
361 assert(MainFileID.
isInvalid() &&
"expected uninitialized SourceManager");
366 Clone->ContentsEntry =
Cache->ContentsEntry;
367 Clone->BufferOverridden =
Cache->BufferOverridden;
368 Clone->IsSystemFile =
Cache->IsSystemFile;
369 Clone->IsTransient =
Cache->IsTransient;
370 Clone->replaceBuffer(
Cache->getRawBuffer(),
true);
375 for (
unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
376 if (!Old.SLocEntryLoaded[I])
377 Old.loadSLocEntry(I,
nullptr);
380 for (
auto &
FileInfo : Old.FileInfos) {
384 Slot = CloneContentCache(
FileInfo.second);
391 SourceManager::getOrCreateContentCache(
const FileEntry *FileEnt,
393 assert(FileEnt &&
"Didn't specify a file entry to use?");
397 if (Entry)
return Entry;
402 if (OverriddenFilesInfo) {
405 llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
406 overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
407 if (overI == OverriddenFilesInfo->OverriddenFiles.end())
410 new (Entry)
ContentCache(OverridenFilesKeepOriginalName ? FileEnt
426 SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer,
431 MemBufferInfos.push_back(Entry);
437 bool *Invalid)
const {
438 assert(!SLocEntryLoaded[Index]);
439 if (ExternalSLocEntries->
ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
443 if (!SLocEntryLoaded[Index]) {
445 LoadedSLocEntryTable[Index] = SLocEntry::get(0,
447 getFakeContentCacheForRecovery(),
452 return LoadedSLocEntryTable[Index];
455 std::pair<int, unsigned>
457 unsigned TotalSize) {
458 assert(ExternalSLocEntries &&
"Don't have an external sloc source");
460 if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
461 return std::make_pair(0, 0);
462 LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
463 SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
464 CurrentLoadedOffset -= TotalSize;
465 int ID = LoadedSLocEntryTable.size();
466 return std::make_pair(-ID - 1, CurrentLoadedOffset);
471 llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery()
const {
472 if (!FakeBufferForRecovery)
473 FakeBufferForRecovery =
474 llvm::MemoryBuffer::getMemBuffer(
"<<<INVALID BUFFER>>");
476 return FakeBufferForRecovery.get();
482 SourceManager::getFakeContentCacheForRecovery()
const {
483 if (!FakeContentCacheForRecovery) {
484 FakeContentCacheForRecovery = llvm::make_unique<SrcMgr::ContentCache>();
485 FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
488 return FakeContentCacheForRecovery.get();
493 FileID SourceManager::getPreviousFileID(
FileID FID)
const {
504 }
else if (
unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
508 return FileID::get(ID-1);
521 }
else if (ID+1 >= -1) {
525 return FileID::get(ID+1);
538 int LoadedID,
unsigned LoadedOffset) {
540 assert(LoadedID != -1 &&
"Loading sentinel FileID");
541 unsigned Index = unsigned(-LoadedID) - 2;
542 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
543 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
544 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
545 FileInfo::get(IncludePos, File, FileCharacter));
546 SLocEntryLoaded[Index] =
true;
547 return FileID::get(LoadedID);
549 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
550 FileInfo::get(IncludePos, File,
552 unsigned FileSize = File->
getSize();
553 assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
554 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
555 "Ran out of source locations!");
558 NextLocalOffset += FileSize + 1;
562 FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
563 return LastFileIDLookup = FID;
569 unsigned TokLength) {
570 ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
572 return createExpansionLocImpl(Info, TokLength);
581 unsigned LoadedOffset) {
584 return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
588 SourceManager::createExpansionLocImpl(
const ExpansionInfo &Info,
591 unsigned LoadedOffset) {
593 assert(LoadedID != -1 &&
"Loading sentinel FileID");
594 unsigned Index = unsigned(-LoadedID) - 2;
595 assert(Index < LoadedSLocEntryTable.size() &&
"FileID out of range");
596 assert(!SLocEntryLoaded[Index] &&
"FileID already loaded");
597 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
598 SLocEntryLoaded[Index] =
true;
599 return SourceLocation::getMacroLoc(LoadedOffset);
601 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
602 assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
603 NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
604 "Ran out of source locations!");
606 NextLocalOffset += TokLength + 1;
607 return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
613 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
618 llvm::MemoryBuffer *Buffer,
621 assert(IR &&
"getOrCreateContentCache() cannot return NULL");
626 getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
632 "Different sizes, use the FileManager to create a virtual file with " 634 assert(FileInfos.count(SourceFile) == 0 &&
635 "This function should be called at the initialization stage, before " 636 "any parsing occurs.");
637 getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
648 assert(OverriddenFilesInfo);
649 OverriddenFilesInfo->OverriddenFiles.erase(File);
650 OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
659 bool MyInvalid =
false;
661 if (!SLoc.
isFile() || MyInvalid) {
664 return "<<<<<INVALID SOURCE LOCATION>>>>>";
670 *Invalid = MyInvalid;
673 return "<<<<<INVALID SOURCE LOCATION>>>>>";
675 return Buf->getBuffer();
687 FileID SourceManager::getFileIDSlow(
unsigned SLocOffset)
const {
689 return FileID::get(0);
693 if (SLocOffset < NextLocalOffset)
694 return getFileIDLocal(SLocOffset);
695 return getFileIDLoaded(SLocOffset);
702 FileID SourceManager::getFileIDLocal(
unsigned SLocOffset)
const {
703 assert(SLocOffset < NextLocalOffset &&
"Bad function choice");
718 if (LastFileIDLookup.ID < 0 ||
719 LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
721 I = LocalSLocEntryTable.end();
724 I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
729 unsigned NumProbes = 0;
733 FileID Res = FileID::get(
int(I - LocalSLocEntryTable.begin()));
738 LastFileIDLookup = Res;
739 NumLinearScans += NumProbes+1;
742 if (++NumProbes == 8)
748 unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
752 unsigned LessIndex = 0;
755 bool Invalid =
false;
756 unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
759 return FileID::get(0);
765 if (MidOffset > SLocOffset) {
766 GreaterIndex = MiddleIndex;
773 if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
774 FileID Res = FileID::get(MiddleIndex);
778 if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
779 LastFileIDLookup = Res;
780 NumBinaryProbes += NumProbes;
785 LessIndex = MiddleIndex;
793 FileID SourceManager::getFileIDLoaded(
unsigned SLocOffset)
const {
795 if (SLocOffset < CurrentLoadedOffset) {
796 assert(0 &&
"Invalid SLocOffset or bad function choice");
805 int LastID = LastFileIDLookup.ID;
806 if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
809 I = (-LastID - 2) + 1;
812 for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) {
816 FileID Res = FileID::get(-
int(I) - 2);
819 LastFileIDLookup = Res;
820 NumLinearScans += NumProbes + 1;
828 unsigned GreaterIndex = I;
829 unsigned LessIndex = LoadedSLocEntryTable.size();
833 unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
842 if (GreaterIndex == MiddleIndex) {
843 assert(0 &&
"binary search missed the entry");
846 GreaterIndex = MiddleIndex;
850 if (isOffsetInFileID(FileID::get(-
int(MiddleIndex) - 2), SLocOffset)) {
851 FileID Res = FileID::get(-
int(MiddleIndex) - 2);
853 LastFileIDLookup = Res;
854 NumBinaryProbes += NumProbes;
859 if (LessIndex == MiddleIndex) {
860 assert(0 &&
"binary search missed the entry");
863 LessIndex = MiddleIndex;
902 std::pair<FileID, unsigned>
903 SourceManager::getDecomposedExpansionLocSlowCase(
917 return std::make_pair(FID, Offset);
920 std::pair<FileID, unsigned>
935 return std::make_pair(FID, Offset);
951 std::pair<SourceLocation,SourceLocation>
953 assert(Loc.
isMacroID() &&
"Not a macro expansion loc!");
960 std::pair<SourceLocation,SourceLocation>
962 if (Loc.
isFileID())
return std::make_pair(Loc, Loc);
964 std::pair<SourceLocation,SourceLocation> Res =
969 while (!Res.first.isFileID())
971 while (!Res.second.isFileID())
1002 if (DecompLoc.second > 0)
1005 bool Invalid =
false;
1016 FileID PrevFID = getPreviousFileID(DecompLoc.first);
1028 *MacroBegin = ExpLoc;
1041 bool Invalid =
false;
1051 FileID NextFID = getNextFileID(FID);
1075 bool *Invalid)
const {
1081 bool CharDataInvalid =
false;
1083 if (CharDataInvalid || !Entry.
isFile()) {
1087 return "<<<<INVALID BUFFER>>>>";
1092 *Invalid = CharDataInvalid;
1093 return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
1099 bool *Invalid)
const {
1100 bool MyInvalid =
false;
1101 llvm::MemoryBuffer *MemBuf =
getBuffer(FID, &MyInvalid);
1103 *Invalid = MyInvalid;
1109 if (FilePos > MemBuf->getBufferSize()) {
1115 const char *Buf = MemBuf->getBufferStart();
1118 if (LastLineNoFileIDQuery == FID &&
1120 LastLineNoResult < LastLineNoContentCache->NumLines) {
1122 unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1123 unsigned LineEnd = SourceLineCache[LastLineNoResult];
1124 if (FilePos >= LineStart && FilePos < LineEnd) {
1129 if (FilePos + 1 == LineEnd && FilePos > LineStart) {
1130 if (Buf[FilePos - 1] ==
'\r' || Buf[FilePos - 1] ==
'\n')
1133 return FilePos - LineStart + 1;
1137 unsigned LineStart = FilePos;
1138 while (LineStart && Buf[LineStart-1] !=
'\n' && Buf[LineStart-1] !=
'\r')
1140 return FilePos-LineStart+1;
1145 template<
typename LocType>
1147 bool MyInvalid = Loc.isInvalid();
1149 *Invalid = MyInvalid;
1154 bool *Invalid)
const {
1161 bool *Invalid)
const {
1168 bool *Invalid)
const {
1178 static LLVM_ATTRIBUTE_NOINLINE
void 1180 llvm::BumpPtrAllocator &Alloc,
1183 llvm::BumpPtrAllocator &Alloc,
1195 LineOffsets.push_back(0);
1197 const unsigned char *Buf = (
const unsigned char *)Buffer->getBufferStart();
1198 const unsigned char *
End = (
const unsigned char *)Buffer->getBufferEnd();
1202 const unsigned char *NextBuf = (
const unsigned char *)Buf;
1212 while (((
uintptr_t)NextBuf & 0xF) != 0) {
1213 if (*NextBuf ==
'\n' || *NextBuf ==
'\r' || *NextBuf ==
'\0')
1214 goto FoundSpecialChar;
1219 while (NextBuf+16 <= End) {
1220 const __m128i Chunk = *(
const __m128i*)NextBuf;
1227 NextBuf += llvm::countTrailingZeros(Mask);
1228 goto FoundSpecialChar;
1234 while (*NextBuf !=
'\n' && *NextBuf !=
'\r' && *NextBuf !=
'\0')
1240 Offs += NextBuf-Buf;
1243 if (Buf[0] ==
'\n' || Buf[0] ==
'\r') {
1245 if ((Buf[1] ==
'\n' || Buf[1] ==
'\r') && Buf[0] != Buf[1]) {
1251 LineOffsets.push_back(Offs);
1254 if (Buf == End)
break;
1264 std::copy(LineOffsets.begin(), LineOffsets.end(), FI->
SourceLineCache);
1272 bool *Invalid)
const {
1280 if (LastLineNoFileIDQuery == FID)
1281 Content = LastLineNoContentCache;
1283 bool MyInvalid =
false;
1285 if (MyInvalid || !Entry.
isFile()) {
1297 bool MyInvalid =
false;
1300 *Invalid = MyInvalid;
1309 unsigned *SourceLineCacheStart = SourceLineCache;
1310 unsigned *SourceLineCacheEnd = SourceLineCache + Content->
NumLines;
1312 unsigned QueriedFilePos = FilePos+1;
1327 if (LastLineNoFileIDQuery == FID) {
1328 if (QueriedFilePos >= LastLineNoFilePos) {
1330 SourceLineCache = SourceLineCache+LastLineNoResult-1;
1336 if (SourceLineCache+5 < SourceLineCacheEnd) {
1337 if (SourceLineCache[5] > QueriedFilePos)
1338 SourceLineCacheEnd = SourceLineCache+5;
1339 else if (SourceLineCache+10 < SourceLineCacheEnd) {
1340 if (SourceLineCache[10] > QueriedFilePos)
1341 SourceLineCacheEnd = SourceLineCache+10;
1342 else if (SourceLineCache+20 < SourceLineCacheEnd) {
1343 if (SourceLineCache[20] > QueriedFilePos)
1344 SourceLineCacheEnd = SourceLineCache+20;
1349 if (LastLineNoResult < Content->NumLines)
1350 SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1355 = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1356 unsigned LineNo = Pos-SourceLineCacheStart;
1358 LastLineNoFileIDQuery = FID;
1359 LastLineNoContentCache = Content;
1360 LastLineNoFilePos = QueriedFilePos;
1361 LastLineNoResult = LineNo;
1366 bool *Invalid)
const {
1372 bool *Invalid)
const {
1378 bool *Invalid)
const {
1394 assert(Loc.
isValid() &&
"Can't get file characteristic of invalid loc!");
1396 bool Invalid =
false;
1398 if (Invalid || !SEntry.
isFile())
1408 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1424 bool *Invalid)
const {
1425 if (
isInvalid(Loc, Invalid))
return "<invalid loc>";
1438 bool UseLineDirectives)
const {
1444 bool Invalid =
false;
1446 if (Invalid || !Entry.
isFile())
1459 Filename = C->
getBuffer(Diag, *
this)->getBufferIdentifier();
1461 unsigned LineNo =
getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1464 unsigned ColNo =
getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1473 assert(LineTable &&
"Can't have linetable entries without a LineTable!");
1478 if (Entry->FilenameID != -1)
1479 Filename = LineTable->
getFilename(Entry->FilenameID);
1485 unsigned MarkerLineNo =
getLineNumber(LocInfo.first, Entry->FileOffset);
1486 LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1491 if (Entry->IncludeOffset) {
1498 return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc);
1514 bool Invalid =
false;
1516 if (Invalid || !Entry.
isFile())
1525 if (Entry->IncludeOffset)
1533 bool Invalid =
false;
1539 unsigned NextOffset;
1542 else if (ID+1 == -1)
1543 NextOffset = MaxLoadedOffset;
1547 return NextOffset - Entry.
getOffset() - 1;
1563 llvm::sys::fs::UniqueID
ID;
1564 if (llvm::sys::fs::getUniqueID(File->
getName(),
ID))
1576 unsigned Col)
const {
1577 assert(SourceFile &&
"Null source file!");
1578 assert(Line && Col &&
"Line and column should start from 1!");
1589 assert(SourceFile &&
"Null source file!");
1599 bool Invalid =
false;
1607 if (!MainContentCache) {
1609 }
else if (MainContentCache->
OrigEntry == SourceFile) {
1610 FirstFID = MainFileID;
1615 SourceFileName = llvm::sys::path::filename(SourceFile->
getName());
1616 if (*SourceFileName == llvm::sys::path::filename(MainFile->
getName())) {
1618 if (SourceFileUID) {
1621 if (*SourceFileUID == *MainFileUID) {
1622 FirstFID = MainFileID;
1623 SourceFile = MainFile;
1636 bool Invalid =
false;
1644 FirstFID = FileID::get(I);
1655 FirstFID = FileID::get(-
int(I) - 2);
1667 (SourceFileName = llvm::sys::path::filename(SourceFile->
getName()))) &&
1669 bool Invalid =
false;
1683 *SourceFileName == llvm::sys::path::filename(Entry->
getName())) {
1686 if (*SourceFileUID == *EntryUID) {
1687 FirstFID = FileID::get(I);
1705 unsigned Col)
const {
1708 assert(Line && Col &&
"Line and column should start from 1!");
1713 bool Invalid =
false;
1723 if (Line == 1 && Col == 1)
1734 bool MyInvalid =
false;
1741 unsigned Size = Content->
getBuffer(Diag, *
this)->getBufferSize();
1747 llvm::MemoryBuffer *Buffer = Content->
getBuffer(Diag, *
this);
1749 const char *Buf = Buffer->getBufferStart() + FilePos;
1750 unsigned BufLength = Buffer->getBufferSize() - FilePos;
1757 while (i < BufLength-1 && i < Col-1 && Buf[i] !=
'\n' && Buf[i] !=
'\r')
1769 void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
1783 }
else if (ID == -1) {
1787 bool Invalid =
false;
1800 if (Entry.
getFile().NumCreatedFIDs)
1801 ID += Entry.
getFile().NumCreatedFIDs - 1;
1815 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1817 SourceLocation::getMacroLoc(Entry.
getOffset()),
1822 void SourceManager::associateFileChunkWithMacroArgExp(
1823 MacroArgsMap &MacroArgsCache,
1827 unsigned ExpansionLength)
const {
1829 unsigned SpellBeginOffs = SpellLoc.getOffset();
1830 unsigned SpellEndOffs = SpellBeginOffs + ExpansionLength;
1838 unsigned SpellRelativeOffs;
1842 unsigned SpellFIDBeginOffs = Entry.
getOffset();
1844 unsigned SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1847 unsigned CurrSpellLength;
1848 if (SpellFIDEndOffs < SpellEndOffs)
1849 CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1851 CurrSpellLength = ExpansionLength;
1852 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1854 ExpansionLoc, CurrSpellLength);
1857 if (SpellFIDEndOffs >= SpellEndOffs)
1861 unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1863 ExpansionLength -= advance;
1865 SpellRelativeOffs = 0;
1875 unsigned EndOffs = BeginOffs + ExpansionLength;
1894 MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1897 MacroArgsCache[BeginOffs] = ExpansionLoc;
1898 MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1921 std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
1922 if (!MacroArgsCache) {
1923 MacroArgsCache = llvm::make_unique<MacroArgsMap>();
1924 computeMacroArgsCache(*MacroArgsCache, FID);
1927 assert(!MacroArgsCache->empty());
1928 MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1931 unsigned MacroArgBeginOffs = I->first;
1933 if (MacroArgExpandedLoc.
isValid())
1939 std::pair<FileID, unsigned>
1942 return std::make_pair(
FileID(), 0);
1946 using DecompTy = std::pair<FileID, unsigned>;
1947 using MapTy = llvm::DenseMap<FileID, DecompTy>;
1948 std::pair<MapTy::iterator, bool>
1949 InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy()));
1950 DecompTy &DecompLoc = InsertOp.first->second;
1951 if (!InsertOp.second)
1955 bool Invalid =
false;
1977 if (UpperLoc.first.isInvalid())
1991 enum { MagicCacheSize = 300 };
1992 IsBeforeInTUCacheKey Key(LFID, RFID);
1998 if (IBTUCache.size() < MagicCacheSize)
1999 return IBTUCache[Key];
2002 InBeforeInTUCache::iterator I = IBTUCache.find(Key);
2003 if (I != IBTUCache.end())
2007 return IBTUCacheOverflow;
2015 assert(LHS.
isValid() && RHS.
isValid() &&
"Passed invalid source location!");
2025 if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
2026 return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
2030 return InSameTU.second;
2035 StringRef LB =
getBuffer(LOffs.first)->getBufferIdentifier();
2036 StringRef RB =
getBuffer(ROffs.first)->getBufferIdentifier();
2037 bool LIsBuiltins = LB ==
"<built-in>";
2038 bool RIsBuiltins = RB ==
"<built-in>";
2040 if (LIsBuiltins || RIsBuiltins) {
2041 if (LIsBuiltins != RIsBuiltins)
2045 return LOffs.first < ROffs.first;
2047 bool LIsAsm = LB ==
"<inline asm>";
2048 bool RIsAsm = RB ==
"<inline asm>";
2050 if (LIsAsm || RIsAsm) {
2051 if (LIsAsm != RIsAsm)
2053 assert(LOffs.first == ROffs.first);
2056 bool LIsScratch = LB ==
"<scratch space>";
2057 bool RIsScratch = RB ==
"<scratch space>";
2059 if (LIsScratch || RIsScratch) {
2060 if (LIsScratch != RIsScratch)
2062 return LOffs.second < ROffs.second;
2064 llvm_unreachable(
"Unsortable locations found");
2068 std::pair<FileID, unsigned> &LOffs,
2069 std::pair<FileID, unsigned> &ROffs)
const {
2071 if (LOffs.first == ROffs.first)
2072 return std::make_pair(
true, LOffs.second < ROffs.second);
2077 getInBeforeInTUCache(LOffs.first, ROffs.first);
2081 if (IsBeforeInTUCache.
isCacheValid(LOffs.first, ROffs.first))
2082 return std::make_pair(
2086 IsBeforeInTUCache.
setQueryFIDs(LOffs.first, ROffs.first,
2087 LOffs.first.ID < ROffs.first.ID);
2094 using LocSet = llvm::SmallDenseMap<FileID, unsigned, 16>;
2097 LChain.insert(LOffs);
2102 while((I = LChain.find(ROffs.first)) == LChain.end()) {
2106 if (I != LChain.end())
2111 if (LOffs.first == ROffs.first) {
2112 IsBeforeInTUCache.
setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
2113 return std::make_pair(
2117 IsBeforeInTUCache.
clear();
2118 return std::make_pair(
false,
false);
2122 llvm::errs() <<
"\n*** Source Manager Stats:\n";
2123 llvm::errs() << FileInfos.size() <<
" files mapped, " << MemBufferInfos.size()
2124 <<
" mem buffers mapped.\n";
2125 llvm::errs() << LocalSLocEntryTable.size() <<
" local SLocEntry's allocated (" 2126 << llvm::capacity_in_bytes(LocalSLocEntryTable)
2127 <<
" bytes of capacity), " 2128 << NextLocalOffset <<
"B of Sloc address space used.\n";
2129 llvm::errs() << LoadedSLocEntryTable.size()
2130 <<
" loaded SLocEntries allocated, " 2131 << MaxLoadedOffset - CurrentLoadedOffset
2132 <<
"B of Sloc address space used.\n";
2134 unsigned NumLineNumsComputed = 0;
2135 unsigned NumFileBytesMapped = 0;
2137 NumLineNumsComputed += I->second->SourceLineCache !=
nullptr;
2138 NumFileBytesMapped += I->second->getSizeBytesMapped();
2140 unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2142 llvm::errs() << NumFileBytesMapped <<
" bytes of files mapped, " 2143 << NumLineNumsComputed <<
" files with line #'s computed, " 2144 << NumMacroArgsComputed <<
" files with macro args computed.\n";
2145 llvm::errs() <<
"FileID scans: " << NumLinearScans <<
" linear, " 2146 << NumBinaryProbes <<
" binary.\n";
2150 llvm::raw_ostream &out = llvm::errs();
2154 out <<
"SLocEntry <FileID " << ID <<
"> " << (Entry.isFile() ?
"file" :
"expansion")
2155 <<
" <SourceLocation " << Entry.getOffset() <<
":";
2157 out << *NextStart <<
">\n";
2160 if (Entry.isFile()) {
2161 auto &FI = Entry.getFile();
2162 if (FI.NumCreatedFIDs)
2163 out <<
" covers <FileID " << ID <<
":" << int(ID + FI.NumCreatedFIDs)
2165 if (FI.getIncludeLoc().isValid())
2166 out <<
" included from " << FI.getIncludeLoc().getOffset() <<
"\n";
2167 if (
auto *CC = FI.getContentCache()) {
2168 out <<
" for " << (CC->OrigEntry ? CC->OrigEntry->getName() :
"<none>")
2170 if (CC->BufferOverridden)
2171 out <<
" contents overridden\n";
2172 if (CC->ContentsEntry != CC->OrigEntry) {
2173 out <<
" contents from " 2174 << (CC->ContentsEntry ? CC->ContentsEntry->getName() :
"<none>")
2179 auto &EI = Entry.getExpansion();
2180 out <<
" spelling from " << EI.getSpellingLoc().getOffset() <<
"\n";
2181 out <<
" macro " << (EI.isMacroArgExpansion() ?
"arg" :
"body")
2182 <<
" range <" << EI.getExpansionLocStart().getOffset() <<
":" 2183 << EI.getExpansionLocEnd().getOffset() <<
">\n";
2188 for (
unsigned ID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++
ID) {
2189 DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2190 ID == NumIDs - 1 ? NextLocalOffset
2191 : LocalSLocEntryTable[ID + 1].getOffset());
2195 for (
unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2196 int ID = -(int)Index - 2;
2197 if (SLocEntryLoaded[Index]) {
2198 DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2199 NextStart = LoadedSLocEntryTable[Index].getOffset();
2211 size_t malloc_bytes = 0;
2212 size_t mmap_bytes = 0;
2214 for (
unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2215 if (
size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2216 switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2217 case llvm::MemoryBuffer::MemoryBuffer_MMap:
2218 mmap_bytes += sized_mapped;
2220 case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2221 malloc_bytes += sized_mapped;
2229 size_t size = llvm::capacity_in_bytes(MemBufferInfos)
2230 + llvm::capacity_in_bytes(LocalSLocEntryTable)
2231 + llvm::capacity_in_bytes(LoadedSLocEntryTable)
2232 + llvm::capacity_in_bytes(SLocEntryLoaded)
2233 + llvm::capacity_in_bytes(FileInfos);
2235 if (OverriddenFilesInfo)
2236 size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
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.
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 translateFileLineCol(const FileEntry *SourceFile, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
One instance of this struct is kept for every file loaded or used.
const LineEntry * FindNearestLineEntry(FileID FID, unsigned Offset)
Find the line entry nearest to FID that is before it.
unsigned IsTransient
True if this file may be transient, that is, if it might not exist at some later point in time when t...
void setSourceManager(SourceManager *SrcMgr)
bool isAtEndOfImmediateMacroExpansion(SourceLocation Loc, SourceLocation *MacroEnd=nullptr) const
Returns true if the given MacroID location points at the character end of the immediate macro expansi...
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
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. ...
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.
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.
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 ...
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...
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...
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.
std::pair< SourceLocation, SourceLocation > getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
StringRef getName() const
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). ...
std::pair< SourceLocation, SourceLocation > getExpansionLocRange() const
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
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.
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...
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.
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.
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...
unsigned loaded_sloc_entry_size() const
Get the number of loaded SLocEntries we have.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
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.
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.
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...
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.