]> granicus.if.org Git - clang/blob - include/clang/AST/ExternalASTSource.h
remove some now-redundant forward declarations.
[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_EXTERNAL_AST_SOURCE_H
15 #define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
16
17 #include "clang/AST/DeclBase.h"
18
19 namespace clang {
20
21 class ASTConsumer;
22 class CXXBaseSpecifier;
23 class DeclarationName;
24 class ExternalSemaSource; // layering violation required for downcasting
25 class NamedDecl;
26 class Selector;
27 class Stmt;
28 class TagDecl;
29
30 /// \brief Enumeration describing the result of loading information from
31 /// an external source.
32 enum ExternalLoadResult {
33   /// \brief Loading the external information has succeeded.
34   ELR_Success,
35   
36   /// \brief Loading the external information has failed.
37   ELR_Failure,
38   
39   /// \brief The external information has already been loaded, and therefore
40   /// no additional processing is required.
41   ELR_AlreadyLoaded
42 };
43   
44 /// \brief Abstract interface for external sources of AST nodes.
45 ///
46 /// External AST sources provide AST nodes constructed from some
47 /// external source, such as a precompiled header. External AST
48 /// sources can resolve types and declarations from abstract IDs into
49 /// actual type and declaration nodes, and read parts of declaration
50 /// contexts.
51 class ExternalASTSource {
52   /// \brief Whether this AST source also provides information for
53   /// semantic analysis.
54   bool SemaSource;
55
56   friend class ExternalSemaSource;
57
58 public:
59   ExternalASTSource() : SemaSource(false) { }
60
61   virtual ~ExternalASTSource();
62
63   /// \brief RAII class for safely pairing a StartedDeserializing call
64   /// with FinishedDeserializing.
65   class Deserializing {
66     ExternalASTSource *Source;
67   public:
68     explicit Deserializing(ExternalASTSource *source) : Source(source) {
69       assert(Source);
70       Source->StartedDeserializing();
71     }
72     ~Deserializing() {
73       Source->FinishedDeserializing();
74     }
75   };
76
77   /// \brief Resolve a declaration ID into a declaration, potentially
78   /// building a new declaration.
79   ///
80   /// This method only needs to be implemented if the AST source ever
81   /// passes back decl sets as VisibleDeclaration objects.
82   ///
83   /// The default implementation of this method is a no-op.
84   virtual Decl *GetExternalDecl(uint32_t ID);
85
86   /// \brief Resolve a selector ID into a selector.
87   ///
88   /// This operation only needs to be implemented if the AST source
89   /// returns non-zero for GetNumKnownSelectors().
90   ///
91   /// The default implementation of this method is a no-op.
92   virtual Selector GetExternalSelector(uint32_t ID);
93
94   /// \brief Returns the number of selectors known to the external AST
95   /// source.
96   ///
97   /// The default implementation of this method is a no-op.
98   virtual uint32_t GetNumExternalSelectors();
99
100   /// \brief Resolve the offset of a statement in the decl stream into
101   /// a statement.
102   ///
103   /// This operation is meant to be used via a LazyOffsetPtr.  It only
104   /// needs to be implemented if the AST source uses methods like
105   /// FunctionDecl::setLazyBody when building decls.
106   ///
107   /// The default implementation of this method is a no-op.
108   virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
109
110   /// \brief Resolve the offset of a set of C++ base specifiers in the decl
111   /// stream into an array of specifiers.
112   ///
113   /// The default implementation of this method is a no-op.
114   virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
115
116   /// \brief Finds all declarations with the given name in the
117   /// given context.
118   ///
119   /// Generally the final step of this method is either to call
120   /// SetExternalVisibleDeclsForName or to recursively call lookup on
121   /// the DeclContext after calling SetExternalVisibleDecls.
122   ///
123   /// The default implementation of this method is a no-op.
124   virtual DeclContextLookupResult
125   FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
126
127   /// \brief Deserialize all the visible declarations from external storage.
128   ///
129   /// Name lookup deserializes visible declarations lazily, thus a DeclContext
130   /// may not have a complete name lookup table. This function deserializes
131   /// the rest of visible declarations from the external storage and completes
132   /// the name lookup table of the DeclContext.
133   ///
134   /// The default implementation of this method is a no-op.
135   virtual void MaterializeVisibleDecls(const DeclContext *DC);
136
137   /// \brief Finds all declarations lexically contained within the given
138   /// DeclContext, after applying an optional filter predicate.
139   ///
140   /// \param isKindWeWant a predicate function that returns true if the passed
141   /// declaration kind is one we are looking for. If NULL, all declarations
142   /// are returned.
143   ///
144   /// \return an indication of whether the load succeeded or failed.
145   ///
146   /// The default implementation of this method is a no-op.
147   virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
148                                         bool (*isKindWeWant)(Decl::Kind),
149                                         SmallVectorImpl<Decl*> &Result);
150
151   /// \brief Finds all declarations lexically contained within the given
152   /// DeclContext.
153   ///
154   /// \return true if an error occurred
155   ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
156                                 SmallVectorImpl<Decl*> &Result) {
157     return FindExternalLexicalDecls(DC, 0, Result);
158   }
159
160   template <typename DeclTy>
161   ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC,
162                                   SmallVectorImpl<Decl*> &Result) {
163     return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
164   }
165
166   /// \brief Gives the external AST source an opportunity to complete
167   /// an incomplete type.
168   virtual void CompleteType(TagDecl *Tag) {}
169
170   /// \brief Gives the external AST source an opportunity to complete an
171   /// incomplete Objective-C class.
172   ///
173   /// This routine will only be invoked if the "externally completed" bit is
174   /// set on the ObjCInterfaceDecl via the function 
175   /// \c ObjCInterfaceDecl::setExternallyCompleted().
176   virtual void CompleteType(ObjCInterfaceDecl *Class) { }
177
178   /// \brief Notify ExternalASTSource that we started deserialization of
179   /// a decl or type so until FinishedDeserializing is called there may be
180   /// decls that are initializing. Must be paired with FinishedDeserializing.
181   ///
182   /// The default implementation of this method is a no-op.
183   virtual void StartedDeserializing() { }
184
185   /// \brief Notify ExternalASTSource that we finished the deserialization of
186   /// a decl or type. Must be paired with StartedDeserializing.
187   ///
188   /// The default implementation of this method is a no-op.
189   virtual void FinishedDeserializing() { }
190
191   /// \brief Function that will be invoked when we begin parsing a new
192   /// translation unit involving this external AST source.
193   ///
194   /// The default implementation of this method is a no-op.
195   virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
196
197   /// \brief Print any statistics that have been gathered regarding
198   /// the external AST source.
199   ///
200   /// The default implementation of this method is a no-op.
201   virtual void PrintStats();
202   
203   //===--------------------------------------------------------------------===//
204   // Queries for performance analysis.
205   //===--------------------------------------------------------------------===//
206   
207   struct MemoryBufferSizes {
208     size_t malloc_bytes;
209     size_t mmap_bytes;
210     
211     MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
212     : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
213   };
214   
215   /// Return the amount of memory used by memory buffers, breaking down
216   /// by heap-backed versus mmap'ed memory.
217   MemoryBufferSizes getMemoryBufferSizes() const {
218     MemoryBufferSizes sizes(0, 0);
219     getMemoryBufferSizes(sizes);
220     return sizes;
221   }
222
223   virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
224
225 protected:
226   static DeclContextLookupResult
227   SetExternalVisibleDeclsForName(const DeclContext *DC,
228                                  DeclarationName Name,
229                                  SmallVectorImpl<NamedDecl*> &Decls);
230
231   static DeclContextLookupResult
232   SetNoExternalVisibleDeclsForName(const DeclContext *DC,
233                                    DeclarationName Name);
234
235   void MaterializeVisibleDeclsForName(const DeclContext *DC,
236                                       DeclarationName Name,
237                                  SmallVectorImpl<NamedDecl*> &Decls);
238 };
239
240 /// \brief A lazy pointer to an AST node (of base type T) that resides
241 /// within an external AST source.
242 ///
243 /// The AST node is identified within the external AST source by a
244 /// 63-bit offset, and can be retrieved via an operation on the
245 /// external AST source itself.
246 template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
247 struct LazyOffsetPtr {
248   /// \brief Either a pointer to an AST node or the offset within the
249   /// external AST source where the AST node can be found.
250   ///
251   /// If the low bit is clear, a pointer to the AST node. If the low
252   /// bit is set, the upper 63 bits are the offset.
253   mutable uint64_t Ptr;
254
255 public:
256   LazyOffsetPtr() : Ptr(0) { }
257
258   explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
259   explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
260     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
261     if (Offset == 0)
262       Ptr = 0;
263   }
264
265   LazyOffsetPtr &operator=(T *Ptr) {
266     this->Ptr = reinterpret_cast<uint64_t>(Ptr);
267     return *this;
268   }
269
270   LazyOffsetPtr &operator=(uint64_t Offset) {
271     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
272     if (Offset == 0)
273       Ptr = 0;
274     else
275       Ptr = (Offset << 1) | 0x01;
276
277     return *this;
278   }
279
280   /// \brief Whether this pointer is non-NULL.
281   ///
282   /// This operation does not require the AST node to be deserialized.
283   operator bool() const { return Ptr != 0; }
284
285   /// \brief Whether this pointer is currently stored as an offset.
286   bool isOffset() const { return Ptr & 0x01; }
287
288   /// \brief Retrieve the pointer to the AST node that this lazy pointer
289   ///
290   /// \param Source the external AST source.
291   ///
292   /// \returns a pointer to the AST node.
293   T* get(ExternalASTSource *Source) const {
294     if (isOffset()) {
295       assert(Source &&
296              "Cannot deserialize a lazy pointer without an AST source");
297       Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
298     }
299     return reinterpret_cast<T*>(Ptr);
300   }
301 };
302
303 /// \brief A lazy pointer to a statement.
304 typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
305   LazyDeclStmtPtr;
306
307 /// \brief A lazy pointer to a declaration.
308 typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
309   LazyDeclPtr;
310
311 /// \brief A lazy pointer to a set of CXXBaseSpecifiers.
312 typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, 
313                       &ExternalASTSource::GetExternalCXXBaseSpecifiers>
314   LazyCXXBaseSpecifiersPtr;
315
316 } // end namespace clang
317
318 #endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H