blob: 002bab79dfa7185088697dc6822120b922a307c4 [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
Anders Carlsson1329c272009-03-25 23:38:06 +0000147#ifndef NDEBUG
148 void CheckAccessDeclContext() const;
149#else
150 void CheckAccessDeclContext() const { }
151#endif
152
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000153protected:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000154 /// Access - Used by C++ decls for the access specifier.
155 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
156 unsigned Access : 2;
157 friend class CXXClassMemberWrapper;
158
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000159 Decl(Kind DK, DeclContext *DC, SourceLocation L)
Daniel Dunbar39d76502009-03-04 02:26:41 +0000160 : NextDeclarator(0), NextDeclInScope(0),
Chris Lattner10d83792009-03-27 18:46:15 +0000161 DeclCtx(DC, 0),
Daniel Dunbar39d76502009-03-04 02:26:41 +0000162 Loc(L), DeclKind(DK), InvalidDecl(0),
Anders Carlsson1329c272009-03-25 23:38:06 +0000163 HasAttrs(false), Implicit(false), Access(AS_none) {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000164 if (Decl::CollectingStats()) addDeclKind(DK);
165 }
Sam Bishop1bb19632008-04-11 18:04:39 +0000166
Chris Lattner0ed844b2008-04-04 06:12:32 +0000167 virtual ~Decl();
Sam Bishop1bb19632008-04-11 18:04:39 +0000168
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000169 /// setDeclContext - Set both the semantic and lexical DeclContext
170 /// to DC.
171 void setDeclContext(DeclContext *DC);
172
Sam Bishop1bb19632008-04-11 18:04:39 +0000173public:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000174 SourceLocation getLocation() const { return Loc; }
175 void setLocation(SourceLocation L) { Loc = L; }
176
177 Kind getKind() const { return DeclKind; }
178 const char *getDeclKindName() const;
179
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000180 const DeclContext *getDeclContext() const {
Chris Lattner10d83792009-03-27 18:46:15 +0000181 return const_cast<Decl*>(this)->getDeclContext();
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000182 }
183 DeclContext *getDeclContext() {
Chris Lattner10d83792009-03-27 18:46:15 +0000184 if (isInSemaDC())
185 return getSemanticDC();
186 return getMultipleDC()->SemanticDC;
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000187 }
188
Anders Carlsson1329c272009-03-25 23:38:06 +0000189 void setAccess(AccessSpecifier AS) {
Anders Carlssonb8547e82009-03-25 20:19:57 +0000190 Access = AS;
Anders Carlsson1329c272009-03-25 23:38:06 +0000191 CheckAccessDeclContext();
Anders Carlssonb8547e82009-03-25 20:19:57 +0000192 }
Anders Carlsson1329c272009-03-25 23:38:06 +0000193
194 AccessSpecifier getAccess() const {
195 CheckAccessDeclContext();
196 return AccessSpecifier(Access);
197 }
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000198
Chris Lattner76a642f2009-02-15 22:43:40 +0000199 bool hasAttrs() const { return HasAttrs; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000200 void addAttr(Attr *attr);
Chris Lattner81abbdd2009-03-21 06:27:31 +0000201 const Attr *getAttrs() const {
202 if (!HasAttrs) return 0; // common case, no attributes.
203 return getAttrsImpl(); // Uncommon case, out of line hash lookup.
204 }
Chris Lattnera212c562008-05-04 02:29:49 +0000205 void swapAttrs(Decl *D);
Nuno Lopes9141bee2008-06-01 22:53:53 +0000206 void invalidateAttrs();
Chris Lattner0ed844b2008-04-04 06:12:32 +0000207
208 template<typename T> const T *getAttr() const {
209 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
210 if (const T *V = dyn_cast<T>(attr))
211 return V;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000212 return 0;
213 }
214
215 /// setInvalidDecl - Indicates the Decl had a semantic error. This
216 /// allows for graceful error recovery.
217 void setInvalidDecl() { InvalidDecl = 1; }
218 bool isInvalidDecl() const { return (bool) InvalidDecl; }
Douglas Gregor6b3945f2009-01-07 19:46:03 +0000219
220 /// isImplicit - Indicates whether the declaration was implicitly
221 /// generated by the implementation. If false, this declaration
222 /// was written explicitly in the source code.
223 bool isImplicit() const { return Implicit; }
224 void setImplicit(bool I = true) { Implicit = I; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000225
Douglas Gregorcc636682009-02-17 23:15:12 +0000226 unsigned getIdentifierNamespace() const {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000227 switch (DeclKind) {
Douglas Gregor9d350972008-12-12 08:25:50 +0000228 default:
229 if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast)
230 return IDNS_Ordinary;
231 assert(0 && "Unknown decl kind!");
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000232 case OverloadedFunction:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000233 case Typedef:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000234 case EnumConstant:
Steve Naroff248a7532008-04-15 22:42:06 +0000235 case Var:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000236 case ImplicitParam:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000237 case ParmVar:
Fariborz Jahanian73da9e42008-12-20 20:56:12 +0000238 case OriginalParmVar:
Douglas Gregor72c3f312008-12-05 18:15:24 +0000239 case NonTypeTemplateParm:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000240 case ObjCMethod:
241 case ObjCContainer:
242 case ObjCCategory:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000243 case ObjCInterface:
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000244 case ObjCCategoryImpl:
245 case ObjCProperty:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000246 case ObjCCompatibleAlias:
247 return IDNS_Ordinary;
Douglas Gregor72de6672009-01-08 20:45:30 +0000248
Douglas Gregor7dda67d2009-02-05 19:25:20 +0000249 case ObjCProtocol:
250 return IDNS_Protocol;
251
Douglas Gregor72de6672009-01-08 20:45:30 +0000252 case Field:
253 case ObjCAtDefsField:
254 case ObjCIvar:
255 return IDNS_Member;
256
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000257 case Record:
258 case CXXRecord:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000259 case Enum:
Douglas Gregorefe38bd2009-01-23 22:28:29 +0000260 case TemplateTypeParm:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000261 return IDNS_Tag;
Douglas Gregor3fd56d72009-01-23 21:30:56 +0000262
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000263 case Namespace:
Douglas Gregoraaba5e32009-02-04 19:02:06 +0000264 case Template:
265 case FunctionTemplate:
266 case ClassTemplate:
267 case TemplateTemplateParm:
Douglas Gregorcc636682009-02-17 23:15:12 +0000268 return IDNS_Tag | IDNS_Ordinary;
269
270 case ClassTemplateSpecialization:
271 return 0;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000272 }
273 }
Ted Kremenek792481e2008-06-20 21:39:47 +0000274
Chris Lattnerd62fdc42009-01-06 07:16:40 +0000275 bool isInIdentifierNamespace(unsigned NS) const {
276 return getIdentifierNamespace() & NS;
277 }
278
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000279 /// getLexicalDeclContext - The declaration context where this Decl was
280 /// lexically declared (LexicalDC). May be different from
281 /// getDeclContext() (SemanticDC).
282 /// e.g.:
283 ///
284 /// namespace A {
285 /// void f(); // SemanticDC == LexicalDC == 'namespace A'
286 /// }
287 /// void A::f(); // SemanticDC == namespace 'A'
288 /// // LexicalDC == global namespace
Chris Lattner10d83792009-03-27 18:46:15 +0000289 DeclContext *getLexicalDeclContext() {
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000290 if (isInSemaDC())
Chris Lattner10d83792009-03-27 18:46:15 +0000291 return getSemanticDC();
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000292 return getMultipleDC()->LexicalDC;
293 }
Chris Lattner10d83792009-03-27 18:46:15 +0000294 const DeclContext *getLexicalDeclContext() const {
295 return const_cast<Decl*>(this)->getLexicalDeclContext();
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000296 }
Chris Lattner10d83792009-03-27 18:46:15 +0000297
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000298 void setLexicalDeclContext(DeclContext *DC);
299
300 /// getNextDeclarator - If this decl was part of a multi-declarator
301 /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
302 /// declarator. Otherwise it returns null.
303 Decl *getNextDeclarator() { return NextDeclarator; }
304 const Decl *getNextDeclarator() const { return NextDeclarator; }
305 void setNextDeclarator(Decl *N) { NextDeclarator = N; }
306
307 // isDefinedOutsideFunctionOrMethod - This predicate returns true if this
308 // scoped decl is defined outside the current function or method. This is
309 // roughly global variables and functions, but also handles enums (which could
310 // be defined inside or outside a function etc).
311 bool isDefinedOutsideFunctionOrMethod() const;
312
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000313 // getBody - If this Decl represents a declaration for a body of code,
Ted Kremenek792481e2008-06-20 21:39:47 +0000314 // such as a function or method definition, this method returns the top-level
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000315 // Stmt* of that body. Otherwise this method returns null.
Ted Kremenekeaab2062009-03-12 18:33:24 +0000316 virtual CompoundStmt* getBody() const { return 0; }
Ted Kremenek792481e2008-06-20 21:39:47 +0000317
Chris Lattner0ed844b2008-04-04 06:12:32 +0000318 // global temp stats (until we have a per-module visitor)
319 static void addDeclKind(Kind k);
320 static bool CollectingStats(bool Enable = false);
321 static void PrintStats();
322
Douglas Gregorf57172b2008-12-08 18:40:42 +0000323 /// isTemplateParameter - Determines whether this declartion is a
324 /// template parameter.
325 bool isTemplateParameter() const;
326
Chris Lattner0ed844b2008-04-04 06:12:32 +0000327 // Implement isa/cast/dyncast/etc.
328 static bool classof(const Decl *) { return true; }
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000329 static DeclContext *castToDeclContext(const Decl *);
330 static Decl *castFromDeclContext(const DeclContext *);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000331
332 /// Emit - Serialize this Decl to Bitcode.
333 void Emit(llvm::Serializer& S) const;
334
335 /// Create - Deserialize a Decl from Bitcode.
Sam Bishope2563ca2008-04-07 21:55:54 +0000336 static Decl* Create(llvm::Deserializer& D, ASTContext& C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000337
Sam Bishopbb45c512008-04-11 15:01:25 +0000338 /// Destroy - Call destructors and release memory.
Ted Kremenek27f8a282008-05-20 00:43:19 +0000339 virtual void Destroy(ASTContext& C);
Sam Bishopbb45c512008-04-11 15:01:25 +0000340
Chris Lattner0ed844b2008-04-04 06:12:32 +0000341protected:
342 /// EmitImpl - Provides the subclass-specific serialization logic for
343 /// serializing out a decl.
344 virtual void EmitImpl(llvm::Serializer& S) const {
345 // FIXME: This will eventually be a pure virtual function.
346 assert (false && "Not implemented.");
347 }
Chris Lattner81abbdd2009-03-21 06:27:31 +0000348private:
349 const Attr *getAttrsImpl() const;
350
Chris Lattner0ed844b2008-04-04 06:12:32 +0000351};
352
Chris Lattner49f28ca2009-03-05 08:00:35 +0000353/// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when
354/// doing something to a specific decl.
355class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
356 Decl *TheDecl;
357 SourceLocation Loc;
358 SourceManager &SM;
359 const char *Message;
360public:
361 PrettyStackTraceDecl(Decl *theDecl, SourceLocation L,
362 SourceManager &sm, const char *Msg)
363 : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
364
365 virtual void print(llvm::raw_ostream &OS) const;
366};
367
368
Chris Lattnerb048c982008-04-06 04:47:34 +0000369/// DeclContext - This is used only as base class of specific decl types that
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000370/// can act as declaration contexts. These decls are (only the top classes
371/// that directly derive from DeclContext are mentioned, not their subclasses):
Chris Lattner0ed844b2008-04-04 06:12:32 +0000372///
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000373/// TranslationUnitDecl
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000374/// NamespaceDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000375/// FunctionDecl
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000376/// TagDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000377/// ObjCMethodDecl
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000378/// ObjCContainerDecl
379/// ObjCCategoryImplDecl
380/// ObjCImplementationDecl
Douglas Gregor074149e2009-01-05 19:45:36 +0000381/// LinkageSpecDecl
Steve Naroff56ee6892008-10-08 17:01:13 +0000382/// BlockDecl
Argyrios Kyrtzidis1ad4dd72009-02-16 14:28:33 +0000383///
Chris Lattnerb048c982008-04-06 04:47:34 +0000384class DeclContext {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000385 /// DeclKind - This indicates which class this is.
386 Decl::Kind DeclKind : 8;
387
Douglas Gregor44b43212008-12-11 16:49:14 +0000388 /// LookupPtrKind - Describes what kind of pointer LookupPtr
389 /// actually is.
390 enum LookupPtrKind {
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000391 /// LookupIsMap - Indicates that LookupPtr is actually a map.
Douglas Gregor44b43212008-12-11 16:49:14 +0000392 LookupIsMap = 7
393 };
394
395 /// LookupPtr - Pointer to a data structure used to lookup
396 /// declarations within this context. If the context contains fewer
397 /// than seven declarations, the number of declarations is provided
398 /// in the 3 lowest-order bits and the upper bits are treated as a
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000399 /// pointer to an array of NamedDecl pointers. If the context
Douglas Gregor44b43212008-12-11 16:49:14 +0000400 /// contains seven or more declarations, the upper bits are treated
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000401 /// as a pointer to a DenseMap<DeclarationName, std::vector<NamedDecl*>>.
Douglas Gregor3fc749d2008-12-23 00:26:44 +0000402 /// FIXME: We need a better data structure for this.
Douglas Gregor44b43212008-12-11 16:49:14 +0000403 llvm::PointerIntPair<void*, 3> LookupPtr;
404
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000405 /// FirstDecl - The first declaration stored within this declaration
406 /// context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000407 Decl *FirstDecl;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000408
409 /// LastDecl - The last declaration stored within this declaration
410 /// context. FIXME: We could probably cache this value somewhere
411 /// outside of the DeclContext, to reduce the size of DeclContext by
412 /// another pointer.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000413 Decl *LastDecl;
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000414
Douglas Gregor44b43212008-12-11 16:49:14 +0000415 /// isLookupMap - Determine if the lookup structure is a
416 /// DenseMap. Othewise, it is an array.
417 bool isLookupMap() const { return LookupPtr.getInt() == LookupIsMap; }
418
Douglas Gregor0cba8552009-01-20 04:04:17 +0000419 static Decl *getNextDeclInScope(Decl *D) { return D->NextDeclInScope; }
420
Chris Lattner0ed844b2008-04-04 06:12:32 +0000421protected:
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000422 DeclContext(Decl::Kind K)
423 : DeclKind(K), LookupPtr(), FirstDecl(0), LastDecl(0) { }
Douglas Gregor44b43212008-12-11 16:49:14 +0000424
425 void DestroyDecls(ASTContext &C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000426
427public:
Douglas Gregor44b43212008-12-11 16:49:14 +0000428 ~DeclContext();
429
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000430 Decl::Kind getDeclKind() const {
431 return DeclKind;
432 }
Steve Naroff0a473932009-01-20 19:53:53 +0000433 const char *getDeclKindName() const;
Argyrios Kyrtzidis9b9ca012009-01-13 13:11:58 +0000434
Argyrios Kyrtzidis305ec422009-02-17 20:26:05 +0000435 /// getParent - Returns the containing DeclContext.
436 const DeclContext *getParent() const {
437 return cast<Decl>(this)->getDeclContext();
438 }
Argyrios Kyrtzidis20bc6762008-11-19 17:36:39 +0000439 DeclContext *getParent() {
440 return const_cast<DeclContext*>(
441 const_cast<const DeclContext*>(this)->getParent());
Argyrios Kyrtzidisd2595ec2008-10-12 18:40:01 +0000442 }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000443
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000444 /// getLexicalParent - Returns the containing lexical DeclContext. May be
Douglas Gregor44b43212008-12-11 16:49:14 +0000445 /// different from getParent, e.g.:
446 ///
447 /// namespace A {
448 /// struct S;
449 /// }
450 /// struct A::S {}; // getParent() == namespace 'A'
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000451 /// // getLexicalParent() == translation unit
452 ///
Argyrios Kyrtzidis305ec422009-02-17 20:26:05 +0000453 const DeclContext *getLexicalParent() const {
454 return cast<Decl>(this)->getLexicalDeclContext();
455 }
Argyrios Kyrtzidis77407b82008-11-19 18:01:13 +0000456 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 {
Douglas Gregor65100792009-02-26 00:02:51 +0000483 return DeclKind >= Decl::RecordFirst && DeclKind <= Decl::RecordLast;
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 Gregor88b70942009-02-25 22:02:03 +0000533 /// \brief Retrieve the nearest enclosing namespace context.
534 DeclContext *getEnclosingNamespaceContext();
535 const DeclContext *getEnclosingNamespaceContext() const {
536 return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
537 }
538
Douglas Gregor44b43212008-12-11 16:49:14 +0000539 /// getNextContext - If this is a DeclContext that may have other
540 /// DeclContexts that are semantically connected but syntactically
541 /// different, such as C++ namespaces, this routine retrieves the
542 /// next DeclContext in the link. Iteration through the chain of
543 /// DeclContexts should begin at the primary DeclContext and
544 /// continue until this function returns NULL. For example, given:
545 /// @code
546 /// namespace N {
547 /// int x;
548 /// }
549 /// namespace N {
550 /// int y;
551 /// }
552 /// @endcode
553 /// The first occurrence of namespace N will be the primary
554 /// DeclContext. Its getNextContext will return the second
555 /// occurrence of namespace N.
556 DeclContext *getNextContext();
557
558 /// decl_iterator - Iterates through the declarations stored
559 /// within this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000560 class decl_iterator {
561 /// Current - The current declaration.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000562 Decl *Current;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000563
564 public:
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000565 typedef Decl* value_type;
566 typedef Decl* reference;
567 typedef Decl* pointer;
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000568 typedef std::forward_iterator_tag iterator_category;
569 typedef std::ptrdiff_t difference_type;
570
571 decl_iterator() : Current(0) { }
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000572 explicit decl_iterator(Decl *C) : Current(C) { }
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000573
574 reference operator*() const { return Current; }
575 pointer operator->() const { return Current; }
576
577 decl_iterator& operator++();
578
579 decl_iterator operator++(int) {
580 decl_iterator tmp(*this);
581 ++(*this);
582 return tmp;
583 }
584
585 friend bool operator==(decl_iterator x, decl_iterator y) {
586 return x.Current == y.Current;
587 }
588 friend bool operator!=(decl_iterator x, decl_iterator y) {
589 return x.Current != y.Current;
590 }
591 };
Douglas Gregor44b43212008-12-11 16:49:14 +0000592
Douglas Gregor44b43212008-12-11 16:49:14 +0000593 /// decls_begin/decls_end - Iterate over the declarations stored in
594 /// this context.
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000595 decl_iterator decls_begin() const { return decl_iterator(FirstDecl); }
596 decl_iterator decls_end() const { return decl_iterator(); }
Douglas Gregor44b43212008-12-11 16:49:14 +0000597
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000598 /// specific_decl_iterator - Iterates over a subrange of
599 /// declarations stored in a DeclContext, providing only those that
Douglas Gregor669c9a22009-02-02 18:25:48 +0000600 /// are of type SpecificDecl (or a class derived from it). This
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000601 /// iterator is used, for example, to provide iteration over just
Douglas Gregor669c9a22009-02-02 18:25:48 +0000602 /// the fields within a RecordDecl (with SpecificDecl = FieldDecl).
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000603 template<typename SpecificDecl>
604 class specific_decl_iterator {
605 /// Current - The current, underlying declaration iterator, which
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000606 /// will either be NULL or will point to a declaration of
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000607 /// type SpecificDecl.
608 DeclContext::decl_iterator Current;
609
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000610 /// SkipToNextDecl - Advances the current position up to the next
611 /// declaration of type SpecificDecl that also meets the criteria
612 /// required by Acceptable.
613 void SkipToNextDecl() {
Douglas Gregor669c9a22009-02-02 18:25:48 +0000614 while (*Current && !isa<SpecificDecl>(*Current))
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000615 ++Current;
616 }
617
618 public:
619 typedef SpecificDecl* value_type;
620 typedef SpecificDecl* reference;
621 typedef SpecificDecl* pointer;
622 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
623 difference_type;
624 typedef std::forward_iterator_tag iterator_category;
625
Douglas Gregor669c9a22009-02-02 18:25:48 +0000626 specific_decl_iterator() : Current() { }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000627
628 /// specific_decl_iterator - Construct a new iterator over a
Douglas Gregord6f0b4e2009-02-02 17:56:05 +0000629 /// subset of the declarations the range [C,
630 /// end-of-declarations). If A is non-NULL, it is a pointer to a
631 /// member function of SpecificDecl that should return true for
632 /// all of the SpecificDecl instances that will be in the subset
633 /// of iterators. For example, if you want Objective-C instance
634 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
635 /// &ObjCMethodDecl::isInstanceMethod.
Douglas Gregor669c9a22009-02-02 18:25:48 +0000636 explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000637 SkipToNextDecl();
638 }
639
Douglas Gregor6037fcb2009-01-09 19:42:16 +0000640 reference operator*() const { return cast<SpecificDecl>(*Current); }
641 pointer operator->() const { return cast<SpecificDecl>(*Current); }
Douglas Gregorf8d49f62009-01-09 17:18:27 +0000642
643 specific_decl_iterator& operator++() {
644 ++Current;
645 SkipToNextDecl();
646 return *this;
647 }
648
649 specific_decl_iterator operator++(int) {
650 specific_decl_iterator tmp(*this);
651 ++(*this);
652 return tmp;
653 }
654
655 friend bool
656 operator==(const specific_decl_iterator& x, const specific_decl_iterator& y) {
657 return x.Current == y.Current;
658 }
659
660 friend bool
661 operator!=(const specific_decl_iterator& x, const specific_decl_iterator& y) {
662 return x.Current != y.Current;
663 }
664 };
665
Douglas Gregor669c9a22009-02-02 18:25:48 +0000666 /// \brief Iterates over a filtered subrange of declarations stored
667 /// in a DeclContext.
668 ///
669 /// This iterator visits only those declarations that are of type
670 /// SpecificDecl (or a class derived from it) and that meet some
671 /// additional run-time criteria. This iterator is used, for
672 /// example, to provide access to the instance methods within an
673 /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and
674 /// Acceptable = ObjCMethodDecl::isInstanceMethod).
675 template<typename SpecificDecl, bool (SpecificDecl::*Acceptable)() const>
676 class filtered_decl_iterator {
677 /// Current - The current, underlying declaration iterator, which
678 /// will either be NULL or will point to a declaration of
679 /// type SpecificDecl.
680 DeclContext::decl_iterator Current;
681
682 /// SkipToNextDecl - Advances the current position up to the next
683 /// declaration of type SpecificDecl that also meets the criteria
684 /// required by Acceptable.
685 void SkipToNextDecl() {
686 while (*Current &&
687 (!isa<SpecificDecl>(*Current) ||
688 (Acceptable && !(cast<SpecificDecl>(*Current)->*Acceptable)())))
689 ++Current;
690 }
691
692 public:
693 typedef SpecificDecl* value_type;
694 typedef SpecificDecl* reference;
695 typedef SpecificDecl* pointer;
696 typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type
697 difference_type;
698 typedef std::forward_iterator_tag iterator_category;
699
700 filtered_decl_iterator() : Current() { }
701
702 /// specific_decl_iterator - Construct a new iterator over a
703 /// subset of the declarations the range [C,
704 /// end-of-declarations). If A is non-NULL, it is a pointer to a
705 /// member function of SpecificDecl that should return true for
706 /// all of the SpecificDecl instances that will be in the subset
707 /// of iterators. For example, if you want Objective-C instance
708 /// methods, SpecificDecl will be ObjCMethodDecl and A will be
709 /// &ObjCMethodDecl::isInstanceMethod.
710 explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) {
711 SkipToNextDecl();
712 }
713
714 reference operator*() const { return cast<SpecificDecl>(*Current); }
715 pointer operator->() const { return cast<SpecificDecl>(*Current); }
716
717 filtered_decl_iterator& operator++() {
718 ++Current;
719 SkipToNextDecl();
720 return *this;
721 }
722
723 filtered_decl_iterator operator++(int) {
724 filtered_decl_iterator tmp(*this);
725 ++(*this);
726 return tmp;
727 }
728
729 friend bool
730 operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
731 return x.Current == y.Current;
732 }
733
734 friend bool
735 operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) {
736 return x.Current != y.Current;
737 }
738 };
739
Douglas Gregor40f4e692009-01-20 16:54:50 +0000740 /// @brief Add the declaration D into this context.
741 ///
742 /// This routine should be invoked when the declaration D has first
743 /// been declared, to place D into the context where it was
744 /// (lexically) defined. Every declaration must be added to one
745 /// (and only one!) context, where it can be visited via
746 /// [decls_begin(), decls_end()). Once a declaration has been added
747 /// to its lexical context, the corresponding DeclContext owns the
748 /// declaration.
749 ///
750 /// If D is also a NamedDecl, it will be made visible within its
751 /// semantic context via makeDeclVisibleInContext.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000752 void addDecl(Decl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000753
Douglas Gregor44b43212008-12-11 16:49:14 +0000754 /// lookup_iterator - An iterator that provides access to the results
755 /// of looking up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000756 typedef NamedDecl **lookup_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000757
758 /// lookup_const_iterator - An iterator that provides non-mutable
759 /// access to the results of lookup up a name within this context.
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000760 typedef NamedDecl * const * lookup_const_iterator;
Douglas Gregor44b43212008-12-11 16:49:14 +0000761
762 typedef std::pair<lookup_iterator, lookup_iterator> lookup_result;
763 typedef std::pair<lookup_const_iterator, lookup_const_iterator>
764 lookup_const_result;
765
766 /// lookup - Find the declarations (if any) with the given Name in
767 /// this context. Returns a range of iterators that contains all of
Douglas Gregor40f4e692009-01-20 16:54:50 +0000768 /// the declarations with this name, with object, function, member,
769 /// and enumerator names preceding any tag name. Note that this
770 /// routine will not look into parent contexts.
Steve Naroff0701bbb2009-01-08 17:28:14 +0000771 lookup_result lookup(DeclarationName Name);
772 lookup_const_result lookup(DeclarationName Name) const;
Douglas Gregor44b43212008-12-11 16:49:14 +0000773
Douglas Gregor40f4e692009-01-20 16:54:50 +0000774 /// @brief Makes a declaration visible within this context.
775 ///
776 /// This routine makes the declaration D visible to name lookup
777 /// within this context and, if this is a transparent context,
778 /// within its parent contexts up to the first enclosing
779 /// non-transparent context. Making a declaration visible within a
780 /// context does not transfer ownership of a declaration, and a
781 /// declaration can be visible in many contexts that aren't its
782 /// lexical context.
783 ///
784 /// If D is a redeclaration of an existing declaration that is
785 /// visible from this context, as determined by
786 /// NamedDecl::declarationReplaces, the previous declaration will be
787 /// replaced with D.
788 void makeDeclVisibleInContext(NamedDecl *D);
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000789
Douglas Gregor2a3009a2009-02-03 19:21:40 +0000790 /// udir_iterator - Iterates through the using-directives stored
791 /// within this context.
792 typedef UsingDirectiveDecl * const * udir_iterator;
793
794 typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
795
796 udir_iterator_range getUsingDirectives() const;
797
798 udir_iterator using_directives_begin() const {
799 return getUsingDirectives().first;
800 }
801
802 udir_iterator using_directives_end() const {
803 return getUsingDirectives().second;
804 }
805
Argyrios Kyrtzidis3d7641e2009-02-16 14:29:28 +0000806 static bool classof(const Decl *D);
Chris Lattnerb048c982008-04-06 04:47:34 +0000807 static bool classof(const DeclContext *D) { return true; }
Douglas Gregor64650af2009-02-02 23:39:07 +0000808#define DECL_CONTEXT(Name) \
809 static bool classof(const Name##Decl *D) { return true; }
810#include "clang/AST/DeclNodes.def"
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000811
812private:
Douglas Gregor40f4e692009-01-20 16:54:50 +0000813 void buildLookup(DeclContext *DCtx);
814 void makeDeclVisibleInContextImpl(NamedDecl *D);
Douglas Gregor44b43212008-12-11 16:49:14 +0000815
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000816 void EmitOutRec(llvm::Serializer& S) const;
817 void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
818
819 friend class Decl;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000820};
821
Douglas Gregorf57172b2008-12-08 18:40:42 +0000822inline bool Decl::isTemplateParameter() const {
823 return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm;
824}
825
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000826inline bool Decl::isDefinedOutsideFunctionOrMethod() const {
827 if (getDeclContext())
828 return !getDeclContext()->getLookupContext()->isFunctionOrMethod();
829 else
830 return true;
831}
832
833inline DeclContext::decl_iterator& DeclContext::decl_iterator::operator++() {
Douglas Gregor0cba8552009-01-20 04:04:17 +0000834 Current = getNextDeclInScope(Current);
Douglas Gregor4afa39d2009-01-20 01:17:11 +0000835 return *this;
836}
837
Chris Lattner0ed844b2008-04-04 06:12:32 +0000838} // end clang.
839
840namespace llvm {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000841
842/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
843/// a specific Decl.
844template<class ToTy>
845struct isa_impl_wrap<ToTy,
846 const ::clang::DeclContext,const ::clang::DeclContext> {
847 static bool doit(const ::clang::DeclContext &Val) {
848 return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000849 }
850};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000851template<class ToTy>
852struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
853 : public isa_impl_wrap<ToTy,
854 const ::clang::DeclContext,const ::clang::DeclContext> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000855
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000856/// Implement cast_convert_val for Decl -> DeclContext conversions.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000857template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000858struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000859 static ::clang::DeclContext &doit(const FromTy &Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000860 return *FromTy::castToDeclContext(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000861 }
862};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000863
864template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000865struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000866 static ::clang::DeclContext *doit(const FromTy *Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000867 return FromTy::castToDeclContext(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000868 }
869};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000870
Douglas Gregor44b43212008-12-11 16:49:14 +0000871template<class FromTy>
872struct cast_convert_val< const ::clang::DeclContext, FromTy, FromTy> {
873 static const ::clang::DeclContext &doit(const FromTy &Val) {
874 return *FromTy::castToDeclContext(&Val);
875 }
876};
877
878template<class FromTy>
879struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> {
880 static const ::clang::DeclContext *doit(const FromTy *Val) {
881 return FromTy::castToDeclContext(Val);
882 }
883};
884
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000885/// Implement cast_convert_val for DeclContext -> Decl conversions.
886template<class ToTy>
887struct cast_convert_val<ToTy,
888 const ::clang::DeclContext,const ::clang::DeclContext> {
889 static ToTy &doit(const ::clang::DeclContext &Val) {
890 return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
891 }
892};
893template<class ToTy>
894struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
895 : public cast_convert_val<ToTy,
896 const ::clang::DeclContext,const ::clang::DeclContext> {};
897
898template<class ToTy>
899struct cast_convert_val<ToTy,
900 const ::clang::DeclContext*, const ::clang::DeclContext*> {
901 static ToTy *doit(const ::clang::DeclContext *Val) {
902 return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
903 }
904};
905template<class ToTy>
906struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
907 : public cast_convert_val<ToTy,
908 const ::clang::DeclContext*,const ::clang::DeclContext*> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000909
910} // end namespace llvm
911
912#endif