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