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