]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h
svn merge svn+ssh://svn.freebsd.org/base/head@208996
[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 "clang/AST/DeclarationName.h"
18 #include "clang/AST/Type.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include <cassert>
21 #include <vector>
22 namespace clang {
23
24 class ASTConsumer;
25 class Decl;
26 class DeclContext;
27 class ExternalSemaSource; // layering violation required for downcasting
28 class Stmt;
29
30 /// \brief The deserialized representation of a set of declarations
31 /// with the same name that are visible in a given context.
32 struct VisibleDeclaration {
33   /// \brief The name of the declarations.
34   DeclarationName Name;
35
36   /// \brief The ID numbers of all of the declarations with this name.
37   ///
38   /// These declarations have not necessarily been de-serialized.
39   llvm::SmallVector<unsigned, 4> Declarations;
40 };
41
42 /// \brief Abstract interface for external sources of AST nodes.
43 ///
44 /// External AST sources provide AST nodes constructed from some
45 /// external source, such as a precompiled header. External AST
46 /// sources can resolve types and declarations from abstract IDs into
47 /// actual type and declaration nodes, and read parts of declaration
48 /// contexts.
49 class ExternalASTSource {
50   /// \brief Whether this AST source also provides information for
51   /// semantic analysis.
52   bool SemaSource;
53
54   friend class ExternalSemaSource;
55
56 public:
57   ExternalASTSource() : SemaSource(false) { }
58
59   virtual ~ExternalASTSource();
60
61   /// \brief Resolve a type ID into a type, potentially building a new
62   /// type.
63   virtual QualType GetType(uint32_t ID) = 0;
64
65   /// \brief Resolve a declaration ID into a declaration, potentially
66   /// building a new declaration.
67   virtual Decl *GetDecl(uint32_t ID) = 0;
68
69   /// \brief Resolve a selector ID into a selector.
70   virtual Selector GetSelector(uint32_t ID) = 0;
71
72   /// \brief Returns the number of selectors known to the external AST
73   /// source.
74   virtual uint32_t GetNumKnownSelectors() = 0;
75
76   /// \brief Resolve the offset of a statement in the decl stream into a
77   /// statement.
78   ///
79   /// This operation will read a new statement from the external
80   /// source each time it is called, and is meant to be used via a
81   /// LazyOffsetPtr.
82   virtual Stmt *GetDeclStmt(uint64_t Offset) = 0;
83
84   /// \brief Read all of the declarations lexically stored in a
85   /// declaration context.
86   ///
87   /// \param DC The declaration context whose declarations will be
88   /// read.
89   ///
90   /// \param Decls Vector that will contain the declarations loaded
91   /// from the external source. The caller is responsible for merging
92   /// these declarations with any declarations already stored in the
93   /// declaration context.
94   ///
95   /// \returns true if there was an error while reading the
96   /// declarations for this declaration context.
97   virtual bool ReadDeclsLexicallyInContext(DeclContext *DC,
98                                   llvm::SmallVectorImpl<uint32_t> &Decls) = 0;
99
100   /// \brief Read all of the declarations visible from a declaration
101   /// context.
102   ///
103   /// \param DC The declaration context whose visible declarations
104   /// will be read.
105   ///
106   /// \param Decls A vector of visible declaration structures,
107   /// providing the mapping from each name visible in the declaration
108   /// context to the declaration IDs of declarations with that name.
109   ///
110   /// \returns true if there was an error while reading the
111   /// declarations for this declaration context.
112   virtual bool ReadDeclsVisibleInContext(DeclContext *DC,
113                        llvm::SmallVectorImpl<VisibleDeclaration> & Decls) = 0;
114
115   /// \brief Function that will be invoked when we begin parsing a new
116   /// translation unit involving this external AST source.
117   virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
118
119   /// \brief Print any statistics that have been gathered regarding
120   /// the external AST source.
121   virtual void PrintStats();
122 };
123
124 /// \brief A lazy pointer to an AST node (of base type T) that resides
125 /// within an external AST source.
126 ///
127 /// The AST node is identified within the external AST source by a
128 /// 63-bit offset, and can be retrieved via an operation on the
129 /// external AST source itself.
130 template<typename T, T* (ExternalASTSource::*Get)(uint64_t Offset)>
131 struct LazyOffsetPtr {
132   /// \brief Either a pointer to an AST node or the offset within the
133   /// external AST source where the AST node can be found.
134   ///
135   /// If the low bit is clear, a pointer to the AST node. If the low
136   /// bit is set, the upper 63 bits are the offset.
137   mutable uint64_t Ptr;
138
139 public:
140   LazyOffsetPtr() : Ptr(0) { }
141
142   explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { }
143   explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) {
144     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
145     if (Offset == 0)
146       Ptr = 0;
147   }
148
149   LazyOffsetPtr &operator=(T *Ptr) {
150     this->Ptr = reinterpret_cast<uint64_t>(Ptr);
151     return *this;
152   }
153
154   LazyOffsetPtr &operator=(uint64_t Offset) {
155     assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits");
156     if (Offset == 0)
157       Ptr = 0;
158     else
159       Ptr = (Offset << 1) | 0x01;
160
161     return *this;
162   }
163
164   /// \brief Whether this pointer is non-NULL.
165   ///
166   /// This operation does not require the AST node to be deserialized.
167   operator bool() const { return Ptr != 0; }
168
169   /// \brief Whether this pointer is currently stored as an offset.
170   bool isOffset() const { return Ptr & 0x01; }
171
172   /// \brief Retrieve the pointer to the AST node that this lazy pointer
173   ///
174   /// \param Source the external AST source.
175   ///
176   /// \returns a pointer to the AST node.
177   T* get(ExternalASTSource *Source) const {
178     if (isOffset()) {
179       assert(Source &&
180              "Cannot deserialize a lazy pointer without an AST source");
181       Ptr = reinterpret_cast<uint64_t>((Source->*Get)(Ptr >> 1));
182     }
183     return reinterpret_cast<T*>(Ptr);
184   }
185 };
186
187 /// \brief A lazy pointer to a statement.
188 typedef LazyOffsetPtr<Stmt, &ExternalASTSource::GetDeclStmt> LazyDeclStmtPtr;
189
190 } // end namespace clang
191
192 #endif // LLVM_CLANG_AST_EXTERNAL_AST_SOURCE_H