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