blob: 86626fe3881fca3fce3c0871a6f1656e5a4d4592 [file] [log] [blame]
Chris Lattner0ed844b2008-04-04 06:12:32 +00001//===-- DeclBase.h - Base Classes for representing declarations *- 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//
Chris Lattnerb048c982008-04-06 04:47:34 +000010// This file defines the Decl and DeclContext interfaces.
Chris Lattner0ed844b2008-04-04 06:12:32 +000011//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_DECLBASE_H
15#define LLVM_CLANG_AST_DECLBASE_H
16
17#include "clang/AST/Attr.h"
18#include "clang/AST/Type.h"
Douglas Gregor4afa39d2009-01-20 01:17:11 +000019// FIXME: Layering violation
20#include "clang/Parse/AccessSpecifier.h"
Chris Lattner49f28ca2009-03-05 08:00:35 +000021#include "llvm/Support/PrettyStackTrace.h"
Chris Lattner0ed844b2008-04-04 06:12:32 +000022
23namespace clang {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +000024class DeclContext;
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +000025class TranslationUnitDecl;
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000026class NamespaceDecl;
Douglas Gregor2a3009a2009-02-03 19:21:40 +000027class UsingDirectiveDecl;
Douglas Gregor44b43212008-12-11 16:49:14 +000028class NamedDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000029class FunctionDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000030class CXXRecordDecl;
Chris Lattnerb048c982008-04-06 04:47:34 +000031class EnumDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000032class ObjCMethodDecl;
Douglas Gregor64650af2009-02-02 23:39:07 +000033class ObjCContainerDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000034class ObjCInterfaceDecl;
Steve Naroff0701bbb2009-01-08 17:28:14 +000035class ObjCCategoryDecl;
36class ObjCProtocolDecl;
37class ObjCImplementationDecl;
38class ObjCCategoryImplDecl;
Douglas Gregor074149e2009-01-05 19:45:36 +000039class LinkageSpecDecl;
Steve Naroff56ee6892008-10-08 17:01:13 +000040class BlockDecl;
Douglas Gregor44b43212008-12-11 16:49:14 +000041class DeclarationName;
Ted Kremenekeaab2062009-03-12 18:33:24 +000042class CompoundStmt;
Chris Lattner0ed844b2008-04-04 06:12:32 +000043
44/// Decl - This represents one declaration (or definition), e.g. a variable,
45/// typedef, function, struct, etc.
46///
47class Decl {
48public:
Douglas Gregor64650af2009-02-02 23:39:07 +000049 /// \brief Lists the kind of concrete classes of Decl.
Chris Lattner0ed844b2008-04-04 06:12:32 +000050 enum Kind {
Douglas Gregor64650af2009-02-02 23:39:07 +000051#define DECL(Derived, Base) Derived,
52#define DECL_RANGE(CommonBase, Start, End) \
53 CommonBase##First = Start, CommonBase##Last = End,
54#define LAST_DECL_RANGE(CommonBase, Start, End) \
55 CommonBase##First = Start, CommonBase##Last = End
56#include "clang/AST/DeclNodes.def"
Chris Lattner0ed844b2008-04-04 06:12:32 +000057 };
58
59 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
Douglas Gregor2ce52f32008-04-13 21:07:44 +000060 /// labels, tags, members and ordinary identifiers. These are meant
61 /// as bitmasks, so that searches in C++ can look into the "tag" namespace
62 /// during ordinary lookup.
Chris Lattner0ed844b2008-04-04 06:12:32 +000063 enum IdentifierNamespace {
Douglas Gregor2ce52f32008-04-13 21:07:44 +000064 IDNS_Label = 0x1,
65 IDNS_Tag = 0x2,
66 IDNS_Member = 0x4,
Douglas Gregor7dda67d2009-02-05 19:25:20 +000067 IDNS_Ordinary = 0x8,
68 IDNS_Protocol = 0x10
Chris Lattner0ed844b2008-04-04 06:12:32 +000069 };
70
71 /// ObjCDeclQualifier - Qualifier used on types in method declarations
72 /// for remote messaging. They are meant for the arguments though and
73 /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
74 enum ObjCDeclQualifier {
75 OBJC_TQ_None = 0x0,
76 OBJC_TQ_In = 0x1,
77 OBJC_TQ_Inout = 0x2,
78 OBJC_TQ_Out = 0x4,
79 OBJC_TQ_Bycopy = 0x8,
80 OBJC_TQ_Byref = 0x10,
81 OBJC_TQ_Oneway = 0x20
82 };
83
84private:
Douglas Gregor4afa39d2009-01-20 01:17:11 +000085 /// NextDeclarator - If this decl was part of a multi-declarator declaration,
86 /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
87 Decl *NextDeclarator;
88
89 /// NextDeclInScope - The next declaration within the same lexical
90 /// DeclContext. These pointers form the linked list that is
91 /// traversed via DeclContext's decls_begin()/decls_end().
92 /// FIXME: If NextDeclarator is non-NULL, will it always be the same
93 /// as NextDeclInScope? If so, we can use a
94 /// PointerIntPair<Decl*, 1> to make Decl smaller.
95 Decl *NextDeclInScope;
96
97 friend class DeclContext;
98
99 /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
100 /// For declarations that don't contain C++ scope specifiers, it contains
101 /// the DeclContext where the Decl was declared.
102 /// For declarations with C++ scope specifiers, it contains a MultipleDC*
103 /// with the context where it semantically belongs (SemanticDC) and the
104 /// context where it was lexically declared (LexicalDC).
105 /// e.g.:
106 ///
107 /// namespace A {
108 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
109 /// }
110 /// void A::f(); // SemanticDC == namespace 'A'
111 /// // LexicalDC == global namespace
Chris Lattner10d83792009-03-27 18:46:15 +0000112 llvm::PointerIntPair<void*, 1, bool> DeclCtx;
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000113
114 struct MultipleDC {
115 DeclContext *SemanticDC;
116 DeclContext *LexicalDC;
117 };
118
Chris Lattner10d83792009-03-27 18:46:15 +0000119 inline bool isInSemaDC() const { return DeclCtx.getInt() == 0; }
120 inline bool isOutOfSemaDC() const { return DeclCtx.getInt() != 0; }
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000121 inline MultipleDC *getMultipleDC() const {
Chris Lattner10d83792009-03-27 18:46:15 +0000122 assert(isOutOfSemaDC() && "Invalid accessor");
123 return static_cast<MultipleDC*>(DeclCtx.getPointer());
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000124 }
125
Chris Lattner10d83792009-03-27 18:46:15 +0000126 inline DeclContext *getSemanticDC() const {
127 assert(isInSemaDC() && "Invalid accessor");
128 return static_cast<DeclContext*>(DeclCtx.getPointer());
129 }
130
Daniel Dunbar39d76502009-03-04 02:26:41 +0000131 /// Loc - The location that this decl.
132 SourceLocation Loc;
133
Chris Lattner0ed844b2008-04-04 06:12:32 +0000134 /// DeclKind - This indicates which class this is.
135 Kind DeclKind : 8;
136
137 /// InvalidDecl - This indicates a semantic error occurred.
138 unsigned int InvalidDecl : 1;
139
140 /// HasAttrs - This indicates whether the decl has attributes or not.
141 unsigned int HasAttrs : 1;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000142
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000143 /// Implicit - Whether this declaration was implicitly generated by
144 /// the implementation rather than explicitly written by the user.
145 bool Implicit : 1;
146
Chris Lattner769dbdf2009-03-27 20:18:19 +0000147 /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
148 unsigned IdentifierNamespace : 5;
149
Anders Carlsson1329c272009-03-25 23:38:06 +0000150#ifndef NDEBUG
151 void CheckAccessDeclContext() const;
152#else
153 void CheckAccessDeclContext() const { }
154#endif
155
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000156protected:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000157 /// Access - Used by C++ decls for the access specifier.
158 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
159 unsigned Access : 2;
160 friend class CXXClassMemberWrapper;
161
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000162 Decl(Kind DK, DeclContext *DC, SourceLocation L)
Daniel Dunbar39d76502009-03-04 02:26:41 +0000163 : NextDeclarator(0), NextDeclInScope(0),
Chris Lattner10d83792009-03-27 18:46:15 +0000164 DeclCtx(DC, 0),
Daniel Dunbar39d76502009-03-04 02:26:41 +0000165 Loc(L), DeclKind(DK), InvalidDecl(0),
Chris Lattner769dbdf2009-03-27 20:18:19 +0000166 HasAttrs(false), Implicit(false),
167 IdentifierNamespace(getIdentifierNamespaceForKind(DK)), Access(AS_none) {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000168 if (Decl::CollectingStats()) addDeclKind(DK);
169 }
Sam Bishop1bb19632008-04-11 18:04:39 +0000170
Chris Lattner0ed844b2008-04-04 06:12:32 +0000171 virtual ~Decl();
Sam Bishop1bb19632008-04-11 18:04:39 +0000172
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000173 /// setDeclContext - Set both the semantic and lexical DeclContext
174 /// to DC.
175 void setDeclContext(DeclContext *DC);
176
Sam Bishop1bb19632008-04-11 18:04:39 +0000177public:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000178 SourceLocation getLocation() const { return Loc; }
179 void setLocation(SourceLocation L) { Loc = L; }
180
181 Kind getKind() const { return DeclKind; }
182 const char *getDeclKindName() const;
183
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000184 DeclContext *getDeclContext() {
Chris Lattner10d83792009-03-27 18:46:15 +0000185 if (isInSemaDC())
186 return getSemanticDC();
187 return getMultipleDC()->SemanticDC;
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000188 }
Chris Lattner0cf2b192009-03-27 19:19:59 +0000189 const DeclContext *getDeclContext() const {
190 return const_cast<Decl*>(this)->getDeclContext();
191 }
192
Anders Carlsson1329c272009-03-25 23:38:06 +0000193 void setAccess(AccessSpecifier AS) {
Anders Carlssonb8547e82009-03-25 20:19:57 +0000194 Access = AS;
Anders Carlsson1329c272009-03-25 23:38:06 +0000195 CheckAccessDeclContext();
Anders Carlssonb8547e82009-03-25 20:19:57 +0000196 }
Anders Carlsson1329c272009-03-25 23:38:06 +0000197
198 AccessSpecifier getAccess() const {
199 CheckAccessDeclContext();
200 return AccessSpecifier(Access);
201 }
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000202
Chris Lattner76a642f2009-02-15 22:43:40 +0000203 bool hasAttrs() const { return HasAttrs; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000204 void addAttr(Attr *attr);
Chris Lattner81abbdd2009-03-21 06:27:31 +0000205 const Attr *getAttrs() const {
206 if (!HasAttrs) return 0; // common case, no attributes.
207 return getAttrsImpl(); // Uncommon case, out of line hash lookup.
208 }
Chris Lattnera212c562008-05-04 02:29:49 +0000209 void swapAttrs(Decl *D);
Nuno Lopes9141bee2008-06-01 22:53:53 +0000210 void invalidateAttrs();
Chris Lattner0ed844b2008-04-04 06:12:32 +0000211
212 template<typename T> const T *getAttr() const {
213 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
214 if (const T *V = dyn_cast<T>(attr))
215 return V;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000216 return 0;
217 }
218
219 /// setInvalidDecl - Indicates the Decl had a semantic error. This
220 /// allows for graceful error recovery.
221 void setInvalidDecl() { InvalidDecl = 1; }
222 bool isInvalidDecl() const { return (bool) InvalidDecl; }
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000223
224 /// isImplicit - Indicates whether the declaration was implicitly
225 /// generated by the implementation. If false, this declaration
226 /// was written explicitly in the source code.
227 bool isImplicit() const { return Implicit; }
228 void setImplicit(bool I = true) { Implicit = I; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000229
Douglas Gregorcc636682009-02-17 23:15:12 +0000230 unsigned getIdentifierNamespace() const {
Chris Lattner769dbdf2009-03-27 20:18:19 +0000231 return IdentifierNamespace;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000232 }
Chris Lattnerd62fdc42009-01-06 07:16:40 +0000233 bool isInIdentifierNamespace(unsigned NS) const {
234 return getIdentifierNamespace() & NS;
235 }
Chris Lattner769dbdf2009-03-27 20:18:19 +0000236 static unsigned getIdentifierNamespaceForKind(Kind DK);
237
Chris Lattnerd62fdc42009-01-06 07:16:40 +0000238
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000239 /// getLexicalDeclContext - The declaration context where this Decl was
240 /// lexically declared (LexicalDC). May be different from
241 /// getDeclContext() (SemanticDC).
242 /// e.g.:
243 ///
244 /// namespace A {
245 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
246 /// }
247 /// void A::f(); // SemanticDC == namespace 'A'
248 /// // LexicalDC == global namespace
Chris Lattner10d83792009-03-27 18:46:15 +0000249 DeclContext *getLexicalDeclContext() {
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000250 if (isInSemaDC())
Chris Lattner10d83792009-03-27 18:46:15 +0000251 return getSemanticDC();
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000252 return getMultipleDC()->LexicalDC;
253 }
Chris Lattner10d83792009-03-27 18:46:15 +0000254 const DeclContext *getLexicalDeclContext() const {
255 return const_cast<Decl*>(this)->getLexicalDeclContext();
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000256 }
Chris Lattner10d83792009-03-27 18:46:15 +0000257
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000258 void setLexicalDeclContext(DeclContext *DC);
259
260 /// getNextDeclarator - If this decl was part of a multi-declarator
261 /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
262 /// declarator. Otherwise it returns null.
263 Decl *getNextDeclarator() { return NextDeclarator; }
264 const Decl *getNextDeclarator() const { return NextDeclarator; }
265 void setNextDeclarator(Decl *N) { NextDeclarator = N; }
266
267 // isDefinedOutsideFunctionOrMethod - This predicate returns true if this
268 // scoped decl is defined outside the current function or method. This is
269 // roughly global variables and functions, but also handles enums (which could
270 // be defined inside or outside a function etc).
271 bool isDefinedOutsideFunctionOrMethod() const;
272
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000273 // getBody - If this Decl represents a declaration for a body of code,
Ted Kremenek792481e2008-06-20 21:39:47 +0000274 // such as a function or method definition, this method returns the top-level
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000275 // Stmt* of that body. Otherwise this method returns null.
Ted Kremenekeaab2062009-03-12 18:33:24 +0000276 virtual CompoundStmt* getBody() const { return 0; }
Ted Kremenek792481e2008-06-20 21:39:47 +0000277
Chris Lattner0ed844b2008-04-04 06:12:32 +0000278 // global temp stats (until we have a per-module visitor)
279 static void addDeclKind(Kind k);
280 static bool CollectingStats(bool Enable = false);
281 static void PrintStats();
282
Douglas Gregorf57172b2008-12-08 18:40:42 +0000283 /// isTemplateParameter - Determines whether this declartion is a
284 /// template parameter.
285 bool isTemplateParameter() const;
286
Chris Lattner0ed844b2008-04-04 06:12:32 +0000287 // Implement isa/cast/dyncast/etc.
288 static bool classof(const Decl *) { return true; }
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000289 static DeclContext *castToDeclContext(const Decl *);
290 static Decl *castFromDeclContext(const DeclContext *);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000291
292 /// Emit - Serialize this Decl to Bitcode.
293 void Emit(llvm::Serializer& S) const;
294
295 /// Create - Deserialize a Decl from Bitcode.
Sam Bishope2563ca2008-04-07 21:55:54 +0000296 static Decl* Create(llvm::Deserializer& D, ASTContext& C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000297
Sam Bishopbb45c512008-04-11 15:01:25 +0000298 /// Destroy - Call destructors and release memory.
Ted Kremenek27f8a282008-05-20 00:43:19 +0000299 virtual void Destroy(ASTContext& C);
Sam Bishopbb45c512008-04-11 15:01:25 +0000300
Chris Lattner0ed844b2008-04-04 06:12:32 +0000301protected:
302 /// EmitImpl - Provides the subclass-specific serialization logic for
303 /// serializing out a decl.
304 virtual void EmitImpl(llvm::Serializer& S) const {
305 // FIXME: This will eventually be a pure virtual function.
306 assert (false && "Not implemented.");
307 }
Chris Lattner81abbdd2009-03-21 06:27:31 +0000308private:
309 const Attr *getAttrsImpl() const;
310
Chris Lattner0ed844b2008-04-04 06:12:32 +0000311};
312
Chris Lattner49f28ca2009-03-05 08:00:35 +0000313/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
314/// doing something to a specific decl.
315class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
316 Decl *TheDecl;
317 SourceLocation Loc;
318 SourceManager &SM;
319 const char *Message;
320public:
321 PrettyStackTraceDecl(Decl *theDecl, SourceLocation L,
322 SourceManager &sm, const char *Msg)
323 : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
324
325 virtual void print(llvm::raw_ostream &OS) const;
326};
327
328
Chris Lattnerb048c982008-04-06 04:47:34 +0000329/// DeclContext - This is used only as base class of specific decl types that
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000330/// can act as declaration contexts. These decls are (only the top classes
331/// that directly derive from DeclContext are mentioned, not their subclasses):
Chris Lattner0ed844b2008-04-04 06:12:32 +0000332///
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000333/// TranslationUnitDecl
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000334/// NamespaceDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000335/// FunctionDecl
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000336/// TagDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000337/// ObjCMethodDecl
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000338/// ObjCContainerDecl
339/// ObjCCategoryImplDecl
340/// ObjCImplementationDecl
Douglas Gregor074149e2009-01-05 19:45:36 +0000341/// LinkageSpecDecl
Steve Naroff56ee6892008-10-08 17:01:13 +0000342/// BlockDecl
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000343///
Chris Lattnerb048c982008-04-06 04:47:34 +0000344class DeclContext {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000345 /// DeclKind - This indicates which class this is.
346 Decl::Kind DeclKind : 8;
347
Douglas Gregor44b43212008-12-11 16:49:14 +0000348 /// LookupPtrKind - Describes what kind of pointer LookupPtr
349 /// actually is.
350 enum LookupPtrKind {
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000351 /// LookupIsMap - Indicates that LookupPtr is actually a map.
Douglas Gregor44b43212008-12-11 16:49:14 +0000352 LookupIsMap = 7
353 };
354
355 /// LookupPtr - Pointer to a data structure used to lookup
356 /// declarations within this context. If the context contains fewer
357 /// than seven declarations, the number of declarations is provided
358 /// in the 3 lowest-order bits and the upper bits are treated as a
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000359 /// pointer to an array of NamedDecl pointers. If the context
Douglas Gregor44b43212008-12-11 16:49:14 +0000360 /// contains seven or more declarations, the upper bits are treated
Chris Lattner769dbdf2009-03-27 20:18:19 +0000361 /// as a pointer to a DenseMap<DeclarationName, StoredDeclsList>.
Douglas Gregor44b43212008-12-11 16:49:14 +0000362 llvm::PointerIntPair<void*, 3> LookupPtr;
363
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000364 /// FirstDecl - The first declaration stored within this declaration
365 /// context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000366 Decl *FirstDecl;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000367
368 /// LastDecl - The last declaration stored within this declaration
369 /// context. FIXME: We could probably cache this value somewhere
370 /// outside of the DeclContext, to reduce the size of DeclContext by
371 /// another pointer.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000372 Decl *LastDecl;
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000373
Douglas Gregor44b43212008-12-11 16:49:14 +0000374 /// isLookupMap - Determine if the lookup structure is a
375 /// DenseMap. Othewise, it is an array.
376 bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; }
377
Douglas Gregor0cba8552009-01-20 04:04:17 +0000378 static Decl *getNextDeclInScope(Decl *D) { return D->NextDeclInScope; }
379
Chris Lattner0ed844b2008-04-04 06:12:32 +0000380protected:
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000381 DeclContext(Decl::Kind K)
382 : DeclKind(K), LookupPtr(), FirstDecl(0), LastDecl(0) { }
Douglas Gregor44b43212008-12-11 16:49:14 +0000383
384 void DestroyDecls(ASTContext &C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000385
386public:
Douglas Gregor44b43212008-12-11 16:49:14 +0000387 ~DeclContext();
388
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000389 Decl::Kind getDeclKind() const {
390 return DeclKind;
391 }
Steve Naroff0a473932009-01-20 19:53:53 +0000392 const char *getDeclKindName() const;
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000393
Argyrios Kyrtzidis305ec422009-02-17 20:26:05 +0000394 /// getParent - Returns the containing DeclContext.
Chris Lattner0cf2b192009-03-27 19:19:59 +0000395 DeclContext *getParent() {
Argyrios Kyrtzidis305ec422009-02-17 20:26:05 +0000396 return cast<Decl>(this)->getDeclContext();
397 }
Chris Lattner0cf2b192009-03-27 19:19:59 +0000398 const DeclContext *getParent() const {
399 return const_cast<DeclContext*>(this)->getParent();
Argyrios Kyrtzidisd2595ec2008-10-12 18:40:01 +0000400 }
Chris Lattner0cf2b192009-03-27 19:19:59 +0000401
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000402 /// getLexicalParent - Returns the containing lexical DeclContext. May be
Douglas Gregor44b43212008-12-11 16:49:14 +0000403 /// different from getParent, e.g.:
404 ///
405 /// namespace A {
406 /// struct S;
407 /// }
408 /// struct A::S {}; // getParent() == namespace 'A'
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000409 /// // getLexicalParent() == translation unit
410 ///
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000411 DeclContext *getLexicalParent() {
Chris Lattner0cf2b192009-03-27 19:19:59 +0000412 return cast<Decl>(this)->getLexicalDeclContext();
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000413 }
Chris Lattner0cf2b192009-03-27 19:19:59 +0000414 const DeclContext *getLexicalParent() const {
415 return const_cast<DeclContext*>(this)->getLexicalParent();
416 }
417
Chris Lattner0ed844b2008-04-04 06:12:32 +0000418 bool isFunctionOrMethod() const {
419 switch (DeclKind) {
Chris Lattner0cf2b192009-03-27 19:19:59 +0000420 case Decl::Block:
421 case Decl::ObjCMethod:
422 return true;
423 default:
424 return DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000425 }
426 }
427
Argyrios Kyrtzidisef6e6472008-11-08 17:17:31 +0000428 bool isFileContext() const {
429 return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
430 }
431
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000432 bool isTranslationUnit() const {
433 return DeclKind == Decl::TranslationUnit;
434 }
435
Douglas Gregorbcbffc42009-01-07 00:43:41 +0000436 bool isRecord() const {
Douglas Gregor65100792009-02-26 00:02:51 +0000437 return DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast;
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +0000438 }
439
Douglas Gregor44b43212008-12-11 16:49:14 +0000440 bool isNamespace() const {
441 return DeclKind == Decl::Namespace;
442 }
443
Douglas Gregor074149e2009-01-05 19:45:36 +0000444 /// isTransparentContext - Determines whether this context is a
445 /// "transparent" context, meaning that the members declared in this
446 /// context are semantically declared in the nearest enclosing
447 /// non-transparent (opaque) context but are lexically declared in
448 /// this context. For example, consider the enumerators of an
449 /// enumeration type:
450 /// @code
451 /// enum E {
452 /// Val1
453 /// };
454 /// @endcode
455 /// Here, E is a transparent context, so its enumerator (Val1) will
456 /// appear (semantically) that it is in the same context of E.
457 /// Examples of transparent contexts include: enumerations (except for
458 /// C++0x scoped enums), C++ linkage specifications, and C++0x
459 /// inline namespaces.
460 bool isTransparentContext() const;
461
Argyrios Kyrtzidisef6e6472008-11-08 17:17:31 +0000462 bool Encloses(DeclContext *DC) const {
463 for (; DC; DC = DC->getParent())
464 if (DC == this)
465 return true;
466 return false;
467 }
468
Douglas Gregor44b43212008-12-11 16:49:14 +0000469 /// getPrimaryContext - There may be many different
470 /// declarations of the same entity (including forward declarations
471 /// of classes, multiple definitions of namespaces, etc.), each with
472 /// a different set of declarations. This routine returns the
473 /// "primary" DeclContext structure, which will contain the
474 /// information needed to perform name lookup into this context.
Steve Naroff0701bbb2009-01-08 17:28:14 +0000475 DeclContext *getPrimaryContext();
Douglas Gregor44b43212008-12-11 16:49:14 +0000476
Douglas Gregorce356072009-01-06 23:51:29 +0000477 /// getLookupContext - Retrieve the innermost non-transparent
478 /// context of this context, which corresponds to the innermost
479 /// location from which name lookup can find the entities in this
480 /// context.
Chris Lattner0cf2b192009-03-27 19:19:59 +0000481 DeclContext *getLookupContext();
482 const DeclContext *getLookupContext() const {
483 return const_cast<DeclContext *>(this)->getLookupContext();
Douglas Gregor17a9b9e2009-01-07 02:48:43 +0000484 }
Chris Lattner0cf2b192009-03-27 19:19:59 +0000485
Douglas Gregor88b70942009-02-25 22:02:03 +0000486 /// \brief Retrieve the nearest enclosing namespace context.
487 DeclContext *getEnclosingNamespaceContext();
488 const DeclContext *getEnclosingNamespaceContext() const {
489 return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
490 }
491
Douglas Gregor44b43212008-12-11 16:49:14 +0000492 /// getNextContext - If this is a DeclContext that may have other
493 /// DeclContexts that are semantically connected but syntactically
494 /// different, such as C++ namespaces, this routine retrieves the
495 /// next DeclContext in the link. Iteration through the chain of
496 /// DeclContexts should begin at the primary DeclContext and
497 /// continue until this function returns NULL. For example, given:
498 /// @code
499 /// namespace N {
500 /// int x;
501 /// }
502 /// namespace N {
503 /// int y;
504 /// }
505 /// @endcode
506 /// The first occurrence of namespace N will be the primary
507 /// DeclContext. Its getNextContext will return the second
508 /// occurrence of namespace N.
509 DeclContext *getNextContext();
510
511 /// decl_iterator - Iterates through the declarations stored
512 /// within this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000513 class decl_iterator {
514 /// Current - The current declaration.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000515 Decl *Current;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000516
517 public:
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000518 typedef Decl* value_type;
519 typedef Decl* reference;
520 typedef Decl* pointer;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000521 typedef std::forward_iterator_tag iterator_category;
522 typedef std::ptrdiff_t difference_type;
523
524 decl_iterator() : Current(0) { }
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000525 explicit decl_iterator(Decl *C) : Current(C) { }
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000526
527 reference operator*() const { return Current; }
528 pointer operator->() const { return Current; }
529
530 decl_iterator& operator++();
531
532 decl_iterator operator++(int) {
533 decl_iterator tmp(*this);
534 ++(*this);
535 return tmp;
536 }
537
538 friend bool operator==(decl_iterator x, decl_iterator y) {
539 return x.Current == y.Current;
540 }
541 friend bool operator!=(decl_iterator x, decl_iterator y) {
542 return x.Current != y.Current;
543 }
544 };
Douglas Gregor44b43212008-12-11 16:49:14 +0000545
Douglas Gregor44b43212008-12-11 16:49:14 +0000546 /// decls_begin/decls_end - Iterate over the declarations stored in
547 /// this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000548 decl_iterator decls_begin() const { return decl_iterator(FirstDecl); }
549 decl_iterator decls_end() const { return decl_iterator(); }
Douglas Gregor44b43212008-12-11 16:49:14 +0000550
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000551 /// specific_decl_iterator - Iterates over a subrange of
552 /// declarations stored in a DeclContext, providing only those that
Douglas Gregor669c9a22009-02-02 18:25:48 +0000553 /// are of type SpecificDecl (or a class derived from it). This
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000554 /// iterator is used, for example, to provide iteration over just
Douglas Gregor669c9a22009-02-02 18:25:48 +0000555 /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000556 template<typename SpecificDecl>
557 class specific_decl_iterator {
558 /// Current - The current, underlying declaration iterator, which
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000559 /// will either be NULL or will point to a declaration of
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000560 /// type SpecificDecl.
561 DeclContext::decl_iterator Current;
562
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000563 /// SkipToNextDecl - Advances the current position up to the next
564 /// declaration of type SpecificDecl that also meets the criteria
565 /// required by Acceptable.
566 void SkipToNextDecl() {
Douglas Gregor669c9a22009-02-02 18:25:48 +0000567 while (*Current && !isa<SpecificDecl>(*Current))
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000568 ++Current;
569 }
570
571 public:
572 typedef SpecificDecl* value_type;
573 typedef SpecificDecl* reference;
574 typedef SpecificDecl* pointer;
575 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
576 difference_type;
577 typedef std::forward_iterator_tag iterator_category;
578
Douglas Gregor669c9a22009-02-02 18:25:48 +0000579 specific_decl_iterator() : Current() { }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000580
581 /// specific_decl_iterator - Construct a new iterator over a
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000582 /// subset of the declarations the range [C,
583 /// end-of-declarations). If A is non-NULL, it is a pointer to a
584 /// member function of SpecificDecl that should return true for
585 /// all of the SpecificDecl instances that will be in the subset
586 /// of iterators. For example, if you want Objective-C instance
587 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
588 /// &ObjCMethodDecl::isInstanceMethod.
Douglas Gregor669c9a22009-02-02 18:25:48 +0000589 explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000590 SkipToNextDecl();
591 }
592
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000593 reference operator*() const { return cast<SpecificDecl>(*Current); }
594 pointer operator->() const { return cast<SpecificDecl>(*Current); }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000595
596 specific_decl_iterator& operator++() {
597 ++Current;
598 SkipToNextDecl();
599 return *this;
600 }
601
602 specific_decl_iterator operator++(int) {
603 specific_decl_iterator tmp(*this);
604 ++(*this);
605 return tmp;
606 }
607
608 friend bool
609 operator==(const specific_decl_iterator& x, const specific_decl_iterator& y) {
610 return x.Current == y.Current;
611 }
612
613 friend bool
614 operator!=(const specific_decl_iterator& x, const specific_decl_iterator& y) {
615 return x.Current != y.Current;
616 }
617 };
618
Douglas Gregor669c9a22009-02-02 18:25:48 +0000619 /// \brief Iterates over a filtered subrange of declarations stored
620 /// in a DeclContext.
621 ///
622 /// This iterator visits only those declarations that are of type
623 /// SpecificDecl (or a class derived from it) and that meet some
624 /// additional run-time criteria. This iterator is used, for
625 /// example, to provide access to the instance methods within an
626 /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
627 /// Acceptable = ObjCMethodDecl::isInstanceMethod).
628 template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
629 class filtered_decl_iterator {
630 /// Current - The current, underlying declaration iterator, which
631 /// will either be NULL or will point to a declaration of
632 /// type SpecificDecl.
633 DeclContext::decl_iterator Current;
634
635 /// SkipToNextDecl - Advances the current position up to the next
636 /// declaration of type SpecificDecl that also meets the criteria
637 /// required by Acceptable.
638 void SkipToNextDecl() {
639 while (*Current &&
640 (!isa<SpecificDecl>(*Current) ||
641 (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
642 ++Current;
643 }
644
645 public:
646 typedef SpecificDecl* value_type;
647 typedef SpecificDecl* reference;
648 typedef SpecificDecl* pointer;
649 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
650 difference_type;
651 typedef std::forward_iterator_tag iterator_category;
652
653 filtered_decl_iterator() : Current() { }
654
655 /// specific_decl_iterator - Construct a new iterator over a
656 /// subset of the declarations the range [C,
657 /// end-of-declarations). If A is non-NULL, it is a pointer to a
658 /// member function of SpecificDecl that should return true for
659 /// all of the SpecificDecl instances that will be in the subset
660 /// of iterators. For example, if you want Objective-C instance
661 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
662 /// &ObjCMethodDecl::isInstanceMethod.
663 explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
664 SkipToNextDecl();
665 }
666
667 reference operator*() const { return cast<SpecificDecl>(*Current); }
668 pointer operator->() const { return cast<SpecificDecl>(*Current); }
669
670 filtered_decl_iterator& operator++() {
671 ++Current;
672 SkipToNextDecl();
673 return *this;
674 }
675
676 filtered_decl_iterator operator++(int) {
677 filtered_decl_iterator tmp(*this);
678 ++(*this);
679 return tmp;
680 }
681
682 friend bool
683 operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
684 return x.Current == y.Current;
685 }
686
687 friend bool
688 operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
689 return x.Current != y.Current;
690 }
691 };
692
Douglas Gregor40f4e692009-01-20 16:54:50 +0000693 /// @brief Add the declaration D into this context.
694 ///
695 /// This routine should be invoked when the declaration D has first
696 /// been declared, to place D into the context where it was
697 /// (lexically) defined. Every declaration must be added to one
698 /// (and only one!) context, where it can be visited via
699 /// [decls_begin(), decls_end()). Once a declaration has been added
700 /// to its lexical context, the corresponding DeclContext owns the
701 /// declaration.
702 ///
703 /// If D is also a NamedDecl, it will be made visible within its
704 /// semantic context via makeDeclVisibleInContext.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000705 void addDecl(Decl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000706
Douglas Gregor44b43212008-12-11 16:49:14 +0000707 /// lookup_iterator - An iterator that provides access to the results
708 /// of looking up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000709 typedef NamedDecl **lookup_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000710
711 /// lookup_const_iterator - An iterator that provides non-mutable
712 /// access to the results of lookup up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000713 typedef NamedDecl * const * lookup_const_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000714
715 typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
716 typedef std::pair<lookup_const_iterator, lookup_const_iterator>
717 lookup_const_result;
718
719 /// lookup - Find the declarations (if any) with the given Name in
720 /// this context. Returns a range of iterators that contains all of
Douglas Gregor40f4e692009-01-20 16:54:50 +0000721 /// the declarations with this name, with object, function, member,
722 /// and enumerator names preceding any tag name. Note that this
723 /// routine will not look into parent contexts.
Steve Naroff0701bbb2009-01-08 17:28:14 +0000724 lookup_result lookup(DeclarationName Name);
725 lookup_const_result lookup(DeclarationName Name) const;
Douglas Gregor44b43212008-12-11 16:49:14 +0000726
Douglas Gregor40f4e692009-01-20 16:54:50 +0000727 /// @brief Makes a declaration visible within this context.
728 ///
729 /// This routine makes the declaration D visible to name lookup
730 /// within this context and, if this is a transparent context,
731 /// within its parent contexts up to the first enclosing
732 /// non-transparent context. Making a declaration visible within a
733 /// context does not transfer ownership of a declaration, and a
734 /// declaration can be visible in many contexts that aren't its
735 /// lexical context.
736 ///
737 /// If D is a redeclaration of an existing declaration that is
738 /// visible from this context, as determined by
739 /// NamedDecl::declarationReplaces, the previous declaration will be
740 /// replaced with D.
741 void makeDeclVisibleInContext(NamedDecl *D);
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000742
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000743 /// udir_iterator - Iterates through the using-directives stored
744 /// within this context.
745 typedef UsingDirectiveDecl * const * udir_iterator;
746
747 typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
748
749 udir_iterator_range getUsingDirectives() const;
750
751 udir_iterator using_directives_begin() const {
752 return getUsingDirectives().first;
753 }
754
755 udir_iterator using_directives_end() const {
756 return getUsingDirectives().second;
757 }
758
Argyrios Kyrtzidis3d7641e2009-02-16 14:29:28 +0000759 static bool classof(const Decl *D);
Chris Lattnerb048c982008-04-06 04:47:34 +0000760 static bool classof(const DeclContext *D) { return true; }
Douglas Gregor64650af2009-02-02 23:39:07 +0000761#define DECL_CONTEXT(Name) \
762 static bool classof(const Name##Decl *D) { return true; }
763#include "clang/AST/DeclNodes.def"
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000764
765private:
Douglas Gregor40f4e692009-01-20 16:54:50 +0000766 void buildLookup(DeclContext *DCtx);
767 void makeDeclVisibleInContextImpl(NamedDecl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000768
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000769 void EmitOutRec(llvm::Serializer& S) const;
770 void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
771
772 friend class Decl;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000773};
774
Douglas Gregorf57172b2008-12-08 18:40:42 +0000775inline bool Decl::isTemplateParameter() const {
776 return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm;
777}
778
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000779inline bool Decl::isDefinedOutsideFunctionOrMethod() const {
780 if (getDeclContext())
781 return !getDeclContext()->getLookupContext()->isFunctionOrMethod();
782 else
783 return true;
784}
785
786inline DeclContext::decl_iterator& DeclContext::decl_iterator::operator++() {
Douglas Gregor0cba8552009-01-20 04:04:17 +0000787 Current = getNextDeclInScope(Current);
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000788 return *this;
789}
790
Chris Lattner0ed844b2008-04-04 06:12:32 +0000791} // end clang.
792
793namespace llvm {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000794
795/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
796/// a specific Decl.
797template<class ToTy>
798struct isa_impl_wrap<ToTy,
799 const ::clang::DeclContext,const ::clang::DeclContext> {
800 static bool doit(const ::clang::DeclContext &Val) {
801 return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000802 }
803};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000804template<class ToTy>
805struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
806 : public isa_impl_wrap<ToTy,
807 const ::clang::DeclContext,const ::clang::DeclContext> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000808
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000809/// Implement cast_convert_val for Decl -> DeclContext conversions.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000810template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000811struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000812 static ::clang::DeclContext &doit(const FromTy &Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000813 return *FromTy::castToDeclContext(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000814 }
815};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000816
817template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000818struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000819 static ::clang::DeclContext *doit(const FromTy *Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000820 return FromTy::castToDeclContext(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000821 }
822};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000823
Douglas Gregor44b43212008-12-11 16:49:14 +0000824template<class FromTy>
825struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
826 static const ::clang::DeclContext &doit(const FromTy &Val) {
827 return *FromTy::castToDeclContext(&Val);
828 }
829};
830
831template<class FromTy>
832struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
833 static const ::clang::DeclContext *doit(const FromTy *Val) {
834 return FromTy::castToDeclContext(Val);
835 }
836};
837
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000838/// Implement cast_convert_val for DeclContext -> Decl conversions.
839template<class ToTy>
840struct cast_convert_val<ToTy,
841 const ::clang::DeclContext,const ::clang::DeclContext> {
842 static ToTy &doit(const ::clang::DeclContext &Val) {
843 return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
844 }
845};
846template<class ToTy>
847struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
848 : public cast_convert_val<ToTy,
849 const ::clang::DeclContext,const ::clang::DeclContext> {};
850
851template<class ToTy>
852struct cast_convert_val<ToTy,
853 const ::clang::DeclContext*, const ::clang::DeclContext*> {
854 static ToTy *doit(const ::clang::DeclContext *Val) {
855 return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
856 }
857};
858template<class ToTy>
859struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
860 : public cast_convert_val<ToTy,
861 const ::clang::DeclContext*,const ::clang::DeclContext*> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000862
863} // end namespace llvm
864
865#endif