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