Coverage Report

Created: 2017-10-03 07:32

/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