]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h
Merge ^/vendor/binutils/dist@214571 into contrib/binutils, which brings
[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.x
12 //
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
15 #define LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H
16
17 #include <cassert>
18 #include <vector>
19
20 namespace llvm {
21 template <class T> class SmallVectorImpl;
22 }
23
24 namespace clang {
25
26 class ASTConsumer;
27 class Decl;
28 class DeclContext;
29 class DeclContextLookupResult;
30 class DeclarationName;
31 class ExternalSemaSource; // layering violation required for downcasting
32 class NamedDecl;
33 class Selector;
34 class Stmt;
35
36 /// \brief Abstract interface for external sources of AST nodes.
37 ///
38 /// External AST sources provide AST nodes constructed from some
39 /// external source, such as a precompiled header. External AST
40 /// sources can resolve types and declarations from abstract IDs into
41 /// actual type and declaration nodes, and read parts of declaration
42 /// contexts.
43 class ExternalASTSource {
44   /// \brief Whether this AST source also provides information for
45   /// semantic analysis.
46   bool SemaSource;
47
48   friend class ExternalSemaSource;
49
50 public:
51   ExternalASTSource() : SemaSource(false) { }
52
53   virtual ~ExternalASTSource();
54
55   /// \brief RAII class for safely pairing a StartedDeserializing call
56   /// with FinishedDeserializing.
57   class Deserializing {
58     ExternalASTSource *Source;
59   public:
60     explicit Deserializing(ExternalASTSource *source) : Source(source) {
61       assert(Source);
62       Source->StartedDeserializing();
63     }
64     ~Deserializing() {
65       Source->FinishedDeserializing();
66     }
67   };
68
69   /// \brief Resolve a declaration ID into a declaration, potentially
70   /// building a new declaration.
71   ///
72   /// This method only needs to be implemented if the AST source ever
73   /// passes back decl sets as VisibleDeclaration objects.
74   virtual Decl *GetExternalDecl(uint32_t ID) = 0;
75
76   /// \brief Resolve a selector ID into a selector.
77   ///
78   /// This operation only needs to be implemented if the AST source
79   /// returns non-zero for GetNumKnownSelectors().
80   virtual Selector GetExternalSelector(uint32_t ID) = 0;
81
82   /// \brief Returns the number of selectors known to the external AST
83   /// source.
84   virtual uint32_t GetNumExternalSelectors() = 0;
85
86   /// \brief Resolve the offset of a statement in the decl stream into
87   /// a statement.
88   ///
89   /// This operation is meant to be used via a LazyOffsetPtr.  It only
90   /// needs to be implemented if the AST source uses methods like
91   /// FunctionDecl::setLazyBody when building decls.
92   virtual Stmt *GetExternalDeclStmt(uint64_t Offset) = 0;
93
94   /// \brief Finds all declarations with the given name in the
95   /// given context.
96   ///
97   /// Generally the final step of this method is either to call
98   /// SetExternalVisibleDeclsForName or to recursively call lookup on
99   /// the DeclContext after calling SetExternalVisibleDecls.
100   virtual DeclContextLookupResult
101   FindExternalVisibleDeclsByName(const DeclContext *DC,
102                                  DeclarationName Name) = 0;
103
104   /// \brief Deserialize all the visible declarations from external storage.
105   ///
106   /// Name lookup deserializes visible declarations lazily, thus a DeclContext
107   /// may not have a complete name lookup table. This function deserializes
108   /// the rest of visible declarations from the external storage and completes
109   /// the name lookup table of the DeclContext.
110   virtual void MaterializeVisibleDecls(const DeclContext *DC) = 0;
111
112   /// \brief Finds all declarations lexically contained within the given
113   /// DeclContext.
114   ///
115   /// \return true if an error occurred
116   virtual bool FindExternalLexicalDecls(const DeclContext *DC,
117                                 llvm::SmallVectorImpl<Decl*> &Result) = 0;
118
119   /// \brief Notify ExternalASTSource that we started deserialization of
120   /// a decl or type so until FinishedDeserializing is called there may be
121   /// decls that are initializing. Must be paired with FinishedDeserializing.
122   ///
123   /// The default implementation of this method is a no-op.
124   virtual void StartedDeserializing() { }
125
126   /// \brief Notify ExternalASTSource that we finished the deserialization of
127   /// a decl or type. Must be paired with StartedDeserializing.
128   ///
129   /// The default implementation of this method is a no-op.
130   virtual void FinishedDeserializing() { }
131
132   /// \brief Function that will be invoked when we begin parsing a new
133   /// translation unit involving this external AST source.
134   ///
135   /// The default implementation of this method is a no-op.
136   virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
137
138   /// \brief Print any statistics that have been gathered regarding
139   /// the external AST source.
140   ///
141   /// The default implementation of this method is a no-op.
142   virtual void PrintStats();
143
144 protected:
145   static DeclContextLookupResult
146   SetExternalVisibleDeclsForName(const DeclContext *DC,
147                                  DeclarationName Name,
148                                  llvm::SmallVectorImpl<NamedDecl*> &Decls);
149
150   static DeclContextLookupResult
151   SetNoExternalVisibleDeclsForName(const DeclContext *DC,
152                                    DeclarationName Name);
153
154   void MaterializeVisibleDeclsForName(const DeclContext *DC,
155                                       DeclarationName Name,
156                                  llvm::SmallVectorImpl<NamedDecl*> &Decls);
157 };
158
159 /// \brief A lazy pointer to an AST node (of base type T) that resides
160 /// within an external AST source.
161 ///
162 /// The AST node is identified within the external AST source by a
163 /// 63-bit offset, and can be retrieved via an operation on the
164 /// external AST source itself.
165 template<typename T, typename OffsT, T* (ExternalASTSource::*Get)(OffsT Offset)>
166 struct LazyOffsetPtr {
167   /// \brief Either a pointer to an AST node or the offset within the
168   /// external AST source where the AST node can be found.
169   ///
170   /// If the low bit is clear, a pointer to the AST node. If the low
171   /// bit is set, the upper 63 bits are the offset.
172   mutable uint64_t Ptr;
173
174 public:
175   LazyOffsetPtr() : Ptr(0) { }
176
177   explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
178   explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
179     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
180     if (Offset == 0)
181       Ptr = 0;
182   }
183
184   LazyOffsetPtr &operator=(T *Ptr) {
185     this->Ptr = reinterpret_cast<uint64_t>(Ptr);
186     return *this;
187   }
188
189   LazyOffsetPtr &operator=(uint64_t Offset) {
190     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
191     if (Offset == 0)
192       Ptr = 0;
193     else
194       Ptr = (Offset << 1) | 0x01;
195
196     return *this;
197   }
198
199   /// \brief Whether this pointer is non-NULL.
200   ///
201   /// This operation does not require the AST node to be deserialized.
202   operator bool() const { return Ptr != 0; }
203
204   /// \brief Whether this pointer is currently stored as an offset.
205   bool isOffset() const { return Ptr & 0x01; }
206
207   /// \brief Retrieve the pointer to the AST node that this lazy pointer
208   ///
209   /// \param Source the external AST source.
210   ///
211   /// \returns a pointer to the AST node.
212   T* get(ExternalASTSource *Source) const {
213     if (isOffset()) {
214       assert(Source &&
215              "Cannot deserialize a lazy pointer without an AST source");
216       Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
217     }
218     return reinterpret_cast<T*>(Ptr);
219   }
220 };
221
222 /// \brief A lazy pointer to a statement.
223 typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>
224   LazyDeclStmtPtr;
225
226 /// \brief A lazy pointer to a declaration.
227 typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>
228   LazyDeclPtr;
229
230 } // end namespace clang
231
232 #endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H