blob: 23bcd58a2a3b18305ac85c261ac3942e2d8760b2 [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 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;
Chris Lattner0ed844b2008-04-04 06:12:32 +000042
43/// Decl - This represents one declaration (or definition), e.g. a variable,
44/// typedef, function, struct, etc.
45///
46class Decl {
47public:
Douglas Gregor64650af2009-02-02 23:39:07 +000048 /// \brief Lists the kind of concrete classes of Decl.
Chris Lattner0ed844b2008-04-04 06:12:32 +000049 enum Kind {
Douglas Gregor64650af2009-02-02 23:39:07 +000050#define DECL(Derived, Base) Derived,
51#define DECL_RANGE(CommonBase, Start, End) \
52 CommonBase##First = Start, CommonBase##Last = End,
53#define LAST_DECL_RANGE(CommonBase, Start, End) \
54 CommonBase##First = Start, CommonBase##Last = End
55#include "clang/AST/DeclNodes.def"
Chris Lattner0ed844b2008-04-04 06:12:32 +000056 };
57
58 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
Douglas Gregor2ce52f32008-04-13 21:07:44 +000059 /// labels, tags, members and ordinary identifiers. These are meant
60 /// as bitmasks, so that searches in C++ can look into the "tag" namespace
61 /// during ordinary lookup.
Chris Lattner0ed844b2008-04-04 06:12:32 +000062 enum IdentifierNamespace {
Douglas Gregor2ce52f32008-04-13 21:07:44 +000063 IDNS_Label = 0x1,
64 IDNS_Tag = 0x2,
65 IDNS_Member = 0x4,
66 IDNS_Ordinary = 0x8
Chris Lattner0ed844b2008-04-04 06:12:32 +000067 };
68
69 /// ObjCDeclQualifier - Qualifier used on types in method declarations
70 /// for remote messaging. They are meant for the arguments though and
71 /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
72 enum ObjCDeclQualifier {
73 OBJC_TQ_None = 0x0,
74 OBJC_TQ_In = 0x1,
75 OBJC_TQ_Inout = 0x2,
76 OBJC_TQ_Out = 0x4,
77 OBJC_TQ_Bycopy = 0x8,
78 OBJC_TQ_Byref = 0x10,
79 OBJC_TQ_Oneway = 0x20
80 };
81
82private:
83 /// Loc - The location that this decl.
84 SourceLocation Loc;
85
Douglas Gregor4afa39d2009-01-20 01:17:11 +000086 /// NextDeclarator - If this decl was part of a multi-declarator declaration,
87 /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
88 Decl *NextDeclarator;
89
90 /// NextDeclInScope - The next declaration within the same lexical
91 /// DeclContext. These pointers form the linked list that is
92 /// traversed via DeclContext's decls_begin()/decls_end().
93 /// FIXME: If NextDeclarator is non-NULL, will it always be the same
94 /// as NextDeclInScope? If so, we can use a
95 /// PointerIntPair<Decl*, 1> to make Decl smaller.
96 Decl *NextDeclInScope;
97
98 friend class DeclContext;
99
100 /// DeclCtx - Holds either a DeclContext* or a MultipleDC*.
101 /// For declarations that don't contain C++ scope specifiers, it contains
102 /// the DeclContext where the Decl was declared.
103 /// For declarations with C++ scope specifiers, it contains a MultipleDC*
104 /// with the context where it semantically belongs (SemanticDC) and the
105 /// context where it was lexically declared (LexicalDC).
106 /// e.g.:
107 ///
108 /// namespace A {
109 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
110 /// }
111 /// void A::f(); // SemanticDC == namespace 'A'
112 /// // LexicalDC == global namespace
113 uintptr_t DeclCtx;
114
115 struct MultipleDC {
116 DeclContext *SemanticDC;
117 DeclContext *LexicalDC;
118 };
119
120 inline bool isInSemaDC() const { return (DeclCtx & 0x1) == 0; }
121 inline bool isOutOfSemaDC() const { return (DeclCtx & 0x1) != 0; }
122 inline MultipleDC *getMultipleDC() const {
123 return reinterpret_cast<MultipleDC*>(DeclCtx & ~0x1);
124 }
125
Chris Lattner0ed844b2008-04-04 06:12:32 +0000126 /// DeclKind - This indicates which class this is.
127 Kind DeclKind : 8;
128
129 /// InvalidDecl - This indicates a semantic error occurred.
130 unsigned int InvalidDecl : 1;
131
132 /// HasAttrs - This indicates whether the decl has attributes or not.
133 unsigned int HasAttrs : 1;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000134
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000135 /// Implicit - Whether this declaration was implicitly generated by
136 /// the implementation rather than explicitly written by the user.
137 bool Implicit : 1;
138
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000139protected:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000140 /// Access - Used by C++ decls for the access specifier.
141 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
142 unsigned Access : 2;
143 friend class CXXClassMemberWrapper;
144
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000145 Decl(Kind DK, DeclContext *DC, SourceLocation L)
146 : Loc(L), NextDeclarator(0), NextDeclInScope(0),
147 DeclCtx(reinterpret_cast<uintptr_t>(DC)), DeclKind(DK), InvalidDecl(0),
148 HasAttrs(false), Implicit(false) {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000149 if (Decl::CollectingStats()) addDeclKind(DK);
150 }
Sam Bishop1bb19632008-04-11 18:04:39 +0000151
Chris Lattner0ed844b2008-04-04 06:12:32 +0000152 virtual ~Decl();
Sam Bishop1bb19632008-04-11 18:04:39 +0000153
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000154 /// setDeclContext - Set both the semantic and lexical DeclContext
155 /// to DC.
156 void setDeclContext(DeclContext *DC);
157
Sam Bishop1bb19632008-04-11 18:04:39 +0000158public:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000159 SourceLocation getLocation() const { return Loc; }
160 void setLocation(SourceLocation L) { Loc = L; }
161
162 Kind getKind() const { return DeclKind; }
163 const char *getDeclKindName() const;
164
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000165 const DeclContext *getDeclContext() const {
166 if (isInSemaDC())
167 return reinterpret_cast<DeclContext*>(DeclCtx);
168 return getMultipleDC()->SemanticDC;
169 }
170 DeclContext *getDeclContext() {
171 return const_cast<DeclContext*>(
172 const_cast<const Decl*>(this)->getDeclContext());
173 }
174
175 void setAccess(AccessSpecifier AS) { Access = AS; }
176 AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
177
Chris Lattner0ed844b2008-04-04 06:12:32 +0000178 void addAttr(Attr *attr);
179 const Attr *getAttrs() const;
Chris Lattnera212c562008-05-04 02:29:49 +0000180 void swapAttrs(Decl *D);
Nuno Lopes9141bee2008-06-01 22:53:53 +0000181 void invalidateAttrs();
Chris Lattner0ed844b2008-04-04 06:12:32 +0000182
183 template<typename T> const T *getAttr() const {
184 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
185 if (const T *V = dyn_cast<T>(attr))
186 return V;
187
188 return 0;
189 }
190
191 /// setInvalidDecl - Indicates the Decl had a semantic error. This
192 /// allows for graceful error recovery.
193 void setInvalidDecl() { InvalidDecl = 1; }
194 bool isInvalidDecl() const { return (bool) InvalidDecl; }
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000195
196 /// isImplicit - Indicates whether the declaration was implicitly
197 /// generated by the implementation. If false, this declaration
198 /// was written explicitly in the source code.
199 bool isImplicit() const { return Implicit; }
200 void setImplicit(bool I = true) { Implicit = I; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000201
202 IdentifierNamespace getIdentifierNamespace() const {
203 switch (DeclKind) {
Douglas Gregor9d350972008-12-12 08:25:50 +0000204 default:
205 if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast)
206 return IDNS_Ordinary;
207 assert(0 && "Unknown decl kind!");
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000208 case OverloadedFunction:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000209 case Typedef:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000210 case EnumConstant:
Steve Naroff248a7532008-04-15 22:42:06 +0000211 case Var:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000212 case CXXClassVar:
213 case ImplicitParam:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000214 case ParmVar:
Fariborz Jahanian73da9e42008-12-20 20:56:12 +0000215 case OriginalParmVar:
Douglas Gregor72c3f312008-12-05 18:15:24 +0000216 case NonTypeTemplateParm:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000217 case ObjCMethod:
218 case ObjCContainer:
219 case ObjCCategory:
220 case ObjCProtocol:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000221 case ObjCInterface:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000222 case ObjCCategoryImpl:
223 case ObjCProperty:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000224 case ObjCCompatibleAlias:
225 return IDNS_Ordinary;
Douglas Gregor72de6672009-01-08 20:45:30 +0000226
227 case Field:
228 case ObjCAtDefsField:
229 case ObjCIvar:
230 return IDNS_Member;
231
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000232 case Record:
233 case CXXRecord:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000234 case Enum:
Douglas Gregorefe38bd2009-01-23 22:28:29 +0000235 case TemplateTypeParm:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000236 return IDNS_Tag;
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000237
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000238 case Namespace:
239 return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000240 }
241 }
Ted Kremenek792481e2008-06-20 21:39:47 +0000242
Chris Lattnerd62fdc42009-01-06 07:16:40 +0000243 bool isInIdentifierNamespace(unsigned NS) const {
244 return getIdentifierNamespace() & NS;
245 }
246
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000247 /// getLexicalDeclContext - The declaration context where this Decl was
248 /// lexically declared (LexicalDC). May be different from
249 /// getDeclContext() (SemanticDC).
250 /// e.g.:
251 ///
252 /// namespace A {
253 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
254 /// }
255 /// void A::f(); // SemanticDC == namespace 'A'
256 /// // LexicalDC == global namespace
257 const DeclContext *getLexicalDeclContext() const {
258 if (isInSemaDC())
259 return reinterpret_cast<DeclContext*>(DeclCtx);
260 return getMultipleDC()->LexicalDC;
261 }
262 DeclContext *getLexicalDeclContext() {
263 return const_cast<DeclContext*>(
264 const_cast<const Decl*>(this)->getLexicalDeclContext());
265 }
266
267 void setLexicalDeclContext(DeclContext *DC);
268
269 /// getNextDeclarator - If this decl was part of a multi-declarator
270 /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
271 /// declarator. Otherwise it returns null.
272 Decl *getNextDeclarator() { return NextDeclarator; }
273 const Decl *getNextDeclarator() const { return NextDeclarator; }
274 void setNextDeclarator(Decl *N) { NextDeclarator = N; }
275
276 // isDefinedOutsideFunctionOrMethod - This predicate returns true if this
277 // scoped decl is defined outside the current function or method. This is
278 // roughly global variables and functions, but also handles enums (which could
279 // be defined inside or outside a function etc).
280 bool isDefinedOutsideFunctionOrMethod() const;
281
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000282 // getBody - If this Decl represents a declaration for a body of code,
Ted Kremenek792481e2008-06-20 21:39:47 +0000283 // such as a function or method definition, this method returns the top-level
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000284 // Stmt* of that body. Otherwise this method returns null.
285 virtual Stmt* getBody() const { return 0; }
Ted Kremenek792481e2008-06-20 21:39:47 +0000286
Chris Lattner0ed844b2008-04-04 06:12:32 +0000287 // global temp stats (until we have a per-module visitor)
288 static void addDeclKind(Kind k);
289 static bool CollectingStats(bool Enable = false);
290 static void PrintStats();
291
Douglas Gregorf57172b2008-12-08 18:40:42 +0000292 /// isTemplateParameter - Determines whether this declartion is a
293 /// template parameter.
294 bool isTemplateParameter() const;
295
Chris Lattner0ed844b2008-04-04 06:12:32 +0000296 // Implement isa/cast/dyncast/etc.
297 static bool classof(const Decl *) { return true; }
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000298 static DeclContext *castToDeclContext(const Decl *);
299 static Decl *castFromDeclContext(const DeclContext *);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000300
301 /// Emit - Serialize this Decl to Bitcode.
302 void Emit(llvm::Serializer& S) const;
303
304 /// Create - Deserialize a Decl from Bitcode.
Sam Bishope2563ca2008-04-07 21:55:54 +0000305 static Decl* Create(llvm::Deserializer& D, ASTContext& C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000306
Sam Bishopbb45c512008-04-11 15:01:25 +0000307 /// Destroy - Call destructors and release memory.
Ted Kremenek27f8a282008-05-20 00:43:19 +0000308 virtual void Destroy(ASTContext& C);
Sam Bishopbb45c512008-04-11 15:01:25 +0000309
Chris Lattner0ed844b2008-04-04 06:12:32 +0000310protected:
311 /// EmitImpl - Provides the subclass-specific serialization logic for
312 /// serializing out a decl.
313 virtual void EmitImpl(llvm::Serializer& S) const {
314 // FIXME: This will eventually be a pure virtual function.
315 assert (false && "Not implemented.");
316 }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000317};
318
Chris Lattnerb048c982008-04-06 04:47:34 +0000319/// DeclContext - This is used only as base class of specific decl types that
Chris Lattner0ed844b2008-04-04 06:12:32 +0000320/// can act as declaration contexts. These decls are:
321///
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000322/// TranslationUnitDecl
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000323/// NamespaceDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000324/// FunctionDecl
Douglas Gregor44b43212008-12-11 16:49:14 +0000325/// RecordDecl/CXXRecordDecl
Chris Lattnerb048c982008-04-06 04:47:34 +0000326/// EnumDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000327/// ObjCMethodDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000328/// ObjCInterfaceDecl
Douglas Gregor074149e2009-01-05 19:45:36 +0000329/// LinkageSpecDecl
Steve Naroff56ee6892008-10-08 17:01:13 +0000330/// BlockDecl
Chris Lattnerb048c982008-04-06 04:47:34 +0000331class DeclContext {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000332 /// DeclKind - This indicates which class this is.
333 Decl::Kind DeclKind : 8;
334
Douglas Gregor44b43212008-12-11 16:49:14 +0000335 /// LookupPtrKind - Describes what kind of pointer LookupPtr
336 /// actually is.
337 enum LookupPtrKind {
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000338 /// LookupIsMap - Indicates that LookupPtr is actually a map.
Douglas Gregor44b43212008-12-11 16:49:14 +0000339 LookupIsMap = 7
340 };
341
342 /// LookupPtr - Pointer to a data structure used to lookup
343 /// declarations within this context. If the context contains fewer
344 /// than seven declarations, the number of declarations is provided
345 /// in the 3 lowest-order bits and the upper bits are treated as a
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000346 /// pointer to an array of NamedDecl pointers. If the context
Douglas Gregor44b43212008-12-11 16:49:14 +0000347 /// contains seven or more declarations, the upper bits are treated
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000348 /// as a pointer to a DenseMap<DeclarationName, std::vector<NamedDecl*>>.
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000349 /// FIXME: We need a better data structure for this.
Douglas Gregor44b43212008-12-11 16:49:14 +0000350 llvm::PointerIntPair<void*, 3> LookupPtr;
351
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000352 /// FirstDecl - The first declaration stored within this declaration
353 /// context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000354 Decl *FirstDecl;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000355
356 /// LastDecl - The last declaration stored within this declaration
357 /// context. FIXME: We could probably cache this value somewhere
358 /// outside of the DeclContext, to reduce the size of DeclContext by
359 /// another pointer.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000360 Decl *LastDecl;
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000361
Chris Lattner0ed844b2008-04-04 06:12:32 +0000362 // Used in the CastTo template to get the DeclKind
Chris Lattnerb048c982008-04-06 04:47:34 +0000363 // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
Chris Lattner0ed844b2008-04-04 06:12:32 +0000364 // to avoid 'ambiguous access' compiler errors.
365 template<typename T> struct KindTrait {
366 static Decl::Kind getKind(const T *D) { return D->getKind(); }
367 };
368
369 // Used only by the ToDecl and FromDecl methods
370 template<typename To, typename From>
371 static To *CastTo(const From *D) {
372 Decl::Kind DK = KindTrait<From>::getKind(D);
373 switch(DK) {
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000374 case Decl::TranslationUnit:
375 return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000376 case Decl::Namespace:
377 return static_cast<NamespaceDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000378 case Decl::Enum:
379 return static_cast<EnumDecl*>(const_cast<From*>(D));
Douglas Gregor44b43212008-12-11 16:49:14 +0000380 case Decl::Record:
381 return static_cast<RecordDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000382 case Decl::CXXRecord:
383 return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000384 case Decl::ObjCMethod:
385 return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
386 case Decl::ObjCInterface:
387 return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
Steve Naroff0701bbb2009-01-08 17:28:14 +0000388 case Decl::ObjCCategory:
389 return static_cast<ObjCCategoryDecl*>(const_cast<From*>(D));
390 case Decl::ObjCProtocol:
391 return static_cast<ObjCProtocolDecl*>(const_cast<From*>(D));
392 case Decl::ObjCImplementation:
393 return static_cast<ObjCImplementationDecl*>(const_cast<From*>(D));
394 case Decl::ObjCCategoryImpl:
395 return static_cast<ObjCCategoryImplDecl*>(const_cast<From*>(D));
Douglas Gregor074149e2009-01-05 19:45:36 +0000396 case Decl::LinkageSpec:
397 return static_cast<LinkageSpecDecl*>(const_cast<From*>(D));
398 case Decl::Block:
399 return static_cast<BlockDecl*>(const_cast<From*>(D));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000400 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000401 if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
402 return static_cast<FunctionDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000403
Chris Lattnerb048c982008-04-06 04:47:34 +0000404 assert(false && "a decl that inherits DeclContext isn't handled");
Chris Lattner0ed844b2008-04-04 06:12:32 +0000405 return 0;
406 }
407 }
408
Douglas Gregor44b43212008-12-11 16:49:14 +0000409 /// isLookupMap - Determine if the lookup structure is a
410 /// DenseMap. Othewise, it is an array.
411 bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; }
412
Douglas Gregor0cba8552009-01-20 04:04:17 +0000413 static Decl *getNextDeclInScope(Decl *D) { return D->NextDeclInScope; }
414
Chris Lattner0ed844b2008-04-04 06:12:32 +0000415protected:
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000416 DeclContext(Decl::Kind K)
417 : DeclKind(K), LookupPtr(), FirstDecl(0), LastDecl(0) { }
Douglas Gregor44b43212008-12-11 16:49:14 +0000418
419 void DestroyDecls(ASTContext &C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000420
421public:
Douglas Gregor44b43212008-12-11 16:49:14 +0000422 ~DeclContext();
423
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000424 Decl::Kind getDeclKind() const {
425 return DeclKind;
426 }
Steve Naroff0a473932009-01-20 19:53:53 +0000427 const char *getDeclKindName() const;
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000428
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000429 /// getParent - Returns the containing DeclContext if this is a Decl,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000430 /// else returns NULL.
Argyrios Kyrtzidis20bc6762008-11-19 17:36:39 +0000431 const DeclContext *getParent() const;
432 DeclContext *getParent() {
433 return const_cast<DeclContext*>(
434 const_cast<const DeclContext*>(this)->getParent());
Argyrios Kyrtzidisd2595ec2008-10-12 18:40:01 +0000435 }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000436
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000437 /// getLexicalParent - Returns the containing lexical DeclContext. May be
Douglas Gregor44b43212008-12-11 16:49:14 +0000438 /// different from getParent, e.g.:
439 ///
440 /// namespace A {
441 /// struct S;
442 /// }
443 /// struct A::S {}; // getParent() == namespace 'A'
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000444 /// // getLexicalParent() == translation unit
445 ///
446 const DeclContext *getLexicalParent() const;
447 DeclContext *getLexicalParent() {
448 return const_cast<DeclContext*>(
449 const_cast<const DeclContext*>(this)->getLexicalParent());
450 }
451
Chris Lattner0ed844b2008-04-04 06:12:32 +0000452 bool isFunctionOrMethod() const {
453 switch (DeclKind) {
Steve Naroff56ee6892008-10-08 17:01:13 +0000454 case Decl::Block:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000455 case Decl::ObjCMethod:
456 return true;
Douglas Gregor44b43212008-12-11 16:49:14 +0000457
Chris Lattner0ed844b2008-04-04 06:12:32 +0000458 default:
Douglas Gregor44b43212008-12-11 16:49:14 +0000459 if (DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast)
460 return true;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000461 return false;
462 }
463 }
464
Argyrios Kyrtzidisef6e6472008-11-08 17:17:31 +0000465 bool isFileContext() const {
466 return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace;
467 }
468
Douglas Gregorbcbffc42009-01-07 00:43:41 +0000469 bool isRecord() const {
470 return DeclKind == Decl::Record || DeclKind == Decl::CXXRecord;
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +0000471 }
472
Douglas Gregor44b43212008-12-11 16:49:14 +0000473 bool isNamespace() const {
474 return DeclKind == Decl::Namespace;
475 }
476
Douglas Gregor074149e2009-01-05 19:45:36 +0000477 /// isTransparentContext - Determines whether this context is a
478 /// "transparent" context, meaning that the members declared in this
479 /// context are semantically declared in the nearest enclosing
480 /// non-transparent (opaque) context but are lexically declared in
481 /// this context. For example, consider the enumerators of an
482 /// enumeration type:
483 /// @code
484 /// enum E {
485 /// Val1
486 /// };
487 /// @endcode
488 /// Here, E is a transparent context, so its enumerator (Val1) will
489 /// appear (semantically) that it is in the same context of E.
490 /// Examples of transparent contexts include: enumerations (except for
491 /// C++0x scoped enums), C++ linkage specifications, and C++0x
492 /// inline namespaces.
493 bool isTransparentContext() const;
494
Argyrios Kyrtzidisef6e6472008-11-08 17:17:31 +0000495 bool Encloses(DeclContext *DC) const {
496 for (; DC; DC = DC->getParent())
497 if (DC == this)
498 return true;
499 return false;
500 }
501
Douglas Gregor44b43212008-12-11 16:49:14 +0000502 /// getPrimaryContext - There may be many different
503 /// declarations of the same entity (including forward declarations
504 /// of classes, multiple definitions of namespaces, etc.), each with
505 /// a different set of declarations. This routine returns the
506 /// "primary" DeclContext structure, which will contain the
507 /// information needed to perform name lookup into this context.
Steve Naroff0701bbb2009-01-08 17:28:14 +0000508 DeclContext *getPrimaryContext();
Douglas Gregor44b43212008-12-11 16:49:14 +0000509
Douglas Gregorce356072009-01-06 23:51:29 +0000510 /// getLookupContext - Retrieve the innermost non-transparent
511 /// context of this context, which corresponds to the innermost
512 /// location from which name lookup can find the entities in this
513 /// context.
Douglas Gregor17a9b9e2009-01-07 02:48:43 +0000514 DeclContext *getLookupContext() {
515 return const_cast<DeclContext *>(
516 const_cast<const DeclContext *>(this)->getLookupContext());
517 }
518 const DeclContext *getLookupContext() const;
Douglas Gregorce356072009-01-06 23:51:29 +0000519
Douglas Gregor44b43212008-12-11 16:49:14 +0000520 /// getNextContext - If this is a DeclContext that may have other
521 /// DeclContexts that are semantically connected but syntactically
522 /// different, such as C++ namespaces, this routine retrieves the
523 /// next DeclContext in the link. Iteration through the chain of
524 /// DeclContexts should begin at the primary DeclContext and
525 /// continue until this function returns NULL. For example, given:
526 /// @code
527 /// namespace N {
528 /// int x;
529 /// }
530 /// namespace N {
531 /// int y;
532 /// }
533 /// @endcode
534 /// The first occurrence of namespace N will be the primary
535 /// DeclContext. Its getNextContext will return the second
536 /// occurrence of namespace N.
537 DeclContext *getNextContext();
538
539 /// decl_iterator - Iterates through the declarations stored
540 /// within this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000541 class decl_iterator {
542 /// Current - The current declaration.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000543 Decl *Current;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000544
545 public:
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000546 typedef Decl* value_type;
547 typedef Decl* reference;
548 typedef Decl* pointer;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000549 typedef std::forward_iterator_tag iterator_category;
550 typedef std::ptrdiff_t difference_type;
551
552 decl_iterator() : Current(0) { }
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000553 explicit decl_iterator(Decl *C) : Current(C) { }
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000554
555 reference operator*() const { return Current; }
556 pointer operator->() const { return Current; }
557
558 decl_iterator& operator++();
559
560 decl_iterator operator++(int) {
561 decl_iterator tmp(*this);
562 ++(*this);
563 return tmp;
564 }
565
566 friend bool operator==(decl_iterator x, decl_iterator y) {
567 return x.Current == y.Current;
568 }
569 friend bool operator!=(decl_iterator x, decl_iterator y) {
570 return x.Current != y.Current;
571 }
572 };
Douglas Gregor44b43212008-12-11 16:49:14 +0000573
Douglas Gregor44b43212008-12-11 16:49:14 +0000574 /// decls_begin/decls_end - Iterate over the declarations stored in
575 /// this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000576 decl_iterator decls_begin() const { return decl_iterator(FirstDecl); }
577 decl_iterator decls_end() const { return decl_iterator(); }
Douglas Gregor44b43212008-12-11 16:49:14 +0000578
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000579 /// specific_decl_iterator - Iterates over a subrange of
580 /// declarations stored in a DeclContext, providing only those that
Douglas Gregor669c9a22009-02-02 18:25:48 +0000581 /// are of type SpecificDecl (or a class derived from it). This
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000582 /// iterator is used, for example, to provide iteration over just
Douglas Gregor669c9a22009-02-02 18:25:48 +0000583 /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000584 template<typename SpecificDecl>
585 class specific_decl_iterator {
586 /// Current - The current, underlying declaration iterator, which
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000587 /// will either be NULL or will point to a declaration of
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000588 /// type SpecificDecl.
589 DeclContext::decl_iterator Current;
590
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000591 /// SkipToNextDecl - Advances the current position up to the next
592 /// declaration of type SpecificDecl that also meets the criteria
593 /// required by Acceptable.
594 void SkipToNextDecl() {
Douglas Gregor669c9a22009-02-02 18:25:48 +0000595 while (*Current && !isa<SpecificDecl>(*Current))
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000596 ++Current;
597 }
598
599 public:
600 typedef SpecificDecl* value_type;
601 typedef SpecificDecl* reference;
602 typedef SpecificDecl* pointer;
603 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
604 difference_type;
605 typedef std::forward_iterator_tag iterator_category;
606
Douglas Gregor669c9a22009-02-02 18:25:48 +0000607 specific_decl_iterator() : Current() { }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000608
609 /// specific_decl_iterator - Construct a new iterator over a
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000610 /// subset of the declarations the range [C,
611 /// end-of-declarations). If A is non-NULL, it is a pointer to a
612 /// member function of SpecificDecl that should return true for
613 /// all of the SpecificDecl instances that will be in the subset
614 /// of iterators. For example, if you want Objective-C instance
615 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
616 /// &ObjCMethodDecl::isInstanceMethod.
Douglas Gregor669c9a22009-02-02 18:25:48 +0000617 explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000618 SkipToNextDecl();
619 }
620
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000621 reference operator*() const { return cast<SpecificDecl>(*Current); }
622 pointer operator->() const { return cast<SpecificDecl>(*Current); }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000623
624 specific_decl_iterator& operator++() {
625 ++Current;
626 SkipToNextDecl();
627 return *this;
628 }
629
630 specific_decl_iterator operator++(int) {
631 specific_decl_iterator tmp(*this);
632 ++(*this);
633 return tmp;
634 }
635
636 friend bool
637 operator==(const specific_decl_iterator& x, const specific_decl_iterator& y) {
638 return x.Current == y.Current;
639 }
640
641 friend bool
642 operator!=(const specific_decl_iterator& x, const specific_decl_iterator& y) {
643 return x.Current != y.Current;
644 }
645 };
646
Douglas Gregor669c9a22009-02-02 18:25:48 +0000647 /// \brief Iterates over a filtered subrange of declarations stored
648 /// in a DeclContext.
649 ///
650 /// This iterator visits only those declarations that are of type
651 /// SpecificDecl (or a class derived from it) and that meet some
652 /// additional run-time criteria. This iterator is used, for
653 /// example, to provide access to the instance methods within an
654 /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
655 /// Acceptable = ObjCMethodDecl::isInstanceMethod).
656 template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
657 class filtered_decl_iterator {
658 /// Current - The current, underlying declaration iterator, which
659 /// will either be NULL or will point to a declaration of
660 /// type SpecificDecl.
661 DeclContext::decl_iterator Current;
662
663 /// SkipToNextDecl - Advances the current position up to the next
664 /// declaration of type SpecificDecl that also meets the criteria
665 /// required by Acceptable.
666 void SkipToNextDecl() {
667 while (*Current &&
668 (!isa<SpecificDecl>(*Current) ||
669 (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
670 ++Current;
671 }
672
673 public:
674 typedef SpecificDecl* value_type;
675 typedef SpecificDecl* reference;
676 typedef SpecificDecl* pointer;
677 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
678 difference_type;
679 typedef std::forward_iterator_tag iterator_category;
680
681 filtered_decl_iterator() : Current() { }
682
683 /// specific_decl_iterator - Construct a new iterator over a
684 /// subset of the declarations the range [C,
685 /// end-of-declarations). If A is non-NULL, it is a pointer to a
686 /// member function of SpecificDecl that should return true for
687 /// all of the SpecificDecl instances that will be in the subset
688 /// of iterators. For example, if you want Objective-C instance
689 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
690 /// &ObjCMethodDecl::isInstanceMethod.
691 explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
692 SkipToNextDecl();
693 }
694
695 reference operator*() const { return cast<SpecificDecl>(*Current); }
696 pointer operator->() const { return cast<SpecificDecl>(*Current); }
697
698 filtered_decl_iterator& operator++() {
699 ++Current;
700 SkipToNextDecl();
701 return *this;
702 }
703
704 filtered_decl_iterator operator++(int) {
705 filtered_decl_iterator tmp(*this);
706 ++(*this);
707 return tmp;
708 }
709
710 friend bool
711 operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
712 return x.Current == y.Current;
713 }
714
715 friend bool
716 operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
717 return x.Current != y.Current;
718 }
719 };
720
Douglas Gregor40f4e692009-01-20 16:54:50 +0000721 /// @brief Add the declaration D into this context.
722 ///
723 /// This routine should be invoked when the declaration D has first
724 /// been declared, to place D into the context where it was
725 /// (lexically) defined. Every declaration must be added to one
726 /// (and only one!) context, where it can be visited via
727 /// [decls_begin(), decls_end()). Once a declaration has been added
728 /// to its lexical context, the corresponding DeclContext owns the
729 /// declaration.
730 ///
731 /// If D is also a NamedDecl, it will be made visible within its
732 /// semantic context via makeDeclVisibleInContext.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000733 void addDecl(Decl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000734
Douglas Gregor44b43212008-12-11 16:49:14 +0000735 /// lookup_iterator - An iterator that provides access to the results
736 /// of looking up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000737 typedef NamedDecl **lookup_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000738
739 /// lookup_const_iterator - An iterator that provides non-mutable
740 /// access to the results of lookup up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000741 typedef NamedDecl * const * lookup_const_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000742
743 typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
744 typedef std::pair<lookup_const_iterator, lookup_const_iterator>
745 lookup_const_result;
746
747 /// lookup - Find the declarations (if any) with the given Name in
748 /// this context. Returns a range of iterators that contains all of
Douglas Gregor40f4e692009-01-20 16:54:50 +0000749 /// the declarations with this name, with object, function, member,
750 /// and enumerator names preceding any tag name. Note that this
751 /// routine will not look into parent contexts.
Steve Naroff0701bbb2009-01-08 17:28:14 +0000752 lookup_result lookup(DeclarationName Name);
753 lookup_const_result lookup(DeclarationName Name) const;
Douglas Gregor44b43212008-12-11 16:49:14 +0000754
Douglas Gregor40f4e692009-01-20 16:54:50 +0000755 /// @brief Makes a declaration visible within this context.
756 ///
757 /// This routine makes the declaration D visible to name lookup
758 /// within this context and, if this is a transparent context,
759 /// within its parent contexts up to the first enclosing
760 /// non-transparent context. Making a declaration visible within a
761 /// context does not transfer ownership of a declaration, and a
762 /// declaration can be visible in many contexts that aren't its
763 /// lexical context.
764 ///
765 /// If D is a redeclaration of an existing declaration that is
766 /// visible from this context, as determined by
767 /// NamedDecl::declarationReplaces, the previous declaration will be
768 /// replaced with D.
769 void makeDeclVisibleInContext(NamedDecl *D);
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000770
Chris Lattner0ed844b2008-04-04 06:12:32 +0000771 static bool classof(const Decl *D) {
772 switch (D->getKind()) {
Douglas Gregor64650af2009-02-02 23:39:07 +0000773#define DECL_CONTEXT(Name) case Decl::Name:
774#include "clang/AST/DeclNodes.def"
Chris Lattner0ed844b2008-04-04 06:12:32 +0000775 return true;
776 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000777 if (D->getKind() >= Decl::FunctionFirst &&
778 D->getKind() <= Decl::FunctionLast)
779 return true;
Chris Lattnerb048c982008-04-06 04:47:34 +0000780 return false;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000781 }
782 }
Chris Lattnerb048c982008-04-06 04:47:34 +0000783 static bool classof(const DeclContext *D) { return true; }
Douglas Gregor64650af2009-02-02 23:39:07 +0000784#define DECL_CONTEXT(Name) \
785 static bool classof(const Name##Decl *D) { return true; }
786#include "clang/AST/DeclNodes.def"
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000787
788private:
Douglas Gregor40f4e692009-01-20 16:54:50 +0000789 void buildLookup(DeclContext *DCtx);
790 void makeDeclVisibleInContextImpl(NamedDecl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000791
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000792 void EmitOutRec(llvm::Serializer& S) const;
793 void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
794
795 friend class Decl;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000796};
797
Chris Lattnerb048c982008-04-06 04:47:34 +0000798template<> struct DeclContext::KindTrait<DeclContext> {
799 static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000800};
801
Douglas Gregorf57172b2008-12-08 18:40:42 +0000802inline bool Decl::isTemplateParameter() const {
803 return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm;
804}
805
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000806inline bool Decl::isDefinedOutsideFunctionOrMethod() const {
807 if (getDeclContext())
808 return !getDeclContext()->getLookupContext()->isFunctionOrMethod();
809 else
810 return true;
811}
812
813inline DeclContext::decl_iterator& DeclContext::decl_iterator::operator++() {
Douglas Gregor0cba8552009-01-20 04:04:17 +0000814 Current = getNextDeclInScope(Current);
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000815 return *this;
816}
817
Chris Lattner0ed844b2008-04-04 06:12:32 +0000818} // end clang.
819
820namespace llvm {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000821
822/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
823/// a specific Decl.
824template<class ToTy>
825struct isa_impl_wrap<ToTy,
826 const ::clang::DeclContext,const ::clang::DeclContext> {
827 static bool doit(const ::clang::DeclContext &Val) {
828 return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000829 }
830};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000831template<class ToTy>
832struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
833 : public isa_impl_wrap<ToTy,
834 const ::clang::DeclContext,const ::clang::DeclContext> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000835
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000836/// Implement cast_convert_val for Decl -> DeclContext conversions.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000837template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000838struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000839 static ::clang::DeclContext &doit(const FromTy &Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000840 return *FromTy::castToDeclContext(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000841 }
842};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000843
844template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000845struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000846 static ::clang::DeclContext *doit(const FromTy *Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000847 return FromTy::castToDeclContext(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000848 }
849};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000850
Douglas Gregor44b43212008-12-11 16:49:14 +0000851template<class FromTy>
852struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
853 static const ::clang::DeclContext &doit(const FromTy &Val) {
854 return *FromTy::castToDeclContext(&Val);
855 }
856};
857
858template<class FromTy>
859struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
860 static const ::clang::DeclContext *doit(const FromTy *Val) {
861 return FromTy::castToDeclContext(Val);
862 }
863};
864
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000865/// Implement cast_convert_val for DeclContext -> Decl conversions.
866template<class ToTy>
867struct cast_convert_val<ToTy,
868 const ::clang::DeclContext,const ::clang::DeclContext> {
869 static ToTy &doit(const ::clang::DeclContext &Val) {
870 return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
871 }
872};
873template<class ToTy>
874struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
875 : public cast_convert_val<ToTy,
876 const ::clang::DeclContext,const ::clang::DeclContext> {};
877
878template<class ToTy>
879struct cast_convert_val<ToTy,
880 const ::clang::DeclContext*, const ::clang::DeclContext*> {
881 static ToTy *doit(const ::clang::DeclContext *Val) {
882 return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
883 }
884};
885template<class ToTy>
886struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
887 : public cast_convert_val<ToTy,
888 const ::clang::DeclContext*,const ::clang::DeclContext*> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000889
890} // end namespace llvm
891
892#endif