/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/ExternalASTSource.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ExternalASTSource.h - Abstract External AST Interface ----*- 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 | | // This file defines the ExternalASTSource interface, which enables |
10 | | // construction of AST nodes from some external source. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H |
15 | | #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H |
16 | | |
17 | | #include "clang/AST/CharUnits.h" |
18 | | #include "clang/AST/DeclBase.h" |
19 | | #include "clang/Basic/LLVM.h" |
20 | | #include "llvm/ADT/ArrayRef.h" |
21 | | #include "llvm/ADT/DenseMap.h" |
22 | | #include "llvm/ADT/IntrusiveRefCntPtr.h" |
23 | | #include "llvm/ADT/Optional.h" |
24 | | #include "llvm/ADT/PointerUnion.h" |
25 | | #include "llvm/ADT/STLExtras.h" |
26 | | #include "llvm/ADT/SmallVector.h" |
27 | | #include "llvm/ADT/iterator.h" |
28 | | #include "llvm/Support/PointerLikeTypeTraits.h" |
29 | | #include <cassert> |
30 | | #include <cstddef> |
31 | | #include <cstdint> |
32 | | #include <iterator> |
33 | | #include <utility> |
34 | | |
35 | | namespace clang { |
36 | | |
37 | | class ASTConsumer; |
38 | | class ASTContext; |
39 | | class ASTSourceDescriptor; |
40 | | class CXXBaseSpecifier; |
41 | | class CXXCtorInitializer; |
42 | | class CXXRecordDecl; |
43 | | class DeclarationName; |
44 | | class FieldDecl; |
45 | | class IdentifierInfo; |
46 | | class NamedDecl; |
47 | | class ObjCInterfaceDecl; |
48 | | class RecordDecl; |
49 | | class Selector; |
50 | | class Stmt; |
51 | | class TagDecl; |
52 | | |
53 | | /// Abstract interface for external sources of AST nodes. |
54 | | /// |
55 | | /// External AST sources provide AST nodes constructed from some |
56 | | /// external source, such as a precompiled header. External AST |
57 | | /// sources can resolve types and declarations from abstract IDs into |
58 | | /// actual type and declaration nodes, and read parts of declaration |
59 | | /// contexts. |
60 | | class ExternalASTSource : public RefCountedBase<ExternalASTSource> { |
61 | | friend class ExternalSemaSource; |
62 | | |
63 | | /// Generation number for this external AST source. Must be increased |
64 | | /// whenever we might have added new redeclarations for existing decls. |
65 | | uint32_t CurrentGeneration = 0; |
66 | | |
67 | | /// LLVM-style RTTI. |
68 | | static char ID; |
69 | | |
70 | | public: |
71 | 57.8k | ExternalASTSource() = default; |
72 | | virtual ~ExternalASTSource(); |
73 | | |
74 | | /// RAII class for safely pairing a StartedDeserializing call |
75 | | /// with FinishedDeserializing. |
76 | | class Deserializing { |
77 | | ExternalASTSource *Source; |
78 | | |
79 | | public: |
80 | 34.0M | explicit Deserializing(ExternalASTSource *source) : Source(source) { |
81 | 34.0M | assert(Source); |
82 | 0 | Source->StartedDeserializing(); |
83 | 34.0M | } |
84 | | |
85 | 34.0M | ~Deserializing() { |
86 | 34.0M | Source->FinishedDeserializing(); |
87 | 34.0M | } |
88 | | }; |
89 | | |
90 | | /// Get the current generation of this AST source. This number |
91 | | /// is incremented each time the AST source lazily extends an existing |
92 | | /// entity. |
93 | 167M | uint32_t getGeneration() const { return CurrentGeneration; } |
94 | | |
95 | | /// Resolve a declaration ID into a declaration, potentially |
96 | | /// building a new declaration. |
97 | | /// |
98 | | /// This method only needs to be implemented if the AST source ever |
99 | | /// passes back decl sets as VisibleDeclaration objects. |
100 | | /// |
101 | | /// The default implementation of this method is a no-op. |
102 | | virtual Decl *GetExternalDecl(uint32_t ID); |
103 | | |
104 | | /// Resolve a selector ID into a selector. |
105 | | /// |
106 | | /// This operation only needs to be implemented if the AST source |
107 | | /// returns non-zero for GetNumKnownSelectors(). |
108 | | /// |
109 | | /// The default implementation of this method is a no-op. |
110 | | virtual Selector GetExternalSelector(uint32_t ID); |
111 | | |
112 | | /// Returns the number of selectors known to the external AST |
113 | | /// source. |
114 | | /// |
115 | | /// The default implementation of this method is a no-op. |
116 | | virtual uint32_t GetNumExternalSelectors(); |
117 | | |
118 | | /// Resolve the offset of a statement in the decl stream into |
119 | | /// a statement. |
120 | | /// |
121 | | /// This operation is meant to be used via a LazyOffsetPtr. It only |
122 | | /// needs to be implemented if the AST source uses methods like |
123 | | /// FunctionDecl::setLazyBody when building decls. |
124 | | /// |
125 | | /// The default implementation of this method is a no-op. |
126 | | virtual Stmt *GetExternalDeclStmt(uint64_t Offset); |
127 | | |
128 | | /// Resolve the offset of a set of C++ constructor initializers in |
129 | | /// the decl stream into an array of initializers. |
130 | | /// |
131 | | /// The default implementation of this method is a no-op. |
132 | | virtual CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset); |
133 | | |
134 | | /// Resolve the offset of a set of C++ base specifiers in the decl |
135 | | /// stream into an array of specifiers. |
136 | | /// |
137 | | /// The default implementation of this method is a no-op. |
138 | | virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); |
139 | | |
140 | | /// Update an out-of-date identifier. |
141 | 0 | virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {} |
142 | | |
143 | | /// Find all declarations with the given name in the given context, |
144 | | /// and add them to the context by calling SetExternalVisibleDeclsForName |
145 | | /// or SetNoExternalVisibleDeclsForName. |
146 | | /// \return \c true if any declarations might have been found, \c false if |
147 | | /// we definitely have no declarations with tbis name. |
148 | | /// |
149 | | /// The default implementation of this method is a no-op returning \c false. |
150 | | virtual bool |
151 | | FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); |
152 | | |
153 | | /// Ensures that the table of all visible declarations inside this |
154 | | /// context is up to date. |
155 | | /// |
156 | | /// The default implementation of this function is a no-op. |
157 | | virtual void completeVisibleDeclsMap(const DeclContext *DC); |
158 | | |
159 | | /// Retrieve the module that corresponds to the given module ID. |
160 | 0 | virtual Module *getModule(unsigned ID) { return nullptr; } |
161 | | |
162 | | /// Return a descriptor for the corresponding module, if one exists. |
163 | | virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID); |
164 | | |
165 | | enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy }; |
166 | | |
167 | | virtual ExtKind hasExternalDefinitions(const Decl *D); |
168 | | |
169 | | /// Finds all declarations lexically contained within the given |
170 | | /// DeclContext, after applying an optional filter predicate. |
171 | | /// |
172 | | /// \param IsKindWeWant a predicate function that returns true if the passed |
173 | | /// declaration kind is one we are looking for. |
174 | | /// |
175 | | /// The default implementation of this method is a no-op. |
176 | | virtual void |
177 | | FindExternalLexicalDecls(const DeclContext *DC, |
178 | | llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, |
179 | | SmallVectorImpl<Decl *> &Result); |
180 | | |
181 | | /// Finds all declarations lexically contained within the given |
182 | | /// DeclContext. |
183 | | void FindExternalLexicalDecls(const DeclContext *DC, |
184 | 261k | SmallVectorImpl<Decl *> &Result) { |
185 | 2.72M | FindExternalLexicalDecls(DC, [](Decl::Kind) { return true; }, Result); |
186 | 261k | } |
187 | | |
188 | | /// Get the decls that are contained in a file in the Offset/Length |
189 | | /// range. \p Length can be 0 to indicate a point at \p Offset instead of |
190 | | /// a range. |
191 | | virtual void FindFileRegionDecls(FileID File, unsigned Offset, |
192 | | unsigned Length, |
193 | | SmallVectorImpl<Decl *> &Decls); |
194 | | |
195 | | /// Gives the external AST source an opportunity to complete |
196 | | /// the redeclaration chain for a declaration. Called each time we |
197 | | /// need the most recent declaration of a declaration after the |
198 | | /// generation count is incremented. |
199 | | virtual void CompleteRedeclChain(const Decl *D); |
200 | | |
201 | | /// Gives the external AST source an opportunity to complete |
202 | | /// an incomplete type. |
203 | | virtual void CompleteType(TagDecl *Tag); |
204 | | |
205 | | /// Gives the external AST source an opportunity to complete an |
206 | | /// incomplete Objective-C class. |
207 | | /// |
208 | | /// This routine will only be invoked if the "externally completed" bit is |
209 | | /// set on the ObjCInterfaceDecl via the function |
210 | | /// \c ObjCInterfaceDecl::setExternallyCompleted(). |
211 | | virtual void CompleteType(ObjCInterfaceDecl *Class); |
212 | | |
213 | | /// Loads comment ranges. |
214 | | virtual void ReadComments(); |
215 | | |
216 | | /// Notify ExternalASTSource that we started deserialization of |
217 | | /// a decl or type so until FinishedDeserializing is called there may be |
218 | | /// decls that are initializing. Must be paired with FinishedDeserializing. |
219 | | /// |
220 | | /// The default implementation of this method is a no-op. |
221 | | virtual void StartedDeserializing(); |
222 | | |
223 | | /// Notify ExternalASTSource that we finished the deserialization of |
224 | | /// a decl or type. Must be paired with StartedDeserializing. |
225 | | /// |
226 | | /// The default implementation of this method is a no-op. |
227 | | virtual void FinishedDeserializing(); |
228 | | |
229 | | /// Function that will be invoked when we begin parsing a new |
230 | | /// translation unit involving this external AST source. |
231 | | /// |
232 | | /// The default implementation of this method is a no-op. |
233 | | virtual void StartTranslationUnit(ASTConsumer *Consumer); |
234 | | |
235 | | /// Print any statistics that have been gathered regarding |
236 | | /// the external AST source. |
237 | | /// |
238 | | /// The default implementation of this method is a no-op. |
239 | | virtual void PrintStats(); |
240 | | |
241 | | /// Perform layout on the given record. |
242 | | /// |
243 | | /// This routine allows the external AST source to provide an specific |
244 | | /// layout for a record, overriding the layout that would normally be |
245 | | /// constructed. It is intended for clients who receive specific layout |
246 | | /// details rather than source code (such as LLDB). The client is expected |
247 | | /// to fill in the field offsets, base offsets, virtual base offsets, and |
248 | | /// complete object size. |
249 | | /// |
250 | | /// \param Record The record whose layout is being requested. |
251 | | /// |
252 | | /// \param Size The final size of the record, in bits. |
253 | | /// |
254 | | /// \param Alignment The final alignment of the record, in bits. |
255 | | /// |
256 | | /// \param FieldOffsets The offset of each of the fields within the record, |
257 | | /// expressed in bits. All of the fields must be provided with offsets. |
258 | | /// |
259 | | /// \param BaseOffsets The offset of each of the direct, non-virtual base |
260 | | /// classes. If any bases are not given offsets, the bases will be laid |
261 | | /// out according to the ABI. |
262 | | /// |
263 | | /// \param VirtualBaseOffsets The offset of each of the virtual base classes |
264 | | /// (either direct or not). If any bases are not given offsets, the bases will be laid |
265 | | /// out according to the ABI. |
266 | | /// |
267 | | /// \returns true if the record layout was provided, false otherwise. |
268 | | virtual bool layoutRecordType( |
269 | | const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, |
270 | | llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets, |
271 | | llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets, |
272 | | llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets); |
273 | | |
274 | | //===--------------------------------------------------------------------===// |
275 | | // Queries for performance analysis. |
276 | | //===--------------------------------------------------------------------===// |
277 | | |
278 | | struct MemoryBufferSizes { |
279 | | size_t malloc_bytes; |
280 | | size_t mmap_bytes; |
281 | | |
282 | | MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) |
283 | 0 | : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} |
284 | | }; |
285 | | |
286 | | /// Return the amount of memory used by memory buffers, breaking down |
287 | | /// by heap-backed versus mmap'ed memory. |
288 | 0 | MemoryBufferSizes getMemoryBufferSizes() const { |
289 | 0 | MemoryBufferSizes sizes(0, 0); |
290 | 0 | getMemoryBufferSizes(sizes); |
291 | 0 | return sizes; |
292 | 0 | } |
293 | | |
294 | | virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const; |
295 | | |
296 | | /// LLVM-style RTTI. |
297 | | /// \{ |
298 | 9.05M | virtual bool isA(const void *ClassID) const { return ClassID == &ID; } |
299 | 0 | static bool classof(const ExternalASTSource *S) { return S->isA(&ID); } |
300 | | /// \} |
301 | | |
302 | | protected: |
303 | | static DeclContextLookupResult |
304 | | SetExternalVisibleDeclsForName(const DeclContext *DC, |
305 | | DeclarationName Name, |
306 | | ArrayRef<NamedDecl*> Decls); |
307 | | |
308 | | static DeclContextLookupResult |
309 | | SetNoExternalVisibleDeclsForName(const DeclContext *DC, |
310 | | DeclarationName Name); |
311 | | |
312 | | /// Increment the current generation. |
313 | | uint32_t incrementGeneration(ASTContext &C); |
314 | | }; |
315 | | |
316 | | /// A lazy pointer to an AST node (of base type T) that resides |
317 | | /// within an external AST source. |
318 | | /// |
319 | | /// The AST node is identified within the external AST source by a |
320 | | /// 63-bit offset, and can be retrieved via an operation on the |
321 | | /// external AST source itself. |
322 | | template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)> |
323 | | struct LazyOffsetPtr { |
324 | | /// Either a pointer to an AST node or the offset within the |
325 | | /// external AST source where the AST node can be found. |
326 | | /// |
327 | | /// If the low bit is clear, a pointer to the AST node. If the low |
328 | | /// bit is set, the upper 63 bits are the offset. |
329 | | mutable uint64_t Ptr = 0; |
330 | | |
331 | | public: |
332 | 45.4M | LazyOffsetPtr() = default; clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::LazyOffsetPtr() Line | Count | Source | 332 | 31.7M | LazyOffsetPtr() = default; |
clang::LazyOffsetPtr<clang::CXXBaseSpecifier, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXBaseSpecifiers(unsigned long long))>::LazyOffsetPtr() Line | Count | Source | 332 | 7.85M | LazyOffsetPtr() = default; |
clang::LazyOffsetPtr<clang::CXXCtorInitializer*, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXCtorInitializers(unsigned long long))>::LazyOffsetPtr() Line | Count | Source | 332 | 1.30M | LazyOffsetPtr() = default; |
clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::LazyOffsetPtr() Line | Count | Source | 332 | 4.53M | LazyOffsetPtr() = default; |
|
333 | 4.54M | explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::LazyOffsetPtr(clang::Stmt*) Line | Count | Source | 333 | 4.54M | explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} |
clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::LazyOffsetPtr(clang::Decl*) Line | Count | Source | 333 | 1.33k | explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} |
|
334 | | |
335 | 681k | explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) { |
336 | 681k | assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); |
337 | 681k | if (Offset == 0) |
338 | 0 | Ptr = 0; |
339 | 681k | } |
340 | | |
341 | 1.16M | LazyOffsetPtr &operator=(T *Ptr) { |
342 | 1.16M | this->Ptr = reinterpret_cast<uint64_t>(Ptr); |
343 | 1.16M | return *this; |
344 | 1.16M | } clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::operator=(clang::Decl*) Line | Count | Source | 341 | 163k | LazyOffsetPtr &operator=(T *Ptr) { | 342 | 163k | this->Ptr = reinterpret_cast<uint64_t>(Ptr); | 343 | 163k | return *this; | 344 | 163k | } |
clang::LazyOffsetPtr<clang::CXXCtorInitializer*, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXCtorInitializers(unsigned long long))>::operator=(clang::CXXCtorInitializer**) Line | Count | Source | 341 | 320k | LazyOffsetPtr &operator=(T *Ptr) { | 342 | 320k | this->Ptr = reinterpret_cast<uint64_t>(Ptr); | 343 | 320k | return *this; | 344 | 320k | } |
clang::LazyOffsetPtr<clang::CXXBaseSpecifier, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXBaseSpecifiers(unsigned long long))>::operator=(clang::CXXBaseSpecifier*) Line | Count | Source | 341 | 678k | LazyOffsetPtr &operator=(T *Ptr) { | 342 | 678k | this->Ptr = reinterpret_cast<uint64_t>(Ptr); | 343 | 678k | return *this; | 344 | 678k | } |
clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::operator=(clang::Stmt*) Line | Count | Source | 341 | 7.45k | LazyOffsetPtr &operator=(T *Ptr) { | 342 | 7.45k | this->Ptr = reinterpret_cast<uint64_t>(Ptr); | 343 | 7.45k | return *this; | 344 | 7.45k | } |
|
345 | | |
346 | 1.95M | LazyOffsetPtr &operator=(uint64_t Offset) { |
347 | 1.95M | assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); |
348 | 1.95M | if (Offset == 0) |
349 | 1.26M | Ptr = 0; |
350 | 686k | else |
351 | 686k | Ptr = (Offset << 1) | 0x01; |
352 | | |
353 | 1.95M | return *this; |
354 | 1.95M | } clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::operator=(unsigned long long) Line | Count | Source | 346 | 18 | LazyOffsetPtr &operator=(uint64_t Offset) { | 347 | 18 | assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); | 348 | 18 | if (Offset == 0) | 349 | 0 | Ptr = 0; | 350 | 18 | else | 351 | 18 | Ptr = (Offset << 1) | 0x01; | 352 | | | 353 | 18 | return *this; | 354 | 18 | } |
clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::operator=(unsigned long long) Line | Count | Source | 346 | 1.37M | LazyOffsetPtr &operator=(uint64_t Offset) { | 347 | 1.37M | assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); | 348 | 1.37M | if (Offset == 0) | 349 | 1.26M | Ptr = 0; | 350 | 110k | else | 351 | 110k | Ptr = (Offset << 1) | 0x01; | 352 | | | 353 | 1.37M | return *this; | 354 | 1.37M | } |
clang::LazyOffsetPtr<clang::CXXCtorInitializer*, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXCtorInitializers(unsigned long long))>::operator=(unsigned long long) Line | Count | Source | 346 | 77.2k | LazyOffsetPtr &operator=(uint64_t Offset) { | 347 | 77.2k | assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); | 348 | 77.2k | if (Offset == 0) | 349 | 0 | Ptr = 0; | 350 | 77.2k | else | 351 | 77.2k | Ptr = (Offset << 1) | 0x01; | 352 | | | 353 | 77.2k | return *this; | 354 | 77.2k | } |
clang::LazyOffsetPtr<clang::CXXBaseSpecifier, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXBaseSpecifiers(unsigned long long))>::operator=(unsigned long long) Line | Count | Source | 346 | 498k | LazyOffsetPtr &operator=(uint64_t Offset) { | 347 | 498k | assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); | 348 | 498k | if (Offset == 0) | 349 | 0 | Ptr = 0; | 350 | 498k | else | 351 | 498k | Ptr = (Offset << 1) | 0x01; | 352 | | | 353 | 498k | return *this; | 354 | 498k | } |
|
355 | | |
356 | | /// Whether this pointer is non-NULL. |
357 | | /// |
358 | | /// This operation does not require the AST node to be deserialized. |
359 | 107M | explicit operator bool() const { return Ptr != 0; } clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::operator bool() const Line | Count | Source | 359 | 106M | explicit operator bool() const { return Ptr != 0; } |
clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::operator bool() const Line | Count | Source | 359 | 1.13M | explicit operator bool() const { return Ptr != 0; } |
|
360 | | |
361 | | /// Whether this pointer is non-NULL. |
362 | | /// |
363 | | /// This operation does not require the AST node to be deserialized. |
364 | 225k | bool isValid() const { return Ptr != 0; } clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::isValid() const Line | Count | Source | 364 | 167k | bool isValid() const { return Ptr != 0; } |
clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::isValid() const Line | Count | Source | 364 | 58.1k | bool isValid() const { return Ptr != 0; } |
|
365 | | |
366 | | /// Whether this pointer is currently stored as an offset. |
367 | 125M | bool isOffset() const { return Ptr & 0x01; } clang::LazyOffsetPtr<clang::CXXBaseSpecifier, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXBaseSpecifiers(unsigned long long))>::isOffset() const Line | Count | Source | 367 | 109M | bool isOffset() const { return Ptr & 0x01; } |
clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::isOffset() const Line | Count | Source | 367 | 11.8M | bool isOffset() const { return Ptr & 0x01; } |
clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::isOffset() const Line | Count | Source | 367 | 3.79M | bool isOffset() const { return Ptr & 0x01; } |
clang::LazyOffsetPtr<clang::CXXCtorInitializer*, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXCtorInitializers(unsigned long long))>::isOffset() const Line | Count | Source | 367 | 682k | bool isOffset() const { return Ptr & 0x01; } |
|
368 | | |
369 | | /// Retrieve the pointer to the AST node that this lazy pointer points to. |
370 | | /// |
371 | | /// \param Source the external AST source. |
372 | | /// |
373 | | /// \returns a pointer to the AST node. |
374 | 69.3M | T* get(ExternalASTSource *Source) const { |
375 | 69.3M | if (isOffset()) { |
376 | 552k | assert(Source && |
377 | 552k | "Cannot deserialize a lazy pointer without an AST source"); |
378 | 0 | Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1)); |
379 | 552k | } |
380 | 0 | return reinterpret_cast<T*>(Ptr); |
381 | 69.3M | } clang::LazyOffsetPtr<clang::CXXBaseSpecifier, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXBaseSpecifiers(unsigned long long))>::get(clang::ExternalASTSource*) const Line | Count | Source | 374 | 54.1M | T* get(ExternalASTSource *Source) const { | 375 | 54.1M | if (isOffset()) { | 376 | 54.6k | assert(Source && | 377 | 54.6k | "Cannot deserialize a lazy pointer without an AST source"); | 378 | 0 | Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1)); | 379 | 54.6k | } | 380 | 0 | return reinterpret_cast<T*>(Ptr); | 381 | 54.1M | } |
clang::LazyOffsetPtr<clang::Stmt, unsigned long long, &(clang::ExternalASTSource::GetExternalDeclStmt(unsigned long long))>::get(clang::ExternalASTSource*) const Line | Count | Source | 374 | 11.8M | T* get(ExternalASTSource *Source) const { | 375 | 11.8M | if (isOffset()) { | 376 | 402k | assert(Source && | 377 | 402k | "Cannot deserialize a lazy pointer without an AST source"); | 378 | 0 | Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1)); | 379 | 402k | } | 380 | 0 | return reinterpret_cast<T*>(Ptr); | 381 | 11.8M | } |
clang::LazyOffsetPtr<clang::Decl, unsigned int, &(clang::ExternalASTSource::GetExternalDecl(unsigned int))>::get(clang::ExternalASTSource*) const Line | Count | Source | 374 | 2.59M | T* get(ExternalASTSource *Source) const { | 375 | 2.59M | if (isOffset()) { | 376 | 39.0k | assert(Source && | 377 | 39.0k | "Cannot deserialize a lazy pointer without an AST source"); | 378 | 0 | Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1)); | 379 | 39.0k | } | 380 | 0 | return reinterpret_cast<T*>(Ptr); | 381 | 2.59M | } |
clang::LazyOffsetPtr<clang::CXXCtorInitializer*, unsigned long long, &(clang::ExternalASTSource::GetExternalCXXCtorInitializers(unsigned long long))>::get(clang::ExternalASTSource*) const Line | Count | Source | 374 | 682k | T* get(ExternalASTSource *Source) const { | 375 | 682k | if (isOffset()) { | 376 | 56.8k | assert(Source && | 377 | 56.8k | "Cannot deserialize a lazy pointer without an AST source"); | 378 | 0 | Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1)); | 379 | 56.8k | } | 380 | 0 | return reinterpret_cast<T*>(Ptr); | 381 | 682k | } |
|
382 | | }; |
383 | | |
384 | | /// A lazy value (of type T) that is within an AST node of type Owner, |
385 | | /// where the value might change in later generations of the external AST |
386 | | /// source. |
387 | | template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)> |
388 | | struct LazyGenerationalUpdatePtr { |
389 | | /// A cache of the value of this pointer, in the most recent generation in |
390 | | /// which we queried it. |
391 | | struct LazyData { |
392 | | ExternalASTSource *ExternalSource; |
393 | | uint32_t LastGeneration = 0; |
394 | | T LastValue; |
395 | | |
396 | | LazyData(ExternalASTSource *Source, T Value) |
397 | 11.9M | : ExternalSource(Source), LastValue(Value) {} |
398 | | }; |
399 | | |
400 | | // Our value is represented as simply T if there is no external AST source. |
401 | | using ValueType = llvm::PointerUnion<T, LazyData*>; |
402 | | ValueType Value; |
403 | | |
404 | 831M | LazyGenerationalUpdatePtr(ValueType V) : Value(V) {} |
405 | | |
406 | | // Defined in ASTContext.h |
407 | | static ValueType makeValue(const ASTContext &Ctx, T Value); |
408 | | |
409 | | public: |
410 | | explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T()) |
411 | 114M | : Value(makeValue(Ctx, Value)) {} |
412 | | |
413 | | /// Create a pointer that is not potentially updated by later generations of |
414 | | /// the external AST source. |
415 | | enum NotUpdatedTag { NotUpdated }; |
416 | | LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T()) |
417 | | : Value(Value) {} |
418 | | |
419 | | /// Forcibly set this pointer (which must be lazy) as needing updates. |
420 | 709k | void markIncomplete() { |
421 | 709k | Value.template get<LazyData *>()->LastGeneration = 0; |
422 | 709k | } |
423 | | |
424 | | /// Set the value of this pointer, in the current generation. |
425 | 2.99M | void set(T NewValue) { |
426 | 2.99M | if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) { |
427 | 1.88M | LazyVal->LastValue = NewValue; |
428 | 1.88M | return; |
429 | 1.88M | } |
430 | 1.10M | Value = NewValue; |
431 | 1.10M | } |
432 | | |
433 | | /// Set the value of this pointer, for this and all future generations. |
434 | | void setNotUpdated(T NewValue) { Value = NewValue; } |
435 | | |
436 | | /// Get the value of this pointer, updating its owner if necessary. |
437 | 827M | T get(Owner O) { |
438 | 827M | if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) { |
439 | 155M | if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) { |
440 | 5.86M | LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration(); |
441 | 5.86M | (LazyVal->ExternalSource->*Update)(O); |
442 | 5.86M | } |
443 | 155M | return LazyVal->LastValue; |
444 | 155M | } |
445 | 671M | return Value.template get<T>(); |
446 | 827M | } |
447 | | |
448 | | /// Get the most recently computed value of this pointer without updating it. |
449 | 571k | T getNotUpdated() const { |
450 | 571k | if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) |
451 | 571k | return LazyVal->LastValue; |
452 | 0 | return Value.template get<T>(); |
453 | 571k | } |
454 | | |
455 | 117M | void *getOpaqueValue() { return Value.getOpaqueValue(); } |
456 | 831M | static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) { |
457 | 831M | return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr)); |
458 | 831M | } |
459 | | }; |
460 | | |
461 | | } // namespace clang |
462 | | |
463 | | namespace llvm { |
464 | | |
465 | | /// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be |
466 | | /// placed into a PointerUnion. |
467 | | template<typename Owner, typename T, |
468 | | void (clang::ExternalASTSource::*Update)(Owner)> |
469 | | struct PointerLikeTypeTraits< |
470 | | clang::LazyGenerationalUpdatePtr<Owner, T, Update>> { |
471 | | using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>; |
472 | | |
473 | 117M | static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } |
474 | 831M | static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } |
475 | | |
476 | | static constexpr int NumLowBitsAvailable = |
477 | | PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1; |
478 | | }; |
479 | | |
480 | | } // namespace llvm |
481 | | |
482 | | namespace clang { |
483 | | |
484 | | /// Represents a lazily-loaded vector of data. |
485 | | /// |
486 | | /// The lazily-loaded vector of data contains data that is partially loaded |
487 | | /// from an external source and partially added by local translation. The |
488 | | /// items loaded from the external source are loaded lazily, when needed for |
489 | | /// iteration over the complete vector. |
490 | | template<typename T, typename Source, |
491 | | void (Source::*Loader)(SmallVectorImpl<T>&), |
492 | | unsigned LoadedStorage = 2, unsigned LocalStorage = 4> |
493 | | class LazyVector { |
494 | | SmallVector<T, LoadedStorage> Loaded; |
495 | | SmallVector<T, LocalStorage> Local; |
496 | | |
497 | | public: |
498 | | /// Iteration over the elements in the vector. |
499 | | /// |
500 | | /// In a complete iteration, the iterator walks the range [-M, N), |
501 | | /// where negative values are used to indicate elements |
502 | | /// loaded from the external source while non-negative values are used to |
503 | | /// indicate elements added via \c push_back(). |
504 | | /// However, to provide iteration in source order (for, e.g., chained |
505 | | /// precompiled headers), dereferencing the iterator flips the negative |
506 | | /// values (corresponding to loaded entities), so that position -M |
507 | | /// corresponds to element 0 in the loaded entities vector, position -M+1 |
508 | | /// corresponds to element 1 in the loaded entities vector, etc. This |
509 | | /// gives us a reasonably efficient, source-order walk. |
510 | | /// |
511 | | /// We define this as a wrapping iterator around an int. The |
512 | | /// iterator_adaptor_base class forwards the iterator methods to basic integer |
513 | | /// arithmetic. |
514 | | class iterator |
515 | | : public llvm::iterator_adaptor_base< |
516 | | iterator, int, std::random_access_iterator_tag, T, int, T *, T &> { |
517 | | friend class LazyVector; |
518 | | |
519 | | LazyVector *Self; |
520 | | |
521 | | iterator(LazyVector *Self, int Position) |
522 | 711k | : iterator::iterator_adaptor_base(Position), Self(Self) {} clang::LazyVector<clang::CXXConstructorDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl*>&)), 2u, 2u>::iterator::iterator(clang::LazyVector<clang::CXXConstructorDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl*>&)), 2u, 2u>*, int) Line | Count | Source | 522 | 120k | : iterator::iterator_adaptor_base(Position), Self(Self) {} |
clang::LazyVector<clang::TypedefNameDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl*>&)), 2u, 2u>::iterator::iterator(clang::LazyVector<clang::TypedefNameDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl*>&)), 2u, 2u>*, int) Line | Count | Source | 522 | 11.5k | : iterator::iterator_adaptor_base(Position), Self(Self) {} |
clang::LazyVector<clang::DeclaratorDecl const*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<clang::DeclaratorDecl const*>&)), 2u, 2u>::iterator::iterator(clang::LazyVector<clang::DeclaratorDecl const*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<clang::DeclaratorDecl const*>&)), 2u, 2u>*, int) Line | Count | Source | 522 | 404k | : iterator::iterator_adaptor_base(Position), Self(Self) {} |
clang::LazyVector<clang::VarDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl*>&)), 2u, 2u>::iterator::iterator(clang::LazyVector<clang::VarDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl*>&)), 2u, 2u>*, int) Line | Count | Source | 522 | 174k | : iterator::iterator_adaptor_base(Position), Self(Self) {} |
|
523 | | |
524 | 425k | bool isLoaded() const { return this->I < 0; } clang::LazyVector<clang::CXXConstructorDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl*>&)), 2u, 2u>::iterator::isLoaded() const Line | Count | Source | 524 | 546 | bool isLoaded() const { return this->I < 0; } |
clang::LazyVector<clang::TypedefNameDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl*>&)), 2u, 2u>::iterator::isLoaded() const Line | Count | Source | 524 | 748 | bool isLoaded() const { return this->I < 0; } |
clang::LazyVector<clang::DeclaratorDecl const*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<clang::DeclaratorDecl const*>&)), 2u, 2u>::iterator::isLoaded() const Line | Count | Source | 524 | 412k | bool isLoaded() const { return this->I < 0; } |
clang::LazyVector<clang::VarDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl*>&)), 2u, 2u>::iterator::isLoaded() const Line | Count | Source | 524 | 11.4k | bool isLoaded() const { return this->I < 0; } |
|
525 | | |
526 | | public: |
527 | | iterator() : iterator(nullptr, 0) {} |
528 | | |
529 | 254k | typename iterator::reference operator*() const { |
530 | 254k | if (isLoaded()) |
531 | 1.64k | return Self->Loaded.end()[this->I]; |
532 | 253k | return Self->Local.begin()[this->I]; |
533 | 254k | } clang::LazyVector<clang::CXXConstructorDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl*>&)), 2u, 2u>::iterator::operator*() const Line | Count | Source | 529 | 546 | typename iterator::reference operator*() const { | 530 | 546 | if (isLoaded()) | 531 | 3 | return Self->Loaded.end()[this->I]; | 532 | 543 | return Self->Local.begin()[this->I]; | 533 | 546 | } |
clang::LazyVector<clang::TypedefNameDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl*>&)), 2u, 2u>::iterator::operator*() const Line | Count | Source | 529 | 748 | typename iterator::reference operator*() const { | 530 | 748 | if (isLoaded()) | 531 | 4 | return Self->Loaded.end()[this->I]; | 532 | 744 | return Self->Local.begin()[this->I]; | 533 | 748 | } |
clang::LazyVector<clang::VarDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl*>&)), 2u, 2u>::iterator::operator*() const Line | Count | Source | 529 | 11.4k | typename iterator::reference operator*() const { | 530 | 11.4k | if (isLoaded()) | 531 | 1.24k | return Self->Loaded.end()[this->I]; | 532 | 10.2k | return Self->Local.begin()[this->I]; | 533 | 11.4k | } |
clang::LazyVector<clang::DeclaratorDecl const*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<clang::DeclaratorDecl const*>&)), 2u, 2u>::iterator::operator*() const Line | Count | Source | 529 | 241k | typename iterator::reference operator*() const { | 530 | 241k | if (isLoaded()) | 531 | 392 | return Self->Loaded.end()[this->I]; | 532 | 241k | return Self->Local.begin()[this->I]; | 533 | 241k | } |
|
534 | | }; |
535 | | |
536 | 313k | iterator begin(Source *source, bool LocalOnly = false) { |
537 | 313k | if (LocalOnly) |
538 | 103k | return iterator(this, 0); |
539 | | |
540 | 209k | if (source) |
541 | 31.1k | (source->*Loader)(Loaded); |
542 | 209k | return iterator(this, -(int)Loaded.size()); |
543 | 313k | } clang::LazyVector<clang::CXXConstructorDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl*>&)), 2u, 2u>::begin(clang::ExternalSemaSource*, bool) Line | Count | Source | 536 | 60.2k | iterator begin(Source *source, bool LocalOnly = false) { | 537 | 60.2k | if (LocalOnly) | 538 | 3.47k | return iterator(this, 0); | 539 | | | 540 | 56.7k | if (source) | 541 | 9.83k | (source->*Loader)(Loaded); | 542 | 56.7k | return iterator(this, -(int)Loaded.size()); | 543 | 60.2k | } |
clang::LazyVector<clang::TypedefNameDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl*>&)), 2u, 2u>::begin(clang::ExternalSemaSource*, bool) Line | Count | Source | 536 | 5.77k | iterator begin(Source *source, bool LocalOnly = false) { | 537 | 5.77k | if (LocalOnly) | 538 | 5.62k | return iterator(this, 0); | 539 | | | 540 | 151 | if (source) | 541 | 2 | (source->*Loader)(Loaded); | 542 | 151 | return iterator(this, -(int)Loaded.size()); | 543 | 5.77k | } |
clang::LazyVector<clang::DeclaratorDecl const*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<clang::DeclaratorDecl const*>&)), 2u, 2u>::begin(clang::ExternalSemaSource*, bool) Line | Count | Source | 536 | 159k | iterator begin(Source *source, bool LocalOnly = false) { | 537 | 159k | if (LocalOnly) | 538 | 88.8k | return iterator(this, 0); | 539 | | | 540 | 70.7k | if (source) | 541 | 9.12k | (source->*Loader)(Loaded); | 542 | 70.7k | return iterator(this, -(int)Loaded.size()); | 543 | 159k | } |
clang::LazyVector<clang::VarDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl*>&)), 2u, 2u>::begin(clang::ExternalSemaSource*, bool) Line | Count | Source | 536 | 87.4k | iterator begin(Source *source, bool LocalOnly = false) { | 537 | 87.4k | if (LocalOnly) | 538 | 5.62k | return iterator(this, 0); | 539 | | | 540 | 81.8k | if (source) | 541 | 12.1k | (source->*Loader)(Loaded); | 542 | 81.8k | return iterator(this, -(int)Loaded.size()); | 543 | 87.4k | } |
|
544 | | |
545 | 398k | iterator end() { |
546 | 398k | return iterator(this, Local.size()); |
547 | 398k | } clang::LazyVector<clang::CXXConstructorDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl*>&)), 2u, 2u>::end() Line | Count | Source | 545 | 60.2k | iterator end() { | 546 | 60.2k | return iterator(this, Local.size()); | 547 | 60.2k | } |
clang::LazyVector<clang::TypedefNameDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl*>&)), 2u, 2u>::end() Line | Count | Source | 545 | 5.77k | iterator end() { | 546 | 5.77k | return iterator(this, Local.size()); | 547 | 5.77k | } |
clang::LazyVector<clang::DeclaratorDecl const*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<clang::DeclaratorDecl const*>&)), 2u, 2u>::end() Line | Count | Source | 545 | 244k | iterator end() { | 546 | 244k | return iterator(this, Local.size()); | 547 | 244k | } |
clang::LazyVector<clang::VarDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl*>&)), 2u, 2u>::end() Line | Count | Source | 545 | 87.4k | iterator end() { | 546 | 87.4k | return iterator(this, Local.size()); | 547 | 87.4k | } |
|
548 | | |
549 | 40.0k | void push_back(const T& LocalValue) { |
550 | 40.0k | Local.push_back(LocalValue); |
551 | 40.0k | } clang::LazyVector<clang::DeclaratorDecl const*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadUnusedFileScopedDecls(llvm::SmallVectorImpl<clang::DeclaratorDecl const*>&)), 2u, 2u>::push_back(clang::DeclaratorDecl const* const&) Line | Count | Source | 549 | 24.8k | void push_back(const T& LocalValue) { | 550 | 24.8k | Local.push_back(LocalValue); | 551 | 24.8k | } |
clang::LazyVector<clang::VarDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadTentativeDefinitions(llvm::SmallVectorImpl<clang::VarDecl*>&)), 2u, 2u>::push_back(clang::VarDecl* const&) Line | Count | Source | 549 | 9.90k | void push_back(const T& LocalValue) { | 550 | 9.90k | Local.push_back(LocalValue); | 551 | 9.90k | } |
clang::LazyVector<clang::TypedefNameDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadExtVectorDecls(llvm::SmallVectorImpl<clang::TypedefNameDecl*>&)), 2u, 2u>::push_back(clang::TypedefNameDecl* const&) Line | Count | Source | 549 | 4.70k | void push_back(const T& LocalValue) { | 550 | 4.70k | Local.push_back(LocalValue); | 551 | 4.70k | } |
clang::LazyVector<clang::CXXConstructorDecl*, clang::ExternalSemaSource, &(clang::ExternalSemaSource::ReadDelegatingConstructors(llvm::SmallVectorImpl<clang::CXXConstructorDecl*>&)), 2u, 2u>::push_back(clang::CXXConstructorDecl* const&) Line | Count | Source | 549 | 543 | void push_back(const T& LocalValue) { | 550 | 543 | Local.push_back(LocalValue); | 551 | 543 | } |
|
552 | | |
553 | 85.3k | void erase(iterator From, iterator To) { |
554 | 85.3k | if (From.isLoaded() && To.isLoaded()0 ) { |
555 | 0 | Loaded.erase(&*From, &*To); |
556 | 0 | return; |
557 | 0 | } |
558 | | |
559 | 85.3k | if (From.isLoaded()) { |
560 | 0 | Loaded.erase(&*From, Loaded.end()); |
561 | 0 | From = begin(nullptr, true); |
562 | 0 | } |
563 | | |
564 | 85.3k | Local.erase(&*From, &*To); |
565 | 85.3k | } |
566 | | }; |
567 | | |
568 | | /// A lazy pointer to a statement. |
569 | | using LazyDeclStmtPtr = |
570 | | LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>; |
571 | | |
572 | | /// A lazy pointer to a declaration. |
573 | | using LazyDeclPtr = |
574 | | LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>; |
575 | | |
576 | | /// A lazy pointer to a set of CXXCtorInitializers. |
577 | | using LazyCXXCtorInitializersPtr = |
578 | | LazyOffsetPtr<CXXCtorInitializer *, uint64_t, |
579 | | &ExternalASTSource::GetExternalCXXCtorInitializers>; |
580 | | |
581 | | /// A lazy pointer to a set of CXXBaseSpecifiers. |
582 | | using LazyCXXBaseSpecifiersPtr = |
583 | | LazyOffsetPtr<CXXBaseSpecifier, uint64_t, |
584 | | &ExternalASTSource::GetExternalCXXBaseSpecifiers>; |
585 | | |
586 | | } // namespace clang |
587 | | |
588 | | #endif // LLVM_CLANG_AST_EXTERNALASTSOURCE_H |