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