Coverage Report

Created: 2019-07-24 05:18

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