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