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