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