1 //===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ExternalASTSource interface, which enables
11 // construction of AST nodes from some external source.x
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
15 #define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
17 #include "clang/AST/DeclBase.h"
22 template <class T> class SmallVectorImpl;
28 class CXXBaseSpecifier;
31 class DeclContextLookupResult;
32 class DeclarationName;
33 class ExternalSemaSource; // layering violation required for downcasting
39 /// \brief Abstract interface for external sources of AST nodes.
41 /// External AST sources provide AST nodes constructed from some
42 /// external source, such as a precompiled header. External AST
43 /// sources can resolve types and declarations from abstract IDs into
44 /// actual type and declaration nodes, and read parts of declaration
46 class ExternalASTSource {
47 /// \brief Whether this AST source also provides information for
48 /// semantic analysis.
51 friend class ExternalSemaSource;
54 ExternalASTSource() : SemaSource(false) { }
56 virtual ~ExternalASTSource();
58 /// \brief RAII class for safely pairing a StartedDeserializing call
59 /// with FinishedDeserializing.
61 ExternalASTSource *Source;
63 explicit Deserializing(ExternalASTSource *source) : Source(source) {
65 Source->StartedDeserializing();
68 Source->FinishedDeserializing();
72 /// \brief Resolve a declaration ID into a declaration, potentially
73 /// building a new declaration.
75 /// This method only needs to be implemented if the AST source ever
76 /// passes back decl sets as VisibleDeclaration objects.
77 virtual Decl *GetExternalDecl(uint32_t ID) = 0;
79 /// \brief Resolve a selector ID into a selector.
81 /// This operation only needs to be implemented if the AST source
82 /// returns non-zero for GetNumKnownSelectors().
83 virtual Selector GetExternalSelector(uint32_t ID) = 0;
85 /// \brief Returns the number of selectors known to the external AST
87 virtual uint32_t GetNumExternalSelectors() = 0;
89 /// \brief Resolve the offset of a statement in the decl stream into
92 /// This operation is meant to be used via a LazyOffsetPtr. It only
93 /// needs to be implemented if the AST source uses methods like
94 /// FunctionDecl::setLazyBody when building decls.
95 virtual Stmt *GetExternalDeclStmt(uint64_t Offset) = 0;
97 /// \brief Resolve the offset of a set of C++ base specifiers in the decl
98 /// stream into an array of specifiers.
99 virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) = 0;
101 /// \brief Finds all declarations with the given name in the
104 /// Generally the final step of this method is either to call
105 /// SetExternalVisibleDeclsForName or to recursively call lookup on
106 /// the DeclContext after calling SetExternalVisibleDecls.
107 virtual DeclContextLookupResult
108 FindExternalVisibleDeclsByName(const DeclContext *DC,
109 DeclarationName Name) = 0;
111 /// \brief Deserialize all the visible declarations from external storage.
113 /// Name lookup deserializes visible declarations lazily, thus a DeclContext
114 /// may not have a complete name lookup table. This function deserializes
115 /// the rest of visible declarations from the external storage and completes
116 /// the name lookup table of the DeclContext.
117 virtual void MaterializeVisibleDecls(const DeclContext *DC) = 0;
119 /// \brief Finds all declarations lexically contained within the given
120 /// DeclContext, after applying an optional filter predicate.
122 /// \param isKindWeWant a predicate function that returns true if the passed
123 /// declaration kind is one we are looking for. If NULL, all declarations
126 /// \return true if an error occurred
127 virtual bool FindExternalLexicalDecls(const DeclContext *DC,
128 bool (*isKindWeWant)(Decl::Kind),
129 llvm::SmallVectorImpl<Decl*> &Result) = 0;
131 /// \brief Finds all declarations lexically contained within the given
134 /// \return true if an error occurred
135 bool FindExternalLexicalDecls(const DeclContext *DC,
136 llvm::SmallVectorImpl<Decl*> &Result) {
137 return FindExternalLexicalDecls(DC, 0, Result);
140 template <typename DeclTy>
141 bool FindExternalLexicalDeclsBy(const DeclContext *DC,
142 llvm::SmallVectorImpl<Decl*> &Result) {
143 return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result);
146 /// \brief Gives the external AST source an opportunity to complete
147 /// an incomplete type.
148 virtual void CompleteType(TagDecl *Tag) {}
150 /// \brief Notify ExternalASTSource that we started deserialization of
151 /// a decl or type so until FinishedDeserializing is called there may be
152 /// decls that are initializing. Must be paired with FinishedDeserializing.
154 /// The default implementation of this method is a no-op.
155 virtual void StartedDeserializing() { }
157 /// \brief Notify ExternalASTSource that we finished the deserialization of
158 /// a decl or type. Must be paired with StartedDeserializing.
160 /// The default implementation of this method is a no-op.
161 virtual void FinishedDeserializing() { }
163 /// \brief Function that will be invoked when we begin parsing a new
164 /// translation unit involving this external AST source.
166 /// The default implementation of this method is a no-op.
167 virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
169 /// \brief Print any statistics that have been gathered regarding
170 /// the external AST source.
172 /// The default implementation of this method is a no-op.
173 virtual void PrintStats();
176 static DeclContextLookupResult
177 SetExternalVisibleDeclsForName(const DeclContext *DC,
178 DeclarationName Name,
179 llvm::SmallVectorImpl<NamedDecl*> &Decls);
181 static DeclContextLookupResult
182 SetNoExternalVisibleDeclsForName(const DeclContext *DC,
183 DeclarationName Name);
185 void MaterializeVisibleDeclsForName(const DeclContext *DC,
186 DeclarationName Name,
187 llvm::SmallVectorImpl<NamedDecl*> &Decls);
190 /// \brief A lazy pointer to an AST node (of base type T) that resides
191 /// within an external AST source.
193 /// The AST node is identified within the external AST source by a
194 /// 63-bit offset, and can be retrieved via an operation on the
195 /// external AST source itself.
196 template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
197 struct LazyOffsetPtr {
198 /// \brief Either a pointer to an AST node or the offset within the
199 /// external AST source where the AST node can be found.
201 /// If the low bit is clear, a pointer to the AST node. If the low
202 /// bit is set, the upper 63 bits are the offset.
203 mutable uint64_t Ptr;
206 LazyOffsetPtr() : Ptr(0) { }
208 explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
209 explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
210 assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
215 LazyOffsetPtr &operator=(T *Ptr) {
216 this->Ptr = reinterpret_cast<uint64_t>(Ptr);
220 LazyOffsetPtr &operator=(uint64_t Offset) {
221 assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
225 Ptr = (Offset << 1) | 0x01;
230 /// \brief Whether this pointer is non-NULL.
232 /// This operation does not require the AST node to be deserialized.
233 operator bool() const { return Ptr != 0; }
235 /// \brief Whether this pointer is currently stored as an offset.
236 bool isOffset() const { return Ptr & 0x01; }
238 /// \brief Retrieve the pointer to the AST node that this lazy pointer
240 /// \param Source the external AST source.
242 /// \returns a pointer to the AST node.
243 T* get(ExternalASTSource *Source) const {
246 "Cannot deserialize a lazy pointer without an AST source");
247 Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
249 return reinterpret_cast<T*>(Ptr);
253 /// \brief A lazy pointer to a statement.
254 typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
257 /// \brief A lazy pointer to a declaration.
258 typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
261 /// \brief A lazy pointer to a set of CXXBaseSpecifiers.
262 typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t,
263 &ExternalASTSource::GetExternalCXXBaseSpecifiers>
264 LazyCXXBaseSpecifiersPtr;
266 } // end namespace clang
268 #endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H