clang 20.0.0git
SourceManager.cpp
Go to the documentation of this file.
1//===- SourceManager.cpp - Track and cache source files -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the SourceManager interface.
10//
11//===----------------------------------------------------------------------===//
12
16#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/Statistic.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/ADT/StringSwitch.h"
26#include "llvm/Support/Allocator.h"
27#include "llvm/Support/Capacity.h"
28#include "llvm/Support/Compiler.h"
29#include "llvm/Support/Endian.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"
36#include <algorithm>
37#include <cassert>
38#include <cstddef>
39#include <cstdint>
40#include <memory>
41#include <optional>
42#include <tuple>
43#include <utility>
44#include <vector>
45
46using namespace clang;
47using namespace SrcMgr;
48using llvm::MemoryBuffer;
49
50#define DEBUG_TYPE "source-manager"
51
52// Reaching a limit of 2^31 results in a hard error. This metric allows to track
53// if particular invocation of the compiler is close to it.
54STATISTIC(MaxUsedSLocBytes, "Maximum number of bytes used by source locations "
55 "(both loaded and local).");
56
57//===----------------------------------------------------------------------===//
58// SourceManager Helper Classes
59//===----------------------------------------------------------------------===//
60
61/// getSizeBytesMapped - Returns the number of bytes actually mapped for this
62/// ContentCache. This can be 0 if the MemBuffer was not actually expanded.
64 return Buffer ? Buffer->getBufferSize() : 0;
65}
66
67/// Returns the kind of memory used to back the memory buffer for
68/// this content cache. This is used for performance analysis.
69llvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind() const {
70 if (Buffer == nullptr) {
71 assert(0 && "Buffer should never be null");
72 return llvm::MemoryBuffer::MemoryBuffer_Malloc;
73 }
74 return Buffer->getBufferKind();
75}
76
77/// getSize - Returns the size of the content encapsulated by this ContentCache.
78/// This can be the size of the source file or the size of an arbitrary
79/// scratch buffer. If the ContentCache encapsulates a source file, that
80/// file is not lazily brought in from disk to satisfy this query.
81unsigned ContentCache::getSize() const {
82 return Buffer ? (unsigned)Buffer->getBufferSize()
84}
85
86const char *ContentCache::getInvalidBOM(StringRef BufStr) {
87 // If the buffer is valid, check to see if it has a UTF Byte Order Mark
88 // (BOM). We only support UTF-8 with and without a BOM right now. See
89 // http://en.wikipedia.org/wiki/Byte_order_mark for more information.
90 const char *InvalidBOM =
91 llvm::StringSwitch<const char *>(BufStr)
92 .StartsWith(llvm::StringLiteral::withInnerNUL("\x00\x00\xFE\xFF"),
93 "UTF-32 (BE)")
94 .StartsWith(llvm::StringLiteral::withInnerNUL("\xFF\xFE\x00\x00"),
95 "UTF-32 (LE)")
96 .StartsWith("\xFE\xFF", "UTF-16 (BE)")
97 .StartsWith("\xFF\xFE", "UTF-16 (LE)")
98 .StartsWith("\x2B\x2F\x76", "UTF-7")
99 .StartsWith("\xF7\x64\x4C", "UTF-1")
100 .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC")
101 .StartsWith("\x0E\xFE\xFF", "SCSU")
102 .StartsWith("\xFB\xEE\x28", "BOCU-1")
103 .StartsWith("\x84\x31\x95\x33", "GB-18030")
104 .Default(nullptr);
105
106 return InvalidBOM;
107}
108
109std::optional<llvm::MemoryBufferRef>
111 SourceLocation Loc) const {
112 // Lazily create the Buffer for ContentCaches that wrap files. If we already
113 // computed it, just return what we have.
114 if (IsBufferInvalid)
115 return std::nullopt;
116 if (Buffer)
117 return Buffer->getMemBufferRef();
118 if (!ContentsEntry)
119 return std::nullopt;
120
121 // Start with the assumption that the buffer is invalid to simplify early
122 // return paths.
123 IsBufferInvalid = true;
124
125 auto BufferOrError = FM.getBufferForFile(*ContentsEntry, IsFileVolatile);
126
127 // If we were unable to open the file, then we are in an inconsistent
128 // situation where the content cache referenced a file which no longer
129 // exists. Most likely, we were using a stat cache with an invalid entry but
130 // the file could also have been removed during processing. Since we can't
131 // really deal with this situation, just create an empty buffer.
132 if (!BufferOrError) {
133 if (Diag.isDiagnosticInFlight())
134 Diag.SetDelayedDiagnostic(diag::err_cannot_open_file,
136 BufferOrError.getError().message());
137 else
138 Diag.Report(Loc, diag::err_cannot_open_file)
139 << ContentsEntry->getName() << BufferOrError.getError().message();
140
141 return std::nullopt;
142 }
143
144 Buffer = std::move(*BufferOrError);
145
146 // Check that the file's size fits in an 'unsigned' (with room for a
147 // past-the-end value). This is deeply regrettable, but various parts of
148 // Clang (including elsewhere in this file!) use 'unsigned' to represent file
149 // offsets, line numbers, string literal lengths, and so on, and fail
150 // miserably on large source files.
151 //
152 // Note: ContentsEntry could be a named pipe, in which case
153 // ContentsEntry::getSize() could have the wrong size. Use
154 // MemoryBuffer::getBufferSize() instead.
155 if (Buffer->getBufferSize() >= std::numeric_limits<unsigned>::max()) {
156 if (Diag.isDiagnosticInFlight())
157 Diag.SetDelayedDiagnostic(diag::err_file_too_large,
159 else
160 Diag.Report(Loc, diag::err_file_too_large)
162
163 return std::nullopt;
164 }
165
166 // Unless this is a named pipe (in which case we can handle a mismatch),
167 // check that the file's size is the same as in the file entry (which may
168 // have come from a stat cache).
169 if (!ContentsEntry->isNamedPipe() &&
170 Buffer->getBufferSize() != (size_t)ContentsEntry->getSize()) {
171 if (Diag.isDiagnosticInFlight())
172 Diag.SetDelayedDiagnostic(diag::err_file_modified,
174 else
175 Diag.Report(Loc, diag::err_file_modified)
177
178 return std::nullopt;
179 }
180
181 // If the buffer is valid, check to see if it has a UTF Byte Order Mark
182 // (BOM). We only support UTF-8 with and without a BOM right now. See
183 // http://en.wikipedia.org/wiki/Byte_order_mark for more information.
184 StringRef BufStr = Buffer->getBuffer();
185 const char *InvalidBOM = getInvalidBOM(BufStr);
186
187 if (InvalidBOM) {
188 Diag.Report(Loc, diag::err_unsupported_bom)
189 << InvalidBOM << ContentsEntry->getName();
190 return std::nullopt;
191 }
192
193 // Buffer has been validated.
194 IsBufferInvalid = false;
195 return Buffer->getMemBufferRef();
196}
197
199 auto IterBool = FilenameIDs.try_emplace(Name, FilenamesByID.size());
200 if (IterBool.second)
201 FilenamesByID.push_back(&*IterBool.first);
202 return IterBool.first->second;
203}
204
205/// Add a line note to the line table that indicates that there is a \#line or
206/// GNU line marker at the specified FID/Offset location which changes the
207/// presumed location to LineNo/FilenameID. If EntryExit is 0, then this doesn't
208/// change the presumed \#include stack. If it is 1, this is a file entry, if
209/// it is 2 then this is a file exit. FileKind specifies whether this is a
210/// system header or extern C system header.
211void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, unsigned LineNo,
212 int FilenameID, unsigned EntryExit,
214 std::vector<LineEntry> &Entries = LineEntries[FID];
215
216 assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
217 "Adding line entries out of order!");
218
219 unsigned IncludeOffset = 0;
220 if (EntryExit == 1) {
221 // Push #include
222 IncludeOffset = Offset-1;
223 } else {
224 const auto *PrevEntry = Entries.empty() ? nullptr : &Entries.back();
225 if (EntryExit == 2) {
226 // Pop #include
227 assert(PrevEntry && PrevEntry->IncludeOffset &&
228 "PPDirectives should have caught case when popping empty include "
229 "stack");
230 PrevEntry = FindNearestLineEntry(FID, PrevEntry->IncludeOffset);
231 }
232 if (PrevEntry) {
233 IncludeOffset = PrevEntry->IncludeOffset;
234 if (FilenameID == -1) {
235 // An unspecified FilenameID means use the previous (or containing)
236 // filename if available, or the main source file otherwise.
237 FilenameID = PrevEntry->FilenameID;
238 }
239 }
240 }
241
242 Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind,
243 IncludeOffset));
244}
245
246/// FindNearestLineEntry - Find the line entry nearest to FID that is before
247/// it. If there is no line entry before Offset in FID, return null.
249 unsigned Offset) {
250 const std::vector<LineEntry> &Entries = LineEntries[FID];
251 assert(!Entries.empty() && "No #line entries for this FID after all!");
252
253 // It is very common for the query to be after the last #line, check this
254 // first.
255 if (Entries.back().FileOffset <= Offset)
256 return &Entries.back();
257
258 // Do a binary search to find the maximal element that is still before Offset.
259 std::vector<LineEntry>::const_iterator I = llvm::upper_bound(Entries, Offset);
260 if (I == Entries.begin())
261 return nullptr;
262 return &*--I;
263}
264
265/// Add a new line entry that has already been encoded into
266/// the internal representation of the line table.
268 const std::vector<LineEntry> &Entries) {
269 LineEntries[FID] = Entries;
270}
271
272/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
274 return getLineTable().getLineTableFilenameID(Name);
275}
276
277/// AddLineNote - Add a line note to the line table for the FileID and offset
278/// specified by Loc. If FilenameID is -1, it is considered to be
279/// unspecified.
281 int FilenameID, bool IsFileEntry,
282 bool IsFileExit,
284 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
285
286 bool Invalid = false;
287 SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
288 if (!Entry.isFile() || Invalid)
289 return;
290
292
293 // Remember that this file has #line directives now if it doesn't already.
295
296 (void) getLineTable();
297
298 unsigned EntryExit = 0;
299 if (IsFileEntry)
300 EntryExit = 1;
301 else if (IsFileExit)
302 EntryExit = 2;
303
304 LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID,
305 EntryExit, FileKind);
306}
307
309 if (!LineTable)
310 LineTable.reset(new LineTableInfo());
311 return *LineTable;
312}
313
314//===----------------------------------------------------------------------===//
315// Private 'Create' methods.
316//===----------------------------------------------------------------------===//
317
319 bool UserFilesAreVolatile)
320 : Diag(Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) {
322 Diag.setSourceManager(this);
323}
324
326 // Delete FileEntry objects corresponding to content caches. Since the actual
327 // content cache objects are bump pointer allocated, we just have to run the
328 // dtors, but we call the deallocate method for completeness.
329 for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i) {
330 if (MemBufferInfos[i]) {
331 MemBufferInfos[i]->~ContentCache();
332 ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
333 }
334 }
335 for (auto I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
336 if (I->second) {
337 I->second->~ContentCache();
338 ContentCacheAlloc.Deallocate(I->second);
339 }
340 }
341}
342
344 MainFileID = FileID();
345 LocalSLocEntryTable.clear();
346 LoadedSLocEntryTable.clear();
347 SLocEntryLoaded.clear();
348 SLocEntryOffsetLoaded.clear();
349 LastLineNoFileIDQuery = FileID();
350 LastLineNoContentCache = nullptr;
351 LastFileIDLookup = FileID();
352
353 if (LineTable)
354 LineTable->clear();
355
356 // Use up FileID #0 as an invalid expansion.
357 NextLocalOffset = 0;
358 CurrentLoadedOffset = MaxLoadedOffset;
360}
361
362bool SourceManager::isMainFile(const FileEntry &SourceFile) {
363 assert(MainFileID.isValid() && "expected initialized SourceManager");
364 if (auto *FE = getFileEntryForID(MainFileID))
365 return FE->getUID() == SourceFile.getUID();
366 return false;
367}
368
370 assert(MainFileID.isInvalid() && "expected uninitialized SourceManager");
371
372 auto CloneContentCache = [&](const ContentCache *Cache) -> ContentCache * {
373 auto *Clone = new (ContentCacheAlloc.Allocate<ContentCache>()) ContentCache;
374 Clone->OrigEntry = Cache->OrigEntry;
375 Clone->ContentsEntry = Cache->ContentsEntry;
376 Clone->BufferOverridden = Cache->BufferOverridden;
377 Clone->IsFileVolatile = Cache->IsFileVolatile;
378 Clone->IsTransient = Cache->IsTransient;
379 Clone->setUnownedBuffer(Cache->getBufferIfLoaded());
380 return Clone;
381 };
382
383 // Ensure all SLocEntries are loaded from the external source.
384 for (unsigned I = 0, N = Old.LoadedSLocEntryTable.size(); I != N; ++I)
385 if (!Old.SLocEntryLoaded[I])
386 Old.loadSLocEntry(I, nullptr);
387
388 // Inherit any content cache data from the old source manager.
389 for (auto &FileInfo : Old.FileInfos) {
390 SrcMgr::ContentCache *&Slot = FileInfos[FileInfo.first];
391 if (Slot)
392 continue;
393 Slot = CloneContentCache(FileInfo.second);
394 }
395}
396
397ContentCache &SourceManager::getOrCreateContentCache(FileEntryRef FileEnt,
398 bool isSystemFile) {
399 // Do we already have information about this file?
400 ContentCache *&Entry = FileInfos[FileEnt];
401 if (Entry)
402 return *Entry;
403
404 // Nope, create a new Cache entry.
405 Entry = ContentCacheAlloc.Allocate<ContentCache>();
406
407 if (OverriddenFilesInfo) {
408 // If the file contents are overridden with contents from another file,
409 // pass that file to ContentCache.
410 auto overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
411 if (overI == OverriddenFilesInfo->OverriddenFiles.end())
412 new (Entry) ContentCache(FileEnt);
413 else
414 new (Entry) ContentCache(OverridenFilesKeepOriginalName ? FileEnt
415 : overI->second,
416 overI->second);
417 } else {
418 new (Entry) ContentCache(FileEnt);
419 }
420
421 Entry->IsFileVolatile = UserFilesAreVolatile && !isSystemFile;
422 Entry->IsTransient = FilesAreTransient;
423 Entry->BufferOverridden |= FileEnt.isNamedPipe();
424
425 return *Entry;
426}
427
428/// Create a new ContentCache for the specified memory buffer.
429/// This does no caching.
430ContentCache &SourceManager::createMemBufferContentCache(
431 std::unique_ptr<llvm::MemoryBuffer> Buffer) {
432 // Add a new ContentCache to the MemBufferInfos list and return it.
433 ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>();
434 new (Entry) ContentCache();
435 MemBufferInfos.push_back(Entry);
436 Entry->setBuffer(std::move(Buffer));
437 return *Entry;
438}
439
440const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index,
441 bool *Invalid) const {
442 return const_cast<SourceManager *>(this)->loadSLocEntry(Index, Invalid);
443}
444
445SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index, bool *Invalid) {
446 assert(!SLocEntryLoaded[Index]);
447 if (ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2))) {
448 if (Invalid)
449 *Invalid = true;
450 // If the file of the SLocEntry changed we could still have loaded it.
451 if (!SLocEntryLoaded[Index]) {
452 // Try to recover; create a SLocEntry so the rest of clang can handle it.
453 if (!FakeSLocEntryForRecovery)
454 FakeSLocEntryForRecovery = std::make_unique<SLocEntry>(SLocEntry::get(
455 0, FileInfo::get(SourceLocation(), getFakeContentCacheForRecovery(),
456 SrcMgr::C_User, "")));
457 return *FakeSLocEntryForRecovery;
458 }
459 }
460
461 return LoadedSLocEntryTable[Index];
462}
463
464std::pair<int, SourceLocation::UIntTy>
466 SourceLocation::UIntTy TotalSize) {
467 assert(ExternalSLocEntries && "Don't have an external sloc source");
468 // Make sure we're not about to run out of source locations.
469 if (CurrentLoadedOffset < TotalSize ||
470 CurrentLoadedOffset - TotalSize < NextLocalOffset) {
471 return std::make_pair(0, 0);
472 }
473 LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
474 SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
475 SLocEntryOffsetLoaded.resize(LoadedSLocEntryTable.size());
476 CurrentLoadedOffset -= TotalSize;
477 updateSlocUsageStats();
478 int BaseID = -int(LoadedSLocEntryTable.size()) - 1;
479 LoadedSLocEntryAllocBegin.push_back(FileID::get(BaseID));
480 return std::make_pair(BaseID, CurrentLoadedOffset);
481}
482
483/// As part of recovering from missing or changed content, produce a
484/// fake, non-empty buffer.
485llvm::MemoryBufferRef SourceManager::getFakeBufferForRecovery() const {
486 if (!FakeBufferForRecovery)
487 FakeBufferForRecovery =
488 llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>");
489
490 return *FakeBufferForRecovery;
491}
492
493/// As part of recovering from missing or changed content, produce a
494/// fake content cache.
495SrcMgr::ContentCache &SourceManager::getFakeContentCacheForRecovery() const {
496 if (!FakeContentCacheForRecovery) {
497 FakeContentCacheForRecovery = std::make_unique<SrcMgr::ContentCache>();
498 FakeContentCacheForRecovery->setUnownedBuffer(getFakeBufferForRecovery());
499 }
500 return *FakeContentCacheForRecovery;
501}
502
503/// Returns the previous in-order FileID or an invalid FileID if there
504/// is no previous one.
505FileID SourceManager::getPreviousFileID(FileID FID) const {
506 if (FID.isInvalid())
507 return FileID();
508
509 int ID = FID.ID;
510 if (ID == -1)
511 return FileID();
512
513 if (ID > 0) {
514 if (ID-1 == 0)
515 return FileID();
516 } else if (unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
517 return FileID();
518 }
519
520 return FileID::get(ID-1);
521}
522
523/// Returns the next in-order FileID or an invalid FileID if there is
524/// no next one.
525FileID SourceManager::getNextFileID(FileID FID) const {
526 if (FID.isInvalid())
527 return FileID();
528
529 int ID = FID.ID;
530 if (ID > 0) {
531 if (unsigned(ID+1) >= local_sloc_entry_size())
532 return FileID();
533 } else if (ID+1 >= -1) {
534 return FileID();
535 }
536
537 return FileID::get(ID+1);
538}
539
540//===----------------------------------------------------------------------===//
541// Methods to create new FileID's and macro expansions.
542//===----------------------------------------------------------------------===//
543
544/// Create a new FileID that represents the specified file
545/// being \#included from the specified IncludePosition.
547 SourceLocation IncludePos,
548 SrcMgr::CharacteristicKind FileCharacter,
549 int LoadedID,
550 SourceLocation::UIntTy LoadedOffset) {
551 SrcMgr::ContentCache &IR = getOrCreateContentCache(SourceFile,
552 isSystem(FileCharacter));
553
554 // If this is a named pipe, immediately load the buffer to ensure subsequent
555 // calls to ContentCache::getSize() are accurate.
556 if (IR.ContentsEntry->isNamedPipe())
557 (void)IR.getBufferOrNone(Diag, getFileManager(), SourceLocation());
558
559 return createFileIDImpl(IR, SourceFile.getName(), IncludePos, FileCharacter,
560 LoadedID, LoadedOffset);
561}
562
563/// Create a new FileID that represents the specified memory buffer.
564///
565/// This does no caching of the buffer and takes ownership of the
566/// MemoryBuffer, so only pass a MemoryBuffer to this once.
567FileID SourceManager::createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer,
568 SrcMgr::CharacteristicKind FileCharacter,
569 int LoadedID,
570 SourceLocation::UIntTy LoadedOffset,
571 SourceLocation IncludeLoc) {
572 StringRef Name = Buffer->getBufferIdentifier();
573 return createFileIDImpl(createMemBufferContentCache(std::move(Buffer)), Name,
574 IncludeLoc, FileCharacter, LoadedID, LoadedOffset);
575}
576
577/// Create a new FileID that represents the specified memory buffer.
578///
579/// This does not take ownership of the MemoryBuffer. The memory buffer must
580/// outlive the SourceManager.
581FileID SourceManager::createFileID(const llvm::MemoryBufferRef &Buffer,
582 SrcMgr::CharacteristicKind FileCharacter,
583 int LoadedID,
584 SourceLocation::UIntTy LoadedOffset,
585 SourceLocation IncludeLoc) {
586 return createFileID(llvm::MemoryBuffer::getMemBuffer(Buffer), FileCharacter,
587 LoadedID, LoadedOffset, IncludeLoc);
588}
589
590/// Get the FileID for \p SourceFile if it exists. Otherwise, create a
591/// new FileID for the \p SourceFile.
592FileID
594 SrcMgr::CharacteristicKind FileCharacter) {
595 FileID ID = translateFile(SourceFile);
596 return ID.isValid() ? ID : createFileID(SourceFile, SourceLocation(),
597 FileCharacter);
598}
599
600/// createFileID - Create a new FileID for the specified ContentCache and
601/// include position. This works regardless of whether the ContentCache
602/// corresponds to a file or some other input source.
603FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename,
604 SourceLocation IncludePos,
605 SrcMgr::CharacteristicKind FileCharacter,
606 int LoadedID,
607 SourceLocation::UIntTy LoadedOffset) {
608 if (LoadedID < 0) {
609 assert(LoadedID != -1 && "Loading sentinel FileID");
610 unsigned Index = unsigned(-LoadedID) - 2;
611 assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
612 assert(!SLocEntryLoaded[Index] && "FileID already loaded");
613 LoadedSLocEntryTable[Index] = SLocEntry::get(
614 LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename));
615 SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true;
616 return FileID::get(LoadedID);
617 }
618 unsigned FileSize = File.getSize();
619 if (!(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
620 NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) {
621 Diag.Report(IncludePos, diag::err_sloc_space_too_large);
623 return FileID();
624 }
625 LocalSLocEntryTable.push_back(
626 SLocEntry::get(NextLocalOffset,
627 FileInfo::get(IncludePos, File, FileCharacter, Filename)));
628 // We do a +1 here because we want a SourceLocation that means "the end of the
629 // file", e.g. for the "no newline at the end of the file" diagnostic.
630 NextLocalOffset += FileSize + 1;
631 updateSlocUsageStats();
632
633 // Set LastFileIDLookup to the newly created file. The next getFileID call is
634 // almost guaranteed to be from that file.
635 FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
636 return LastFileIDLookup = FID;
637}
638
640 SourceLocation SpellingLoc, SourceLocation ExpansionLoc, unsigned Length) {
642 ExpansionLoc);
643 return createExpansionLocImpl(Info, Length);
644}
645
647 SourceLocation SpellingLoc, SourceLocation ExpansionLocStart,
648 SourceLocation ExpansionLocEnd, unsigned Length,
649 bool ExpansionIsTokenRange, int LoadedID,
650 SourceLocation::UIntTy LoadedOffset) {
652 SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange);
653 return createExpansionLocImpl(Info, Length, LoadedID, LoadedOffset);
654}
655
657 SourceLocation TokenStart,
658 SourceLocation TokenEnd) {
659 assert(getFileID(TokenStart) == getFileID(TokenEnd) &&
660 "token spans multiple files");
661 return createExpansionLocImpl(
662 ExpansionInfo::createForTokenSplit(Spelling, TokenStart, TokenEnd),
663 TokenEnd.getOffset() - TokenStart.getOffset());
664}
665
667SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
668 unsigned Length, int LoadedID,
669 SourceLocation::UIntTy LoadedOffset) {
670 if (LoadedID < 0) {
671 assert(LoadedID != -1 && "Loading sentinel FileID");
672 unsigned Index = unsigned(-LoadedID) - 2;
673 assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
674 assert(!SLocEntryLoaded[Index] && "FileID already loaded");
675 LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
676 SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true;
677 return SourceLocation::getMacroLoc(LoadedOffset);
678 }
679 LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
680 if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
681 NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
682 Diag.Report(SourceLocation(), diag::err_sloc_space_too_large);
683 // FIXME: call `noteSLocAddressSpaceUsage` to report details to users and
684 // use a source location from `Info` to point at an error.
685 // Currently, both cause Clang to run indefinitely, this needs to be fixed.
686 // FIXME: return an error instead of crashing. Returning invalid source
687 // locations causes compiler to run indefinitely.
688 llvm::report_fatal_error("ran out of source locations");
689 }
690 // See createFileID for that +1.
691 NextLocalOffset += Length + 1;
692 updateSlocUsageStats();
693 return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));
694}
695
696std::optional<llvm::MemoryBufferRef>
698 SrcMgr::ContentCache &IR = getOrCreateContentCache(File);
699 return IR.getBufferOrNone(Diag, getFileManager(), SourceLocation());
700}
701
703 FileEntryRef SourceFile, std::unique_ptr<llvm::MemoryBuffer> Buffer) {
704 SrcMgr::ContentCache &IR = getOrCreateContentCache(SourceFile);
705
706 IR.setBuffer(std::move(Buffer));
707 IR.BufferOverridden = true;
708
709 getOverriddenFilesInfo().OverriddenFilesWithBuffer.insert(SourceFile);
710}
711
713 FileEntryRef NewFile) {
714 assert(SourceFile->getSize() == NewFile.getSize() &&
715 "Different sizes, use the FileManager to create a virtual file with "
716 "the correct size");
717 assert(FileInfos.find_as(SourceFile) == FileInfos.end() &&
718 "This function should be called at the initialization stage, before "
719 "any parsing occurs.");
720 // FileEntryRef is not default-constructible.
721 auto Pair = getOverriddenFilesInfo().OverriddenFiles.insert(
722 std::make_pair(SourceFile, NewFile));
723 if (!Pair.second)
724 Pair.first->second = NewFile;
725}
726
729 assert(isFileOverridden(&File.getFileEntry()));
730 OptionalFileEntryRef BypassFile = FileMgr.getBypassFile(File);
731
732 // If the file can't be found in the FS, give up.
733 if (!BypassFile)
734 return std::nullopt;
735
736 (void)getOrCreateContentCache(*BypassFile);
737 return BypassFile;
738}
739
741 getOrCreateContentCache(File).IsTransient = true;
742}
743
744std::optional<StringRef>
746 if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID))
747 if (Entry->getFile().getContentCache().OrigEntry)
748 return Entry->getFile().getName();
749 return std::nullopt;
750}
751
752StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
753 auto B = getBufferDataOrNone(FID);
754 if (Invalid)
755 *Invalid = !B;
756 return B ? *B : "<<<<<INVALID SOURCE LOCATION>>>>>";
757}
758
759std::optional<StringRef>
761 if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID))
762 return Entry->getFile().getContentCache().getBufferDataIfLoaded();
763 return std::nullopt;
764}
765
766std::optional<StringRef> SourceManager::getBufferDataOrNone(FileID FID) const {
767 if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID))
768 if (auto B = Entry->getFile().getContentCache().getBufferOrNone(
769 Diag, getFileManager(), SourceLocation()))
770 return B->getBuffer();
771 return std::nullopt;
772}
773
774//===----------------------------------------------------------------------===//
775// SourceLocation manipulation methods.
776//===----------------------------------------------------------------------===//
777
778/// Return the FileID for a SourceLocation.
779///
780/// This is the cache-miss path of getFileID. Not as hot as that function, but
781/// still very important. It is responsible for finding the entry in the
782/// SLocEntry tables that contains the specified location.
783FileID SourceManager::getFileIDSlow(SourceLocation::UIntTy SLocOffset) const {
784 if (!SLocOffset)
785 return FileID::get(0);
786
787 // Now it is time to search for the correct file. See where the SLocOffset
788 // sits in the global view and consult local or loaded buffers for it.
789 if (SLocOffset < NextLocalOffset)
790 return getFileIDLocal(SLocOffset);
791 return getFileIDLoaded(SLocOffset);
792}
793
794/// Return the FileID for a SourceLocation with a low offset.
795///
796/// This function knows that the SourceLocation is in a local buffer, not a
797/// loaded one.
798FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
799 assert(SLocOffset < NextLocalOffset && "Bad function choice");
800
801 // After the first and second level caches, I see two common sorts of
802 // behavior: 1) a lot of searched FileID's are "near" the cached file
803 // location or are "near" the cached expansion location. 2) others are just
804 // completely random and may be a very long way away.
805 //
806 // To handle this, we do a linear search for up to 8 steps to catch #1 quickly
807 // then we fall back to a less cache efficient, but more scalable, binary
808 // search to find the location.
809
810 // See if this is near the file point - worst case we start scanning from the
811 // most newly created FileID.
812
813 // LessIndex - This is the lower bound of the range that we're searching.
814 // We know that the offset corresponding to the FileID is less than
815 // SLocOffset.
816 unsigned LessIndex = 0;
817 // upper bound of the search range.
818 unsigned GreaterIndex = LocalSLocEntryTable.size();
819 if (LastFileIDLookup.ID >= 0) {
820 // Use the LastFileIDLookup to prune the search space.
821 if (LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset)
822 LessIndex = LastFileIDLookup.ID;
823 else
824 GreaterIndex = LastFileIDLookup.ID;
825 }
826
827 // Find the FileID that contains this.
828 unsigned NumProbes = 0;
829 while (true) {
830 --GreaterIndex;
831 assert(GreaterIndex < LocalSLocEntryTable.size());
832 if (LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) {
833 FileID Res = FileID::get(int(GreaterIndex));
834 // Remember it. We have good locality across FileID lookups.
835 LastFileIDLookup = Res;
836 NumLinearScans += NumProbes+1;
837 return Res;
838 }
839 if (++NumProbes == 8)
840 break;
841 }
842
843 NumProbes = 0;
844 while (true) {
845 unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
846 SourceLocation::UIntTy MidOffset =
847 getLocalSLocEntry(MiddleIndex).getOffset();
848
849 ++NumProbes;
850
851 // If the offset of the midpoint is too large, chop the high side of the
852 // range to the midpoint.
853 if (MidOffset > SLocOffset) {
854 GreaterIndex = MiddleIndex;
855 continue;
856 }
857
858 // If the middle index contains the value, succeed and return.
859 if (MiddleIndex + 1 == LocalSLocEntryTable.size() ||
860 SLocOffset < getLocalSLocEntry(MiddleIndex + 1).getOffset()) {
861 FileID Res = FileID::get(MiddleIndex);
862
863 // Remember it. We have good locality across FileID lookups.
864 LastFileIDLookup = Res;
865 NumBinaryProbes += NumProbes;
866 return Res;
867 }
868
869 // Otherwise, move the low-side up to the middle index.
870 LessIndex = MiddleIndex;
871 }
872}
873
874/// Return the FileID for a SourceLocation with a high offset.
875///
876/// This function knows that the SourceLocation is in a loaded buffer, not a
877/// local one.
878FileID SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const {
879 if (SLocOffset < CurrentLoadedOffset) {
880 assert(0 && "Invalid SLocOffset or bad function choice");
881 return FileID();
882 }
883
884 return FileID::get(ExternalSLocEntries->getSLocEntryID(SLocOffset));
885}
886
887SourceLocation SourceManager::
888getExpansionLocSlowCase(SourceLocation Loc) const {
889 do {
890 // Note: If Loc indicates an offset into a token that came from a macro
891 // expansion (e.g. the 5th character of the token) we do not want to add
892 // this offset when going to the expansion location. The expansion
893 // location is the macro invocation, which the offset has nothing to do
894 // with. This is unlike when we get the spelling loc, because the offset
895 // directly correspond to the token whose spelling we're inspecting.
897 } while (!Loc.isFileID());
898
899 return Loc;
900}
901
902SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
903 do {
904 std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
905 Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc();
906 Loc = Loc.getLocWithOffset(LocInfo.second);
907 } while (!Loc.isFileID());
908 return Loc;
909}
910
911SourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const {
912 do {
915 else
917 } while (!Loc.isFileID());
918 return Loc;
919}
920
921
922std::pair<FileID, unsigned>
923SourceManager::getDecomposedExpansionLocSlowCase(
924 const SrcMgr::SLocEntry *E) const {
925 // If this is an expansion record, walk through all the expansion points.
926 FileID FID;
928 unsigned Offset;
929 do {
930 Loc = E->getExpansion().getExpansionLocStart();
931
932 FID = getFileID(Loc);
933 E = &getSLocEntry(FID);
934 Offset = Loc.getOffset()-E->getOffset();
935 } while (!Loc.isFileID());
936
937 return std::make_pair(FID, Offset);
938}
939
940std::pair<FileID, unsigned>
941SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
942 unsigned Offset) const {
943 // If this is an expansion record, walk through all the expansion points.
944 FileID FID;
946 do {
947 Loc = E->getExpansion().getSpellingLoc();
948 Loc = Loc.getLocWithOffset(Offset);
949
950 FID = getFileID(Loc);
951 E = &getSLocEntry(FID);
952 Offset = Loc.getOffset()-E->getOffset();
953 } while (!Loc.isFileID());
954
955 return std::make_pair(FID, Offset);
956}
957
958/// getImmediateSpellingLoc - Given a SourceLocation object, return the
959/// spelling location referenced by the ID. This is the first level down
960/// towards the place where the characters that make up the lexed token can be
961/// found. This should not generally be used by clients.
963 if (Loc.isFileID()) return Loc;
964 std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
965 Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc();
966 return Loc.getLocWithOffset(LocInfo.second);
967}
968
969/// Return the filename of the file containing a SourceLocation.
970StringRef SourceManager::getFilename(SourceLocation SpellingLoc) const {
972 return F->getName();
973 return StringRef();
974}
975
976/// getImmediateExpansionRange - Loc is required to be an expansion location.
977/// Return the start/end of the expansion information.
980 assert(Loc.isMacroID() && "Not a macro expansion loc!");
981 const ExpansionInfo &Expansion = getSLocEntry(getFileID(Loc)).getExpansion();
982 return Expansion.getExpansionLocRange();
983}
984
986 while (isMacroArgExpansion(Loc))
988 return Loc;
989}
990
991/// getExpansionRange - Given a SourceLocation object, return the range of
992/// tokens covered by the expansion in the ultimate file.
994 if (Loc.isFileID())
995 return CharSourceRange(SourceRange(Loc, Loc), true);
996
998
999 // Fully resolve the start and end locations to their ultimate expansion
1000 // points.
1001 while (!Res.getBegin().isFileID())
1003 while (!Res.getEnd().isFileID()) {
1005 Res.setEnd(EndRange.getEnd());
1006 Res.setTokenRange(EndRange.isTokenRange());
1007 }
1008 return Res;
1009}
1010
1012 SourceLocation *StartLoc) const {
1013 if (!Loc.isMacroID()) return false;
1014
1015 FileID FID = getFileID(Loc);
1016 const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion();
1017 if (!Expansion.isMacroArgExpansion()) return false;
1018
1019 if (StartLoc)
1020 *StartLoc = Expansion.getExpansionLocStart();
1021 return true;
1022}
1023
1025 if (!Loc.isMacroID()) return false;
1026
1027 FileID FID = getFileID(Loc);
1028 const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion();
1029 return Expansion.isMacroBodyExpansion();
1030}
1031
1033 SourceLocation *MacroBegin) const {
1034 assert(Loc.isValid() && Loc.isMacroID() && "Expected a valid macro loc");
1035
1036 std::pair<FileID, unsigned> DecompLoc = getDecomposedLoc(Loc);
1037 if (DecompLoc.second > 0)
1038 return false; // Does not point at the start of expansion range.
1039
1040 bool Invalid = false;
1041 const SrcMgr::ExpansionInfo &ExpInfo =
1042 getSLocEntry(DecompLoc.first, &Invalid).getExpansion();
1043 if (Invalid)
1044 return false;
1045 SourceLocation ExpLoc = ExpInfo.getExpansionLocStart();
1046
1047 if (ExpInfo.isMacroArgExpansion()) {
1048 // For macro argument expansions, check if the previous FileID is part of
1049 // the same argument expansion, in which case this Loc is not at the
1050 // beginning of the expansion.
1051 FileID PrevFID = getPreviousFileID(DecompLoc.first);
1052 if (!PrevFID.isInvalid()) {
1053 const SrcMgr::SLocEntry &PrevEntry = getSLocEntry(PrevFID, &Invalid);
1054 if (Invalid)
1055 return false;
1056 if (PrevEntry.isExpansion() &&
1057 PrevEntry.getExpansion().getExpansionLocStart() == ExpLoc)
1058 return false;
1059 }
1060 }
1061
1062 if (MacroBegin)
1063 *MacroBegin = ExpLoc;
1064 return true;
1065}
1066
1068 SourceLocation *MacroEnd) const {
1069 assert(Loc.isValid() && Loc.isMacroID() && "Expected a valid macro loc");
1070
1071 FileID FID = getFileID(Loc);
1072 SourceLocation NextLoc = Loc.getLocWithOffset(1);
1073 if (isInFileID(NextLoc, FID))
1074 return false; // Does not point at the end of expansion range.
1075
1076 bool Invalid = false;
1077 const SrcMgr::ExpansionInfo &ExpInfo =
1079 if (Invalid)
1080 return false;
1081
1082 if (ExpInfo.isMacroArgExpansion()) {
1083 // For macro argument expansions, check if the next FileID is part of the
1084 // same argument expansion, in which case this Loc is not at the end of the
1085 // expansion.
1086 FileID NextFID = getNextFileID(FID);
1087 if (!NextFID.isInvalid()) {
1088 const SrcMgr::SLocEntry &NextEntry = getSLocEntry(NextFID, &Invalid);
1089 if (Invalid)
1090 return false;
1091 if (NextEntry.isExpansion() &&
1092 NextEntry.getExpansion().getExpansionLocStart() ==
1093 ExpInfo.getExpansionLocStart())
1094 return false;
1095 }
1096 }
1097
1098 if (MacroEnd)
1099 *MacroEnd = ExpInfo.getExpansionLocEnd();
1100 return true;
1101}
1102
1103//===----------------------------------------------------------------------===//
1104// Queries about the code at a SourceLocation.
1105//===----------------------------------------------------------------------===//
1106
1107/// getCharacterData - Return a pointer to the start of the specified location
1108/// in the appropriate MemoryBuffer.
1110 bool *Invalid) const {
1111 // Note that this is a hot function in the getSpelling() path, which is
1112 // heavily used by -E mode.
1113 std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(SL);
1114
1115 // Note that calling 'getBuffer()' may lazily page in a source file.
1116 bool CharDataInvalid = false;
1117 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &CharDataInvalid);
1118 if (CharDataInvalid || !Entry.isFile()) {
1119 if (Invalid)
1120 *Invalid = true;
1121
1122 return "<<<<INVALID BUFFER>>>>";
1123 }
1124 std::optional<llvm::MemoryBufferRef> Buffer =
1126 SourceLocation());
1127 if (Invalid)
1128 *Invalid = !Buffer;
1129 return Buffer ? Buffer->getBufferStart() + LocInfo.second
1130 : "<<<<INVALID BUFFER>>>>";
1131}
1132
1133/// getColumnNumber - Return the column # for the specified file position.
1134/// this is significantly cheaper to compute than the line number.
1135unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
1136 bool *Invalid) const {
1137 std::optional<llvm::MemoryBufferRef> MemBuf = getBufferOrNone(FID);
1138 if (Invalid)
1139 *Invalid = !MemBuf;
1140
1141 if (!MemBuf)
1142 return 1;
1143
1144 // It is okay to request a position just past the end of the buffer.
1145 if (FilePos > MemBuf->getBufferSize()) {
1146 if (Invalid)
1147 *Invalid = true;
1148 return 1;
1149 }
1150
1151 const char *Buf = MemBuf->getBufferStart();
1152 // See if we just calculated the line number for this FilePos and can use
1153 // that to lookup the start of the line instead of searching for it.
1154 if (LastLineNoFileIDQuery == FID && LastLineNoContentCache->SourceLineCache &&
1155 LastLineNoResult < LastLineNoContentCache->SourceLineCache.size()) {
1156 const unsigned *SourceLineCache =
1157 LastLineNoContentCache->SourceLineCache.begin();
1158 unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
1159 unsigned LineEnd = SourceLineCache[LastLineNoResult];
1160 if (FilePos >= LineStart && FilePos < LineEnd) {
1161 // LineEnd is the LineStart of the next line.
1162 // A line ends with separator LF or CR+LF on Windows.
1163 // FilePos might point to the last separator,
1164 // but we need a column number at most 1 + the last column.
1165 if (FilePos + 1 == LineEnd && FilePos > LineStart) {
1166 if (Buf[FilePos - 1] == '\r' || Buf[FilePos - 1] == '\n')
1167 --FilePos;
1168 }
1169 return FilePos - LineStart + 1;
1170 }
1171 }
1172
1173 unsigned LineStart = FilePos;
1174 while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
1175 --LineStart;
1176 return FilePos-LineStart+1;
1177}
1178
1179// isInvalid - Return the result of calling loc.isInvalid(), and
1180// if Invalid is not null, set its value to same.
1181template<typename LocType>
1182static bool isInvalid(LocType Loc, bool *Invalid) {
1183 bool MyInvalid = Loc.isInvalid();
1184 if (Invalid)
1185 *Invalid = MyInvalid;
1186 return MyInvalid;
1187}
1188
1190 bool *Invalid) const {
1191 if (isInvalid(Loc, Invalid)) return 0;
1192 std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
1193 return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
1194}
1195
1197 bool *Invalid) const {
1198 if (isInvalid(Loc, Invalid)) return 0;
1199 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1200 return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
1201}
1202
1204 bool *Invalid) const {
1206 if (isInvalid(PLoc, Invalid)) return 0;
1207 return PLoc.getColumn();
1208}
1209
1210// Check if mutli-byte word x has bytes between m and n, included. This may also
1211// catch bytes equal to n + 1.
1212// The returned value holds a 0x80 at each byte position that holds a match.
1213// see http://graphics.stanford.edu/~seander/bithacks.html#HasBetweenInWord
1214template <class T>
1215static constexpr inline T likelyhasbetween(T x, unsigned char m,
1216 unsigned char n) {
1217 return ((x - ~static_cast<T>(0) / 255 * (n + 1)) & ~x &
1218 ((x & ~static_cast<T>(0) / 255 * 127) +
1219 (~static_cast<T>(0) / 255 * (127 - (m - 1))))) &
1220 ~static_cast<T>(0) / 255 * 128;
1221}
1222
1223LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer,
1224 llvm::BumpPtrAllocator &Alloc) {
1225
1226 // Find the file offsets of all of the *physical* source lines. This does
1227 // not look at trigraphs, escaped newlines, or anything else tricky.
1228 SmallVector<unsigned, 256> LineOffsets;
1229
1230 // Line #1 starts at char 0.
1231 LineOffsets.push_back(0);
1232
1233 const unsigned char *Start = (const unsigned char *)Buffer.getBufferStart();
1234 const unsigned char *End = (const unsigned char *)Buffer.getBufferEnd();
1235 const unsigned char *Buf = Start;
1236
1237 uint64_t Word;
1238
1239 // scan sizeof(Word) bytes at a time for new lines.
1240 // This is much faster than scanning each byte independently.
1241 if ((unsigned long)(End - Start) > sizeof(Word)) {
1242 do {
1243 Word = llvm::support::endian::read64(Buf, llvm::endianness::little);
1244 // no new line => jump over sizeof(Word) bytes.
1245 auto Mask = likelyhasbetween(Word, '\n', '\r');
1246 if (!Mask) {
1247 Buf += sizeof(Word);
1248 continue;
1249 }
1250
1251 // At that point, Mask contains 0x80 set at each byte that holds a value
1252 // in [\n, \r + 1 [
1253
1254 // Scan for the next newline - it's very likely there's one.
1255 unsigned N = llvm::countr_zero(Mask) - 7; // -7 because 0x80 is the marker
1256 Word >>= N;
1257 Buf += N / 8 + 1;
1258 unsigned char Byte = Word;
1259 switch (Byte) {
1260 case '\r':
1261 // If this is \r\n, skip both characters.
1262 if (*Buf == '\n') {
1263 ++Buf;
1264 }
1265 [[fallthrough]];
1266 case '\n':
1267 LineOffsets.push_back(Buf - Start);
1268 };
1269 } while (Buf < End - sizeof(Word) - 1);
1270 }
1271
1272 // Handle tail using a regular check.
1273 while (Buf < End) {
1274 if (*Buf == '\n') {
1275 LineOffsets.push_back(Buf - Start + 1);
1276 } else if (*Buf == '\r') {
1277 // If this is \r\n, skip both characters.
1278 if (Buf + 1 < End && Buf[1] == '\n') {
1279 ++Buf;
1280 }
1281 LineOffsets.push_back(Buf - Start + 1);
1282 }
1283 ++Buf;
1284 }
1285
1286 return LineOffsetMapping(LineOffsets, Alloc);
1287}
1288
1290 llvm::BumpPtrAllocator &Alloc)
1291 : Storage(Alloc.Allocate<unsigned>(LineOffsets.size() + 1)) {
1292 Storage[0] = LineOffsets.size();
1293 std::copy(LineOffsets.begin(), LineOffsets.end(), Storage + 1);
1294}
1295
1296/// getLineNumber - Given a SourceLocation, return the spelling line number
1297/// for the position indicated. This requires building and caching a table of
1298/// line offsets for the MemoryBuffer, so this is not cheap: use only when
1299/// about to emit a diagnostic.
1300unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos,
1301 bool *Invalid) const {
1302 if (FID.isInvalid()) {
1303 if (Invalid)
1304 *Invalid = true;
1305 return 1;
1306 }
1307
1308 const ContentCache *Content;
1309 if (LastLineNoFileIDQuery == FID)
1310 Content = LastLineNoContentCache;
1311 else {
1312 bool MyInvalid = false;
1313 const SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
1314 if (MyInvalid || !Entry.isFile()) {
1315 if (Invalid)
1316 *Invalid = true;
1317 return 1;
1318 }
1319
1320 Content = &Entry.getFile().getContentCache();
1321 }
1322
1323 // If this is the first use of line information for this buffer, compute the
1324 // SourceLineCache for it on demand.
1325 if (!Content->SourceLineCache) {
1326 std::optional<llvm::MemoryBufferRef> Buffer =
1327 Content->getBufferOrNone(Diag, getFileManager(), SourceLocation());
1328 if (Invalid)
1329 *Invalid = !Buffer;
1330 if (!Buffer)
1331 return 1;
1332
1333 Content->SourceLineCache =
1334 LineOffsetMapping::get(*Buffer, ContentCacheAlloc);
1335 } else if (Invalid)
1336 *Invalid = false;
1337
1338 // Okay, we know we have a line number table. Do a binary search to find the
1339 // line number that this character position lands on.
1340 const unsigned *SourceLineCache = Content->SourceLineCache.begin();
1341 const unsigned *SourceLineCacheStart = SourceLineCache;
1342 const unsigned *SourceLineCacheEnd = Content->SourceLineCache.end();
1343
1344 unsigned QueriedFilePos = FilePos+1;
1345
1346 // FIXME: I would like to be convinced that this code is worth being as
1347 // complicated as it is, binary search isn't that slow.
1348 //
1349 // If it is worth being optimized, then in my opinion it could be more
1350 // performant, simpler, and more obviously correct by just "galloping" outward
1351 // from the queried file position. In fact, this could be incorporated into a
1352 // generic algorithm such as lower_bound_with_hint.
1353 //
1354 // If someone gives me a test case where this matters, and I will do it! - DWD
1355
1356 // If the previous query was to the same file, we know both the file pos from
1357 // that query and the line number returned. This allows us to narrow the
1358 // search space from the entire file to something near the match.
1359 if (LastLineNoFileIDQuery == FID) {
1360 if (QueriedFilePos >= LastLineNoFilePos) {
1361 // FIXME: Potential overflow?
1362 SourceLineCache = SourceLineCache+LastLineNoResult-1;
1363
1364 // The query is likely to be nearby the previous one. Here we check to
1365 // see if it is within 5, 10 or 20 lines. It can be far away in cases
1366 // where big comment blocks and vertical whitespace eat up lines but
1367 // contribute no tokens.
1368 if (SourceLineCache+5 < SourceLineCacheEnd) {
1369 if (SourceLineCache[5] > QueriedFilePos)
1370 SourceLineCacheEnd = SourceLineCache+5;
1371 else if (SourceLineCache+10 < SourceLineCacheEnd) {
1372 if (SourceLineCache[10] > QueriedFilePos)
1373 SourceLineCacheEnd = SourceLineCache+10;
1374 else if (SourceLineCache+20 < SourceLineCacheEnd) {
1375 if (SourceLineCache[20] > QueriedFilePos)
1376 SourceLineCacheEnd = SourceLineCache+20;
1377 }
1378 }
1379 }
1380 } else {
1381 if (LastLineNoResult < Content->SourceLineCache.size())
1382 SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
1383 }
1384 }
1385
1386 const unsigned *Pos =
1387 std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
1388 unsigned LineNo = Pos-SourceLineCacheStart;
1389
1390 LastLineNoFileIDQuery = FID;
1391 LastLineNoContentCache = Content;
1392 LastLineNoFilePos = QueriedFilePos;
1393 LastLineNoResult = LineNo;
1394 return LineNo;
1395}
1396
1398 bool *Invalid) const {
1399 if (isInvalid(Loc, Invalid)) return 0;
1400 std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
1401 return getLineNumber(LocInfo.first, LocInfo.second);
1402}
1404 bool *Invalid) const {
1405 if (isInvalid(Loc, Invalid)) return 0;
1406 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1407 return getLineNumber(LocInfo.first, LocInfo.second);
1408}
1410 bool *Invalid) const {
1411 PresumedLoc PLoc = getPresumedLoc(Loc);
1412 if (isInvalid(PLoc, Invalid)) return 0;
1413 return PLoc.getLine();
1414}
1415
1416/// getFileCharacteristic - return the file characteristic of the specified
1417/// source location, indicating whether this is a normal file, a system
1418/// header, or an "implicit extern C" system header.
1419///
1420/// This state can be modified with flags on GNU linemarker directives like:
1421/// # 4 "foo.h" 3
1422/// which changes all source locations in the current file after that to be
1423/// considered to be from a system header.
1426 assert(Loc.isValid() && "Can't get file characteristic of invalid loc!");
1427 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1428 const SLocEntry *SEntry = getSLocEntryForFile(LocInfo.first);
1429 if (!SEntry)
1430 return C_User;
1431
1432 const SrcMgr::FileInfo &FI = SEntry->getFile();
1433
1434 // If there are no #line directives in this file, just return the whole-file
1435 // state.
1436 if (!FI.hasLineDirectives())
1437 return FI.getFileCharacteristic();
1438
1439 assert(LineTable && "Can't have linetable entries without a LineTable!");
1440 // See if there is a #line directive before the location.
1441 const LineEntry *Entry =
1442 LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second);
1443
1444 // If this is before the first line marker, use the file characteristic.
1445 if (!Entry)
1446 return FI.getFileCharacteristic();
1447
1448 return Entry->FileKind;
1449}
1450
1451/// Return the filename or buffer identifier of the buffer the location is in.
1452/// Note that this name does not respect \#line directives. Use getPresumedLoc
1453/// for normal clients.
1455 bool *Invalid) const {
1456 if (isInvalid(Loc, Invalid)) return "<invalid loc>";
1457
1458 auto B = getBufferOrNone(getFileID(Loc));
1459 if (Invalid)
1460 *Invalid = !B;
1461 return B ? B->getBufferIdentifier() : "<invalid buffer>";
1462}
1463
1464/// getPresumedLoc - This method returns the "presumed" location of a
1465/// SourceLocation specifies. A "presumed location" can be modified by \#line
1466/// or GNU line marker directives. This provides a view on the data that a
1467/// user should see in diagnostics, for example.
1468///
1469/// Note that a presumed location is always given as the expansion point of an
1470/// expansion location, not at the spelling location.
1472 bool UseLineDirectives) const {
1473 if (Loc.isInvalid()) return PresumedLoc();
1474
1475 // Presumed locations are always for expansion points.
1476 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1477
1478 bool Invalid = false;
1479 const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
1480 if (Invalid || !Entry.isFile())
1481 return PresumedLoc();
1482
1483 const SrcMgr::FileInfo &FI = Entry.getFile();
1484 const SrcMgr::ContentCache *C = &FI.getContentCache();
1485
1486 // To get the source name, first consult the FileEntry (if one exists)
1487 // before the MemBuffer as this will avoid unnecessarily paging in the
1488 // MemBuffer.
1489 FileID FID = LocInfo.first;
1490 StringRef Filename;
1491 if (C->OrigEntry)
1492 Filename = C->OrigEntry->getName();
1493 else if (auto Buffer = C->getBufferOrNone(Diag, getFileManager()))
1494 Filename = Buffer->getBufferIdentifier();
1495
1496 unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
1497 if (Invalid)
1498 return PresumedLoc();
1499 unsigned ColNo = getColumnNumber(LocInfo.first, LocInfo.second, &Invalid);
1500 if (Invalid)
1501 return PresumedLoc();
1502
1503 SourceLocation IncludeLoc = FI.getIncludeLoc();
1504
1505 // If we have #line directives in this file, update and overwrite the physical
1506 // location info if appropriate.
1507 if (UseLineDirectives && FI.hasLineDirectives()) {
1508 assert(LineTable && "Can't have linetable entries without a LineTable!");
1509 // See if there is a #line directive before this. If so, get it.
1510 if (const LineEntry *Entry =
1511 LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second)) {
1512 // If the LineEntry indicates a filename, use it.
1513 if (Entry->FilenameID != -1) {
1514 Filename = LineTable->getFilename(Entry->FilenameID);
1515 // The contents of files referenced by #line are not in the
1516 // SourceManager
1517 FID = FileID::get(0);
1518 }
1519
1520 // Use the line number specified by the LineEntry. This line number may
1521 // be multiple lines down from the line entry. Add the difference in
1522 // physical line numbers from the query point and the line marker to the
1523 // total.
1524 unsigned MarkerLineNo = getLineNumber(LocInfo.first, Entry->FileOffset);
1525 LineNo = Entry->LineNo + (LineNo-MarkerLineNo-1);
1526
1527 // Note that column numbers are not molested by line markers.
1528
1529 // Handle virtual #include manipulation.
1530 if (Entry->IncludeOffset) {
1531 IncludeLoc = getLocForStartOfFile(LocInfo.first);
1532 IncludeLoc = IncludeLoc.getLocWithOffset(Entry->IncludeOffset);
1533 }
1534 }
1535 }
1536
1537 return PresumedLoc(Filename.data(), FID, LineNo, ColNo, IncludeLoc);
1538}
1539
1540/// Returns whether the PresumedLoc for a given SourceLocation is
1541/// in the main file.
1542///
1543/// This computes the "presumed" location for a SourceLocation, then checks
1544/// whether it came from a file other than the main file. This is different
1545/// from isWrittenInMainFile() because it takes line marker directives into
1546/// account.
1548 if (Loc.isInvalid()) return false;
1549
1550 // Presumed locations are always for expansion points.
1551 std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
1552
1553 const SLocEntry *Entry = getSLocEntryForFile(LocInfo.first);
1554 if (!Entry)
1555 return false;
1556
1557 const SrcMgr::FileInfo &FI = Entry->getFile();
1558
1559 // Check if there is a line directive for this location.
1560 if (FI.hasLineDirectives())
1561 if (const LineEntry *Entry =
1562 LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second))
1563 if (Entry->IncludeOffset)
1564 return false;
1565
1566 return FI.getIncludeLoc().isInvalid();
1567}
1568
1569/// The size of the SLocEntry that \p FID represents.
1571 bool Invalid = false;
1572 const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
1573 if (Invalid)
1574 return 0;
1575
1576 int ID = FID.ID;
1577 SourceLocation::UIntTy NextOffset;
1578 if ((ID > 0 && unsigned(ID+1) == local_sloc_entry_size()))
1579 NextOffset = getNextLocalOffset();
1580 else if (ID+1 == -1)
1581 NextOffset = MaxLoadedOffset;
1582 else
1583 NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset();
1584
1585 return NextOffset - Entry.getOffset() - 1;
1586}
1587
1588//===----------------------------------------------------------------------===//
1589// Other miscellaneous methods.
1590//===----------------------------------------------------------------------===//
1591
1592/// Get the source location for the given file:line:col triplet.
1593///
1594/// If the source file is included multiple times, the source location will
1595/// be based upon an arbitrary inclusion.
1597 unsigned Line,
1598 unsigned Col) const {
1599 assert(SourceFile && "Null source file!");
1600 assert(Line && Col && "Line and column should start from 1!");
1601
1602 FileID FirstFID = translateFile(SourceFile);
1603 return translateLineCol(FirstFID, Line, Col);
1604}
1605
1606/// Get the FileID for the given file.
1607///
1608/// If the source file is included multiple times, the FileID will be the
1609/// first inclusion.
1611 assert(SourceFile && "Null source file!");
1612
1613 // First, check the main file ID, since it is common to look for a
1614 // location in the main file.
1615 if (MainFileID.isValid()) {
1616 bool Invalid = false;
1617 const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid);
1618 if (Invalid)
1619 return FileID();
1620
1621 if (MainSLoc.isFile()) {
1622 if (MainSLoc.getFile().getContentCache().OrigEntry == SourceFile)
1623 return MainFileID;
1624 }
1625 }
1626
1627 // The location we're looking for isn't in the main file; look
1628 // through all of the local source locations.
1629 for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
1630 const SLocEntry &SLoc = getLocalSLocEntry(I);
1631 if (SLoc.isFile() &&
1632 SLoc.getFile().getContentCache().OrigEntry == SourceFile)
1633 return FileID::get(I);
1634 }
1635
1636 // If that still didn't help, try the modules.
1637 for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) {
1638 const SLocEntry &SLoc = getLoadedSLocEntry(I);
1639 if (SLoc.isFile() &&
1640 SLoc.getFile().getContentCache().OrigEntry == SourceFile)
1641 return FileID::get(-int(I) - 2);
1642 }
1643
1644 return FileID();
1645}
1646
1647/// Get the source location in \arg FID for the given line:col.
1648/// Returns null location if \arg FID is not a file SLocEntry.
1650 unsigned Line,
1651 unsigned Col) const {
1652 // Lines are used as a one-based index into a zero-based array. This assert
1653 // checks for possible buffer underruns.
1654 assert(Line && Col && "Line and column should start from 1!");
1655
1656 if (FID.isInvalid())
1657 return SourceLocation();
1658
1659 bool Invalid = false;
1660 const SLocEntry &Entry = getSLocEntry(FID, &Invalid);
1661 if (Invalid)
1662 return SourceLocation();
1663
1664 if (!Entry.isFile())
1665 return SourceLocation();
1666
1667 SourceLocation FileLoc = SourceLocation::getFileLoc(Entry.getOffset());
1668
1669 if (Line == 1 && Col == 1)
1670 return FileLoc;
1671
1672 const ContentCache *Content = &Entry.getFile().getContentCache();
1673
1674 // If this is the first use of line information for this buffer, compute the
1675 // SourceLineCache for it on demand.
1676 std::optional<llvm::MemoryBufferRef> Buffer =
1677 Content->getBufferOrNone(Diag, getFileManager());
1678 if (!Buffer)
1679 return SourceLocation();
1680 if (!Content->SourceLineCache)
1681 Content->SourceLineCache =
1682 LineOffsetMapping::get(*Buffer, ContentCacheAlloc);
1683
1684 if (Line > Content->SourceLineCache.size()) {
1685 unsigned Size = Buffer->getBufferSize();
1686 if (Size > 0)
1687 --Size;
1688 return FileLoc.getLocWithOffset(Size);
1689 }
1690
1691 unsigned FilePos = Content->SourceLineCache[Line - 1];
1692 const char *Buf = Buffer->getBufferStart() + FilePos;
1693 unsigned BufLength = Buffer->getBufferSize() - FilePos;
1694 if (BufLength == 0)
1695 return FileLoc.getLocWithOffset(FilePos);
1696
1697 unsigned i = 0;
1698
1699 // Check that the given column is valid.
1700 while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
1701 ++i;
1702 return FileLoc.getLocWithOffset(FilePos + i);
1703}
1704
1705/// Compute a map of macro argument chunks to their expanded source
1706/// location. Chunks that are not part of a macro argument will map to an
1707/// invalid source location. e.g. if a file contains one macro argument at
1708/// offset 100 with length 10, this is how the map will be formed:
1709/// 0 -> SourceLocation()
1710/// 100 -> Expanded macro arg location
1711/// 110 -> SourceLocation()
1712void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
1713 FileID FID) const {
1714 assert(FID.isValid());
1715
1716 // Initially no macro argument chunk is present.
1717 MacroArgsCache.insert(std::make_pair(0, SourceLocation()));
1718
1719 int ID = FID.ID;
1720 while (true) {
1721 ++ID;
1722 // Stop if there are no more FileIDs to check.
1723 if (ID > 0) {
1724 if (unsigned(ID) >= local_sloc_entry_size())
1725 return;
1726 } else if (ID == -1) {
1727 return;
1728 }
1729
1730 bool Invalid = false;
1731 const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID, &Invalid);
1732 if (Invalid)
1733 return;
1734 if (Entry.isFile()) {
1735 auto& File = Entry.getFile();
1736 if (File.getFileCharacteristic() == C_User_ModuleMap ||
1737 File.getFileCharacteristic() == C_System_ModuleMap)
1738 continue;
1739
1740 SourceLocation IncludeLoc = File.getIncludeLoc();
1741 bool IncludedInFID =
1742 (IncludeLoc.isValid() && isInFileID(IncludeLoc, FID)) ||
1743 // Predefined header doesn't have a valid include location in main
1744 // file, but any files created by it should still be skipped when
1745 // computing macro args expanded in the main file.
1746 (FID == MainFileID && Entry.getFile().getName() == "<built-in>");
1747 if (IncludedInFID) {
1748 // Skip the files/macros of the #include'd file, we only care about
1749 // macros that lexed macro arguments from our file.
1750 if (Entry.getFile().NumCreatedFIDs)
1751 ID += Entry.getFile().NumCreatedFIDs - 1 /*because of next ++ID*/;
1752 continue;
1753 }
1754 // If file was included but not from FID, there is no more files/macros
1755 // that may be "contained" in this file.
1756 if (IncludeLoc.isValid())
1757 return;
1758 continue;
1759 }
1760
1761 const ExpansionInfo &ExpInfo = Entry.getExpansion();
1762
1763 if (ExpInfo.getExpansionLocStart().isFileID()) {
1764 if (!isInFileID(ExpInfo.getExpansionLocStart(), FID))
1765 return; // No more files/macros that may be "contained" in this file.
1766 }
1767
1768 if (!ExpInfo.isMacroArgExpansion())
1769 continue;
1770
1771 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1772 ExpInfo.getSpellingLoc(),
1773 SourceLocation::getMacroLoc(Entry.getOffset()),
1774 getFileIDSize(FileID::get(ID)));
1775 }
1776}
1777
1778void SourceManager::associateFileChunkWithMacroArgExp(
1779 MacroArgsMap &MacroArgsCache,
1780 FileID FID,
1781 SourceLocation SpellLoc,
1782 SourceLocation ExpansionLoc,
1783 unsigned ExpansionLength) const {
1784 if (!SpellLoc.isFileID()) {
1785 SourceLocation::UIntTy SpellBeginOffs = SpellLoc.getOffset();
1786 SourceLocation::UIntTy SpellEndOffs = SpellBeginOffs + ExpansionLength;
1787
1788 // The spelling range for this macro argument expansion can span multiple
1789 // consecutive FileID entries. Go through each entry contained in the
1790 // spelling range and if one is itself a macro argument expansion, recurse
1791 // and associate the file chunk that it represents.
1792
1793 FileID SpellFID; // Current FileID in the spelling range.
1794 unsigned SpellRelativeOffs;
1795 std::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc);
1796 while (true) {
1797 const SLocEntry &Entry = getSLocEntry(SpellFID);
1798 SourceLocation::UIntTy SpellFIDBeginOffs = Entry.getOffset();
1799 unsigned SpellFIDSize = getFileIDSize(SpellFID);
1800 SourceLocation::UIntTy SpellFIDEndOffs = SpellFIDBeginOffs + SpellFIDSize;
1801 const ExpansionInfo &Info = Entry.getExpansion();
1802 if (Info.isMacroArgExpansion()) {
1803 unsigned CurrSpellLength;
1804 if (SpellFIDEndOffs < SpellEndOffs)
1805 CurrSpellLength = SpellFIDSize - SpellRelativeOffs;
1806 else
1807 CurrSpellLength = ExpansionLength;
1808 associateFileChunkWithMacroArgExp(MacroArgsCache, FID,
1809 Info.getSpellingLoc().getLocWithOffset(SpellRelativeOffs),
1810 ExpansionLoc, CurrSpellLength);
1811 }
1812
1813 if (SpellFIDEndOffs >= SpellEndOffs)
1814 return; // we covered all FileID entries in the spelling range.
1815
1816 // Move to the next FileID entry in the spelling range.
1817 unsigned advance = SpellFIDSize - SpellRelativeOffs + 1;
1818 ExpansionLoc = ExpansionLoc.getLocWithOffset(advance);
1819 ExpansionLength -= advance;
1820 ++SpellFID.ID;
1821 SpellRelativeOffs = 0;
1822 }
1823 }
1824
1825 assert(SpellLoc.isFileID());
1826
1827 unsigned BeginOffs;
1828 if (!isInFileID(SpellLoc, FID, &BeginOffs))
1829 return;
1830
1831 unsigned EndOffs = BeginOffs + ExpansionLength;
1832
1833 // Add a new chunk for this macro argument. A previous macro argument chunk
1834 // may have been lexed again, so e.g. if the map is
1835 // 0 -> SourceLocation()
1836 // 100 -> Expanded loc #1
1837 // 110 -> SourceLocation()
1838 // and we found a new macro FileID that lexed from offset 105 with length 3,
1839 // the new map will be:
1840 // 0 -> SourceLocation()
1841 // 100 -> Expanded loc #1
1842 // 105 -> Expanded loc #2
1843 // 108 -> Expanded loc #1
1844 // 110 -> SourceLocation()
1845 //
1846 // Since re-lexed macro chunks will always be the same size or less of
1847 // previous chunks, we only need to find where the ending of the new macro
1848 // chunk is mapped to and update the map with new begin/end mappings.
1849
1850 MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
1851 --I;
1852 SourceLocation EndOffsMappedLoc = I->second;
1853 MacroArgsCache[BeginOffs] = ExpansionLoc;
1854 MacroArgsCache[EndOffs] = EndOffsMappedLoc;
1855}
1856
1857void SourceManager::updateSlocUsageStats() const {
1858 SourceLocation::UIntTy UsedBytes =
1859 NextLocalOffset + (MaxLoadedOffset - CurrentLoadedOffset);
1860 MaxUsedSLocBytes.updateMax(UsedBytes);
1861}
1862
1863/// If \arg Loc points inside a function macro argument, the returned
1864/// location will be the macro location in which the argument was expanded.
1865/// If a macro argument is used multiple times, the expanded location will
1866/// be at the first expansion of the argument.
1867/// e.g.
1868/// MY_MACRO(foo);
1869/// ^
1870/// Passing a file location pointing at 'foo', will yield a macro location
1871/// where 'foo' was expanded into.
1874 if (Loc.isInvalid() || !Loc.isFileID())
1875 return Loc;
1876
1877 FileID FID;
1878 unsigned Offset;
1879 std::tie(FID, Offset) = getDecomposedLoc(Loc);
1880 if (FID.isInvalid())
1881 return Loc;
1882
1883 std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
1884 if (!MacroArgsCache) {
1885 MacroArgsCache = std::make_unique<MacroArgsMap>();
1886 computeMacroArgsCache(*MacroArgsCache, FID);
1887 }
1888
1889 assert(!MacroArgsCache->empty());
1890 MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
1891 // In case every element in MacroArgsCache is greater than Offset we can't
1892 // decrement the iterator.
1893 if (I == MacroArgsCache->begin())
1894 return Loc;
1895
1896 --I;
1897
1898 SourceLocation::UIntTy MacroArgBeginOffs = I->first;
1899 SourceLocation MacroArgExpandedLoc = I->second;
1900 if (MacroArgExpandedLoc.isValid())
1901 return MacroArgExpandedLoc.getLocWithOffset(Offset - MacroArgBeginOffs);
1902
1903 return Loc;
1904}
1905
1906std::pair<FileID, unsigned>
1908 if (FID.isInvalid())
1909 return std::make_pair(FileID(), 0);
1910
1911 // Uses IncludedLocMap to retrieve/cache the decomposed loc.
1912
1913 using DecompTy = std::pair<FileID, unsigned>;
1914 auto InsertOp = IncludedLocMap.try_emplace(FID);
1915 DecompTy &DecompLoc = InsertOp.first->second;
1916 if (!InsertOp.second)
1917 return DecompLoc; // already in map.
1918
1919 SourceLocation UpperLoc;
1920 bool Invalid = false;
1921 const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
1922 if (!Invalid) {
1923 if (Entry.isExpansion())
1924 UpperLoc = Entry.getExpansion().getExpansionLocStart();
1925 else
1926 UpperLoc = Entry.getFile().getIncludeLoc();
1927 }
1928
1929 if (UpperLoc.isValid())
1930 DecompLoc = getDecomposedLoc(UpperLoc);
1931
1932 return DecompLoc;
1933}
1934
1936 assert(isLoadedSourceLocation(Loc) &&
1937 "Must be a source location in a loaded PCH/Module file");
1938
1939 auto [FID, Ignore] = getDecomposedLoc(Loc);
1940 // `LoadedSLocEntryAllocBegin` stores the sorted lowest FID of each loaded
1941 // allocation. Later allocations have lower FileIDs. The call below is to find
1942 // the lowest FID of a loaded allocation from any FID in the same allocation.
1943 // The lowest FID is used to identify a loaded allocation.
1944 const FileID *FirstFID =
1945 llvm::lower_bound(LoadedSLocEntryAllocBegin, FID, std::greater<FileID>{});
1946
1947 assert(FirstFID &&
1948 "The failure to find the first FileID of a "
1949 "loaded AST from a loaded source location was unexpected.");
1950 return *FirstFID;
1951}
1952
1954 const std::pair<FileID, unsigned> &LOffs,
1955 const std::pair<FileID, unsigned> &ROffs) const {
1956 // If one is local while the other is loaded.
1957 if (isLoadedFileID(LOffs.first) != isLoadedFileID(ROffs.first))
1958 return false;
1959
1960 if (isLoadedFileID(LOffs.first) && isLoadedFileID(ROffs.first)) {
1961 auto FindSLocEntryAlloc = [this](FileID FID) {
1962 // Loaded FileIDs are negative, we store the lowest FileID from each
1963 // allocation, later allocations have lower FileIDs.
1964 return llvm::lower_bound(LoadedSLocEntryAllocBegin, FID,
1965 std::greater<FileID>{});
1966 };
1967
1968 // If both are loaded from different AST files.
1969 if (FindSLocEntryAlloc(LOffs.first) != FindSLocEntryAlloc(ROffs.first))
1970 return false;
1971 }
1972
1973 return true;
1974}
1975
1976/// Given a decomposed source location, move it up the include/expansion stack
1977/// to the parent source location within the same translation unit. If this is
1978/// possible, return the decomposed version of the parent in Loc and return
1979/// false. If Loc is a top-level entry, return true and don't modify it.
1980static bool
1981MoveUpTranslationUnitIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
1982 const SourceManager &SM) {
1983 std::pair<FileID, unsigned> UpperLoc = SM.getDecomposedIncludedLoc(Loc.first);
1984 if (UpperLoc.first.isInvalid() ||
1985 !SM.isInTheSameTranslationUnitImpl(UpperLoc, Loc))
1986 return true; // We reached the top.
1987
1988 Loc = UpperLoc;
1989 return false;
1990}
1991
1992/// Return the cache entry for comparing the given file IDs
1993/// for isBeforeInTranslationUnit.
1994InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID,
1995 FileID RFID) const {
1996 // This is a magic number for limiting the cache size. It was experimentally
1997 // derived from a small Objective-C project (where the cache filled
1998 // out to ~250 items). We can make it larger if necessary.
1999 // FIXME: this is almost certainly full these days. Use an LRU cache?
2000 enum { MagicCacheSize = 300 };
2001 IsBeforeInTUCacheKey Key(LFID, RFID);
2002
2003 // If the cache size isn't too large, do a lookup and if necessary default
2004 // construct an entry. We can then return it to the caller for direct
2005 // use. When they update the value, the cache will get automatically
2006 // updated as well.
2007 if (IBTUCache.size() < MagicCacheSize)
2008 return IBTUCache.try_emplace(Key, LFID, RFID).first->second;
2009
2010 // Otherwise, do a lookup that will not construct a new value.
2011 InBeforeInTUCache::iterator I = IBTUCache.find(Key);
2012 if (I != IBTUCache.end())
2013 return I->second;
2014
2015 // Fall back to the overflow value.
2016 IBTUCacheOverflow.setQueryFIDs(LFID, RFID);
2017 return IBTUCacheOverflow;
2018}
2019
2020/// Determines the order of 2 source locations in the translation unit.
2021///
2022/// \returns true if LHS source location comes before RHS, false otherwise.
2024 SourceLocation RHS) const {
2025 assert(LHS.isValid() && RHS.isValid() && "Passed invalid source location!");
2026 if (LHS == RHS)
2027 return false;
2028
2029 std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
2030 std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
2031
2032 // getDecomposedLoc may have failed to return a valid FileID because, e.g. it
2033 // is a serialized one referring to a file that was removed after we loaded
2034 // the PCH.
2035 if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
2036 return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
2037
2038 std::pair<bool, bool> InSameTU = isInTheSameTranslationUnit(LOffs, ROffs);
2039 if (InSameTU.first)
2040 return InSameTU.second;
2041 // This case is used by libclang: clang_isBeforeInTranslationUnit
2042 return LOffs.first < ROffs.first;
2043}
2044
2046 std::pair<FileID, unsigned> &LOffs,
2047 std::pair<FileID, unsigned> &ROffs) const {
2048 // If the source locations are not in the same TU, return early.
2049 if (!isInTheSameTranslationUnitImpl(LOffs, ROffs))
2050 return std::make_pair(false, false);
2051
2052 // If the source locations are in the same file, just compare offsets.
2053 if (LOffs.first == ROffs.first)
2054 return std::make_pair(true, LOffs.second < ROffs.second);
2055
2056 // If we are comparing a source location with multiple locations in the same
2057 // file, we get a big win by caching the result.
2058 InBeforeInTUCacheEntry &IsBeforeInTUCache =
2059 getInBeforeInTUCache(LOffs.first, ROffs.first);
2060
2061 // If we are comparing a source location with multiple locations in the same
2062 // file, we get a big win by caching the result.
2063 if (IsBeforeInTUCache.isCacheValid())
2064 return std::make_pair(
2065 true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second));
2066
2067 // Okay, we missed in the cache, we'll compute the answer and populate it.
2068 // We need to find the common ancestor. The only way of doing this is to
2069 // build the complete include chain for one and then walking up the chain
2070 // of the other looking for a match.
2071
2072 // A location within a FileID on the path up from LOffs to the main file.
2073 struct Entry {
2074 std::pair<FileID, unsigned> DecomposedLoc; // FileID redundant, but clearer.
2075 FileID ChildFID; // Used for breaking ties. Invalid for the initial loc.
2076 };
2077 llvm::SmallDenseMap<FileID, Entry, 16> LChain;
2078
2079 FileID LChild;
2080 do {
2081 LChain.try_emplace(LOffs.first, Entry{LOffs, LChild});
2082 // We catch the case where LOffs is in a file included by ROffs and
2083 // quit early. The other way round unfortunately remains suboptimal.
2084 if (LOffs.first == ROffs.first)
2085 break;
2086 LChild = LOffs.first;
2087 } while (!MoveUpTranslationUnitIncludeHierarchy(LOffs, *this));
2088
2089 FileID RChild;
2090 do {
2091 auto LIt = LChain.find(ROffs.first);
2092 if (LIt != LChain.end()) {
2093 // Compare the locations within the common file and cache them.
2094 LOffs = LIt->second.DecomposedLoc;
2095 LChild = LIt->second.ChildFID;
2096 // The relative order of LChild and RChild is a tiebreaker when
2097 // - locs expand to the same location (occurs in macro arg expansion)
2098 // - one loc is a parent of the other (we consider the parent as "first")
2099 // For the parent entry to be first, its invalid child file ID must
2100 // compare smaller to the valid child file ID of the other entry.
2101 // However loaded FileIDs are <0, so we perform *unsigned* comparison!
2102 // This changes the relative order of local vs loaded FileIDs, but it
2103 // doesn't matter as these are never mixed in macro expansion.
2104 unsigned LChildID = LChild.ID;
2105 unsigned RChildID = RChild.ID;
2106 assert(((LOffs.second != ROffs.second) ||
2107 (LChildID == 0 || RChildID == 0) ||
2108 isInSameSLocAddrSpace(getComposedLoc(LChild, 0),
2109 getComposedLoc(RChild, 0), nullptr)) &&
2110 "Mixed local/loaded FileIDs with same include location?");
2111 IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second,
2112 LChildID < RChildID);
2113 return std::make_pair(
2114 true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second));
2115 }
2116 RChild = ROffs.first;
2117 } while (!MoveUpTranslationUnitIncludeHierarchy(ROffs, *this));
2118
2119 // If we found no match, the location is either in a built-ins buffer or
2120 // associated with global inline asm. PR5662 and PR22576 are examples.
2121
2122 StringRef LB = getBufferOrFake(LOffs.first).getBufferIdentifier();
2123 StringRef RB = getBufferOrFake(ROffs.first).getBufferIdentifier();
2124
2125 bool LIsBuiltins = LB == "<built-in>";
2126 bool RIsBuiltins = RB == "<built-in>";
2127 // Sort built-in before non-built-in.
2128 if (LIsBuiltins || RIsBuiltins) {
2129 if (LIsBuiltins != RIsBuiltins)
2130 return std::make_pair(true, LIsBuiltins);
2131 // Both are in built-in buffers, but from different files. We just claim
2132 // that lower IDs come first.
2133 return std::make_pair(true, LOffs.first < ROffs.first);
2134 }
2135
2136 bool LIsAsm = LB == "<inline asm>";
2137 bool RIsAsm = RB == "<inline asm>";
2138 // Sort assembler after built-ins, but before the rest.
2139 if (LIsAsm || RIsAsm) {
2140 if (LIsAsm != RIsAsm)
2141 return std::make_pair(true, RIsAsm);
2142 assert(LOffs.first == ROffs.first);
2143 return std::make_pair(true, false);
2144 }
2145
2146 bool LIsScratch = LB == "<scratch space>";
2147 bool RIsScratch = RB == "<scratch space>";
2148 // Sort scratch after inline asm, but before the rest.
2149 if (LIsScratch || RIsScratch) {
2150 if (LIsScratch != RIsScratch)
2151 return std::make_pair(true, LIsScratch);
2152 return std::make_pair(true, LOffs.second < ROffs.second);
2153 }
2154
2155 llvm_unreachable("Unsortable locations found");
2156}
2157
2159 llvm::errs() << "\n*** Source Manager Stats:\n";
2160 llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
2161 << " mem buffers mapped.\n";
2162 llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntries allocated ("
2163 << llvm::capacity_in_bytes(LocalSLocEntryTable)
2164 << " bytes of capacity), " << NextLocalOffset
2165 << "B of SLoc address space used.\n";
2166 llvm::errs() << LoadedSLocEntryTable.size()
2167 << " loaded SLocEntries allocated ("
2168 << llvm::capacity_in_bytes(LoadedSLocEntryTable)
2169 << " bytes of capacity), "
2170 << MaxLoadedOffset - CurrentLoadedOffset
2171 << "B of SLoc address space used.\n";
2172
2173 unsigned NumLineNumsComputed = 0;
2174 unsigned NumFileBytesMapped = 0;
2175 for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
2176 NumLineNumsComputed += bool(I->second->SourceLineCache);
2177 NumFileBytesMapped += I->second->getSizeBytesMapped();
2178 }
2179 unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
2180
2181 llvm::errs() << NumFileBytesMapped << " bytes of files mapped, "
2182 << NumLineNumsComputed << " files with line #'s computed, "
2183 << NumMacroArgsComputed << " files with macro args computed.\n";
2184 llvm::errs() << "FileID scans: " << NumLinearScans << " linear, "
2185 << NumBinaryProbes << " binary.\n";
2186}
2187
2188LLVM_DUMP_METHOD void SourceManager::dump() const {
2189 llvm::raw_ostream &out = llvm::errs();
2190
2191 auto DumpSLocEntry = [&](int ID, const SrcMgr::SLocEntry &Entry,
2192 std::optional<SourceLocation::UIntTy> NextStart) {
2193 out << "SLocEntry <FileID " << ID << "> " << (Entry.isFile() ? "file" : "expansion")
2194 << " <SourceLocation " << Entry.getOffset() << ":";
2195 if (NextStart)
2196 out << *NextStart << ">\n";
2197 else
2198 out << "???\?>\n";
2199 if (Entry.isFile()) {
2200 auto &FI = Entry.getFile();
2201 if (FI.NumCreatedFIDs)
2202 out << " covers <FileID " << ID << ":" << int(ID + FI.NumCreatedFIDs)
2203 << ">\n";
2204 if (FI.getIncludeLoc().isValid())
2205 out << " included from " << FI.getIncludeLoc().getOffset() << "\n";
2206 auto &CC = FI.getContentCache();
2207 out << " for " << (CC.OrigEntry ? CC.OrigEntry->getName() : "<none>")
2208 << "\n";
2209 if (CC.BufferOverridden)
2210 out << " contents overridden\n";
2211 if (CC.ContentsEntry != CC.OrigEntry) {
2212 out << " contents from "
2213 << (CC.ContentsEntry ? CC.ContentsEntry->getName() : "<none>")
2214 << "\n";
2215 }
2216 } else {
2217 auto &EI = Entry.getExpansion();
2218 out << " spelling from " << EI.getSpellingLoc().getOffset() << "\n";
2219 out << " macro " << (EI.isMacroArgExpansion() ? "arg" : "body")
2220 << " range <" << EI.getExpansionLocStart().getOffset() << ":"
2221 << EI.getExpansionLocEnd().getOffset() << ">\n";
2222 }
2223 };
2224
2225 // Dump local SLocEntries.
2226 for (unsigned ID = 0, NumIDs = LocalSLocEntryTable.size(); ID != NumIDs; ++ID) {
2227 DumpSLocEntry(ID, LocalSLocEntryTable[ID],
2228 ID == NumIDs - 1 ? NextLocalOffset
2229 : LocalSLocEntryTable[ID + 1].getOffset());
2230 }
2231 // Dump loaded SLocEntries.
2232 std::optional<SourceLocation::UIntTy> NextStart;
2233 for (unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2234 int ID = -(int)Index - 2;
2235 if (SLocEntryLoaded[Index]) {
2236 DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
2237 NextStart = LoadedSLocEntryTable[Index].getOffset();
2238 } else {
2239 NextStart = std::nullopt;
2240 }
2241 }
2242}
2243
2245 DiagnosticsEngine &Diag, std::optional<unsigned> MaxNotes) const {
2246 struct Info {
2247 // A location where this file was entered.
2249 // Number of times this FileEntry was entered.
2250 unsigned Inclusions = 0;
2251 // Size usage from the file itself.
2252 uint64_t DirectSize = 0;
2253 // Total size usage from the file and its macro expansions.
2254 uint64_t TotalSize = 0;
2255 };
2256 using UsageMap = llvm::MapVector<const FileEntry*, Info>;
2257
2258 UsageMap Usage;
2259 uint64_t CountedSize = 0;
2260
2261 auto AddUsageForFileID = [&](FileID ID) {
2262 // The +1 here is because getFileIDSize doesn't include the extra byte for
2263 // the one-past-the-end location.
2264 unsigned Size = getFileIDSize(ID) + 1;
2265
2266 // Find the file that used this address space, either directly or by
2267 // macro expansion.
2268 SourceLocation FileStart = getFileLoc(getComposedLoc(ID, 0));
2269 FileID FileLocID = getFileID(FileStart);
2270 const FileEntry *Entry = getFileEntryForID(FileLocID);
2271
2272 Info &EntryInfo = Usage[Entry];
2273 if (EntryInfo.Loc.isInvalid())
2274 EntryInfo.Loc = FileStart;
2275 if (ID == FileLocID) {
2276 ++EntryInfo.Inclusions;
2277 EntryInfo.DirectSize += Size;
2278 }
2279 EntryInfo.TotalSize += Size;
2280 CountedSize += Size;
2281 };
2282
2283 // Loaded SLocEntries have indexes counting downwards from -2.
2284 for (size_t Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
2285 AddUsageForFileID(FileID::get(-2 - Index));
2286 }
2287 // Local SLocEntries have indexes counting upwards from 0.
2288 for (size_t Index = 0; Index != LocalSLocEntryTable.size(); ++Index) {
2289 AddUsageForFileID(FileID::get(Index));
2290 }
2291
2292 // Sort the usage by size from largest to smallest. Break ties by raw source
2293 // location.
2294 auto SortedUsage = Usage.takeVector();
2295 auto Cmp = [](const UsageMap::value_type &A, const UsageMap::value_type &B) {
2296 return A.second.TotalSize > B.second.TotalSize ||
2297 (A.second.TotalSize == B.second.TotalSize &&
2298 A.second.Loc < B.second.Loc);
2299 };
2300 auto SortedEnd = SortedUsage.end();
2301 if (MaxNotes && SortedUsage.size() > *MaxNotes) {
2302 SortedEnd = SortedUsage.begin() + *MaxNotes;
2303 std::nth_element(SortedUsage.begin(), SortedEnd, SortedUsage.end(), Cmp);
2304 }
2305 std::sort(SortedUsage.begin(), SortedEnd, Cmp);
2306
2307 // Produce note on sloc address space usage total.
2308 uint64_t LocalUsage = NextLocalOffset;
2309 uint64_t LoadedUsage = MaxLoadedOffset - CurrentLoadedOffset;
2310 int UsagePercent = static_cast<int>(100.0 * double(LocalUsage + LoadedUsage) /
2311 MaxLoadedOffset);
2312 Diag.Report(SourceLocation(), diag::note_total_sloc_usage)
2313 << LocalUsage << LoadedUsage << (LocalUsage + LoadedUsage) << UsagePercent;
2314
2315 // Produce notes on sloc address space usage for each file with a high usage.
2316 uint64_t ReportedSize = 0;
2317 for (auto &[Entry, FileInfo] :
2318 llvm::make_range(SortedUsage.begin(), SortedEnd)) {
2319 Diag.Report(FileInfo.Loc, diag::note_file_sloc_usage)
2320 << FileInfo.Inclusions << FileInfo.DirectSize
2321 << (FileInfo.TotalSize - FileInfo.DirectSize);
2322 ReportedSize += FileInfo.TotalSize;
2323 }
2324
2325 // Describe any remaining usage not reported in the per-file usage.
2326 if (ReportedSize != CountedSize) {
2327 Diag.Report(SourceLocation(), diag::note_file_misc_sloc_usage)
2328 << (SortedUsage.end() - SortedEnd) << CountedSize - ReportedSize;
2329 }
2330}
2331
2333
2334/// Return the amount of memory used by memory buffers, breaking down
2335/// by heap-backed versus mmap'ed memory.
2337 size_t malloc_bytes = 0;
2338 size_t mmap_bytes = 0;
2339
2340 for (unsigned i = 0, e = MemBufferInfos.size(); i != e; ++i)
2341 if (size_t sized_mapped = MemBufferInfos[i]->getSizeBytesMapped())
2342 switch (MemBufferInfos[i]->getMemoryBufferKind()) {
2343 case llvm::MemoryBuffer::MemoryBuffer_MMap:
2344 mmap_bytes += sized_mapped;
2345 break;
2346 case llvm::MemoryBuffer::MemoryBuffer_Malloc:
2347 malloc_bytes += sized_mapped;
2348 break;
2349 }
2350
2351 return MemoryBufferSizes(malloc_bytes, mmap_bytes);
2352}
2353
2355 size_t size = llvm::capacity_in_bytes(MemBufferInfos) +
2356 llvm::capacity_in_bytes(LocalSLocEntryTable) +
2357 llvm::capacity_in_bytes(LoadedSLocEntryTable) +
2358 llvm::capacity_in_bytes(SLocEntryLoaded) +
2359 llvm::capacity_in_bytes(FileInfos);
2360
2361 if (OverriddenFilesInfo)
2362 size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
2363
2364 return size;
2365}
2366
2368 StringRef Content) {
2369 // This is referenced by `FileMgr` and will be released by `FileMgr` when it
2370 // is deleted.
2372 new llvm::vfs::InMemoryFileSystem);
2373 InMemoryFileSystem->addFile(
2374 FileName, 0,
2375 llvm::MemoryBuffer::getMemBuffer(Content, FileName,
2376 /*RequiresNullTerminator=*/false));
2377 // This is passed to `SM` as reference, so the pointer has to be referenced
2378 // in `Environment` so that `FileMgr` can out-live this function scope.
2379 FileMgr =
2380 std::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem);
2381 // This is passed to `SM` as reference, so the pointer has to be referenced
2382 // by `Environment` due to the same reason above.
2383 Diagnostics = std::make_unique<DiagnosticsEngine>(
2385 new DiagnosticOptions);
2386 SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr);
2387 FileEntryRef FE = llvm::cantFail(FileMgr->getFileRef(FileName));
2388 FileID ID =
2389 SourceMgr->createFileID(FE, SourceLocation(), clang::SrcMgr::C_User);
2390 assert(ID.isValid());
2391 SourceMgr->setMainFileID(ID);
2392}
#define SM(sm)
Definition: Cuda.cpp:83
Defines the Diagnostic-related interfaces.
Expr * E
Defines the clang::FileManager interface and associated types.
StringRef Filename
Definition: Format.cpp:3001
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static ParseState advance(ParseState S, size_t N)
Definition: Parsing.cpp:144
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the clang::SourceLocation class and associated facilities.
Defines implementation details of the clang::SourceManager class.
static constexpr T likelyhasbetween(T x, unsigned char m, unsigned char n)
static bool MoveUpTranslationUnitIncludeHierarchy(std::pair< FileID, unsigned > &Loc, const SourceManager &SM)
Given a decomposed source location, move it up the include/expansion stack to the parent source locat...
static bool isInvalid(LocType Loc, bool *Invalid)
STATISTIC(MaxUsedSLocBytes, "Maximum number of bytes used by source locations " "(both loaded and local).")
Defines the SourceManager interface.
__device__ double
__device__ int
Represents a character-granular source range.
void setEnd(SourceLocation e)
bool isTokenRange() const
Return true if the end of this range specifies the start of the last token.
void setBegin(SourceLocation b)
SourceLocation getEnd() const
SourceLocation getBegin() const
void setTokenRange(bool TR)
Used for handling and querying diagnostic IDs.
Options for controlling the compiler diagnostics engine.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1547
void setSourceManager(SourceManager *SrcMgr)
Definition: Diagnostic.h:589
virtual int getSLocEntryID(SourceLocation::UIntTy SLocOffset)=0
Get the index ID for the loaded SourceLocation offset.
virtual bool ReadSLocEntry(int ID)=0
Read the source location entry with index ID, which will always be less than -1.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
Definition: FileEntry.h:57
bool isNamedPipe() const
Definition: FileEntry.h:352
off_t getSize() const
Definition: FileEntry.h:340
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
Cached information about one file (either on disk or in the virtual file system).
Definition: FileEntry.h:300
unsigned getUID() const
Definition: FileEntry.h:326
off_t getSize() const
Definition: FileEntry.h:325
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
bool isValid() const
bool isInvalid() const
Implements support for file system lookup, file system caching, and directory search management.
Definition: FileManager.h:53
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
OptionalFileEntryRef getBypassFile(FileEntryRef VFE)
Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual file entry,...
Keeps track of options that affect how file operations are performed.
Holds the cache used by isBeforeInTranslationUnit.
void setCommonLoc(FileID commonFID, unsigned lCommonOffset, unsigned rCommonOffset, bool LParentBeforeRParent)
bool getCachedResult(unsigned LOffset, unsigned ROffset) const
If the cache is valid, compute the result given the specified offsets in the LHS/RHS FileID's.
bool isCacheValid() const
Return true if the currently cached values match up with the specified LHS/RHS query.
Used to hold and unique data used to represent #line information.
const LineEntry * FindNearestLineEntry(FileID FID, unsigned Offset)
Find the line entry nearest to FID that is before it.
unsigned getLineTableFilenameID(StringRef Str)
void AddEntry(FileID FID, const std::vector< LineEntry > &Entries)
Add a new line entry that has already been encoded into the internal representation of the line table...
void AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, int FilenameID, unsigned EntryExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table that indicates that there is a #line or GNU line marker at the spec...
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
unsigned getLine() const
Return the presumed line number of this location.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
SourceManagerForFile(StringRef FileName, StringRef Content)
Creates SourceManager and necessary dependencies (e.g.
This class handles loading and caching of source files into memory.
std::optional< StringRef > getNonBuiltinFilenameForID(FileID FID) const
Returns the filename for the provided FileID, unless it's a built-in buffer that's not represented by...
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
bool isAtEndOfImmediateMacroExpansion(SourceLocation Loc, SourceLocation *MacroEnd=nullptr) const
Returns true if the given MacroID location points at the character end of the immediate macro expansi...
unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Return the column # for the specified file position.
void noteSLocAddressSpaceUsage(DiagnosticsEngine &Diag, std::optional< unsigned > MaxNotes=32) const
bool isInMainFile(SourceLocation Loc) const
Returns whether the PresumedLoc for a given SourceLocation is in the main file.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, bool IsFileEntry, bool IsFileExit, SrcMgr::CharacteristicKind FileKind)
Add a line note to the line table for the FileID and offset specified by Loc.
SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, bool UserFilesAreVolatile=false)
SourceLocation createTokenSplitLoc(SourceLocation SpellingLoc, SourceLocation TokenStart, SourceLocation TokenEnd)
Return a new SourceLocation that encodes that the token starting at TokenStart ends prematurely at To...
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
MemoryBufferSizes getMemoryBufferSizes() const
Return the amount of memory used by memory buffers, breaking down by heap-backed versus mmap'ed memor...
void setFileIsTransient(FileEntryRef SourceFile)
Specify that a file is transient.
bool isFileOverridden(const FileEntry *File) const
Returns true if the file contents have been overridden.
OptionalFileEntryRef getFileEntryRefForID(FileID FID) const
Returns the FileEntryRef for the provided FileID.
SourceLocation translateLineCol(FileID FID, unsigned Line, unsigned Col) const
Get the source location in FID for the given line:col.
StringRef getBufferName(SourceLocation Loc, bool *Invalid=nullptr) const
Return the filename or buffer identifier of the buffer the location is in.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
std::optional< StringRef > getBufferDataOrNone(FileID FID) const
Return a StringRef to the source buffer data for the specified FileID, returning std::nullopt if inva...
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID translateFile(const FileEntry *SourceFile) const
Get the FileID for the given file.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Create a new FileID that represents the specified file being #included from the specified IncludePosi...
void PrintStats() const
Print statistics to stderr.
FileID getUniqueLoadedASTFileID(SourceLocation Loc) const
bool isMainFile(const FileEntry &SourceFile)
Returns true when the given FileEntry corresponds to the main file.
size_t getDataStructureSizes() const
Return the amount of memory used for various side tables and data structures in the SourceManager.
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
bool isInTheSameTranslationUnitImpl(const std::pair< FileID, unsigned > &LOffs, const std::pair< FileID, unsigned > &ROffs) const
Determines whether the two decomposed source location is in the same TU.
const SrcMgr::SLocEntry & getLocalSLocEntry(unsigned Index) const
Get a local SLocEntry. This is exposed for indexing.
OptionalFileEntryRef bypassFileContentsOverride(FileEntryRef File)
Bypass the overridden contents of a file.
FileManager & getFileManager() const
unsigned local_sloc_entry_size() const
Get the number of local SLocEntries we have.
std::optional< StringRef > getBufferDataIfLoaded(FileID FID) const
Return a StringRef to the source buffer data for the specified FileID, returning std::nullopt if it's...
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
std::pair< int, SourceLocation::UIntTy > AllocateLoadedSLocEntries(unsigned NumSLocEntries, SourceLocation::UIntTy TotalSize)
Allocate a number of loaded SLocEntries, which will be actually loaded on demand from the external so...
void overrideFileContents(FileEntryRef SourceFile, const llvm::MemoryBufferRef &Buffer)
Override the contents of the given source file by providing an already-allocated buffer.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
unsigned getFileIDSize(FileID FID) const
The size of the SLocEntry that FID represents.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
std::pair< bool, bool > isInTheSameTranslationUnit(std::pair< FileID, unsigned > &LOffs, std::pair< FileID, unsigned > &ROffs) const
Determines whether the two decomposed source location is in the same translation unit.
llvm::DenseMap< FileEntryRef, SrcMgr::ContentCache * >::const_iterator fileinfo_iterator
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
CharSourceRange getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
bool isInFileID(SourceLocation Loc, FileID FID, unsigned *RelativeOffset=nullptr) const
Given a specific FileID, returns true if Loc is inside that FileID chunk and sets relative offset (of...
unsigned getLineTableFilenameID(StringRef Str)
Return the uniqued ID for the specified filename.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
void initializeForReplay(const SourceManager &Old)
Initialize this source manager suitably to replay the compilation described by Old.
FileID getOrCreateFileID(FileEntryRef SourceFile, SrcMgr::CharacteristicKind FileCharacter)
Get the FileID for SourceFile if it exists.
SourceLocation translateFileLineCol(const FileEntry *SourceFile, unsigned Line, unsigned Col) const
Get the source location for the given file:line:col triplet.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
std::pair< FileID, unsigned > getDecomposedSpellingLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc, SourceLocation *MacroBegin=nullptr) const
Returns true if the given MacroID location points at the beginning of the immediate macro expansion.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const
Return the file characteristic of the specified source location, indicating whether this is a normal ...
SourceLocation createExpansionLoc(SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned Length, bool ExpansionIsTokenRange=true, int LoadedID=0, SourceLocation::UIntTy LoadedOffset=0)
Creates an expansion SLocEntry for a macro use.
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
std::pair< FileID, unsigned > getDecomposedIncludedLoc(FileID FID) const
Returns the "included/expanded in" decomposed location of the given FileID.
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const
If Loc points inside a function macro argument, the returned location will be the macro location in w...
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
LineTableInfo & getLineTable()
Retrieve the stored line table.
SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
std::optional< llvm::MemoryBufferRef > getMemoryBufferForFileOrNone(FileEntryRef File)
Retrieve the memory buffer associated with the given file.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
SourceLocation createMacroArgExpansionLoc(SourceLocation SpellingLoc, SourceLocation ExpansionLoc, unsigned Length)
Creates an expansion SLocEntry for the substitution of an argument into a function-like macro's body.
A trivial tuple used to represent a source range.
One instance of this struct is kept for every file loaded or used.
void setBuffer(std::unique_ptr< llvm::MemoryBuffer > B)
Set the buffer.
std::optional< StringRef > getBufferDataIfLoaded() const
Return a StringRef to the source buffer data, only if it has already been loaded.
OptionalFileEntryRef ContentsEntry
References the file which the contents were actually loaded from.
unsigned getSizeBytesMapped() const
Returns the number of bytes actually mapped for this ContentCache.
unsigned IsTransient
True if this file may be transient, that is, if it might not exist at some later point in time when t...
unsigned getSize() const
Returns the size of the content encapsulated by this ContentCache.
llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const
Returns the kind of memory used to back the memory buffer for this content cache.
unsigned IsFileVolatile
True if this content cache was initially created for a source file considered to be volatile (likely ...
LineOffsetMapping SourceLineCache
A bump pointer allocated array of offsets for each source line.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, SourceLocation Loc=SourceLocation()) const
Returns the memory buffer for the associated content.
static const char * getInvalidBOM(StringRef BufStr)
unsigned BufferOverridden
Indicates whether the buffer itself was provided to override the actual file contents.
OptionalFileEntryRef OrigEntry
Reference to the file entry representing this ContentCache.
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded,...
SourceLocation getExpansionLocStart() const
static ExpansionInfo create(SourceLocation SpellingLoc, SourceLocation Start, SourceLocation End, bool ExpansionIsTokenRange=true)
Return a ExpansionInfo for an expansion.
SourceLocation getSpellingLoc() const
CharSourceRange getExpansionLocRange() const
static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc, SourceLocation ExpansionLoc)
Return a special ExpansionInfo for the expansion of a macro argument into a function-like macro's bod...
static ExpansionInfo createForTokenSplit(SourceLocation SpellingLoc, SourceLocation Start, SourceLocation End)
Return a special ExpansionInfo representing a token that ends prematurely.
SourceLocation getExpansionLocEnd() const
Information about a FileID, basically just the logical file that it represents and include stack info...
const ContentCache & getContentCache() const
CharacteristicKind getFileCharacteristic() const
Return whether this is a system header or not.
static FileInfo get(SourceLocation IL, ContentCache &Con, CharacteristicKind FileCharacter, StringRef Filename)
Return a FileInfo object.
bool hasLineDirectives() const
Return true if this FileID has #line directives in it.
void setHasLineDirectives()
Set the flag that indicates that this FileID has line table entries associated with it.
SourceLocation getIncludeLoc() const
StringRef getName() const
Returns the name of the file that was used when the file was loaded from the underlying file system.
Mapping of line offsets into a source file.
const unsigned * begin() const
const unsigned * end() const
static LineOffsetMapping get(llvm::MemoryBufferRef Buffer, llvm::BumpPtrAllocator &Alloc)
This is a discriminated union of FileInfo and ExpansionInfo.
SourceLocation::UIntTy getOffset() const
static SLocEntry get(SourceLocation::UIntTy Offset, const FileInfo &FI)
const FileInfo & getFile() const
const ExpansionInfo & getExpansion() const
The type-property cache.
Definition: Type.cpp:4437
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:81
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
Definition: SourceManager.h:90
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
#define bool
Definition: stdbool.h:24
SrcMgr::CharacteristicKind FileKind
Set the 0 if no flags, 1 if a system header,.
static LineEntry get(unsigned Offs, unsigned Line, int Filename, SrcMgr::CharacteristicKind FileKind, unsigned IncludeOffset)