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