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 22namespace clang { 23 24class ASTConsumer; 25class CXXBaseSpecifier; 26class CXXCtorInitializer; 27class DeclarationName; 28class ExternalSemaSource; // layering violation required for downcasting 29class FieldDecl; 30class Module; 31class NamedDecl; 32class RecordDecl; 33class Selector; 34class Stmt; 35class 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. 44class 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 55public: 56 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 explicit Deserializing(ExternalASTSource *source) : Source(source) { 66 assert(Source); 67 Source->StartedDeserializing(); 68 } 69 ~Deserializing() { 70 Source->FinishedDeserializing(); 71 } 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 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 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 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 ASTSourceDescriptor(){}; 158 ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, 159 ASTFileSignature Signature) 160 : PCHModuleName(std::move(Name)), Path(std::move(Path)), 161 ASTFile(std::move(ASTFile)), Signature(Signature){}; 162 ASTSourceDescriptor(const Module &M); 163 std::string getModuleName() const; 164 StringRef getPath() const { return Path; } 165 StringRef getASTFile() const { return ASTFile; } 166 ASTFileSignature getSignature() const { return Signature; } 167 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 SmallVectorImpl<Decl *> &Result) { 193 FindExternalLexicalDecls(DC, [](Decl::Kind) { return true; }, Result); 194 } 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 : 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 MemoryBufferSizes getMemoryBufferSizes() const { 298 MemoryBufferSizes sizes(0, 0); 299 getMemoryBufferSizes(sizes); 300 return sizes; 301 } 302 303 virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const; 304 305protected: 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. 325template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)> 326struct 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 334public: 335 LazyOffsetPtr() : Ptr(0) { } 336 337 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 LazyOffsetPtr &operator=(T *Ptr) { 345 this->Ptr = reinterpret_cast<uint64_t>(Ptr); 346 return *this; 347 } 348 349 LazyOffsetPtr &operator=(uint64_t Offset) { 350 assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); 351 if (Offset == 0) 352 Ptr = 0; 353 else 354 Ptr = (Offset << 1) | 0x01; 355 356 return *this; 357 } 358 359 /// \brief Whether this pointer is non-NULL. 360 /// 361 /// This operation does not require the AST node to be deserialized. 362 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 bool isValid() const { return Ptr != 0; } 368 369 /// \brief Whether this pointer is currently stored as an offset. 370 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 T* get(ExternalASTSource *Source) const { 378 if (isOffset()) { 379 assert(Source && 380 "Cannot deserialize a lazy pointer without an AST source"); 381 Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1)); 382 } 383 return reinterpret_cast<T*>(Ptr); 384 } 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. 390template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)> 391struct 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 : 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 LazyGenerationalUpdatePtr(ValueType V) : Value(V) {} 407 408 // Defined in ASTContext.h 409 static ValueType makeValue(const ASTContext &Ctx, T Value); 410 411public: 412 explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T()) 413 : 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 void markIncomplete() { 423 Value.template get<LazyData *>()->LastGeneration = 0; 424 } 425 426 /// Set the value of this pointer, in the current generation. 427 void set(T NewValue) { 428 if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) { 429 LazyVal->LastValue = NewValue; 430 return; 431 } 432 Value = NewValue; 433 } 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 T get(Owner O) { 440 if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) { 441 if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) { 442 LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration(); 443 (LazyVal->ExternalSource->*Update)(O); 444 } 445 return LazyVal->LastValue; 446 } 447 return Value.template get<T>(); 448 } 449 450 /// Get the most recently computed value of this pointer without updating it. 451 T getNotUpdated() const { 452 if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) 453 return LazyVal->LastValue; 454 return Value.template get<T>(); 455 } 456 457 void *getOpaqueValue() { return Value.getOpaqueValue(); } 458 static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) { 459 return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr)); 460 } 461}; 462} // end namespace clang 463 464/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be 465/// placed into a PointerUnion. 466namespace llvm { 467template<typename Owner, typename T, 468 void (clang::ExternalASTSource::*Update)(Owner)> 469struct PointerLikeTypeTraits< 470 clang::LazyGenerationalUpdatePtr<Owner, T, Update>> { 471 typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr; 472 static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } 473 static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } 474 enum { 475 NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1 476 }; 477}; 478} 479 480namespace 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. 487template<typename T, typename Source, 488 void (Source::*Loader)(SmallVectorImpl<T>&), 489 unsigned LoadedStorage = 2, unsigned LocalStorage = 4> 490class LazyVector { 491 SmallVector<T, LoadedStorage> Loaded; 492 SmallVector<T, LocalStorage> Local; 493 494public: 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 : iterator::iterator_adaptor_base(Position), Self(Self) {} 518 519 bool isLoaded() const { return this->I < 0; } 520 friend class LazyVector; 521 522 public: 523 iterator() : iterator(nullptr, 0) {} 524 525 typename iterator::reference operator*() const { 526 if (isLoaded()) 527 return Self->Loaded.end()[this->I]; 528 return Self->Local.begin()[this->I]; 529 } 530 }; 531 532 iterator begin(Source *source, bool LocalOnly = false) { 533 if (LocalOnly) 534 return iterator(this, 0); 535 536 if (source) 537 (source->*Loader)(Loaded); 538 return iterator(this, -(int)Loaded.size()); 539 } 540 541 iterator end() { 542 return iterator(this, Local.size()); 543 } 544 545 void push_back(const T& LocalValue) { 546 Local.push_back(LocalValue); 547 } 548 549 void erase(iterator From, iterator To) { 550 if (From.isLoaded() && To.isLoaded()) { 551 Loaded.erase(&*From, &*To); 552 return; 553 } 554 555 if (From.isLoaded()) { 556 Loaded.erase(&*From, Loaded.end()); 557 From = begin(nullptr, true); 558 } 559 560 Local.erase(&*From, &*To); 561 } 562}; 563 564/// \brief A lazy pointer to a statement. 565typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt> 566 LazyDeclStmtPtr; 567 568/// \brief A lazy pointer to a declaration. 569typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl> 570 LazyDeclPtr; 571 572/// \brief A lazy pointer to a set of CXXCtorInitializers. 573typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t, 574 &ExternalASTSource::GetExternalCXXCtorInitializers> 575 LazyCXXCtorInitializersPtr; 576 577/// \brief A lazy pointer to a set of CXXBaseSpecifiers. 578typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, 579 &ExternalASTSource::GetExternalCXXBaseSpecifiers> 580 LazyCXXBaseSpecifiersPtr; 581 582} // end namespace clang 583 584#endif 585