File indexing completed on 2026-05-10 08:36:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
0015 #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
0016
0017 #include "clang/AST/CharUnits.h"
0018 #include "clang/AST/DeclBase.h"
0019 #include "clang/Basic/LLVM.h"
0020 #include "llvm/ADT/ArrayRef.h"
0021 #include "llvm/ADT/DenseMap.h"
0022 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0023 #include "llvm/ADT/PointerUnion.h"
0024 #include "llvm/ADT/STLExtras.h"
0025 #include "llvm/ADT/SmallVector.h"
0026 #include "llvm/ADT/iterator.h"
0027 #include "llvm/Support/PointerLikeTypeTraits.h"
0028 #include <algorithm>
0029 #include <cassert>
0030 #include <cstddef>
0031 #include <cstdint>
0032 #include <iterator>
0033 #include <new>
0034 #include <optional>
0035 #include <utility>
0036
0037 namespace clang {
0038
0039 class ASTConsumer;
0040 class ASTContext;
0041 class ASTSourceDescriptor;
0042 class CXXBaseSpecifier;
0043 class CXXCtorInitializer;
0044 class CXXRecordDecl;
0045 class DeclarationName;
0046 class FieldDecl;
0047 class IdentifierInfo;
0048 class NamedDecl;
0049 class ObjCInterfaceDecl;
0050 class RecordDecl;
0051 class Selector;
0052 class Stmt;
0053 class TagDecl;
0054
0055
0056
0057
0058
0059
0060
0061
0062 class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
0063 friend class ExternalSemaSource;
0064
0065
0066
0067 uint32_t CurrentGeneration = 0;
0068
0069
0070 static char ID;
0071
0072 public:
0073 ExternalASTSource() = default;
0074 virtual ~ExternalASTSource();
0075
0076
0077
0078 class Deserializing {
0079 ExternalASTSource *Source;
0080
0081 public:
0082 explicit Deserializing(ExternalASTSource *source) : Source(source) {
0083 assert(Source);
0084 Source->StartedDeserializing();
0085 }
0086
0087 ~Deserializing() {
0088 Source->FinishedDeserializing();
0089 }
0090 };
0091
0092
0093
0094
0095 uint32_t getGeneration() const { return CurrentGeneration; }
0096
0097
0098
0099
0100
0101
0102
0103
0104 virtual Decl *GetExternalDecl(GlobalDeclID ID);
0105
0106
0107
0108
0109
0110
0111
0112 virtual Selector GetExternalSelector(uint32_t ID);
0113
0114
0115
0116
0117
0118 virtual uint32_t GetNumExternalSelectors();
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
0129
0130
0131
0132
0133
0134 virtual CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset);
0135
0136
0137
0138
0139
0140 virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
0141
0142
0143 virtual void updateOutOfDateIdentifier(const IdentifierInfo &II) {}
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC,
0160 DeclarationName Name,
0161 const DeclContext *OriginalDC);
0162
0163
0164
0165
0166
0167
0168 virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial);
0169
0170
0171
0172
0173
0174 virtual bool
0175 LoadExternalSpecializations(const Decl *D,
0176 ArrayRef<TemplateArgument> TemplateArgs);
0177
0178
0179
0180
0181
0182 virtual void completeVisibleDeclsMap(const DeclContext *DC);
0183
0184
0185 virtual Module *getModule(unsigned ID) { return nullptr; }
0186
0187
0188 virtual std::optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);
0189
0190 enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy };
0191
0192 virtual ExtKind hasExternalDefinitions(const Decl *D);
0193
0194
0195
0196
0197
0198
0199
0200
0201 virtual void
0202 FindExternalLexicalDecls(const DeclContext *DC,
0203 llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
0204 SmallVectorImpl<Decl *> &Result);
0205
0206
0207
0208 void FindExternalLexicalDecls(const DeclContext *DC,
0209 SmallVectorImpl<Decl *> &Result) {
0210 FindExternalLexicalDecls(DC, [](Decl::Kind) { return true; }, Result);
0211 }
0212
0213
0214
0215
0216 virtual void FindFileRegionDecls(FileID File, unsigned Offset,
0217 unsigned Length,
0218 SmallVectorImpl<Decl *> &Decls);
0219
0220
0221
0222
0223
0224 virtual void CompleteRedeclChain(const Decl *D);
0225
0226
0227
0228 virtual void CompleteType(TagDecl *Tag);
0229
0230
0231
0232
0233
0234
0235
0236 virtual void CompleteType(ObjCInterfaceDecl *Class);
0237
0238
0239 virtual void ReadComments();
0240
0241
0242
0243
0244
0245
0246 virtual void StartedDeserializing();
0247
0248
0249
0250
0251
0252 virtual void FinishedDeserializing();
0253
0254
0255
0256
0257
0258 virtual void StartTranslationUnit(ASTConsumer *Consumer);
0259
0260
0261
0262
0263
0264 virtual void PrintStats();
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293 virtual bool layoutRecordType(
0294 const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
0295 llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
0296 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
0297 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
0298
0299
0300
0301
0302
0303 struct MemoryBufferSizes {
0304 size_t malloc_bytes;
0305 size_t mmap_bytes;
0306
0307 MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
0308 : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
0309 };
0310
0311
0312
0313 MemoryBufferSizes getMemoryBufferSizes() const {
0314 MemoryBufferSizes sizes(0, 0);
0315 getMemoryBufferSizes(sizes);
0316 return sizes;
0317 }
0318
0319 virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
0320
0321
0322
0323 virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
0324 static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
0325
0326
0327 protected:
0328 static DeclContextLookupResult
0329 SetExternalVisibleDeclsForName(const DeclContext *DC,
0330 DeclarationName Name,
0331 ArrayRef<NamedDecl*> Decls);
0332
0333 static DeclContextLookupResult
0334 SetNoExternalVisibleDeclsForName(const DeclContext *DC,
0335 DeclarationName Name);
0336
0337
0338 uint32_t incrementGeneration(ASTContext &C);
0339 };
0340
0341
0342
0343
0344
0345
0346
0347 template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
0348 struct LazyOffsetPtr {
0349
0350
0351
0352
0353
0354 static constexpr size_t DataSize = std::max(sizeof(uint64_t), sizeof(T *));
0355 alignas(uint64_t) alignas(T *) mutable unsigned char Data[DataSize] = {};
0356
0357 unsigned char GetLSB() const {
0358 return Data[llvm::sys::IsBigEndianHost ? DataSize - 1 : 0];
0359 }
0360
0361 template <typename U> U &As(bool New) const {
0362 unsigned char *Obj =
0363 Data + (llvm::sys::IsBigEndianHost ? DataSize - sizeof(U) : 0);
0364 if (New)
0365 return *new (Obj) U;
0366 return *std::launder(reinterpret_cast<U *>(Obj));
0367 }
0368
0369 T *&GetPtr() const { return As<T *>(false); }
0370 uint64_t &GetU64() const { return As<uint64_t>(false); }
0371 void SetPtr(T *Ptr) const { As<T *>(true) = Ptr; }
0372 void SetU64(uint64_t U64) const { As<uint64_t>(true) = U64; }
0373
0374 public:
0375 LazyOffsetPtr() = default;
0376 explicit LazyOffsetPtr(T *Ptr) : Data() { SetPtr(Ptr); }
0377
0378 explicit LazyOffsetPtr(uint64_t Offset) : Data() {
0379 assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
0380 if (Offset == 0)
0381 SetPtr(nullptr);
0382 else
0383 SetU64((Offset << 1) | 0x01);
0384 }
0385
0386 LazyOffsetPtr &operator=(T *Ptr) {
0387 SetPtr(Ptr);
0388 return *this;
0389 }
0390
0391 LazyOffsetPtr &operator=(uint64_t Offset) {
0392 assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
0393 if (Offset == 0)
0394 SetPtr(nullptr);
0395 else
0396 SetU64((Offset << 1) | 0x01);
0397
0398 return *this;
0399 }
0400
0401
0402
0403
0404 explicit operator bool() const { return isOffset() || GetPtr() != nullptr; }
0405
0406
0407
0408
0409 bool isValid() const { return isOffset() || GetPtr() != nullptr; }
0410
0411
0412 bool isOffset() const { return GetLSB() & 0x01; }
0413
0414
0415
0416
0417
0418
0419 T *get(ExternalASTSource *Source) const {
0420 if (isOffset()) {
0421 assert(Source &&
0422 "Cannot deserialize a lazy pointer without an AST source");
0423 SetPtr((Source->*Get)(OffsT(GetU64() >> 1)));
0424 }
0425 return GetPtr();
0426 }
0427
0428
0429
0430 T **getAddressOfPointer(ExternalASTSource *Source) const {
0431
0432 (void)get(Source);
0433 return &GetPtr();
0434 }
0435 };
0436
0437
0438
0439
0440 template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
0441 struct LazyGenerationalUpdatePtr {
0442
0443
0444 struct LazyData {
0445 ExternalASTSource *ExternalSource;
0446 uint32_t LastGeneration = 0;
0447 T LastValue;
0448
0449 LazyData(ExternalASTSource *Source, T Value)
0450 : ExternalSource(Source), LastValue(Value) {}
0451 };
0452
0453
0454 using ValueType = llvm::PointerUnion<T, LazyData*>;
0455 ValueType Value;
0456
0457 LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
0458
0459
0460 static ValueType makeValue(const ASTContext &Ctx, T Value);
0461
0462 public:
0463 explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
0464 : Value(makeValue(Ctx, Value)) {}
0465
0466
0467
0468 enum NotUpdatedTag { NotUpdated };
0469 LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
0470 : Value(Value) {}
0471
0472
0473 void markIncomplete() { cast<LazyData *>(Value)->LastGeneration = 0; }
0474
0475
0476 void set(T NewValue) {
0477 if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) {
0478 LazyVal->LastValue = NewValue;
0479 return;
0480 }
0481 Value = NewValue;
0482 }
0483
0484
0485 void setNotUpdated(T NewValue) { Value = NewValue; }
0486
0487
0488 T get(Owner O) {
0489 if (auto *LazyVal = Value.template dyn_cast<LazyData *>()) {
0490 if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
0491 LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
0492 (LazyVal->ExternalSource->*Update)(O);
0493 }
0494 return LazyVal->LastValue;
0495 }
0496 return cast<T>(Value);
0497 }
0498
0499
0500 T getNotUpdated() const {
0501 if (auto *LazyVal = Value.template dyn_cast<LazyData *>())
0502 return LazyVal->LastValue;
0503 return cast<T>(Value);
0504 }
0505
0506 void *getOpaqueValue() { return Value.getOpaqueValue(); }
0507 static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
0508 return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
0509 }
0510 };
0511
0512 }
0513
0514 namespace llvm {
0515
0516
0517
0518 template<typename Owner, typename T,
0519 void (clang::ExternalASTSource::*Update)(Owner)>
0520 struct PointerLikeTypeTraits<
0521 clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
0522 using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>;
0523
0524 static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
0525 static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
0526
0527 static constexpr int NumLowBitsAvailable =
0528 PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1;
0529 };
0530
0531 }
0532
0533 namespace clang {
0534
0535
0536
0537
0538
0539
0540
0541 template<typename T, typename Source,
0542 void (Source::*Loader)(SmallVectorImpl<T>&),
0543 unsigned LoadedStorage = 2, unsigned LocalStorage = 4>
0544 class LazyVector {
0545 SmallVector<T, LoadedStorage> Loaded;
0546 SmallVector<T, LocalStorage> Local;
0547
0548 public:
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565 class iterator
0566 : public llvm::iterator_adaptor_base<
0567 iterator, int, std::random_access_iterator_tag, T, int, T *, T &> {
0568 friend class LazyVector;
0569
0570 LazyVector *Self;
0571
0572 iterator(LazyVector *Self, int Position)
0573 : iterator::iterator_adaptor_base(Position), Self(Self) {}
0574
0575 bool isLoaded() const { return this->I < 0; }
0576
0577 public:
0578 iterator() : iterator(nullptr, 0) {}
0579
0580 typename iterator::reference operator*() const {
0581 if (isLoaded())
0582 return Self->Loaded.end()[this->I];
0583 return Self->Local.begin()[this->I];
0584 }
0585 };
0586
0587 iterator begin(Source *source, bool LocalOnly = false) {
0588 if (LocalOnly)
0589 return iterator(this, 0);
0590
0591 if (source)
0592 (source->*Loader)(Loaded);
0593 return iterator(this, -(int)Loaded.size());
0594 }
0595
0596 iterator end() {
0597 return iterator(this, Local.size());
0598 }
0599
0600 void push_back(const T& LocalValue) {
0601 Local.push_back(LocalValue);
0602 }
0603
0604 void erase(iterator From, iterator To) {
0605 if (From.isLoaded() && To.isLoaded()) {
0606 Loaded.erase(&*From, &*To);
0607 return;
0608 }
0609
0610 if (From.isLoaded()) {
0611 Loaded.erase(&*From, Loaded.end());
0612 From = begin(nullptr, true);
0613 }
0614
0615 Local.erase(&*From, &*To);
0616 }
0617 };
0618
0619
0620 using LazyDeclStmtPtr =
0621 LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>;
0622
0623
0624 using LazyDeclPtr =
0625 LazyOffsetPtr<Decl, GlobalDeclID, &ExternalASTSource::GetExternalDecl>;
0626
0627
0628 using LazyCXXCtorInitializersPtr =
0629 LazyOffsetPtr<CXXCtorInitializer *, uint64_t,
0630 &ExternalASTSource::GetExternalCXXCtorInitializers>;
0631
0632
0633 using LazyCXXBaseSpecifiersPtr =
0634 LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
0635 &ExternalASTSource::GetExternalCXXBaseSpecifiers>;
0636
0637 }
0638
0639 #endif