/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Basic/SourceManager.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- SourceManager.h - Track and cache source files -----------*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | /// \file |
10 | | /// Defines the SourceManager interface. |
11 | | /// |
12 | | /// There are three different types of locations in a %file: a spelling |
13 | | /// location, an expansion location, and a presumed location. |
14 | | /// |
15 | | /// Given an example of: |
16 | | /// \code |
17 | | /// #define min(x, y) x < y ? x : y |
18 | | /// \endcode |
19 | | /// |
20 | | /// and then later on a use of min: |
21 | | /// \code |
22 | | /// #line 17 |
23 | | /// return min(a, b); |
24 | | /// \endcode |
25 | | /// |
26 | | /// The expansion location is the line in the source code where the macro |
27 | | /// was expanded (the return statement), the spelling location is the |
28 | | /// location in the source where the macro was originally defined, |
29 | | /// and the presumed location is where the line directive states that |
30 | | /// the line is 17, or any other line. |
31 | | // |
32 | | //===----------------------------------------------------------------------===// |
33 | | |
34 | | #ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H |
35 | | #define LLVM_CLANG_BASIC_SOURCEMANAGER_H |
36 | | |
37 | | #include "clang/Basic/Diagnostic.h" |
38 | | #include "clang/Basic/FileEntry.h" |
39 | | #include "clang/Basic/FileManager.h" |
40 | | #include "clang/Basic/SourceLocation.h" |
41 | | #include "llvm/ADT/ArrayRef.h" |
42 | | #include "llvm/ADT/BitVector.h" |
43 | | #include "llvm/ADT/DenseMap.h" |
44 | | #include "llvm/ADT/DenseSet.h" |
45 | | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
46 | | #include "llvm/ADT/PointerIntPair.h" |
47 | | #include "llvm/ADT/SmallVector.h" |
48 | | #include "llvm/ADT/StringRef.h" |
49 | | #include "llvm/Support/Allocator.h" |
50 | | #include "llvm/Support/Compiler.h" |
51 | | #include "llvm/Support/MemoryBuffer.h" |
52 | | #include <cassert> |
53 | | #include <cstddef> |
54 | | #include <map> |
55 | | #include <memory> |
56 | | #include <string> |
57 | | #include <utility> |
58 | | #include <vector> |
59 | | |
60 | | namespace clang { |
61 | | |
62 | | class ASTReader; |
63 | | class ASTWriter; |
64 | | class FileManager; |
65 | | class LineTableInfo; |
66 | | class SourceManager; |
67 | | |
68 | | /// Public enums and private classes that are part of the |
69 | | /// SourceManager implementation. |
70 | | namespace SrcMgr { |
71 | | |
72 | | /// Indicates whether a file or directory holds normal user code, |
73 | | /// system code, or system code which is implicitly 'extern "C"' in C++ mode. |
74 | | /// |
75 | | /// Entire directories can be tagged with this (this is maintained by |
76 | | /// DirectoryLookup and friends) as can specific FileInfos when a \#pragma |
77 | | /// system_header is seen or in various other cases. |
78 | | /// |
79 | | enum CharacteristicKind { |
80 | | C_User, |
81 | | C_System, |
82 | | C_ExternCSystem, |
83 | | C_User_ModuleMap, |
84 | | C_System_ModuleMap |
85 | | }; |
86 | | |
87 | | /// Determine whether a file / directory characteristic is for system code. |
88 | 184M | inline bool isSystem(CharacteristicKind CK) { |
89 | 184M | return CK != C_User && CK != C_User_ModuleMap90.8M ; |
90 | 184M | } |
91 | | |
92 | | /// Determine whether a file characteristic is for a module map. |
93 | 239k | inline bool isModuleMap(CharacteristicKind CK) { |
94 | 239k | return CK == C_User_ModuleMap || CK == C_System_ModuleMap235k ; |
95 | 239k | } |
96 | | |
97 | | /// Mapping of line offsets into a source file. This does not own the storage |
98 | | /// for the line numbers. |
99 | | class LineOffsetMapping { |
100 | | public: |
101 | 281M | explicit operator bool() const { return Storage; } |
102 | 638M | unsigned size() const { |
103 | 638M | assert(Storage); |
104 | 0 | return Storage[0]; |
105 | 638M | } |
106 | 452M | ArrayRef<unsigned> getLines() const { |
107 | 452M | assert(Storage); |
108 | 0 | return ArrayRef<unsigned>(Storage + 1, Storage + 1 + size()); |
109 | 452M | } |
110 | 281M | const unsigned *begin() const { return getLines().begin(); } |
111 | 171M | const unsigned *end() const { return getLines().end(); } |
112 | 95.6k | const unsigned &operator[](int I) const { return getLines()[I]; } |
113 | | |
114 | | static LineOffsetMapping get(llvm::MemoryBufferRef Buffer, |
115 | | llvm::BumpPtrAllocator &Alloc); |
116 | | |
117 | 11.3M | LineOffsetMapping() = default; |
118 | | LineOffsetMapping(ArrayRef<unsigned> LineOffsets, |
119 | | llvm::BumpPtrAllocator &Alloc); |
120 | | |
121 | | private: |
122 | | /// First element is the size, followed by elements at off-by-one indexes. |
123 | | unsigned *Storage = nullptr; |
124 | | }; |
125 | | |
126 | | /// One instance of this struct is kept for every file loaded or used. |
127 | | /// |
128 | | /// This object owns the MemoryBuffer object. |
129 | | class alignas(8) ContentCache { |
130 | | /// The actual buffer containing the characters from the input |
131 | | /// file. |
132 | | mutable std::unique_ptr<llvm::MemoryBuffer> Buffer; |
133 | | |
134 | | public: |
135 | | /// Reference to the file entry representing this ContentCache. |
136 | | /// |
137 | | /// This reference does not own the FileEntry object. |
138 | | /// |
139 | | /// It is possible for this to be NULL if the ContentCache encapsulates |
140 | | /// an imaginary text buffer. |
141 | | /// |
142 | | /// FIXME: Turn this into a FileEntryRef and remove Filename. |
143 | | const FileEntry *OrigEntry; |
144 | | |
145 | | /// References the file which the contents were actually loaded from. |
146 | | /// |
147 | | /// Can be different from 'Entry' if we overridden the contents of one file |
148 | | /// with the contents of another file. |
149 | | const FileEntry *ContentsEntry; |
150 | | |
151 | | /// The filename that is used to access OrigEntry. |
152 | | /// |
153 | | /// FIXME: Remove this once OrigEntry is a FileEntryRef with a stable name. |
154 | | StringRef Filename; |
155 | | |
156 | | /// A bump pointer allocated array of offsets for each source line. |
157 | | /// |
158 | | /// This is lazily computed. The lines are owned by the SourceManager |
159 | | /// BumpPointerAllocator object. |
160 | | mutable LineOffsetMapping SourceLineCache; |
161 | | |
162 | | /// Indicates whether the buffer itself was provided to override |
163 | | /// the actual file contents. |
164 | | /// |
165 | | /// When true, the original entry may be a virtual file that does not |
166 | | /// exist. |
167 | | unsigned BufferOverridden : 1; |
168 | | |
169 | | /// True if this content cache was initially created for a source file |
170 | | /// considered to be volatile (likely to change between stat and open). |
171 | | unsigned IsFileVolatile : 1; |
172 | | |
173 | | /// True if this file may be transient, that is, if it might not |
174 | | /// exist at some later point in time when this content entry is used, |
175 | | /// after serialization and deserialization. |
176 | | unsigned IsTransient : 1; |
177 | | |
178 | | mutable unsigned IsBufferInvalid : 1; |
179 | | |
180 | 1.43M | ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {} Unexecuted instantiation: clang::SrcMgr::ContentCache::ContentCache(clang::FileEntry const*) clang::SrcMgr::ContentCache::ContentCache(clang::FileEntry const*) Line | Count | Source | 180 | 1.43M | ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {} |
|
181 | | |
182 | | ContentCache(const FileEntry *Ent, const FileEntry *contentEnt) |
183 | | : OrigEntry(Ent), ContentsEntry(contentEnt), BufferOverridden(false), |
184 | 1.43M | IsFileVolatile(false), IsTransient(false), IsBufferInvalid(false) {} |
185 | | |
186 | | /// The copy ctor does not allow copies where source object has either |
187 | | /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory |
188 | | /// is not transferred, so this is a logical error. |
189 | | ContentCache(const ContentCache &RHS) |
190 | | : BufferOverridden(false), IsFileVolatile(false), IsTransient(false), |
191 | 0 | IsBufferInvalid(false) { |
192 | 0 | OrigEntry = RHS.OrigEntry; |
193 | 0 | ContentsEntry = RHS.ContentsEntry; |
194 | 0 |
|
195 | 0 | assert(!RHS.Buffer && !RHS.SourceLineCache && |
196 | 0 | "Passed ContentCache object cannot own a buffer."); |
197 | 0 | } |
198 | | |
199 | | ContentCache &operator=(const ContentCache &RHS) = delete; |
200 | | |
201 | | /// Returns the memory buffer for the associated content. |
202 | | /// |
203 | | /// \param Diag Object through which diagnostics will be emitted if the |
204 | | /// buffer cannot be retrieved. |
205 | | /// |
206 | | /// \param Loc If specified, is the location that invalid file diagnostics |
207 | | /// will be emitted at. |
208 | | llvm::Optional<llvm::MemoryBufferRef> |
209 | | getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, |
210 | | SourceLocation Loc = SourceLocation()) const; |
211 | | |
212 | | /// Returns the size of the content encapsulated by this |
213 | | /// ContentCache. |
214 | | /// |
215 | | /// This can be the size of the source file or the size of an |
216 | | /// arbitrary scratch buffer. If the ContentCache encapsulates a source |
217 | | /// file this size is retrieved from the file's FileEntry. |
218 | | unsigned getSize() const; |
219 | | |
220 | | /// Returns the number of bytes actually mapped for this |
221 | | /// ContentCache. |
222 | | /// |
223 | | /// This can be 0 if the MemBuffer was not actually expanded. |
224 | | unsigned getSizeBytesMapped() const; |
225 | | |
226 | | /// Returns the kind of memory used to back the memory buffer for |
227 | | /// this content cache. This is used for performance analysis. |
228 | | llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const; |
229 | | |
230 | | /// Return the buffer, only if it has been loaded. |
231 | 155 | llvm::Optional<llvm::MemoryBufferRef> getBufferIfLoaded() const { |
232 | 155 | if (Buffer) |
233 | 14 | return Buffer->getMemBufferRef(); |
234 | 141 | return None; |
235 | 155 | } |
236 | | |
237 | | /// Return a StringRef to the source buffer data, only if it has already |
238 | | /// been loaded. |
239 | 0 | llvm::Optional<StringRef> getBufferDataIfLoaded() const { |
240 | 0 | if (Buffer) |
241 | 0 | return Buffer->getBuffer(); |
242 | 0 | return None; |
243 | 0 | } |
244 | | |
245 | | /// Set the buffer. |
246 | 242k | void setBuffer(std::unique_ptr<llvm::MemoryBuffer> B) { |
247 | 242k | IsBufferInvalid = false; |
248 | 242k | Buffer = std::move(B); |
249 | 242k | } |
250 | | |
251 | | /// Set the buffer to one that's not owned (or to nullptr). |
252 | | /// |
253 | | /// \pre Buffer cannot already be set. |
254 | 55 | void setUnownedBuffer(llvm::Optional<llvm::MemoryBufferRef> B) { |
255 | 55 | assert(!Buffer && "Expected to be called right after construction"); |
256 | 55 | if (B) |
257 | 3 | setBuffer(llvm::MemoryBuffer::getMemBuffer(*B)); |
258 | 55 | } |
259 | | |
260 | | // If BufStr has an invalid BOM, returns the BOM name; otherwise, returns |
261 | | // nullptr |
262 | | static const char *getInvalidBOM(StringRef BufStr); |
263 | | }; |
264 | | |
265 | | // Assert that the \c ContentCache objects will always be 8-byte aligned so |
266 | | // that we can pack 3 bits of integer into pointers to such objects. |
267 | | static_assert(alignof(ContentCache) >= 8, |
268 | | "ContentCache must be 8-byte aligned."); |
269 | | |
270 | | /// Information about a FileID, basically just the logical file |
271 | | /// that it represents and include stack information. |
272 | | /// |
273 | | /// Each FileInfo has include stack information, indicating where it came |
274 | | /// from. This information encodes the \#include chain that a token was |
275 | | /// expanded from. The main include file has an invalid IncludeLoc. |
276 | | /// |
277 | | /// FileInfo should not grow larger than ExpansionInfo. Doing so will |
278 | | /// cause memory to bloat in compilations with many unloaded macro |
279 | | /// expansions, since the two data structurs are stored in a union in |
280 | | /// SLocEntry. Extra fields should instead go in "ContentCache *", which |
281 | | /// stores file contents and other bits on the side. |
282 | | /// |
283 | | class FileInfo { |
284 | | friend class clang::SourceManager; |
285 | | friend class clang::ASTWriter; |
286 | | friend class clang::ASTReader; |
287 | | |
288 | | /// The location of the \#include that brought in this file. |
289 | | /// |
290 | | /// This is an invalid SLOC for the main file (top of the \#include chain). |
291 | | SourceLocation IncludeLoc; |
292 | | |
293 | | /// Number of FileIDs (files and macros) that were created during |
294 | | /// preprocessing of this \#include, including this SLocEntry. |
295 | | /// |
296 | | /// Zero means the preprocessor didn't provide such info for this SLocEntry. |
297 | | unsigned NumCreatedFIDs : 31; |
298 | | |
299 | | /// Whether this FileInfo has any \#line directives. |
300 | | unsigned HasLineDirectives : 1; |
301 | | |
302 | | /// The content cache and the characteristic of the file. |
303 | | llvm::PointerIntPair<const ContentCache *, 3, CharacteristicKind> |
304 | | ContentAndKind; |
305 | | |
306 | | public: |
307 | | /// Return a FileInfo object. |
308 | | static FileInfo get(SourceLocation IL, ContentCache &Con, |
309 | 2.17M | CharacteristicKind FileCharacter, StringRef Filename) { |
310 | 2.17M | FileInfo X; |
311 | 2.17M | X.IncludeLoc = IL; |
312 | 2.17M | X.NumCreatedFIDs = 0; |
313 | 2.17M | X.HasLineDirectives = false; |
314 | 2.17M | X.ContentAndKind.setPointer(&Con); |
315 | 2.17M | X.ContentAndKind.setInt(FileCharacter); |
316 | 2.17M | Con.Filename = Filename; |
317 | 2.17M | return X; |
318 | 2.17M | } |
319 | | |
320 | 197M | SourceLocation getIncludeLoc() const { |
321 | 197M | return IncludeLoc; |
322 | 197M | } |
323 | | |
324 | 383M | const ContentCache &getContentCache() const { |
325 | 383M | return *ContentAndKind.getPointer(); |
326 | 383M | } |
327 | | |
328 | | /// Return whether this is a system header or not. |
329 | 143M | CharacteristicKind getFileCharacteristic() const { |
330 | 143M | return ContentAndKind.getInt(); |
331 | 143M | } |
332 | | |
333 | | /// Return true if this FileID has \#line directives in it. |
334 | 364M | bool hasLineDirectives() const { return HasLineDirectives; } |
335 | | |
336 | | /// Set the flag that indicates that this FileID has |
337 | | /// line table entries associated with it. |
338 | 720k | void setHasLineDirectives() { HasLineDirectives = true; } |
339 | | |
340 | | /// Returns the name of the file that was used when the file was loaded from |
341 | | /// the underlying file system. |
342 | 553k | StringRef getName() const { return getContentCache().Filename; } |
343 | | }; |
344 | | |
345 | | /// Each ExpansionInfo encodes the expansion location - where |
346 | | /// the token was ultimately expanded, and the SpellingLoc - where the actual |
347 | | /// character data for the token came from. |
348 | | class ExpansionInfo { |
349 | | // Really these are all SourceLocations. |
350 | | |
351 | | /// Where the spelling for the token can be found. |
352 | | SourceLocation SpellingLoc; |
353 | | |
354 | | /// In a macro expansion, ExpansionLocStart and ExpansionLocEnd |
355 | | /// indicate the start and end of the expansion. In object-like macros, |
356 | | /// they will be the same. In a function-like macro expansion, the start |
357 | | /// will be the identifier and the end will be the ')'. Finally, in |
358 | | /// macro-argument instantiations, the end will be 'SourceLocation()', an |
359 | | /// invalid location. |
360 | | SourceLocation ExpansionLocStart, ExpansionLocEnd; |
361 | | |
362 | | /// Whether the expansion range is a token range. |
363 | | bool ExpansionIsTokenRange; |
364 | | |
365 | | public: |
366 | 85.7M | SourceLocation getSpellingLoc() const { |
367 | 85.7M | return SpellingLoc.isInvalid() ? getExpansionLocStart()1 : SpellingLoc85.7M ; |
368 | 85.7M | } |
369 | | |
370 | 172M | SourceLocation getExpansionLocStart() const { |
371 | 172M | return ExpansionLocStart; |
372 | 172M | } |
373 | | |
374 | 65.5M | SourceLocation getExpansionLocEnd() const { |
375 | 65.5M | return ExpansionLocEnd.isInvalid() ? getExpansionLocStart()8.13M |
376 | 65.5M | : ExpansionLocEnd57.4M ; |
377 | 65.5M | } |
378 | | |
379 | 26.6M | bool isExpansionTokenRange() const { return ExpansionIsTokenRange; } |
380 | | |
381 | 20.9M | CharSourceRange getExpansionLocRange() const { |
382 | 20.9M | return CharSourceRange( |
383 | 20.9M | SourceRange(getExpansionLocStart(), getExpansionLocEnd()), |
384 | 20.9M | isExpansionTokenRange()); |
385 | 20.9M | } |
386 | | |
387 | 73.6M | bool isMacroArgExpansion() const { |
388 | | // Note that this needs to return false for default constructed objects. |
389 | 73.6M | return getExpansionLocStart().isValid() && ExpansionLocEnd.isInvalid(); |
390 | 73.6M | } |
391 | | |
392 | 279k | bool isMacroBodyExpansion() const { |
393 | 279k | return getExpansionLocStart().isValid() && ExpansionLocEnd.isValid(); |
394 | 279k | } |
395 | | |
396 | 3.17k | bool isFunctionMacroExpansion() const { |
397 | 3.17k | return getExpansionLocStart().isValid() && |
398 | 3.17k | getExpansionLocStart() != getExpansionLocEnd(); |
399 | 3.17k | } |
400 | | |
401 | | /// Return a ExpansionInfo for an expansion. |
402 | | /// |
403 | | /// Start and End specify the expansion range (where the macro is |
404 | | /// expanded), and SpellingLoc specifies the spelling location (where |
405 | | /// the characters from the token come from). All three can refer to |
406 | | /// normal File SLocs or expansion locations. |
407 | | static ExpansionInfo create(SourceLocation SpellingLoc, SourceLocation Start, |
408 | | SourceLocation End, |
409 | 132M | bool ExpansionIsTokenRange = true) { |
410 | 132M | ExpansionInfo X; |
411 | 132M | X.SpellingLoc = SpellingLoc; |
412 | 132M | X.ExpansionLocStart = Start; |
413 | 132M | X.ExpansionLocEnd = End; |
414 | 132M | X.ExpansionIsTokenRange = ExpansionIsTokenRange; |
415 | 132M | return X; |
416 | 132M | } |
417 | | |
418 | | /// Return a special ExpansionInfo for the expansion of |
419 | | /// a macro argument into a function-like macro's body. |
420 | | /// |
421 | | /// ExpansionLoc specifies the expansion location (where the macro is |
422 | | /// expanded). This doesn't need to be a range because a macro is always |
423 | | /// expanded at a macro parameter reference, and macro parameters are |
424 | | /// always exactly one token. SpellingLoc specifies the spelling location |
425 | | /// (where the characters from the token come from). ExpansionLoc and |
426 | | /// SpellingLoc can both refer to normal File SLocs or expansion locations. |
427 | | /// |
428 | | /// Given the code: |
429 | | /// \code |
430 | | /// #define F(x) f(x) |
431 | | /// F(42); |
432 | | /// \endcode |
433 | | /// |
434 | | /// When expanding '\c F(42)', the '\c x' would call this with an |
435 | | /// SpellingLoc pointing at '\c 42' and an ExpansionLoc pointing at its |
436 | | /// location in the definition of '\c F'. |
437 | | static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc, |
438 | 41.2M | SourceLocation ExpansionLoc) { |
439 | | // We store an intentionally invalid source location for the end of the |
440 | | // expansion range to mark that this is a macro argument location rather |
441 | | // than a normal one. |
442 | 41.2M | return create(SpellingLoc, ExpansionLoc, SourceLocation()); |
443 | 41.2M | } |
444 | | |
445 | | /// Return a special ExpansionInfo representing a token that ends |
446 | | /// prematurely. This is used to model a '>>' token that has been split |
447 | | /// into '>' tokens and similar cases. Unlike for the other forms of |
448 | | /// expansion, the expansion range in this case is a character range, not |
449 | | /// a token range. |
450 | | static ExpansionInfo createForTokenSplit(SourceLocation SpellingLoc, |
451 | | SourceLocation Start, |
452 | 26.7k | SourceLocation End) { |
453 | 26.7k | return create(SpellingLoc, Start, End, false); |
454 | 26.7k | } |
455 | | }; |
456 | | |
457 | | // Assert that the \c FileInfo objects are no bigger than \c ExpansionInfo |
458 | | // objects. This controls the size of \c SLocEntry, of which we have one for |
459 | | // each macro expansion. The number of (unloaded) macro expansions can be |
460 | | // very large. Any other fields needed in FileInfo should go in ContentCache. |
461 | | static_assert(sizeof(FileInfo) <= sizeof(ExpansionInfo), |
462 | | "FileInfo must be no larger than ExpansionInfo."); |
463 | | |
464 | | /// This is a discriminated union of FileInfo and ExpansionInfo. |
465 | | /// |
466 | | /// SourceManager keeps an array of these objects, and they are uniquely |
467 | | /// identified by the FileID datatype. |
468 | | class SLocEntry { |
469 | | static constexpr int OffsetBits = 8 * sizeof(SourceLocation::UIntTy) - 1; |
470 | | SourceLocation::UIntTy Offset : OffsetBits; |
471 | | SourceLocation::UIntTy IsExpansion : 1; |
472 | | union { |
473 | | FileInfo File; |
474 | | ExpansionInfo Expansion; |
475 | | }; |
476 | | |
477 | | public: |
478 | 373M | SLocEntry() : Offset(), IsExpansion(), File() {} |
479 | | |
480 | 9.33G | SourceLocation::UIntTy getOffset() const { return Offset; } |
481 | | |
482 | 1.62G | bool isExpansion() const { return IsExpansion; } |
483 | 1.40G | bool isFile() const { return !isExpansion(); } |
484 | | |
485 | 657M | const FileInfo &getFile() const { |
486 | 657M | assert(isFile() && "Not a file SLocEntry!"); |
487 | 0 | return File; |
488 | 657M | } |
489 | | |
490 | 210M | const ExpansionInfo &getExpansion() const { |
491 | 210M | assert(isExpansion() && "Not a macro expansion SLocEntry!"); |
492 | 0 | return Expansion; |
493 | 210M | } |
494 | | |
495 | 2.17M | static SLocEntry get(SourceLocation::UIntTy Offset, const FileInfo &FI) { |
496 | 2.17M | assert(!(Offset & (1ULL << OffsetBits)) && "Offset is too large"); |
497 | 0 | SLocEntry E; |
498 | 2.17M | E.Offset = Offset; |
499 | 2.17M | E.IsExpansion = false; |
500 | 2.17M | E.File = FI; |
501 | 2.17M | return E; |
502 | 2.17M | } |
503 | | |
504 | | static SLocEntry get(SourceLocation::UIntTy Offset, |
505 | 132M | const ExpansionInfo &Expansion) { |
506 | 132M | assert(!(Offset & (1ULL << OffsetBits)) && "Offset is too large"); |
507 | 0 | SLocEntry E; |
508 | 132M | E.Offset = Offset; |
509 | 132M | E.IsExpansion = true; |
510 | 132M | new (&E.Expansion) ExpansionInfo(Expansion); |
511 | 132M | return E; |
512 | 132M | } |
513 | | }; |
514 | | |
515 | | } // namespace SrcMgr |
516 | | |
517 | | /// External source of source location entries. |
518 | | class ExternalSLocEntrySource { |
519 | | public: |
520 | | virtual ~ExternalSLocEntrySource(); |
521 | | |
522 | | /// Read the source location entry with index ID, which will always be |
523 | | /// less than -1. |
524 | | /// |
525 | | /// \returns true if an error occurred that prevented the source-location |
526 | | /// entry from being loaded. |
527 | | virtual bool ReadSLocEntry(int ID) = 0; |
528 | | |
529 | | /// Retrieve the module import location and name for the given ID, if |
530 | | /// in fact it was loaded from a module (rather than, say, a precompiled |
531 | | /// header). |
532 | | virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) = 0; |
533 | | }; |
534 | | |
535 | | /// Holds the cache used by isBeforeInTranslationUnit. |
536 | | /// |
537 | | /// The cache structure is complex enough to be worth breaking out of |
538 | | /// SourceManager. |
539 | | class InBeforeInTUCacheEntry { |
540 | | /// The FileID's of the cached query. |
541 | | /// |
542 | | /// If these match up with a subsequent query, the result can be reused. |
543 | | FileID LQueryFID, RQueryFID; |
544 | | |
545 | | /// True if LQueryFID was created before RQueryFID. |
546 | | /// |
547 | | /// This is used to compare macro expansion locations. |
548 | | bool IsLQFIDBeforeRQFID; |
549 | | |
550 | | /// The file found in common between the two \#include traces, i.e., |
551 | | /// the nearest common ancestor of the \#include tree. |
552 | | FileID CommonFID; |
553 | | |
554 | | /// The offset of the previous query in CommonFID. |
555 | | /// |
556 | | /// Usually, this represents the location of the \#include for QueryFID, but |
557 | | /// if LQueryFID is a parent of RQueryFID (or vice versa) then these can be a |
558 | | /// random token in the parent. |
559 | | unsigned LCommonOffset, RCommonOffset; |
560 | | |
561 | | public: |
562 | | /// Return true if the currently cached values match up with |
563 | | /// the specified LHS/RHS query. |
564 | | /// |
565 | | /// If not, we can't use the cache. |
566 | 153k | bool isCacheValid(FileID LHS, FileID RHS) const { |
567 | 153k | return LQueryFID == LHS && RQueryFID == RHS16.4k ; |
568 | 153k | } |
569 | | |
570 | | /// If the cache is valid, compute the result given the |
571 | | /// specified offsets in the LHS/RHS FileID's. |
572 | 20.1k | bool getCachedResult(unsigned LOffset, unsigned ROffset) const { |
573 | | // If one of the query files is the common file, use the offset. Otherwise, |
574 | | // use the #include loc in the common file. |
575 | 20.1k | if (LQueryFID != CommonFID) LOffset = LCommonOffset12.1k ; |
576 | 20.1k | if (RQueryFID != CommonFID) ROffset = RCommonOffset13.0k ; |
577 | | |
578 | | // It is common for multiple macro expansions to be "included" from the same |
579 | | // location (expansion location), in which case use the order of the FileIDs |
580 | | // to determine which came first. This will also take care the case where |
581 | | // one of the locations points at the inclusion/expansion point of the other |
582 | | // in which case its FileID will come before the other. |
583 | 20.1k | if (LOffset == ROffset) |
584 | 283 | return IsLQFIDBeforeRQFID; |
585 | | |
586 | 19.8k | return LOffset < ROffset; |
587 | 20.1k | } |
588 | | |
589 | | /// Set up a new query. |
590 | 136k | void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) { |
591 | 136k | assert(LHS != RHS); |
592 | 0 | LQueryFID = LHS; |
593 | 136k | RQueryFID = RHS; |
594 | 136k | IsLQFIDBeforeRQFID = isLFIDBeforeRFID; |
595 | 136k | } |
596 | | |
597 | 133k | void clear() { |
598 | 133k | LQueryFID = RQueryFID = FileID(); |
599 | 133k | IsLQFIDBeforeRQFID = false; |
600 | 133k | } |
601 | | |
602 | | void setCommonLoc(FileID commonFID, unsigned lCommonOffset, |
603 | 3.71k | unsigned rCommonOffset) { |
604 | 3.71k | CommonFID = commonFID; |
605 | 3.71k | LCommonOffset = lCommonOffset; |
606 | 3.71k | RCommonOffset = rCommonOffset; |
607 | 3.71k | } |
608 | | }; |
609 | | |
610 | | /// The stack used when building modules on demand, which is used |
611 | | /// to provide a link between the source managers of the different compiler |
612 | | /// instances. |
613 | | using ModuleBuildStack = ArrayRef<std::pair<std::string, FullSourceLoc>>; |
614 | | |
615 | | /// This class handles loading and caching of source files into memory. |
616 | | /// |
617 | | /// This object owns the MemoryBuffer objects for all of the loaded |
618 | | /// files and assigns unique FileID's for each unique \#include chain. |
619 | | /// |
620 | | /// The SourceManager can be queried for information about SourceLocation |
621 | | /// objects, turning them into either spelling or expansion locations. Spelling |
622 | | /// locations represent where the bytes corresponding to a token came from and |
623 | | /// expansion locations represent where the location is in the user's view. In |
624 | | /// the case of a macro expansion, for example, the spelling location indicates |
625 | | /// where the expanded token came from and the expansion location specifies |
626 | | /// where it was expanded. |
627 | | class SourceManager : public RefCountedBase<SourceManager> { |
628 | | /// DiagnosticsEngine object. |
629 | | DiagnosticsEngine &Diag; |
630 | | |
631 | | FileManager &FileMgr; |
632 | | |
633 | | mutable llvm::BumpPtrAllocator ContentCacheAlloc; |
634 | | |
635 | | /// Memoized information about all of the files tracked by this |
636 | | /// SourceManager. |
637 | | /// |
638 | | /// This map allows us to merge ContentCache entries based |
639 | | /// on their FileEntry*. All ContentCache objects will thus have unique, |
640 | | /// non-null, FileEntry pointers. |
641 | | llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos; |
642 | | |
643 | | /// True if the ContentCache for files that are overridden by other |
644 | | /// files, should report the original file name. Defaults to true. |
645 | | bool OverridenFilesKeepOriginalName = true; |
646 | | |
647 | | /// True if non-system source files should be treated as volatile |
648 | | /// (likely to change while trying to use them). Defaults to false. |
649 | | bool UserFilesAreVolatile; |
650 | | |
651 | | /// True if all files read during this compilation should be treated |
652 | | /// as transient (may not be present in later compilations using a module |
653 | | /// file created from this compilation). Defaults to false. |
654 | | bool FilesAreTransient = false; |
655 | | |
656 | | struct OverriddenFilesInfoTy { |
657 | | /// Files that have been overridden with the contents from another |
658 | | /// file. |
659 | | llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles; |
660 | | |
661 | | /// Files that were overridden with a memory buffer. |
662 | | llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer; |
663 | | }; |
664 | | |
665 | | /// Lazily create the object keeping overridden files info, since |
666 | | /// it is uncommonly used. |
667 | | std::unique_ptr<OverriddenFilesInfoTy> OverriddenFilesInfo; |
668 | | |
669 | 5.79k | OverriddenFilesInfoTy &getOverriddenFilesInfo() { |
670 | 5.79k | if (!OverriddenFilesInfo) |
671 | 5.59k | OverriddenFilesInfo.reset(new OverriddenFilesInfoTy); |
672 | 5.79k | return *OverriddenFilesInfo; |
673 | 5.79k | } |
674 | | |
675 | | /// Information about various memory buffers that we have read in. |
676 | | /// |
677 | | /// All FileEntry* within the stored ContentCache objects are NULL, |
678 | | /// as they do not refer to a file. |
679 | | std::vector<SrcMgr::ContentCache*> MemBufferInfos; |
680 | | |
681 | | /// The table of SLocEntries that are local to this module. |
682 | | /// |
683 | | /// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid |
684 | | /// expansion. |
685 | | SmallVector<SrcMgr::SLocEntry, 0> LocalSLocEntryTable; |
686 | | |
687 | | /// The table of SLocEntries that are loaded from other modules. |
688 | | /// |
689 | | /// Negative FileIDs are indexes into this table. To get from ID to an index, |
690 | | /// use (-ID - 2). |
691 | | SmallVector<SrcMgr::SLocEntry, 0> LoadedSLocEntryTable; |
692 | | |
693 | | /// The starting offset of the next local SLocEntry. |
694 | | /// |
695 | | /// This is LocalSLocEntryTable.back().Offset + the size of that entry. |
696 | | SourceLocation::UIntTy NextLocalOffset; |
697 | | |
698 | | /// The starting offset of the latest batch of loaded SLocEntries. |
699 | | /// |
700 | | /// This is LoadedSLocEntryTable.back().Offset, except that that entry might |
701 | | /// not have been loaded, so that value would be unknown. |
702 | | SourceLocation::UIntTy CurrentLoadedOffset; |
703 | | |
704 | | /// The highest possible offset is 2^32-1 (2^63-1 for 64-bit source |
705 | | /// locations), so CurrentLoadedOffset starts at 2^31 (2^63 resp.). |
706 | | static const SourceLocation::UIntTy MaxLoadedOffset = |
707 | | 1ULL << (8 * sizeof(SourceLocation::UIntTy) - 1); |
708 | | |
709 | | /// A bitmap that indicates whether the entries of LoadedSLocEntryTable |
710 | | /// have already been loaded from the external source. |
711 | | /// |
712 | | /// Same indexing as LoadedSLocEntryTable. |
713 | | llvm::BitVector SLocEntryLoaded; |
714 | | |
715 | | /// An external source for source location entries. |
716 | | ExternalSLocEntrySource *ExternalSLocEntries = nullptr; |
717 | | |
718 | | /// A one-entry cache to speed up getFileID. |
719 | | /// |
720 | | /// LastFileIDLookup records the last FileID looked up or created, because it |
721 | | /// is very common to look up many tokens from the same file. |
722 | | mutable FileID LastFileIDLookup; |
723 | | |
724 | | /// Holds information for \#line directives. |
725 | | /// |
726 | | /// This is referenced by indices from SLocEntryTable. |
727 | | std::unique_ptr<LineTableInfo> LineTable; |
728 | | |
729 | | /// These ivars serve as a cache used in the getLineNumber |
730 | | /// method which is used to speedup getLineNumber calls to nearby locations. |
731 | | mutable FileID LastLineNoFileIDQuery; |
732 | | mutable const SrcMgr::ContentCache *LastLineNoContentCache; |
733 | | mutable unsigned LastLineNoFilePos; |
734 | | mutable unsigned LastLineNoResult; |
735 | | |
736 | | /// The file ID for the main source file of the translation unit. |
737 | | FileID MainFileID; |
738 | | |
739 | | /// The file ID for the precompiled preamble there is one. |
740 | | FileID PreambleFileID; |
741 | | |
742 | | // Statistics for -print-stats. |
743 | | mutable unsigned NumLinearScans = 0; |
744 | | mutable unsigned NumBinaryProbes = 0; |
745 | | |
746 | | /// Associates a FileID with its "included/expanded in" decomposed |
747 | | /// location. |
748 | | /// |
749 | | /// Used to cache results from and speed-up \c getDecomposedIncludedLoc |
750 | | /// function. |
751 | | mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned>> IncludedLocMap; |
752 | | |
753 | | /// The key value into the IsBeforeInTUCache table. |
754 | | using IsBeforeInTUCacheKey = std::pair<FileID, FileID>; |
755 | | |
756 | | /// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs |
757 | | /// to cache results. |
758 | | using InBeforeInTUCache = |
759 | | llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>; |
760 | | |
761 | | /// Cache results for the isBeforeInTranslationUnit method. |
762 | | mutable InBeforeInTUCache IBTUCache; |
763 | | mutable InBeforeInTUCacheEntry IBTUCacheOverflow; |
764 | | |
765 | | /// Return the cache entry for comparing the given file IDs |
766 | | /// for isBeforeInTranslationUnit. |
767 | | InBeforeInTUCacheEntry &getInBeforeInTUCache(FileID LFID, FileID RFID) const; |
768 | | |
769 | | // Cache for the "fake" buffer used for error-recovery purposes. |
770 | | mutable std::unique_ptr<llvm::MemoryBuffer> FakeBufferForRecovery; |
771 | | |
772 | | mutable std::unique_ptr<SrcMgr::ContentCache> FakeContentCacheForRecovery; |
773 | | |
774 | | mutable std::unique_ptr<SrcMgr::SLocEntry> FakeSLocEntryForRecovery; |
775 | | |
776 | | /// Lazily computed map of macro argument chunks to their expanded |
777 | | /// source location. |
778 | | using MacroArgsMap = std::map<unsigned, SourceLocation>; |
779 | | |
780 | | mutable llvm::DenseMap<FileID, std::unique_ptr<MacroArgsMap>> |
781 | | MacroArgsCacheMap; |
782 | | |
783 | | /// The stack of modules being built, which is used to detect |
784 | | /// cycles in the module dependency graph as modules are being built, as |
785 | | /// well as to describe why we're rebuilding a particular module. |
786 | | /// |
787 | | /// There is no way to set this value from the command line. If we ever need |
788 | | /// to do so (e.g., if on-demand module construction moves out-of-process), |
789 | | /// we can add a cc1-level option to do so. |
790 | | SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack; |
791 | | |
792 | | public: |
793 | | SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, |
794 | | bool UserFilesAreVolatile = false); |
795 | | explicit SourceManager(const SourceManager &) = delete; |
796 | | SourceManager &operator=(const SourceManager &) = delete; |
797 | | ~SourceManager(); |
798 | | |
799 | | void clearIDTables(); |
800 | | |
801 | | /// Initialize this source manager suitably to replay the compilation |
802 | | /// described by \p Old. Requires that \p Old outlive \p *this. |
803 | | void initializeForReplay(const SourceManager &Old); |
804 | | |
805 | 9.88M | DiagnosticsEngine &getDiagnostics() const { return Diag; } |
806 | | |
807 | 252M | FileManager &getFileManager() const { return FileMgr; } |
808 | | |
809 | | /// Set true if the SourceManager should report the original file name |
810 | | /// for contents of files that were overridden by other files. Defaults to |
811 | | /// true. |
812 | 90.8k | void setOverridenFilesKeepOriginalName(bool value) { |
813 | 90.8k | OverridenFilesKeepOriginalName = value; |
814 | 90.8k | } |
815 | | |
816 | | /// True if non-system source files should be treated as volatile |
817 | | /// (likely to change while trying to use them). |
818 | 0 | bool userFilesAreVolatile() const { return UserFilesAreVolatile; } |
819 | | |
820 | | /// Retrieve the module build stack. |
821 | 16.5k | ModuleBuildStack getModuleBuildStack() const { |
822 | 16.5k | return StoredModuleBuildStack; |
823 | 16.5k | } |
824 | | |
825 | | /// Set the module build stack. |
826 | 1.79k | void setModuleBuildStack(ModuleBuildStack stack) { |
827 | 1.79k | StoredModuleBuildStack.clear(); |
828 | 1.79k | StoredModuleBuildStack.append(stack.begin(), stack.end()); |
829 | 1.79k | } |
830 | | |
831 | | /// Push an entry to the module build stack. |
832 | 2.05k | void pushModuleBuildStack(StringRef moduleName, FullSourceLoc importLoc) { |
833 | 2.05k | StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc)); |
834 | 2.05k | } |
835 | | |
836 | | //===--------------------------------------------------------------------===// |
837 | | // MainFileID creation and querying methods. |
838 | | //===--------------------------------------------------------------------===// |
839 | | |
840 | | /// Returns the FileID of the main source file. |
841 | 2.43M | FileID getMainFileID() const { return MainFileID; } |
842 | | |
843 | | /// Set the file ID for the main source file. |
844 | 158k | void setMainFileID(FileID FID) { |
845 | 158k | MainFileID = FID; |
846 | 158k | } |
847 | | |
848 | | /// Returns true when the given FileEntry corresponds to the main file. |
849 | | /// |
850 | | /// The main file should be set prior to calling this function. |
851 | | bool isMainFile(const FileEntry &SourceFile); |
852 | | |
853 | | /// Set the file ID for the precompiled preamble. |
854 | 339 | void setPreambleFileID(FileID Preamble) { |
855 | 339 | assert(PreambleFileID.isInvalid() && "PreambleFileID already set!"); |
856 | 0 | PreambleFileID = Preamble; |
857 | 339 | } |
858 | | |
859 | | /// Get the file ID for the precompiled preamble if there is one. |
860 | 596k | FileID getPreambleFileID() const { return PreambleFileID; } |
861 | | |
862 | | //===--------------------------------------------------------------------===// |
863 | | // Methods to create new FileID's and macro expansions. |
864 | | //===--------------------------------------------------------------------===// |
865 | | |
866 | | /// Create a new FileID that represents the specified file |
867 | | /// being \#included from the specified IncludePosition. |
868 | | /// |
869 | | /// This translates NULL into standard input. |
870 | | FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, |
871 | | SrcMgr::CharacteristicKind FileCharacter, |
872 | | int LoadedID = 0, |
873 | | SourceLocation::UIntTy LoadedOffset = 0); |
874 | | |
875 | | FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, |
876 | | SrcMgr::CharacteristicKind FileCharacter, |
877 | | int LoadedID = 0, |
878 | | SourceLocation::UIntTy LoadedOffset = 0); |
879 | | |
880 | | /// Create a new FileID that represents the specified memory buffer. |
881 | | /// |
882 | | /// This does no caching of the buffer and takes ownership of the |
883 | | /// MemoryBuffer, so only pass a MemoryBuffer to this once. |
884 | | FileID createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer, |
885 | | SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, |
886 | | int LoadedID = 0, SourceLocation::UIntTy LoadedOffset = 0, |
887 | | SourceLocation IncludeLoc = SourceLocation()); |
888 | | |
889 | | /// Create a new FileID that represents the specified memory buffer. |
890 | | /// |
891 | | /// This does not take ownership of the MemoryBuffer. The memory buffer must |
892 | | /// outlive the SourceManager. |
893 | | FileID createFileID(const llvm::MemoryBufferRef &Buffer, |
894 | | SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, |
895 | | int LoadedID = 0, SourceLocation::UIntTy LoadedOffset = 0, |
896 | | SourceLocation IncludeLoc = SourceLocation()); |
897 | | |
898 | | /// Get the FileID for \p SourceFile if it exists. Otherwise, create a |
899 | | /// new FileID for the \p SourceFile. |
900 | | FileID getOrCreateFileID(const FileEntry *SourceFile, |
901 | | SrcMgr::CharacteristicKind FileCharacter); |
902 | | |
903 | | /// Creates an expansion SLocEntry for the substitution of an argument into a |
904 | | /// function-like macro's body. Returns the start of the expansion. |
905 | | /// |
906 | | /// The macro argument was written at \p SpellingLoc with length \p Length. |
907 | | /// \p ExpansionLoc is the parameter name in the (expanded) macro body. |
908 | | SourceLocation createMacroArgExpansionLoc(SourceLocation SpellingLoc, |
909 | | SourceLocation ExpansionLoc, |
910 | | unsigned Length); |
911 | | |
912 | | /// Creates an expansion SLocEntry for a macro use. Returns its start. |
913 | | /// |
914 | | /// The macro body begins at \p SpellingLoc with length \p Length. |
915 | | /// The macro use spans [ExpansionLocStart, ExpansionLocEnd]. |
916 | | SourceLocation createExpansionLoc(SourceLocation SpellingLoc, |
917 | | SourceLocation ExpansionLocStart, |
918 | | SourceLocation ExpansionLocEnd, |
919 | | unsigned Length, |
920 | | bool ExpansionIsTokenRange = true, |
921 | | int LoadedID = 0, |
922 | | SourceLocation::UIntTy LoadedOffset = 0); |
923 | | |
924 | | /// Return a new SourceLocation that encodes that the token starting |
925 | | /// at \p TokenStart ends prematurely at \p TokenEnd. |
926 | | SourceLocation createTokenSplitLoc(SourceLocation SpellingLoc, |
927 | | SourceLocation TokenStart, |
928 | | SourceLocation TokenEnd); |
929 | | |
930 | | /// Retrieve the memory buffer associated with the given file. |
931 | | /// |
932 | | /// Returns None if the buffer is not valid. |
933 | | llvm::Optional<llvm::MemoryBufferRef> |
934 | | getMemoryBufferForFileOrNone(const FileEntry *File); |
935 | | |
936 | | /// Retrieve the memory buffer associated with the given file. |
937 | | /// |
938 | | /// Returns a fake buffer if there isn't a real one. |
939 | 10 | llvm::MemoryBufferRef getMemoryBufferForFileOrFake(const FileEntry *File) { |
940 | 10 | if (auto B = getMemoryBufferForFileOrNone(File)) |
941 | 10 | return *B; |
942 | 0 | return getFakeBufferForRecovery(); |
943 | 10 | } |
944 | | |
945 | | /// Override the contents of the given source file by providing an |
946 | | /// already-allocated buffer. |
947 | | /// |
948 | | /// \param SourceFile the source file whose contents will be overridden. |
949 | | /// |
950 | | /// \param Buffer the memory buffer whose contents will be used as the |
951 | | /// data in the given source file. |
952 | | void overrideFileContents(const FileEntry *SourceFile, |
953 | 567 | const llvm::MemoryBufferRef &Buffer) { |
954 | 567 | overrideFileContents(SourceFile, llvm::MemoryBuffer::getMemBuffer(Buffer)); |
955 | 567 | } |
956 | | |
957 | | /// Override the contents of the given source file by providing an |
958 | | /// already-allocated buffer. |
959 | | /// |
960 | | /// \param SourceFile the source file whose contents will be overridden. |
961 | | /// |
962 | | /// \param Buffer the memory buffer whose contents will be used as the |
963 | | /// data in the given source file. |
964 | | void overrideFileContents(const FileEntry *SourceFile, |
965 | | std::unique_ptr<llvm::MemoryBuffer> Buffer); |
966 | | void overrideFileContents(FileEntryRef SourceFile, |
967 | 90 | std::unique_ptr<llvm::MemoryBuffer> Buffer) { |
968 | 90 | overrideFileContents(&SourceFile.getFileEntry(), std::move(Buffer)); |
969 | 90 | } |
970 | | |
971 | | /// Override the given source file with another one. |
972 | | /// |
973 | | /// \param SourceFile the source file which will be overridden. |
974 | | /// |
975 | | /// \param NewFile the file whose contents will be used as the |
976 | | /// data instead of the contents of the given source file. |
977 | | void overrideFileContents(const FileEntry *SourceFile, |
978 | | const FileEntry *NewFile); |
979 | | |
980 | | /// Returns true if the file contents have been overridden. |
981 | 1.11M | bool isFileOverridden(const FileEntry *File) const { |
982 | 1.11M | if (OverriddenFilesInfo) { |
983 | 172k | if (OverriddenFilesInfo->OverriddenFilesWithBuffer.count(File)) |
984 | 0 | return true; |
985 | 172k | if (OverriddenFilesInfo->OverriddenFiles.find(File) != |
986 | 172k | OverriddenFilesInfo->OverriddenFiles.end()) |
987 | 2 | return true; |
988 | 172k | } |
989 | 1.11M | return false; |
990 | 1.11M | } |
991 | | |
992 | | /// Bypass the overridden contents of a file. This creates a new FileEntry |
993 | | /// and initializes the content cache for it. Returns None if there is no |
994 | | /// such file in the filesystem. |
995 | | /// |
996 | | /// This should be called before parsing has begun. |
997 | | Optional<FileEntryRef> bypassFileContentsOverride(FileEntryRef File); |
998 | | |
999 | | /// Specify that a file is transient. |
1000 | | void setFileIsTransient(const FileEntry *SourceFile); |
1001 | | |
1002 | | /// Specify that all files that are read during this compilation are |
1003 | | /// transient. |
1004 | 10 | void setAllFilesAreTransient(bool Transient) { |
1005 | 10 | FilesAreTransient = Transient; |
1006 | 10 | } |
1007 | | |
1008 | | //===--------------------------------------------------------------------===// |
1009 | | // FileID manipulation methods. |
1010 | | //===--------------------------------------------------------------------===// |
1011 | | |
1012 | | /// Return the buffer for the specified FileID. |
1013 | | /// |
1014 | | /// If there is an error opening this buffer the first time, return None. |
1015 | | llvm::Optional<llvm::MemoryBufferRef> |
1016 | 120M | getBufferOrNone(FileID FID, SourceLocation Loc = SourceLocation()) const { |
1017 | 120M | if (auto *Entry = getSLocEntryForFile(FID)) |
1018 | 120M | return Entry->getFile().getContentCache().getBufferOrNone( |
1019 | 120M | Diag, getFileManager(), Loc); |
1020 | 993 | return None; |
1021 | 120M | } |
1022 | | |
1023 | | /// Return the buffer for the specified FileID. |
1024 | | /// |
1025 | | /// If there is an error opening this buffer the first time, this |
1026 | | /// manufactures a temporary buffer and returns it. |
1027 | | llvm::MemoryBufferRef |
1028 | 933k | getBufferOrFake(FileID FID, SourceLocation Loc = SourceLocation()) const { |
1029 | 933k | if (auto B = getBufferOrNone(FID, Loc)) |
1030 | 933k | return *B; |
1031 | 3 | return getFakeBufferForRecovery(); |
1032 | 933k | } |
1033 | | |
1034 | | /// Returns the FileEntry record for the provided FileID. |
1035 | 7.20M | const FileEntry *getFileEntryForID(FileID FID) const { |
1036 | 7.20M | if (auto *Entry = getSLocEntryForFile(FID)) |
1037 | 7.20M | return Entry->getFile().getContentCache().OrigEntry; |
1038 | 211 | return nullptr; |
1039 | 7.20M | } |
1040 | | |
1041 | | /// Returns the FileEntryRef for the provided FileID. |
1042 | 834k | Optional<FileEntryRef> getFileEntryRefForID(FileID FID) const { |
1043 | 834k | if (auto *Entry = getFileEntryForID(FID)) |
1044 | 833k | return Entry->getLastRef(); |
1045 | 1.56k | return None; |
1046 | 834k | } |
1047 | | |
1048 | | /// Returns the filename for the provided FileID, unless it's a built-in |
1049 | | /// buffer that's not represented by a filename. |
1050 | | /// |
1051 | | /// Returns None for non-files and built-in files. |
1052 | | Optional<StringRef> getNonBuiltinFilenameForID(FileID FID) const; |
1053 | | |
1054 | | /// Returns the FileEntry record for the provided SLocEntry. |
1055 | | const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const |
1056 | 65.9k | { |
1057 | 65.9k | return sloc.getFile().getContentCache().OrigEntry; |
1058 | 65.9k | } |
1059 | | |
1060 | | /// Return a StringRef to the source buffer data for the |
1061 | | /// specified FileID. |
1062 | | /// |
1063 | | /// \param FID The file ID whose contents will be returned. |
1064 | | /// \param Invalid If non-NULL, will be set true if an error occurred. |
1065 | | StringRef getBufferData(FileID FID, bool *Invalid = nullptr) const; |
1066 | | |
1067 | | /// Return a StringRef to the source buffer data for the |
1068 | | /// specified FileID, returning None if invalid. |
1069 | | /// |
1070 | | /// \param FID The file ID whose contents will be returned. |
1071 | | llvm::Optional<StringRef> getBufferDataOrNone(FileID FID) const; |
1072 | | |
1073 | | /// Return a StringRef to the source buffer data for the |
1074 | | /// specified FileID, returning None if it's not yet loaded. |
1075 | | /// |
1076 | | /// \param FID The file ID whose contents will be returned. |
1077 | | llvm::Optional<StringRef> getBufferDataIfLoaded(FileID FID) const; |
1078 | | |
1079 | | /// Get the number of FileIDs (files and macros) that were created |
1080 | | /// during preprocessing of \p FID, including it. |
1081 | | unsigned getNumCreatedFIDsForFileID(FileID FID) const { |
1082 | | if (auto *Entry = getSLocEntryForFile(FID)) |
1083 | | return Entry->getFile().NumCreatedFIDs; |
1084 | | return 0; |
1085 | | } |
1086 | | |
1087 | | /// Set the number of FileIDs (files and macros) that were created |
1088 | | /// during preprocessing of \p FID, including it. |
1089 | | void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs, |
1090 | 818k | bool Force = false) const { |
1091 | 818k | auto *Entry = getSLocEntryForFile(FID); |
1092 | 818k | if (!Entry) |
1093 | 0 | return; |
1094 | 818k | assert((Force || Entry->getFile().NumCreatedFIDs == 0) && "Already set!"); |
1095 | 0 | const_cast<SrcMgr::FileInfo &>(Entry->getFile()).NumCreatedFIDs = NumFIDs; |
1096 | 818k | } |
1097 | | |
1098 | | //===--------------------------------------------------------------------===// |
1099 | | // SourceLocation manipulation methods. |
1100 | | //===--------------------------------------------------------------------===// |
1101 | | |
1102 | | /// Return the FileID for a SourceLocation. |
1103 | | /// |
1104 | | /// This is a very hot method that is used for all SourceManager queries |
1105 | | /// that start with a SourceLocation object. It is responsible for finding |
1106 | | /// the entry in SLocEntryTable which contains the specified location. |
1107 | | /// |
1108 | 1.13G | FileID getFileID(SourceLocation SpellingLoc) const { |
1109 | 1.13G | SourceLocation::UIntTy SLocOffset = SpellingLoc.getOffset(); |
1110 | | |
1111 | | // If our one-entry cache covers this offset, just return it. |
1112 | 1.13G | if (isOffsetInFileID(LastFileIDLookup, SLocOffset)) |
1113 | 761M | return LastFileIDLookup; |
1114 | | |
1115 | 378M | return getFileIDSlow(SLocOffset); |
1116 | 1.13G | } |
1117 | | |
1118 | | /// Return the filename of the file containing a SourceLocation. |
1119 | | StringRef getFilename(SourceLocation SpellingLoc) const; |
1120 | | |
1121 | | /// Return the source location corresponding to the first byte of |
1122 | | /// the specified file. |
1123 | 56.1M | SourceLocation getLocForStartOfFile(FileID FID) const { |
1124 | 56.1M | if (auto *Entry = getSLocEntryForFile(FID)) |
1125 | 56.1M | return SourceLocation::getFileLoc(Entry->getOffset()); |
1126 | 589 | return SourceLocation(); |
1127 | 56.1M | } |
1128 | | |
1129 | | /// Return the source location corresponding to the last byte of the |
1130 | | /// specified file. |
1131 | 111k | SourceLocation getLocForEndOfFile(FileID FID) const { |
1132 | 111k | if (auto *Entry = getSLocEntryForFile(FID)) |
1133 | 111k | return SourceLocation::getFileLoc(Entry->getOffset() + |
1134 | 111k | getFileIDSize(FID)); |
1135 | 0 | return SourceLocation(); |
1136 | 111k | } |
1137 | | |
1138 | | /// Returns the include location if \p FID is a \#include'd file |
1139 | | /// otherwise it returns an invalid location. |
1140 | 1.81M | SourceLocation getIncludeLoc(FileID FID) const { |
1141 | 1.81M | if (auto *Entry = getSLocEntryForFile(FID)) |
1142 | 1.81M | return Entry->getFile().getIncludeLoc(); |
1143 | 1 | return SourceLocation(); |
1144 | 1.81M | } |
1145 | | |
1146 | | // Returns the import location if the given source location is |
1147 | | // located within a module, or an invalid location if the source location |
1148 | | // is within the current translation unit. |
1149 | | std::pair<SourceLocation, StringRef> |
1150 | 1.17k | getModuleImportLoc(SourceLocation Loc) const { |
1151 | 1.17k | FileID FID = getFileID(Loc); |
1152 | | |
1153 | | // Positive file IDs are in the current translation unit, and -1 is a |
1154 | | // placeholder. |
1155 | 1.17k | if (FID.ID >= -1) |
1156 | 1.13k | return std::make_pair(SourceLocation(), ""); |
1157 | | |
1158 | 42 | return ExternalSLocEntries->getModuleImportLoc(FID.ID); |
1159 | 1.17k | } |
1160 | | |
1161 | | /// Given a SourceLocation object \p Loc, return the expansion |
1162 | | /// location referenced by the ID. |
1163 | 148M | SourceLocation getExpansionLoc(SourceLocation Loc) const { |
1164 | | // Handle the non-mapped case inline, defer to out of line code to handle |
1165 | | // expansions. |
1166 | 148M | if (Loc.isFileID()) return Loc139M ; |
1167 | 8.61M | return getExpansionLocSlowCase(Loc); |
1168 | 148M | } |
1169 | | |
1170 | | /// Given \p Loc, if it is a macro location return the expansion |
1171 | | /// location or the spelling location, depending on if it comes from a |
1172 | | /// macro argument or not. |
1173 | 1.20M | SourceLocation getFileLoc(SourceLocation Loc) const { |
1174 | 1.20M | if (Loc.isFileID()) return Loc1.17M ; |
1175 | 31.2k | return getFileLocSlowCase(Loc); |
1176 | 1.20M | } |
1177 | | |
1178 | | /// Return the start/end of the expansion information for an |
1179 | | /// expansion location. |
1180 | | /// |
1181 | | /// \pre \p Loc is required to be an expansion location. |
1182 | | CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const; |
1183 | | |
1184 | | /// Given a SourceLocation object, return the range of |
1185 | | /// tokens covered by the expansion in the ultimate file. |
1186 | | CharSourceRange getExpansionRange(SourceLocation Loc) const; |
1187 | | |
1188 | | /// Given a SourceRange object, return the range of |
1189 | | /// tokens or characters covered by the expansion in the ultimate file. |
1190 | 2.40k | CharSourceRange getExpansionRange(SourceRange Range) const { |
1191 | 2.40k | SourceLocation Begin = getExpansionRange(Range.getBegin()).getBegin(); |
1192 | 2.40k | CharSourceRange End = getExpansionRange(Range.getEnd()); |
1193 | 2.40k | return CharSourceRange(SourceRange(Begin, End.getEnd()), |
1194 | 2.40k | End.isTokenRange()); |
1195 | 2.40k | } |
1196 | | |
1197 | | /// Given a CharSourceRange object, return the range of |
1198 | | /// tokens or characters covered by the expansion in the ultimate file. |
1199 | 457 | CharSourceRange getExpansionRange(CharSourceRange Range) const { |
1200 | 457 | CharSourceRange Expansion = getExpansionRange(Range.getAsRange()); |
1201 | 457 | if (Expansion.getEnd() == Range.getEnd()) |
1202 | 454 | Expansion.setTokenRange(Range.isTokenRange()); |
1203 | 457 | return Expansion; |
1204 | 457 | } |
1205 | | |
1206 | | /// Given a SourceLocation object, return the spelling |
1207 | | /// location referenced by the ID. |
1208 | | /// |
1209 | | /// This is the place where the characters that make up the lexed token |
1210 | | /// can be found. |
1211 | 98.2M | SourceLocation getSpellingLoc(SourceLocation Loc) const { |
1212 | | // Handle the non-mapped case inline, defer to out of line code to handle |
1213 | | // expansions. |
1214 | 98.2M | if (Loc.isFileID()) return Loc19.5M ; |
1215 | 78.7M | return getSpellingLocSlowCase(Loc); |
1216 | 98.2M | } |
1217 | | |
1218 | | /// Given a SourceLocation object, return the spelling location |
1219 | | /// referenced by the ID. |
1220 | | /// |
1221 | | /// This is the first level down towards the place where the characters |
1222 | | /// that make up the lexed token can be found. This should not generally |
1223 | | /// be used by clients. |
1224 | | SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const; |
1225 | | |
1226 | | /// Form a SourceLocation from a FileID and Offset pair. |
1227 | 34.1M | SourceLocation getComposedLoc(FileID FID, unsigned Offset) const { |
1228 | 34.1M | auto *Entry = getSLocEntryOrNull(FID); |
1229 | 34.1M | if (!Entry) |
1230 | 0 | return SourceLocation(); |
1231 | | |
1232 | 34.1M | SourceLocation::UIntTy GlobalOffset = Entry->getOffset() + Offset; |
1233 | 34.1M | return Entry->isFile() ? SourceLocation::getFileLoc(GlobalOffset)27.3M |
1234 | 34.1M | : SourceLocation::getMacroLoc(GlobalOffset)6.81M ; |
1235 | 34.1M | } |
1236 | | |
1237 | | /// Decompose the specified location into a raw FileID + Offset pair. |
1238 | | /// |
1239 | | /// The first element is the FileID, the second is the offset from the |
1240 | | /// start of the buffer of the location. |
1241 | 423M | std::pair<FileID, unsigned> getDecomposedLoc(SourceLocation Loc) const { |
1242 | 423M | FileID FID = getFileID(Loc); |
1243 | 423M | auto *Entry = getSLocEntryOrNull(FID); |
1244 | 423M | if (!Entry) |
1245 | 1.39M | return std::make_pair(FileID(), 0); |
1246 | 422M | return std::make_pair(FID, Loc.getOffset() - Entry->getOffset()); |
1247 | 423M | } |
1248 | | |
1249 | | /// Decompose the specified location into a raw FileID + Offset pair. |
1250 | | /// |
1251 | | /// If the location is an expansion record, walk through it until we find |
1252 | | /// the final location expanded. |
1253 | | std::pair<FileID, unsigned> |
1254 | 372M | getDecomposedExpansionLoc(SourceLocation Loc) const { |
1255 | 372M | FileID FID = getFileID(Loc); |
1256 | 372M | auto *E = getSLocEntryOrNull(FID); |
1257 | 372M | if (!E) |
1258 | 21 | return std::make_pair(FileID(), 0); |
1259 | | |
1260 | 372M | unsigned Offset = Loc.getOffset()-E->getOffset(); |
1261 | 372M | if (Loc.isFileID()) |
1262 | 365M | return std::make_pair(FID, Offset); |
1263 | | |
1264 | 7.23M | return getDecomposedExpansionLocSlowCase(E); |
1265 | 372M | } |
1266 | | |
1267 | | /// Decompose the specified location into a raw FileID + Offset pair. |
1268 | | /// |
1269 | | /// If the location is an expansion record, walk through it until we find |
1270 | | /// its spelling record. |
1271 | | std::pair<FileID, unsigned> |
1272 | 32.7M | getDecomposedSpellingLoc(SourceLocation Loc) const { |
1273 | 32.7M | FileID FID = getFileID(Loc); |
1274 | 32.7M | auto *E = getSLocEntryOrNull(FID); |
1275 | 32.7M | if (!E) |
1276 | 64 | return std::make_pair(FileID(), 0); |
1277 | | |
1278 | 32.7M | unsigned Offset = Loc.getOffset()-E->getOffset(); |
1279 | 32.7M | if (Loc.isFileID()) |
1280 | 31.8M | return std::make_pair(FID, Offset); |
1281 | 872k | return getDecomposedSpellingLocSlowCase(E, Offset); |
1282 | 32.7M | } |
1283 | | |
1284 | | /// Returns the "included/expanded in" decomposed location of the given |
1285 | | /// FileID. |
1286 | | std::pair<FileID, unsigned> getDecomposedIncludedLoc(FileID FID) const; |
1287 | | |
1288 | | /// Returns the offset from the start of the file that the |
1289 | | /// specified SourceLocation represents. |
1290 | | /// |
1291 | | /// This is not very meaningful for a macro ID. |
1292 | 1.64M | unsigned getFileOffset(SourceLocation SpellingLoc) const { |
1293 | 1.64M | return getDecomposedLoc(SpellingLoc).second; |
1294 | 1.64M | } |
1295 | | |
1296 | | /// Tests whether the given source location represents a macro |
1297 | | /// argument's expansion into the function-like macro definition. |
1298 | | /// |
1299 | | /// \param StartLoc If non-null and function returns true, it is set to the |
1300 | | /// start location of the macro argument expansion. |
1301 | | /// |
1302 | | /// Such source locations only appear inside of the expansion |
1303 | | /// locations representing where a particular function-like macro was |
1304 | | /// expanded. |
1305 | | bool isMacroArgExpansion(SourceLocation Loc, |
1306 | | SourceLocation *StartLoc = nullptr) const; |
1307 | | |
1308 | | /// Tests whether the given source location represents the expansion of |
1309 | | /// a macro body. |
1310 | | /// |
1311 | | /// This is equivalent to testing whether the location is part of a macro |
1312 | | /// expansion but not the expansion of an argument to a function-like macro. |
1313 | | bool isMacroBodyExpansion(SourceLocation Loc) const; |
1314 | | |
1315 | | /// Returns true if the given MacroID location points at the beginning |
1316 | | /// of the immediate macro expansion. |
1317 | | /// |
1318 | | /// \param MacroBegin If non-null and function returns true, it is set to the |
1319 | | /// begin location of the immediate macro expansion. |
1320 | | bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc, |
1321 | | SourceLocation *MacroBegin = nullptr) const; |
1322 | | |
1323 | | /// Returns true if the given MacroID location points at the character |
1324 | | /// end of the immediate macro expansion. |
1325 | | /// |
1326 | | /// \param MacroEnd If non-null and function returns true, it is set to the |
1327 | | /// character end location of the immediate macro expansion. |
1328 | | bool |
1329 | | isAtEndOfImmediateMacroExpansion(SourceLocation Loc, |
1330 | | SourceLocation *MacroEnd = nullptr) const; |
1331 | | |
1332 | | /// Returns true if \p Loc is inside the [\p Start, +\p Length) |
1333 | | /// chunk of the source location address space. |
1334 | | /// |
1335 | | /// If it's true and \p RelativeOffset is non-null, it will be set to the |
1336 | | /// relative offset of \p Loc inside the chunk. |
1337 | | bool |
1338 | | isInSLocAddrSpace(SourceLocation Loc, SourceLocation Start, unsigned Length, |
1339 | 976M | SourceLocation::UIntTy *RelativeOffset = nullptr) const { |
1340 | 976M | assert(((Start.getOffset() < NextLocalOffset && |
1341 | 976M | Start.getOffset()+Length <= NextLocalOffset) || |
1342 | 976M | (Start.getOffset() >= CurrentLoadedOffset && |
1343 | 976M | Start.getOffset()+Length < MaxLoadedOffset)) && |
1344 | 976M | "Chunk is not valid SLoc address space"); |
1345 | 0 | SourceLocation::UIntTy LocOffs = Loc.getOffset(); |
1346 | 976M | SourceLocation::UIntTy BeginOffs = Start.getOffset(); |
1347 | 976M | SourceLocation::UIntTy EndOffs = BeginOffs + Length; |
1348 | 976M | if (LocOffs >= BeginOffs && LocOffs < EndOffs) { |
1349 | 976M | if (RelativeOffset) |
1350 | 488M | *RelativeOffset = LocOffs - BeginOffs; |
1351 | 976M | return true; |
1352 | 976M | } |
1353 | | |
1354 | 0 | return false; |
1355 | 976M | } |
1356 | | |
1357 | | /// Return true if both \p LHS and \p RHS are in the local source |
1358 | | /// location address space or the loaded one. |
1359 | | /// |
1360 | | /// If it's true and \p RelativeOffset is non-null, it will be set to the |
1361 | | /// offset of \p RHS relative to \p LHS. |
1362 | | bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS, |
1363 | 167M | SourceLocation::IntTy *RelativeOffset) const { |
1364 | 167M | SourceLocation::UIntTy LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset(); |
1365 | 167M | bool LHSLoaded = LHSOffs >= CurrentLoadedOffset; |
1366 | 167M | bool RHSLoaded = RHSOffs >= CurrentLoadedOffset; |
1367 | | |
1368 | 167M | if (LHSLoaded == RHSLoaded) { |
1369 | 167M | if (RelativeOffset) |
1370 | 167M | *RelativeOffset = RHSOffs - LHSOffs; |
1371 | 167M | return true; |
1372 | 167M | } |
1373 | | |
1374 | 0 | return false; |
1375 | 167M | } |
1376 | | |
1377 | | //===--------------------------------------------------------------------===// |
1378 | | // Queries about the code at a SourceLocation. |
1379 | | //===--------------------------------------------------------------------===// |
1380 | | |
1381 | | /// Return a pointer to the start of the specified location |
1382 | | /// in the appropriate spelling MemoryBuffer. |
1383 | | /// |
1384 | | /// \param Invalid If non-NULL, will be set \c true if an error occurs. |
1385 | | const char *getCharacterData(SourceLocation SL, |
1386 | | bool *Invalid = nullptr) const; |
1387 | | |
1388 | | /// Return the column # for the specified file position. |
1389 | | /// |
1390 | | /// This is significantly cheaper to compute than the line number. This |
1391 | | /// returns zero if the column number isn't known. This may only be called |
1392 | | /// on a file sloc, so you must choose a spelling or expansion location |
1393 | | /// before calling this method. |
1394 | | unsigned getColumnNumber(FileID FID, unsigned FilePos, |
1395 | | bool *Invalid = nullptr) const; |
1396 | | unsigned getSpellingColumnNumber(SourceLocation Loc, |
1397 | | bool *Invalid = nullptr) const; |
1398 | | unsigned getExpansionColumnNumber(SourceLocation Loc, |
1399 | | bool *Invalid = nullptr) const; |
1400 | | unsigned getPresumedColumnNumber(SourceLocation Loc, |
1401 | | bool *Invalid = nullptr) const; |
1402 | | |
1403 | | /// Given a SourceLocation, return the spelling line number |
1404 | | /// for the position indicated. |
1405 | | /// |
1406 | | /// This requires building and caching a table of line offsets for the |
1407 | | /// MemoryBuffer, so this is not cheap: use only when about to emit a |
1408 | | /// diagnostic. |
1409 | | unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const; |
1410 | | unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const; |
1411 | | unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const; |
1412 | | unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const; |
1413 | | |
1414 | | /// Return the filename or buffer identifier of the buffer the |
1415 | | /// location is in. |
1416 | | /// |
1417 | | /// Note that this name does not respect \#line directives. Use |
1418 | | /// getPresumedLoc for normal clients. |
1419 | | StringRef getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const; |
1420 | | |
1421 | | /// Return the file characteristic of the specified source |
1422 | | /// location, indicating whether this is a normal file, a system |
1423 | | /// header, or an "implicit extern C" system header. |
1424 | | /// |
1425 | | /// This state can be modified with flags on GNU linemarker directives like: |
1426 | | /// \code |
1427 | | /// # 4 "foo.h" 3 |
1428 | | /// \endcode |
1429 | | /// which changes all source locations in the current file after that to be |
1430 | | /// considered to be from a system header. |
1431 | | SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const; |
1432 | | |
1433 | | /// Returns the "presumed" location of a SourceLocation specifies. |
1434 | | /// |
1435 | | /// A "presumed location" can be modified by \#line or GNU line marker |
1436 | | /// directives. This provides a view on the data that a user should see |
1437 | | /// in diagnostics, for example. |
1438 | | /// |
1439 | | /// Note that a presumed location is always given as the expansion point of |
1440 | | /// an expansion location, not at the spelling location. |
1441 | | /// |
1442 | | /// \returns The presumed location of the specified SourceLocation. If the |
1443 | | /// presumed location cannot be calculated (e.g., because \p Loc is invalid |
1444 | | /// or the file containing \p Loc has changed on disk), returns an invalid |
1445 | | /// presumed location. |
1446 | | PresumedLoc getPresumedLoc(SourceLocation Loc, |
1447 | | bool UseLineDirectives = true) const; |
1448 | | |
1449 | | /// Returns whether the PresumedLoc for a given SourceLocation is |
1450 | | /// in the main file. |
1451 | | /// |
1452 | | /// This computes the "presumed" location for a SourceLocation, then checks |
1453 | | /// whether it came from a file other than the main file. This is different |
1454 | | /// from isWrittenInMainFile() because it takes line marker directives into |
1455 | | /// account. |
1456 | | bool isInMainFile(SourceLocation Loc) const; |
1457 | | |
1458 | | /// Returns true if the spelling locations for both SourceLocations |
1459 | | /// are part of the same file buffer. |
1460 | | /// |
1461 | | /// This check ignores line marker directives. |
1462 | 36.9M | bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const { |
1463 | 36.9M | return getFileID(Loc1) == getFileID(Loc2); |
1464 | 36.9M | } |
1465 | | |
1466 | | /// Returns true if the spelling location for the given location |
1467 | | /// is in the main file buffer. |
1468 | | /// |
1469 | | /// This check ignores line marker directives. |
1470 | 141k | bool isWrittenInMainFile(SourceLocation Loc) const { |
1471 | 141k | return getFileID(Loc) == getMainFileID(); |
1472 | 141k | } |
1473 | | |
1474 | | /// Returns whether \p Loc is located in a <built-in> file. |
1475 | 83.3M | bool isWrittenInBuiltinFile(SourceLocation Loc) const { |
1476 | 83.3M | PresumedLoc Presumed = getPresumedLoc(Loc); |
1477 | 83.3M | if (Presumed.isInvalid()) |
1478 | 1 | return false; |
1479 | 83.3M | StringRef Filename(Presumed.getFilename()); |
1480 | 83.3M | return Filename.equals("<built-in>"); |
1481 | 83.3M | } |
1482 | | |
1483 | | /// Returns whether \p Loc is located in a <command line> file. |
1484 | 88.0k | bool isWrittenInCommandLineFile(SourceLocation Loc) const { |
1485 | 88.0k | PresumedLoc Presumed = getPresumedLoc(Loc); |
1486 | 88.0k | if (Presumed.isInvalid()) |
1487 | 1 | return false; |
1488 | 88.0k | StringRef Filename(Presumed.getFilename()); |
1489 | 88.0k | return Filename.equals("<command line>"); |
1490 | 88.0k | } |
1491 | | |
1492 | | /// Returns whether \p Loc is located in a <scratch space> file. |
1493 | 16.7k | bool isWrittenInScratchSpace(SourceLocation Loc) const { |
1494 | 16.7k | PresumedLoc Presumed = getPresumedLoc(Loc); |
1495 | 16.7k | if (Presumed.isInvalid()) |
1496 | 1 | return false; |
1497 | 16.7k | StringRef Filename(Presumed.getFilename()); |
1498 | 16.7k | return Filename.equals("<scratch space>"); |
1499 | 16.7k | } |
1500 | | |
1501 | | /// Returns if a SourceLocation is in a system header. |
1502 | 178M | bool isInSystemHeader(SourceLocation Loc) const { |
1503 | 178M | if (Loc.isInvalid()) |
1504 | 1 | return false; |
1505 | 178M | return isSystem(getFileCharacteristic(Loc)); |
1506 | 178M | } |
1507 | | |
1508 | | /// Returns if a SourceLocation is in an "extern C" system header. |
1509 | 15 | bool isInExternCSystemHeader(SourceLocation Loc) const { |
1510 | 15 | return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem; |
1511 | 15 | } |
1512 | | |
1513 | | /// Returns whether \p Loc is expanded from a macro in a system header. |
1514 | 2.95M | bool isInSystemMacro(SourceLocation loc) const { |
1515 | 2.95M | if (!loc.isMacroID()) |
1516 | 2.94M | return false; |
1517 | | |
1518 | | // This happens when the macro is the result of a paste, in that case |
1519 | | // its spelling is the scratch memory, so we take the parent context. |
1520 | | // There can be several level of token pasting. |
1521 | 16.3k | if (isWrittenInScratchSpace(getSpellingLoc(loc))) { |
1522 | 397 | do { |
1523 | 397 | loc = getImmediateMacroCallerLoc(loc); |
1524 | 397 | } while (isWrittenInScratchSpace(getSpellingLoc(loc))); |
1525 | 396 | return isInSystemMacro(loc); |
1526 | 396 | } |
1527 | | |
1528 | 15.9k | return isInSystemHeader(getSpellingLoc(loc)); |
1529 | 16.3k | } |
1530 | | |
1531 | | /// The size of the SLocEntry that \p FID represents. |
1532 | | unsigned getFileIDSize(FileID FID) const; |
1533 | | |
1534 | | /// Given a specific FileID, returns true if \p Loc is inside that |
1535 | | /// FileID chunk and sets relative offset (offset of \p Loc from beginning |
1536 | | /// of FileID) to \p relativeOffset. |
1537 | | bool isInFileID(SourceLocation Loc, FileID FID, |
1538 | 54.4M | unsigned *RelativeOffset = nullptr) const { |
1539 | 54.4M | SourceLocation::UIntTy Offs = Loc.getOffset(); |
1540 | 54.4M | if (isOffsetInFileID(FID, Offs)) { |
1541 | 13.8M | if (RelativeOffset) |
1542 | 8.21M | *RelativeOffset = Offs - getSLocEntry(FID).getOffset(); |
1543 | 13.8M | return true; |
1544 | 13.8M | } |
1545 | | |
1546 | 40.6M | return false; |
1547 | 54.4M | } |
1548 | | |
1549 | | //===--------------------------------------------------------------------===// |
1550 | | // Line Table Manipulation Routines |
1551 | | //===--------------------------------------------------------------------===// |
1552 | | |
1553 | | /// Return the uniqued ID for the specified filename. |
1554 | | unsigned getLineTableFilenameID(StringRef Str); |
1555 | | |
1556 | | /// Add a line note to the line table for the FileID and offset |
1557 | | /// specified by Loc. |
1558 | | /// |
1559 | | /// If FilenameID is -1, it is considered to be unspecified. |
1560 | | void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID, |
1561 | | bool IsFileEntry, bool IsFileExit, |
1562 | | SrcMgr::CharacteristicKind FileKind); |
1563 | | |
1564 | | /// Determine if the source manager has a line table. |
1565 | 5.62k | bool hasLineTable() const { return LineTable != nullptr; } |
1566 | | |
1567 | | /// Retrieve the stored line table. |
1568 | | LineTableInfo &getLineTable(); |
1569 | | |
1570 | | //===--------------------------------------------------------------------===// |
1571 | | // Queries for performance analysis. |
1572 | | //===--------------------------------------------------------------------===// |
1573 | | |
1574 | | /// Return the total amount of physical memory allocated by the |
1575 | | /// ContentCache allocator. |
1576 | 1 | size_t getContentCacheSize() const { |
1577 | 1 | return ContentCacheAlloc.getTotalMemory(); |
1578 | 1 | } |
1579 | | |
1580 | | struct MemoryBufferSizes { |
1581 | | const size_t malloc_bytes; |
1582 | | const size_t mmap_bytes; |
1583 | | |
1584 | | MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) |
1585 | 1 | : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} |
1586 | | }; |
1587 | | |
1588 | | /// Return the amount of memory used by memory buffers, breaking down |
1589 | | /// by heap-backed versus mmap'ed memory. |
1590 | | MemoryBufferSizes getMemoryBufferSizes() const; |
1591 | | |
1592 | | /// Return the amount of memory used for various side tables and |
1593 | | /// data structures in the SourceManager. |
1594 | | size_t getDataStructureSizes() const; |
1595 | | |
1596 | | //===--------------------------------------------------------------------===// |
1597 | | // Other miscellaneous methods. |
1598 | | //===--------------------------------------------------------------------===// |
1599 | | |
1600 | | /// Get the source location for the given file:line:col triplet. |
1601 | | /// |
1602 | | /// If the source file is included multiple times, the source location will |
1603 | | /// be based upon the first inclusion. |
1604 | | SourceLocation translateFileLineCol(const FileEntry *SourceFile, |
1605 | | unsigned Line, unsigned Col) const; |
1606 | | |
1607 | | /// Get the FileID for the given file. |
1608 | | /// |
1609 | | /// If the source file is included multiple times, the FileID will be the |
1610 | | /// first inclusion. |
1611 | | FileID translateFile(const FileEntry *SourceFile) const; |
1612 | 1.33k | FileID translateFile(FileEntryRef SourceFile) const { |
1613 | 1.33k | return translateFile(&SourceFile.getFileEntry()); |
1614 | 1.33k | } |
1615 | | |
1616 | | /// Get the source location in \p FID for the given line:col. |
1617 | | /// Returns null location if \p FID is not a file SLocEntry. |
1618 | | SourceLocation translateLineCol(FileID FID, |
1619 | | unsigned Line, unsigned Col) const; |
1620 | | |
1621 | | /// If \p Loc points inside a function macro argument, the returned |
1622 | | /// location will be the macro location in which the argument was expanded. |
1623 | | /// If a macro argument is used multiple times, the expanded location will |
1624 | | /// be at the first expansion of the argument. |
1625 | | /// e.g. |
1626 | | /// MY_MACRO(foo); |
1627 | | /// ^ |
1628 | | /// Passing a file location pointing at 'foo', will yield a macro location |
1629 | | /// where 'foo' was expanded into. |
1630 | | SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) const; |
1631 | | |
1632 | | /// Determines the order of 2 source locations in the translation unit. |
1633 | | /// |
1634 | | /// \returns true if LHS source location comes before RHS, false otherwise. |
1635 | | bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; |
1636 | | |
1637 | | /// Determines whether the two decomposed source location is in the |
1638 | | /// same translation unit. As a byproduct, it also calculates the order |
1639 | | /// of the source locations in case they are in the same TU. |
1640 | | /// |
1641 | | /// \returns Pair of bools the first component is true if the two locations |
1642 | | /// are in the same TU. The second bool is true if the first is true |
1643 | | /// and \p LOffs is before \p ROffs. |
1644 | | std::pair<bool, bool> |
1645 | | isInTheSameTranslationUnit(std::pair<FileID, unsigned> &LOffs, |
1646 | | std::pair<FileID, unsigned> &ROffs) const; |
1647 | | |
1648 | | /// Determines the order of 2 source locations in the "source location |
1649 | | /// address space". |
1650 | 0 | bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const { |
1651 | 0 | return isBeforeInSLocAddrSpace(LHS, RHS.getOffset()); |
1652 | 0 | } |
1653 | | |
1654 | | /// Determines the order of a source location and a source location |
1655 | | /// offset in the "source location address space". |
1656 | | /// |
1657 | | /// Note that we always consider source locations loaded from |
1658 | | bool isBeforeInSLocAddrSpace(SourceLocation LHS, |
1659 | 550M | SourceLocation::UIntTy RHS) const { |
1660 | 550M | SourceLocation::UIntTy LHSOffset = LHS.getOffset(); |
1661 | 550M | bool LHSLoaded = LHSOffset >= CurrentLoadedOffset; |
1662 | 550M | bool RHSLoaded = RHS >= CurrentLoadedOffset; |
1663 | 550M | if (LHSLoaded == RHSLoaded) |
1664 | 542M | return LHSOffset < RHS; |
1665 | | |
1666 | 7.44M | return LHSLoaded; |
1667 | 550M | } |
1668 | | |
1669 | | /// Return true if the Point is within Start and End. |
1670 | | bool isPointWithin(SourceLocation Location, SourceLocation Start, |
1671 | 9.54k | SourceLocation End) const { |
1672 | 9.54k | return Location == Start || Location == End9.38k || |
1673 | 9.54k | (9.18k isBeforeInTranslationUnit(Start, Location)9.18k && |
1674 | 9.18k | isBeforeInTranslationUnit(Location, End)6.08k ); |
1675 | 9.54k | } |
1676 | | |
1677 | | // Iterators over FileInfos. |
1678 | | using fileinfo_iterator = |
1679 | | llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::const_iterator; |
1680 | | |
1681 | 11.6k | fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); } |
1682 | 11.6k | fileinfo_iterator fileinfo_end() const { return FileInfos.end(); } |
1683 | 680 | bool hasFileInfo(const FileEntry *File) const { |
1684 | 680 | return FileInfos.find(File) != FileInfos.end(); |
1685 | 680 | } |
1686 | | |
1687 | | /// Print statistics to stderr. |
1688 | | void PrintStats() const; |
1689 | | |
1690 | | void dump() const; |
1691 | | |
1692 | | /// Get the number of local SLocEntries we have. |
1693 | 2.37M | unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); } |
1694 | | |
1695 | | /// Get a local SLocEntry. This is exposed for indexing. |
1696 | 6.25G | const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index) const { |
1697 | 6.25G | assert(Index < LocalSLocEntryTable.size() && "Invalid index"); |
1698 | 0 | return LocalSLocEntryTable[Index]; |
1699 | 6.25G | } |
1700 | | |
1701 | | /// Get the number of loaded SLocEntries we have. |
1702 | 1.29k | unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();} |
1703 | | |
1704 | | /// Get a loaded SLocEntry. This is exposed for indexing. |
1705 | | const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index, |
1706 | 1.52G | bool *Invalid = nullptr) const { |
1707 | 1.52G | assert(Index < LoadedSLocEntryTable.size() && "Invalid index"); |
1708 | 1.52G | if (SLocEntryLoaded[Index]) |
1709 | 1.51G | return LoadedSLocEntryTable[Index]; |
1710 | 18.2M | return loadSLocEntry(Index, Invalid); |
1711 | 1.52G | } |
1712 | | |
1713 | | const SrcMgr::SLocEntry &getSLocEntry(FileID FID, |
1714 | 3.24G | bool *Invalid = nullptr) const { |
1715 | 3.24G | if (FID.ID == 0 || FID.ID == -13.24G ) { |
1716 | 1.39M | if (Invalid) *Invalid = true1.39M ; |
1717 | 1.39M | return LocalSLocEntryTable[0]; |
1718 | 1.39M | } |
1719 | 3.24G | return getSLocEntryByID(FID.ID, Invalid); |
1720 | 3.24G | } |
1721 | | |
1722 | 59.4M | SourceLocation::UIntTy getNextLocalOffset() const { return NextLocalOffset; } |
1723 | | |
1724 | 14.2k | void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) { |
1725 | 14.2k | assert(LoadedSLocEntryTable.empty() && |
1726 | 14.2k | "Invalidating existing loaded entries"); |
1727 | 0 | ExternalSLocEntries = Source; |
1728 | 14.2k | } |
1729 | | |
1730 | | /// Allocate a number of loaded SLocEntries, which will be actually |
1731 | | /// loaded on demand from the external source. |
1732 | | /// |
1733 | | /// NumSLocEntries will be allocated, which occupy a total of TotalSize space |
1734 | | /// in the global source view. The lowest ID and the base offset of the |
1735 | | /// entries will be returned. |
1736 | | std::pair<int, SourceLocation::UIntTy> |
1737 | | AllocateLoadedSLocEntries(unsigned NumSLocEntries, |
1738 | | SourceLocation::UIntTy TotalSize); |
1739 | | |
1740 | | /// Returns true if \p Loc came from a PCH/Module. |
1741 | 2.37k | bool isLoadedSourceLocation(SourceLocation Loc) const { |
1742 | 2.37k | return Loc.getOffset() >= CurrentLoadedOffset; |
1743 | 2.37k | } |
1744 | | |
1745 | | /// Returns true if \p Loc did not come from a PCH/Module. |
1746 | 3.96M | bool isLocalSourceLocation(SourceLocation Loc) const { |
1747 | 3.96M | return Loc.getOffset() < NextLocalOffset; |
1748 | 3.96M | } |
1749 | | |
1750 | | /// Returns true if \p FID came from a PCH/Module. |
1751 | 499k | bool isLoadedFileID(FileID FID) const { |
1752 | 499k | assert(FID.ID != -1 && "Using FileID sentinel value"); |
1753 | 0 | return FID.ID < 0; |
1754 | 499k | } |
1755 | | |
1756 | | /// Returns true if \p FID did not come from a PCH/Module. |
1757 | 0 | bool isLocalFileID(FileID FID) const { |
1758 | 0 | return !isLoadedFileID(FID); |
1759 | 0 | } |
1760 | | |
1761 | | /// Gets the location of the immediate macro caller, one level up the stack |
1762 | | /// toward the initial macro typed into the source. |
1763 | 23.0k | SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const { |
1764 | 23.0k | if (!Loc.isMacroID()) return Loc0 ; |
1765 | | |
1766 | | // When we have the location of (part of) an expanded parameter, its |
1767 | | // spelling location points to the argument as expanded in the macro call, |
1768 | | // and therefore is used to locate the macro caller. |
1769 | 23.0k | if (isMacroArgExpansion(Loc)) |
1770 | 11.0k | return getImmediateSpellingLoc(Loc); |
1771 | | |
1772 | | // Otherwise, the caller of the macro is located where this macro is |
1773 | | // expanded (while the spelling is part of the macro definition). |
1774 | 12.0k | return getImmediateExpansionRange(Loc).getBegin(); |
1775 | 23.0k | } |
1776 | | |
1777 | | /// \return Location of the top-level macro caller. |
1778 | | SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const; |
1779 | | |
1780 | | private: |
1781 | | friend class ASTReader; |
1782 | | friend class ASTWriter; |
1783 | | |
1784 | | llvm::MemoryBufferRef getFakeBufferForRecovery() const; |
1785 | | SrcMgr::ContentCache &getFakeContentCacheForRecovery() const; |
1786 | | |
1787 | | const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const; |
1788 | | |
1789 | 1.40G | const SrcMgr::SLocEntry *getSLocEntryOrNull(FileID FID) const { |
1790 | 1.40G | bool Invalid = false; |
1791 | 1.40G | const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); |
1792 | 1.40G | return Invalid ? nullptr1.39M : &Entry1.39G ; |
1793 | 1.40G | } |
1794 | | |
1795 | 537M | const SrcMgr::SLocEntry *getSLocEntryForFile(FileID FID) const { |
1796 | 537M | if (auto *Entry = getSLocEntryOrNull(FID)) |
1797 | 537M | if (Entry->isFile()) |
1798 | 537M | return Entry; |
1799 | 2.02k | return nullptr; |
1800 | 537M | } |
1801 | | |
1802 | | /// Get the entry with the given unwrapped FileID. |
1803 | | /// Invalid will not be modified for Local IDs. |
1804 | | const SrcMgr::SLocEntry &getSLocEntryByID(int ID, |
1805 | 4.19G | bool *Invalid = nullptr) const { |
1806 | 4.19G | assert(ID != -1 && "Using FileID sentinel value"); |
1807 | 4.19G | if (ID < 0) |
1808 | 837M | return getLoadedSLocEntryByID(ID, Invalid); |
1809 | 3.35G | return getLocalSLocEntry(static_cast<unsigned>(ID)); |
1810 | 4.19G | } |
1811 | | |
1812 | | const SrcMgr::SLocEntry & |
1813 | 873M | getLoadedSLocEntryByID(int ID, bool *Invalid = nullptr) const { |
1814 | 873M | return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid); |
1815 | 873M | } |
1816 | | |
1817 | | /// Implements the common elements of storing an expansion info struct into |
1818 | | /// the SLocEntry table and producing a source location that refers to it. |
1819 | | SourceLocation |
1820 | | createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion, |
1821 | | unsigned Length, int LoadedID = 0, |
1822 | | SourceLocation::UIntTy LoadedOffset = 0); |
1823 | | |
1824 | | /// Return true if the specified FileID contains the |
1825 | | /// specified SourceLocation offset. This is a very hot method. |
1826 | | inline bool isOffsetInFileID(FileID FID, |
1827 | 1.44G | SourceLocation::UIntTy SLocOffset) const { |
1828 | 1.44G | const SrcMgr::SLocEntry &Entry = getSLocEntry(FID); |
1829 | | // If the entry is after the offset, it can't contain it. |
1830 | 1.44G | if (SLocOffset < Entry.getOffset()) return false206M ; |
1831 | | |
1832 | | // If this is the very last entry then it does. |
1833 | 1.23G | if (FID.ID == -2) |
1834 | 45.8k | return true; |
1835 | | |
1836 | | // If it is the last local entry, then it does if the location is local. |
1837 | 1.23G | if (FID.ID+1 == static_cast<int>(LocalSLocEntryTable.size())) |
1838 | 285M | return SLocOffset < NextLocalOffset; |
1839 | | |
1840 | | // Otherwise, the entry after it has to not include it. This works for both |
1841 | | // local and loaded entries. |
1842 | 948M | return SLocOffset < getSLocEntryByID(FID.ID+1).getOffset(); |
1843 | 1.23G | } |
1844 | | |
1845 | | /// Returns the previous in-order FileID or an invalid FileID if there |
1846 | | /// is no previous one. |
1847 | | FileID getPreviousFileID(FileID FID) const; |
1848 | | |
1849 | | /// Returns the next in-order FileID or an invalid FileID if there is |
1850 | | /// no next one. |
1851 | | FileID getNextFileID(FileID FID) const; |
1852 | | |
1853 | | /// Create a new fileID for the specified ContentCache and |
1854 | | /// include position. |
1855 | | /// |
1856 | | /// This works regardless of whether the ContentCache corresponds to a |
1857 | | /// file or some other input source. |
1858 | | FileID createFileIDImpl(SrcMgr::ContentCache &File, StringRef Filename, |
1859 | | SourceLocation IncludePos, |
1860 | | SrcMgr::CharacteristicKind DirCharacter, int LoadedID, |
1861 | | SourceLocation::UIntTy LoadedOffset); |
1862 | | |
1863 | | SrcMgr::ContentCache &getOrCreateContentCache(FileEntryRef SourceFile, |
1864 | | bool isSystemFile = false); |
1865 | | |
1866 | | /// Create a new ContentCache for the specified memory buffer. |
1867 | | SrcMgr::ContentCache & |
1868 | | createMemBufferContentCache(std::unique_ptr<llvm::MemoryBuffer> Buf); |
1869 | | |
1870 | | FileID getFileIDSlow(SourceLocation::UIntTy SLocOffset) const; |
1871 | | FileID getFileIDLocal(SourceLocation::UIntTy SLocOffset) const; |
1872 | | FileID getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const; |
1873 | | |
1874 | | SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const; |
1875 | | SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; |
1876 | | SourceLocation getFileLocSlowCase(SourceLocation Loc) const; |
1877 | | |
1878 | | std::pair<FileID, unsigned> |
1879 | | getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const; |
1880 | | std::pair<FileID, unsigned> |
1881 | | getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, |
1882 | | unsigned Offset) const; |
1883 | | void computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const; |
1884 | | void associateFileChunkWithMacroArgExp(MacroArgsMap &MacroArgsCache, |
1885 | | FileID FID, |
1886 | | SourceLocation SpellLoc, |
1887 | | SourceLocation ExpansionLoc, |
1888 | | unsigned ExpansionLength) const; |
1889 | | }; |
1890 | | |
1891 | | /// Comparison function object. |
1892 | | template<typename T> |
1893 | | class BeforeThanCompare; |
1894 | | |
1895 | | /// Compare two source locations. |
1896 | | template<> |
1897 | | class BeforeThanCompare<SourceLocation> { |
1898 | | SourceManager &SM; |
1899 | | |
1900 | | public: |
1901 | 168 | explicit BeforeThanCompare(SourceManager &SM) : SM(SM) {} |
1902 | | |
1903 | 323 | bool operator()(SourceLocation LHS, SourceLocation RHS) const { |
1904 | 323 | return SM.isBeforeInTranslationUnit(LHS, RHS); |
1905 | 323 | } |
1906 | | }; |
1907 | | |
1908 | | /// Compare two non-overlapping source ranges. |
1909 | | template<> |
1910 | | class BeforeThanCompare<SourceRange> { |
1911 | | SourceManager &SM; |
1912 | | |
1913 | | public: |
1914 | 0 | explicit BeforeThanCompare(SourceManager &SM) : SM(SM) {} |
1915 | | |
1916 | 0 | bool operator()(SourceRange LHS, SourceRange RHS) const { |
1917 | 0 | return SM.isBeforeInTranslationUnit(LHS.getBegin(), RHS.getBegin()); |
1918 | 0 | } |
1919 | | }; |
1920 | | |
1921 | | /// SourceManager and necessary depdencies (e.g. VFS, FileManager) for a single |
1922 | | /// in-memorty file. |
1923 | | class SourceManagerForFile { |
1924 | | public: |
1925 | | /// Creates SourceManager and necessary depdencies (e.g. VFS, FileManager). |
1926 | | /// The main file in the SourceManager will be \p FileName with \p Content. |
1927 | | SourceManagerForFile(StringRef FileName, StringRef Content); |
1928 | | |
1929 | 131k | SourceManager &get() { |
1930 | 131k | assert(SourceMgr); |
1931 | 0 | return *SourceMgr; |
1932 | 131k | } |
1933 | | |
1934 | | private: |
1935 | | // The order of these fields are important - they should be in the same order |
1936 | | // as they are created in `createSourceManagerForFile` so that they can be |
1937 | | // deleted in the reverse order as they are created. |
1938 | | std::unique_ptr<FileManager> FileMgr; |
1939 | | std::unique_ptr<DiagnosticsEngine> Diagnostics; |
1940 | | std::unique_ptr<SourceManager> SourceMgr; |
1941 | | }; |
1942 | | |
1943 | | } // namespace clang |
1944 | | |
1945 | | #endif // LLVM_CLANG_BASIC_SOURCEMANAGER_H |