blob: 89ef3b86c818436cc5a7a69db40fd7c32dc52fd8 [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 Lattner0ed844b2008-04-04 06:12:32 +000021#include "clang/Basic/SourceLocation.h"
Douglas Gregor44b43212008-12-11 16:49:14 +000022#include "llvm/ADT/PointerIntPair.h"
Chris Lattner0ed844b2008-04-04 06:12:32 +000023
24namespace clang {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +000025class DeclContext;
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +000026class TranslationUnitDecl;
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000027class NamespaceDecl;
Douglas Gregor2a3009a2009-02-03 19:21:40 +000028class UsingDirectiveDecl;
Douglas Gregor44b43212008-12-11 16:49:14 +000029class NamedDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000030class FunctionDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000031class CXXRecordDecl;
Chris Lattnerb048c982008-04-06 04:47:34 +000032class EnumDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000033class ObjCMethodDecl;
Douglas Gregor64650af2009-02-02 23:39:07 +000034class ObjCContainerDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000035class ObjCInterfaceDecl;
Steve Naroff0701bbb2009-01-08 17:28:14 +000036class ObjCCategoryDecl;
37class ObjCProtocolDecl;
38class ObjCImplementationDecl;
39class ObjCCategoryImplDecl;
Douglas Gregor074149e2009-01-05 19:45:36 +000040class LinkageSpecDecl;
Steve Naroff56ee6892008-10-08 17:01:13 +000041class BlockDecl;
Douglas Gregor44b43212008-12-11 16:49:14 +000042class DeclarationName;
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:
85 /// Loc - The location that this decl.
86 SourceLocation Loc;
87
Douglas Gregor4afa39d2009-01-20 01:17:11 +000088 /// NextDeclarator - If this decl was part of a multi-declarator declaration,
89 /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
90 Decl *NextDeclarator;
91
92 /// NextDeclInScope - The next declaration within the same lexical
93 /// DeclContext. These pointers form the linked list that is
94 /// traversed via DeclContext's decls_begin()/decls_end().
95 /// FIXME: If NextDeclarator is non-NULL, will it always be the same
96 /// as NextDeclInScope? If so, we can use a
97 /// PointerIntPair<Decl*, 1> to make Decl smaller.
98 Decl *NextDeclInScope;
99
100 friend class DeclContext;
101
102 /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
103 /// For declarations that don't contain C++ scope specifiers, it contains
104 /// the DeclContext where the Decl was declared.
105 /// For declarations with C++ scope specifiers, it contains a MultipleDC*
106 /// with the context where it semantically belongs (SemanticDC) and the
107 /// context where it was lexically declared (LexicalDC).
108 /// e.g.:
109 ///
110 /// namespace A {
111 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
112 /// }
113 /// void A::f(); // SemanticDC == namespace 'A'
114 /// // LexicalDC == global namespace
115 uintptr_t DeclCtx;
116
117 struct MultipleDC {
118 DeclContext *SemanticDC;
119 DeclContext *LexicalDC;
120 };
121
122 inline bool isInSemaDC() const { return (DeclCtx & 0x1) == 0; }
123 inline bool isOutOfSemaDC() const { return (DeclCtx & 0x1) != 0; }
124 inline MultipleDC *getMultipleDC() const {
125 return reinterpret_cast<MultipleDC*>(DeclCtx & ~0x1);
126 }
127
Chris Lattner0ed844b2008-04-04 06:12:32 +0000128 /// DeclKind - This indicates which class this is.
129 Kind DeclKind : 8;
130
131 /// InvalidDecl - This indicates a semantic error occurred.
132 unsigned int InvalidDecl : 1;
133
134 /// HasAttrs - This indicates whether the decl has attributes or not.
135 unsigned int HasAttrs : 1;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000136
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000137 /// Implicit - Whether this declaration was implicitly generated by
138 /// the implementation rather than explicitly written by the user.
139 bool Implicit : 1;
140
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000141protected:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000142 /// Access - Used by C++ decls for the access specifier.
143 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
144 unsigned Access : 2;
145 friend class CXXClassMemberWrapper;
146
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000147 Decl(Kind DK, DeclContext *DC, SourceLocation L)
148 : Loc(L), NextDeclarator(0), NextDeclInScope(0),
149 DeclCtx(reinterpret_cast<uintptr_t>(DC)), DeclKind(DK), InvalidDecl(0),
150 HasAttrs(false), Implicit(false) {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000151 if (Decl::CollectingStats()) addDeclKind(DK);
152 }
Sam Bishop1bb19632008-04-11 18:04:39 +0000153
Chris Lattner0ed844b2008-04-04 06:12:32 +0000154 virtual ~Decl();
Sam Bishop1bb19632008-04-11 18:04:39 +0000155
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000156 /// setDeclContext - Set both the semantic and lexical DeclContext
157 /// to DC.
158 void setDeclContext(DeclContext *DC);
159
Sam Bishop1bb19632008-04-11 18:04:39 +0000160public:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000161 SourceLocation getLocation() const { return Loc; }
162 void setLocation(SourceLocation L) { Loc = L; }
163
164 Kind getKind() const { return DeclKind; }
165 const char *getDeclKindName() const;
166
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000167 const DeclContext *getDeclContext() const {
168 if (isInSemaDC())
169 return reinterpret_cast<DeclContext*>(DeclCtx);
170 return getMultipleDC()->SemanticDC;
171 }
172 DeclContext *getDeclContext() {
173 return const_cast<DeclContext*>(
174 const_cast<const Decl*>(this)->getDeclContext());
175 }
176
177 void setAccess(AccessSpecifier AS) { Access = AS; }
178 AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
179
Chris Lattner76a642f2009-02-15 22:43:40 +0000180 bool hasAttrs() const { return HasAttrs; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000181 void addAttr(Attr *attr);
182 const Attr *getAttrs() const;
Chris Lattnera212c562008-05-04 02:29:49 +0000183 void swapAttrs(Decl *D);
Nuno Lopes9141bee2008-06-01 22:53:53 +0000184 void invalidateAttrs();
Chris Lattner0ed844b2008-04-04 06:12:32 +0000185
186 template<typename T> const T *getAttr() const {
187 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
188 if (const T *V = dyn_cast<T>(attr))
189 return V;
190
191 return 0;
192 }
193
194 /// setInvalidDecl - Indicates the Decl had a semantic error. This
195 /// allows for graceful error recovery.
196 void setInvalidDecl() { InvalidDecl = 1; }
197 bool isInvalidDecl() const { return (bool) InvalidDecl; }
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000198
199 /// isImplicit - Indicates whether the declaration was implicitly
200 /// generated by the implementation. If false, this declaration
201 /// was written explicitly in the source code.
202 bool isImplicit() const { return Implicit; }
203 void setImplicit(bool I = true) { Implicit = I; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000204
205 IdentifierNamespace getIdentifierNamespace() const {
206 switch (DeclKind) {
Douglas Gregor9d350972008-12-12 08:25:50 +0000207 default:
208 if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast)
209 return IDNS_Ordinary;
210 assert(0 && "Unknown decl kind!");
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000211 case OverloadedFunction:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000212 case Typedef:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000213 case EnumConstant:
Steve Naroff248a7532008-04-15 22:42:06 +0000214 case Var:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000215 case CXXClassVar:
216 case ImplicitParam:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000217 case ParmVar:
Fariborz Jahanian73da9e42008-12-20 20:56:12 +0000218 case OriginalParmVar:
Douglas Gregor72c3f312008-12-05 18:15:24 +0000219 case NonTypeTemplateParm:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000220 case ObjCMethod:
221 case ObjCContainer:
222 case ObjCCategory:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000223 case ObjCInterface:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000224 case ObjCCategoryImpl:
225 case ObjCProperty:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000226 case ObjCCompatibleAlias:
227 return IDNS_Ordinary;
Douglas Gregor72de6672009-01-08 20:45:30 +0000228
Douglas Gregor7dda67d2009-02-05 19:25:20 +0000229 case ObjCProtocol:
230 return IDNS_Protocol;
231
Douglas Gregor72de6672009-01-08 20:45:30 +0000232 case Field:
233 case ObjCAtDefsField:
234 case ObjCIvar:
235 return IDNS_Member;
236
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000237 case Record:
238 case CXXRecord:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000239 case Enum:
Douglas Gregorefe38bd2009-01-23 22:28:29 +0000240 case TemplateTypeParm:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000241 return IDNS_Tag;
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000242
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000243 case Namespace:
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000244 case Template:
245 case FunctionTemplate:
246 case ClassTemplate:
247 case TemplateTemplateParm:
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000248 return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000249 }
250 }
Ted Kremenek792481e2008-06-20 21:39:47 +0000251
Chris Lattnerd62fdc42009-01-06 07:16:40 +0000252 bool isInIdentifierNamespace(unsigned NS) const {
253 return getIdentifierNamespace() & NS;
254 }
255
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000256 /// getLexicalDeclContext - The declaration context where this Decl was
257 /// lexically declared (LexicalDC). May be different from
258 /// getDeclContext() (SemanticDC).
259 /// e.g.:
260 ///
261 /// namespace A {
262 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
263 /// }
264 /// void A::f(); // SemanticDC == namespace 'A'
265 /// // LexicalDC == global namespace
266 const DeclContext *getLexicalDeclContext() const {
267 if (isInSemaDC())
268 return reinterpret_cast<DeclContext*>(DeclCtx);
269 return getMultipleDC()->LexicalDC;
270 }
271 DeclContext *getLexicalDeclContext() {
272 return const_cast<DeclContext*>(
273 const_cast<const Decl*>(this)->getLexicalDeclContext());
274 }
275
276 void setLexicalDeclContext(DeclContext *DC);
277
278 /// getNextDeclarator - If this decl was part of a multi-declarator
279 /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
280 /// declarator. Otherwise it returns null.
281 Decl *getNextDeclarator() { return NextDeclarator; }
282 const Decl *getNextDeclarator() const { return NextDeclarator; }
283 void setNextDeclarator(Decl *N) { NextDeclarator = N; }
284
285 // isDefinedOutsideFunctionOrMethod - This predicate returns true if this
286 // scoped decl is defined outside the current function or method. This is
287 // roughly global variables and functions, but also handles enums (which could
288 // be defined inside or outside a function etc).
289 bool isDefinedOutsideFunctionOrMethod() const;
290
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000291 // getBody - If this Decl represents a declaration for a body of code,
Ted Kremenek792481e2008-06-20 21:39:47 +0000292 // such as a function or method definition, this method returns the top-level
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000293 // Stmt* of that body. Otherwise this method returns null.
294 virtual Stmt* getBody() const { return 0; }
Ted Kremenek792481e2008-06-20 21:39:47 +0000295
Chris Lattner0ed844b2008-04-04 06:12:32 +0000296 // global temp stats (until we have a per-module visitor)
297 static void addDeclKind(Kind k);
298 static bool CollectingStats(bool Enable = false);
299 static void PrintStats();
300
Douglas Gregorf57172b2008-12-08 18:40:42 +0000301 /// isTemplateParameter - Determines whether this declartion is a
302 /// template parameter.
303 bool isTemplateParameter() const;
304
Chris Lattner0ed844b2008-04-04 06:12:32 +0000305 // Implement isa/cast/dyncast/etc.
306 static bool classof(const Decl *) { return true; }
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000307 static DeclContext *castToDeclContext(const Decl *);
308 static Decl *castFromDeclContext(const DeclContext *);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000309
310 /// Emit - Serialize this Decl to Bitcode.
311 void Emit(llvm::Serializer& S) const;
312
313 /// Create - Deserialize a Decl from Bitcode.
Sam Bishope2563ca2008-04-07 21:55:54 +0000314 static Decl* Create(llvm::Deserializer& D, ASTContext& C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000315
Sam Bishopbb45c512008-04-11 15:01:25 +0000316 /// Destroy - Call destructors and release memory.
Ted Kremenek27f8a282008-05-20 00:43:19 +0000317 virtual void Destroy(ASTContext& C);
Sam Bishopbb45c512008-04-11 15:01:25 +0000318
Chris Lattner0ed844b2008-04-04 06:12:32 +0000319protected:
320 /// EmitImpl - Provides the subclass-specific serialization logic for
321 /// serializing out a decl.
322 virtual void EmitImpl(llvm::Serializer& S) const {
323 // FIXME: This will eventually be a pure virtual function.
324 assert (false && "Not implemented.");
325 }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000326};
327
Chris Lattnerb048c982008-04-06 04:47:34 +0000328/// DeclContext - This is used only as base class of specific decl types that
Chris Lattner0ed844b2008-04-04 06:12:32 +0000329/// can act as declaration contexts. These decls are:
330///
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000331/// TranslationUnitDecl
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000332/// NamespaceDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000333/// FunctionDecl
Douglas Gregor44b43212008-12-11 16:49:14 +0000334/// RecordDecl/CXXRecordDecl
Chris Lattnerb048c982008-04-06 04:47:34 +0000335/// EnumDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000336/// ObjCMethodDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000337/// ObjCInterfaceDecl
Douglas Gregor074149e2009-01-05 19:45:36 +0000338/// LinkageSpecDecl
Steve Naroff56ee6892008-10-08 17:01:13 +0000339/// BlockDecl
Chris Lattnerb048c982008-04-06 04:47:34 +0000340class DeclContext {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000341 /// DeclKind - This indicates which class this is.
342 Decl::Kind DeclKind : 8;
343
Douglas Gregor44b43212008-12-11 16:49:14 +0000344 /// LookupPtrKind - Describes what kind of pointer LookupPtr
345 /// actually is.
346 enum LookupPtrKind {
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000347 /// LookupIsMap - Indicates that LookupPtr is actually a map.
Douglas Gregor44b43212008-12-11 16:49:14 +0000348 LookupIsMap = 7
349 };
350
351 /// LookupPtr - Pointer to a data structure used to lookup
352 /// declarations within this context. If the context contains fewer
353 /// than seven declarations, the number of declarations is provided
354 /// in the 3 lowest-order bits and the upper bits are treated as a
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000355 /// pointer to an array of NamedDecl pointers. If the context
Douglas Gregor44b43212008-12-11 16:49:14 +0000356 /// contains seven or more declarations, the upper bits are treated
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000357 /// as a pointer to a DenseMap<DeclarationName, std::vector<NamedDecl*>>.
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000358 /// FIXME: We need a better data structure for this.
Douglas Gregor44b43212008-12-11 16:49:14 +0000359 llvm::PointerIntPair<void*, 3> LookupPtr;
360
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000361 /// FirstDecl - The first declaration stored within this declaration
362 /// context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000363 Decl *FirstDecl;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000364
365 /// LastDecl - The last declaration stored within this declaration
366 /// context. FIXME: We could probably cache this value somewhere
367 /// outside of the DeclContext, to reduce the size of DeclContext by
368 /// another pointer.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000369 Decl *LastDecl;
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000370
Chris Lattner0ed844b2008-04-04 06:12:32 +0000371 // Used in the CastTo template to get the DeclKind
Chris Lattnerb048c982008-04-06 04:47:34 +0000372 // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
Chris Lattner0ed844b2008-04-04 06:12:32 +0000373 // to avoid 'ambiguous access' compiler errors.
374 template<typename T> struct KindTrait {
375 static Decl::Kind getKind(const T *D) { return D->getKind(); }
376 };
377
378 // Used only by the ToDecl and FromDecl methods
379 template<typename To, typename From>
380 static To *CastTo(const From *D) {
381 Decl::Kind DK = KindTrait<From>::getKind(D);
382 switch(DK) {
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000383 case Decl::TranslationUnit:
384 return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000385 case Decl::Namespace:
386 return static_cast<NamespaceDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000387 case Decl::Enum:
388 return static_cast<EnumDecl*>(const_cast<From*>(D));
Douglas Gregor44b43212008-12-11 16:49:14 +0000389 case Decl::Record:
390 return static_cast<RecordDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000391 case Decl::CXXRecord:
392 return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000393 case Decl::ObjCMethod:
394 return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
395 case Decl::ObjCInterface:
396 return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
Steve Naroff0701bbb2009-01-08 17:28:14 +0000397 case Decl::ObjCCategory:
398 return static_cast<ObjCCategoryDecl*>(const_cast<From*>(D));
399 case Decl::ObjCProtocol:
400 return static_cast<ObjCProtocolDecl*>(const_cast<From*>(D));
401 case Decl::ObjCImplementation:
402 return static_cast<ObjCImplementationDecl*>(const_cast<From*>(D));
403 case Decl::ObjCCategoryImpl:
404 return static_cast<ObjCCategoryImplDecl*>(const_cast<From*>(D));
Douglas Gregor074149e2009-01-05 19:45:36 +0000405 case Decl::LinkageSpec:
406 return static_cast<LinkageSpecDecl*>(const_cast<From*>(D));
407 case Decl::Block:
408 return static_cast<BlockDecl*>(const_cast<From*>(D));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000409 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000410 if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
411 return static_cast<FunctionDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000412
Chris Lattnerb048c982008-04-06 04:47:34 +0000413 assert(false && "a decl that inherits DeclContext isn't handled");
Chris Lattner0ed844b2008-04-04 06:12:32 +0000414 return 0;
415 }
416 }
417
Douglas Gregor44b43212008-12-11 16:49:14 +0000418 /// isLookupMap - Determine if the lookup structure is a
419 /// DenseMap. Othewise, it is an array.
420 bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; }
421
Douglas Gregor0cba8552009-01-20 04:04:17 +0000422 static Decl *getNextDeclInScope(Decl *D) { return D->NextDeclInScope; }
423
Chris Lattner0ed844b2008-04-04 06:12:32 +0000424protected:
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000425 DeclContext(Decl::Kind K)
426 : DeclKind(K), LookupPtr(), FirstDecl(0), LastDecl(0) { }
Douglas Gregor44b43212008-12-11 16:49:14 +0000427
428 void DestroyDecls(ASTContext &C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000429
430public:
Douglas Gregor44b43212008-12-11 16:49:14 +0000431 ~DeclContext();
432
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000433 Decl::Kind getDeclKind() const {
434 return DeclKind;
435 }
Steve Naroff0a473932009-01-20 19:53:53 +0000436 const char *getDeclKindName() const;
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000437
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000438 /// getParent - Returns the containing DeclContext if this is a Decl,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000439 /// else returns NULL.
Argyrios Kyrtzidis20bc6762008-11-19 17:36:39 +0000440 const DeclContext *getParent() const;
441 DeclContext *getParent() {
442 return const_cast<DeclContext*>(
443 const_cast<const DeclContext*>(this)->getParent());
Argyrios Kyrtzidisd2595ec2008-10-12 18:40:01 +0000444 }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000445
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000446 /// getLexicalParent - Returns the containing lexical DeclContext. May be
Douglas Gregor44b43212008-12-11 16:49:14 +0000447 /// different from getParent, e.g.:
448 ///
449 /// namespace A {
450 /// struct S;
451 /// }
452 /// struct A::S {}; // getParent() == namespace 'A'
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000453 /// // getLexicalParent() == translation unit
454 ///
455 const DeclContext *getLexicalParent() const;
456 DeclContext *getLexicalParent() {
457 return const_cast<DeclContext*>(
458 const_cast<const DeclContext*>(this)->getLexicalParent());
459 }
460
Chris Lattner0ed844b2008-04-04 06:12:32 +0000461 bool isFunctionOrMethod() const {
462 switch (DeclKind) {
Steve Naroff56ee6892008-10-08 17:01:13 +0000463 case Decl::Block:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000464 case Decl::ObjCMethod:
465 return true;
Douglas Gregor44b43212008-12-11 16:49:14 +0000466
Chris Lattner0ed844b2008-04-04 06:12:32 +0000467 default:
Douglas Gregor44b43212008-12-11 16:49:14 +0000468 if (DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast)
469 return true;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000470 return false;
471 }
472 }
473
Argyrios Kyrtzidisef6e6472008-11-08 17:17:31 +0000474 bool isFileContext() const {
475 return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
476 }
477
Douglas Gregor5f2bfd42009-02-13 00:10:09 +0000478 bool isTranslationUnit() const {
479 return DeclKind == Decl::TranslationUnit;
480 }
481
Douglas Gregorbcbffc42009-01-07 00:43:41 +0000482 bool isRecord() const {
483 return DeclKind == Decl::Record || DeclKind == Decl::CXXRecord;
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +0000484 }
485
Douglas Gregor44b43212008-12-11 16:49:14 +0000486 bool isNamespace() const {
487 return DeclKind == Decl::Namespace;
488 }
489
Douglas Gregor074149e2009-01-05 19:45:36 +0000490 /// isTransparentContext - Determines whether this context is a
491 /// "transparent" context, meaning that the members declared in this
492 /// context are semantically declared in the nearest enclosing
493 /// non-transparent (opaque) context but are lexically declared in
494 /// this context. For example, consider the enumerators of an
495 /// enumeration type:
496 /// @code
497 /// enum E {
498 /// Val1
499 /// };
500 /// @endcode
501 /// Here, E is a transparent context, so its enumerator (Val1) will
502 /// appear (semantically) that it is in the same context of E.
503 /// Examples of transparent contexts include: enumerations (except for
504 /// C++0x scoped enums), C++ linkage specifications, and C++0x
505 /// inline namespaces.
506 bool isTransparentContext() const;
507
Argyrios Kyrtzidisef6e6472008-11-08 17:17:31 +0000508 bool Encloses(DeclContext *DC) const {
509 for (; DC; DC = DC->getParent())
510 if (DC == this)
511 return true;
512 return false;
513 }
514
Douglas Gregor44b43212008-12-11 16:49:14 +0000515 /// getPrimaryContext - There may be many different
516 /// declarations of the same entity (including forward declarations
517 /// of classes, multiple definitions of namespaces, etc.), each with
518 /// a different set of declarations. This routine returns the
519 /// "primary" DeclContext structure, which will contain the
520 /// information needed to perform name lookup into this context.
Steve Naroff0701bbb2009-01-08 17:28:14 +0000521 DeclContext *getPrimaryContext();
Douglas Gregor44b43212008-12-11 16:49:14 +0000522
Douglas Gregorce356072009-01-06 23:51:29 +0000523 /// getLookupContext - Retrieve the innermost non-transparent
524 /// context of this context, which corresponds to the innermost
525 /// location from which name lookup can find the entities in this
526 /// context.
Douglas Gregor17a9b9e2009-01-07 02:48:43 +0000527 DeclContext *getLookupContext() {
528 return const_cast<DeclContext *>(
529 const_cast<const DeclContext *>(this)->getLookupContext());
530 }
531 const DeclContext *getLookupContext() const;
Douglas Gregorce356072009-01-06 23:51:29 +0000532
Douglas Gregor44b43212008-12-11 16:49:14 +0000533 /// getNextContext - If this is a DeclContext that may have other
534 /// DeclContexts that are semantically connected but syntactically
535 /// different, such as C++ namespaces, this routine retrieves the
536 /// next DeclContext in the link. Iteration through the chain of
537 /// DeclContexts should begin at the primary DeclContext and
538 /// continue until this function returns NULL. For example, given:
539 /// @code
540 /// namespace N {
541 /// int x;
542 /// }
543 /// namespace N {
544 /// int y;
545 /// }
546 /// @endcode
547 /// The first occurrence of namespace N will be the primary
548 /// DeclContext. Its getNextContext will return the second
549 /// occurrence of namespace N.
550 DeclContext *getNextContext();
551
552 /// decl_iterator - Iterates through the declarations stored
553 /// within this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000554 class decl_iterator {
555 /// Current - The current declaration.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000556 Decl *Current;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000557
558 public:
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000559 typedef Decl* value_type;
560 typedef Decl* reference;
561 typedef Decl* pointer;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000562 typedef std::forward_iterator_tag iterator_category;
563 typedef std::ptrdiff_t difference_type;
564
565 decl_iterator() : Current(0) { }
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000566 explicit decl_iterator(Decl *C) : Current(C) { }
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000567
568 reference operator*() const { return Current; }
569 pointer operator->() const { return Current; }
570
571 decl_iterator& operator++();
572
573 decl_iterator operator++(int) {
574 decl_iterator tmp(*this);
575 ++(*this);
576 return tmp;
577 }
578
579 friend bool operator==(decl_iterator x, decl_iterator y) {
580 return x.Current == y.Current;
581 }
582 friend bool operator!=(decl_iterator x, decl_iterator y) {
583 return x.Current != y.Current;
584 }
585 };
Douglas Gregor44b43212008-12-11 16:49:14 +0000586
Douglas Gregor44b43212008-12-11 16:49:14 +0000587 /// decls_begin/decls_end - Iterate over the declarations stored in
588 /// this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000589 decl_iterator decls_begin() const { return decl_iterator(FirstDecl); }
590 decl_iterator decls_end() const { return decl_iterator(); }
Douglas Gregor44b43212008-12-11 16:49:14 +0000591
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000592 /// specific_decl_iterator - Iterates over a subrange of
593 /// declarations stored in a DeclContext, providing only those that
Douglas Gregor669c9a22009-02-02 18:25:48 +0000594 /// are of type SpecificDecl (or a class derived from it). This
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000595 /// iterator is used, for example, to provide iteration over just
Douglas Gregor669c9a22009-02-02 18:25:48 +0000596 /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000597 template<typename SpecificDecl>
598 class specific_decl_iterator {
599 /// Current - The current, underlying declaration iterator, which
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000600 /// will either be NULL or will point to a declaration of
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000601 /// type SpecificDecl.
602 DeclContext::decl_iterator Current;
603
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000604 /// SkipToNextDecl - Advances the current position up to the next
605 /// declaration of type SpecificDecl that also meets the criteria
606 /// required by Acceptable.
607 void SkipToNextDecl() {
Douglas Gregor669c9a22009-02-02 18:25:48 +0000608 while (*Current && !isa<SpecificDecl>(*Current))
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000609 ++Current;
610 }
611
612 public:
613 typedef SpecificDecl* value_type;
614 typedef SpecificDecl* reference;
615 typedef SpecificDecl* pointer;
616 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
617 difference_type;
618 typedef std::forward_iterator_tag iterator_category;
619
Douglas Gregor669c9a22009-02-02 18:25:48 +0000620 specific_decl_iterator() : Current() { }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000621
622 /// specific_decl_iterator - Construct a new iterator over a
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000623 /// subset of the declarations the range [C,
624 /// end-of-declarations). If A is non-NULL, it is a pointer to a
625 /// member function of SpecificDecl that should return true for
626 /// all of the SpecificDecl instances that will be in the subset
627 /// of iterators. For example, if you want Objective-C instance
628 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
629 /// &ObjCMethodDecl::isInstanceMethod.
Douglas Gregor669c9a22009-02-02 18:25:48 +0000630 explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000631 SkipToNextDecl();
632 }
633
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000634 reference operator*() const { return cast<SpecificDecl>(*Current); }
635 pointer operator->() const { return cast<SpecificDecl>(*Current); }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000636
637 specific_decl_iterator& operator++() {
638 ++Current;
639 SkipToNextDecl();
640 return *this;
641 }
642
643 specific_decl_iterator operator++(int) {
644 specific_decl_iterator tmp(*this);
645 ++(*this);
646 return tmp;
647 }
648
649 friend bool
650 operator==(const specific_decl_iterator& x, const specific_decl_iterator& y) {
651 return x.Current == y.Current;
652 }
653
654 friend bool
655 operator!=(const specific_decl_iterator& x, const specific_decl_iterator& y) {
656 return x.Current != y.Current;
657 }
658 };
659
Douglas Gregor669c9a22009-02-02 18:25:48 +0000660 /// \brief Iterates over a filtered subrange of declarations stored
661 /// in a DeclContext.
662 ///
663 /// This iterator visits only those declarations that are of type
664 /// SpecificDecl (or a class derived from it) and that meet some
665 /// additional run-time criteria. This iterator is used, for
666 /// example, to provide access to the instance methods within an
667 /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
668 /// Acceptable = ObjCMethodDecl::isInstanceMethod).
669 template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
670 class filtered_decl_iterator {
671 /// Current - The current, underlying declaration iterator, which
672 /// will either be NULL or will point to a declaration of
673 /// type SpecificDecl.
674 DeclContext::decl_iterator Current;
675
676 /// SkipToNextDecl - Advances the current position up to the next
677 /// declaration of type SpecificDecl that also meets the criteria
678 /// required by Acceptable.
679 void SkipToNextDecl() {
680 while (*Current &&
681 (!isa<SpecificDecl>(*Current) ||
682 (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
683 ++Current;
684 }
685
686 public:
687 typedef SpecificDecl* value_type;
688 typedef SpecificDecl* reference;
689 typedef SpecificDecl* pointer;
690 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
691 difference_type;
692 typedef std::forward_iterator_tag iterator_category;
693
694 filtered_decl_iterator() : Current() { }
695
696 /// specific_decl_iterator - Construct a new iterator over a
697 /// subset of the declarations the range [C,
698 /// end-of-declarations). If A is non-NULL, it is a pointer to a
699 /// member function of SpecificDecl that should return true for
700 /// all of the SpecificDecl instances that will be in the subset
701 /// of iterators. For example, if you want Objective-C instance
702 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
703 /// &ObjCMethodDecl::isInstanceMethod.
704 explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
705 SkipToNextDecl();
706 }
707
708 reference operator*() const { return cast<SpecificDecl>(*Current); }
709 pointer operator->() const { return cast<SpecificDecl>(*Current); }
710
711 filtered_decl_iterator& operator++() {
712 ++Current;
713 SkipToNextDecl();
714 return *this;
715 }
716
717 filtered_decl_iterator operator++(int) {
718 filtered_decl_iterator tmp(*this);
719 ++(*this);
720 return tmp;
721 }
722
723 friend bool
724 operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
725 return x.Current == y.Current;
726 }
727
728 friend bool
729 operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
730 return x.Current != y.Current;
731 }
732 };
733
Douglas Gregor40f4e692009-01-20 16:54:50 +0000734 /// @brief Add the declaration D into this context.
735 ///
736 /// This routine should be invoked when the declaration D has first
737 /// been declared, to place D into the context where it was
738 /// (lexically) defined. Every declaration must be added to one
739 /// (and only one!) context, where it can be visited via
740 /// [decls_begin(), decls_end()). Once a declaration has been added
741 /// to its lexical context, the corresponding DeclContext owns the
742 /// declaration.
743 ///
744 /// If D is also a NamedDecl, it will be made visible within its
745 /// semantic context via makeDeclVisibleInContext.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000746 void addDecl(Decl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000747
Douglas Gregor44b43212008-12-11 16:49:14 +0000748 /// lookup_iterator - An iterator that provides access to the results
749 /// of looking up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000750 typedef NamedDecl **lookup_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000751
752 /// lookup_const_iterator - An iterator that provides non-mutable
753 /// access to the results of lookup up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000754 typedef NamedDecl * const * lookup_const_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000755
756 typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
757 typedef std::pair<lookup_const_iterator, lookup_const_iterator>
758 lookup_const_result;
759
760 /// lookup - Find the declarations (if any) with the given Name in
761 /// this context. Returns a range of iterators that contains all of
Douglas Gregor40f4e692009-01-20 16:54:50 +0000762 /// the declarations with this name, with object, function, member,
763 /// and enumerator names preceding any tag name. Note that this
764 /// routine will not look into parent contexts.
Steve Naroff0701bbb2009-01-08 17:28:14 +0000765 lookup_result lookup(DeclarationName Name);
766 lookup_const_result lookup(DeclarationName Name) const;
Douglas Gregor44b43212008-12-11 16:49:14 +0000767
Douglas Gregor40f4e692009-01-20 16:54:50 +0000768 /// @brief Makes a declaration visible within this context.
769 ///
770 /// This routine makes the declaration D visible to name lookup
771 /// within this context and, if this is a transparent context,
772 /// within its parent contexts up to the first enclosing
773 /// non-transparent context. Making a declaration visible within a
774 /// context does not transfer ownership of a declaration, and a
775 /// declaration can be visible in many contexts that aren't its
776 /// lexical context.
777 ///
778 /// If D is a redeclaration of an existing declaration that is
779 /// visible from this context, as determined by
780 /// NamedDecl::declarationReplaces, the previous declaration will be
781 /// replaced with D.
782 void makeDeclVisibleInContext(NamedDecl *D);
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000783
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000784 /// udir_iterator - Iterates through the using-directives stored
785 /// within this context.
786 typedef UsingDirectiveDecl * const * udir_iterator;
787
788 typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
789
790 udir_iterator_range getUsingDirectives() const;
791
792 udir_iterator using_directives_begin() const {
793 return getUsingDirectives().first;
794 }
795
796 udir_iterator using_directives_end() const {
797 return getUsingDirectives().second;
798 }
799
Chris Lattner0ed844b2008-04-04 06:12:32 +0000800 static bool classof(const Decl *D) {
801 switch (D->getKind()) {
Douglas Gregor64650af2009-02-02 23:39:07 +0000802#define DECL_CONTEXT(Name) case Decl::Name:
803#include "clang/AST/DeclNodes.def"
Chris Lattner0ed844b2008-04-04 06:12:32 +0000804 return true;
805 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000806 if (D->getKind() >= Decl::FunctionFirst &&
807 D->getKind() <= Decl::FunctionLast)
808 return true;
Chris Lattnerb048c982008-04-06 04:47:34 +0000809 return false;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000810 }
811 }
Chris Lattnerb048c982008-04-06 04:47:34 +0000812 static bool classof(const DeclContext *D) { return true; }
Douglas Gregor64650af2009-02-02 23:39:07 +0000813#define DECL_CONTEXT(Name) \
814 static bool classof(const Name##Decl *D) { return true; }
815#include "clang/AST/DeclNodes.def"
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000816
817private:
Douglas Gregor40f4e692009-01-20 16:54:50 +0000818 void buildLookup(DeclContext *DCtx);
819 void makeDeclVisibleInContextImpl(NamedDecl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000820
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000821 void EmitOutRec(llvm::Serializer& S) const;
822 void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
823
824 friend class Decl;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000825};
826
Chris Lattnerb048c982008-04-06 04:47:34 +0000827template<> struct DeclContext::KindTrait<DeclContext> {
828 static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000829};
830
Douglas Gregorf57172b2008-12-08 18:40:42 +0000831inline bool Decl::isTemplateParameter() const {
832 return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm;
833}
834
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000835inline bool Decl::isDefinedOutsideFunctionOrMethod() const {
836 if (getDeclContext())
837 return !getDeclContext()->getLookupContext()->isFunctionOrMethod();
838 else
839 return true;
840}
841
842inline DeclContext::decl_iterator& DeclContext::decl_iterator::operator++() {
Douglas Gregor0cba8552009-01-20 04:04:17 +0000843 Current = getNextDeclInScope(Current);
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000844 return *this;
845}
846
Chris Lattner0ed844b2008-04-04 06:12:32 +0000847} // end clang.
848
849namespace llvm {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000850
851/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
852/// a specific Decl.
853template<class ToTy>
854struct isa_impl_wrap<ToTy,
855 const ::clang::DeclContext,const ::clang::DeclContext> {
856 static bool doit(const ::clang::DeclContext &Val) {
857 return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000858 }
859};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000860template<class ToTy>
861struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
862 : public isa_impl_wrap<ToTy,
863 const ::clang::DeclContext,const ::clang::DeclContext> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000864
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000865/// Implement cast_convert_val for Decl -> DeclContext conversions.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000866template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000867struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000868 static ::clang::DeclContext &doit(const FromTy &Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000869 return *FromTy::castToDeclContext(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000870 }
871};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000872
873template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000874struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000875 static ::clang::DeclContext *doit(const FromTy *Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000876 return FromTy::castToDeclContext(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000877 }
878};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000879
Douglas Gregor44b43212008-12-11 16:49:14 +0000880template<class FromTy>
881struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
882 static const ::clang::DeclContext &doit(const FromTy &Val) {
883 return *FromTy::castToDeclContext(&Val);
884 }
885};
886
887template<class FromTy>
888struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
889 static const ::clang::DeclContext *doit(const FromTy *Val) {
890 return FromTy::castToDeclContext(Val);
891 }
892};
893
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000894/// Implement cast_convert_val for DeclContext -> Decl conversions.
895template<class ToTy>
896struct cast_convert_val<ToTy,
897 const ::clang::DeclContext,const ::clang::DeclContext> {
898 static ToTy &doit(const ::clang::DeclContext &Val) {
899 return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
900 }
901};
902template<class ToTy>
903struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
904 : public cast_convert_val<ToTy,
905 const ::clang::DeclContext,const ::clang::DeclContext> {};
906
907template<class ToTy>
908struct cast_convert_val<ToTy,
909 const ::clang::DeclContext*, const ::clang::DeclContext*> {
910 static ToTy *doit(const ::clang::DeclContext *Val) {
911 return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
912 }
913};
914template<class ToTy>
915struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
916 : public cast_convert_val<ToTy,
917 const ::clang::DeclContext*,const ::clang::DeclContext*> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000918
919} // end namespace llvm
920
921#endif