blob: 7670798d1319b79419208c7348ca4f0bac0083f3 [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"
19#include "clang/Basic/SourceLocation.h"
20
21namespace clang {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +000022class DeclContext;
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +000023class TranslationUnitDecl;
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000024class NamespaceDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000025class ScopedDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000026class FunctionDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000027class CXXRecordDecl;
Chris Lattnerb048c982008-04-06 04:47:34 +000028class EnumDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000029class ObjCMethodDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000030class ObjCInterfaceDecl;
Steve Naroff56ee6892008-10-08 17:01:13 +000031class BlockDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000032
33/// Decl - This represents one declaration (or definition), e.g. a variable,
34/// typedef, function, struct, etc.
35///
36class Decl {
37public:
38 enum Kind {
39 // This lists the concrete classes of Decl in order of the inheritance
40 // hierarchy. This allows us to do efficient classof tests based on the
41 // enums below. The commented out names are abstract class names.
Ted Kremeneka34ea072008-08-04 22:51:42 +000042 // [DeclContext] indicates that the class also inherits from DeclContext.
Chris Lattner0ed844b2008-04-04 06:12:32 +000043
44 // Decl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000045 TranslationUnit, // [DeclContext]
Chris Lattner0ed844b2008-04-04 06:12:32 +000046 // NamedDecl
47 Field,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000048 CXXField,
Chris Lattner0ed844b2008-04-04 06:12:32 +000049 ObjCIvar,
Ted Kremenek01e67792008-08-20 03:26:33 +000050 ObjCAtDefsField,
Douglas Gregor8e9bebd2008-10-21 16:13:35 +000051 OverloadedFunction,
Chris Lattner0ed844b2008-04-04 06:12:32 +000052 ObjCCategory,
53 ObjCCategoryImpl,
54 ObjCImplementation,
55 ObjCProtocol,
Sam Bishop670aa9d2008-04-08 20:49:25 +000056 ObjCProperty,
Chris Lattner0ed844b2008-04-04 06:12:32 +000057 // ScopedDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000058 Namespace, // [DeclContext]
Chris Lattner0ed844b2008-04-04 06:12:32 +000059 // TypeDecl
60 Typedef,
61 // TagDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000062 Enum, // [DeclContext]
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +000063 Record,
64 CXXRecord, // [DeclContext]
Chris Lattner0ed844b2008-04-04 06:12:32 +000065 // ValueDecl
66 EnumConstant,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000067 Function, // [DeclContext]
68 CXXMethod,
Douglas Gregorb48fe382008-10-31 09:07:45 +000069 CXXConstructor,
Douglas Gregor42a552f2008-11-05 20:51:48 +000070 CXXDestructor,
Douglas Gregor2f1bc522008-11-07 20:08:42 +000071 CXXConversion,
Steve Naroff248a7532008-04-15 22:42:06 +000072 Var,
Chris Lattner41110242008-06-17 18:05:57 +000073 ImplicitParam,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000074 CXXClassVar,
Chris Lattner0ed844b2008-04-04 06:12:32 +000075 ParmVar,
Daniel Dunbar226e04a2008-08-15 23:18:35 +000076 ObjCInterface, // [DeclContext]
77 ObjCCompatibleAlias,
78 ObjCMethod, // [DeclContext]
79 ObjCClass,
80 ObjCForwardProtocol,
81 ObjCPropertyImpl,
Chris Lattner0ed844b2008-04-04 06:12:32 +000082 LinkageSpec,
Daniel Dunbar226e04a2008-08-15 23:18:35 +000083 FileScopeAsm,
Steve Naroff56ee6892008-10-08 17:01:13 +000084 Block, // [DeclContext]
Chris Lattner0ed844b2008-04-04 06:12:32 +000085
86 // For each non-leaf class, we now define a mapping to the first/last member
87 // of the class, to allow efficient classof.
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000088 NamedFirst = Field , NamedLast = ParmVar,
Ted Kremenek01e67792008-08-20 03:26:33 +000089 FieldFirst = Field , FieldLast = ObjCAtDefsField,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000090 ScopedFirst = Namespace , ScopedLast = ParmVar,
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +000091 TypeFirst = Typedef , TypeLast = CXXRecord,
92 TagFirst = Enum , TagLast = CXXRecord,
93 RecordFirst = Record , RecordLast = CXXRecord,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000094 ValueFirst = EnumConstant , ValueLast = ParmVar,
Douglas Gregor2f1bc522008-11-07 20:08:42 +000095 FunctionFirst = Function , FunctionLast = CXXConversion,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000096 VarFirst = Var , VarLast = ParmVar
Chris Lattner0ed844b2008-04-04 06:12:32 +000097 };
98
99 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
Douglas Gregor2ce52f32008-04-13 21:07:44 +0000100 /// labels, tags, members and ordinary identifiers. These are meant
101 /// as bitmasks, so that searches in C++ can look into the "tag" namespace
102 /// during ordinary lookup.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000103 enum IdentifierNamespace {
Douglas Gregor2ce52f32008-04-13 21:07:44 +0000104 IDNS_Label = 0x1,
105 IDNS_Tag = 0x2,
106 IDNS_Member = 0x4,
107 IDNS_Ordinary = 0x8
Chris Lattner0ed844b2008-04-04 06:12:32 +0000108 };
109
110 /// ObjCDeclQualifier - Qualifier used on types in method declarations
111 /// for remote messaging. They are meant for the arguments though and
112 /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
113 enum ObjCDeclQualifier {
114 OBJC_TQ_None = 0x0,
115 OBJC_TQ_In = 0x1,
116 OBJC_TQ_Inout = 0x2,
117 OBJC_TQ_Out = 0x4,
118 OBJC_TQ_Bycopy = 0x8,
119 OBJC_TQ_Byref = 0x10,
120 OBJC_TQ_Oneway = 0x20
121 };
122
123private:
124 /// Loc - The location that this decl.
125 SourceLocation Loc;
126
127 /// DeclKind - This indicates which class this is.
128 Kind DeclKind : 8;
129
130 /// InvalidDecl - This indicates a semantic error occurred.
131 unsigned int InvalidDecl : 1;
132
133 /// HasAttrs - This indicates whether the decl has attributes or not.
134 unsigned int HasAttrs : 1;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000135
136 protected:
137 /// Access - Used by C++ decls for the access specifier.
138 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
139 unsigned Access : 2;
140 friend class CXXClassMemberWrapper;
141
Chris Lattner0ed844b2008-04-04 06:12:32 +0000142 Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
143 HasAttrs(false) {
144 if (Decl::CollectingStats()) addDeclKind(DK);
145 }
Sam Bishop1bb19632008-04-11 18:04:39 +0000146
Chris Lattner0ed844b2008-04-04 06:12:32 +0000147 virtual ~Decl();
Sam Bishop1bb19632008-04-11 18:04:39 +0000148
149public:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000150 SourceLocation getLocation() const { return Loc; }
151 void setLocation(SourceLocation L) { Loc = L; }
152
153 Kind getKind() const { return DeclKind; }
154 const char *getDeclKindName() const;
155
156 void addAttr(Attr *attr);
157 const Attr *getAttrs() const;
Chris Lattnera212c562008-05-04 02:29:49 +0000158 void swapAttrs(Decl *D);
Nuno Lopes9141bee2008-06-01 22:53:53 +0000159 void invalidateAttrs();
Chris Lattner0ed844b2008-04-04 06:12:32 +0000160
161 template<typename T> const T *getAttr() const {
162 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
163 if (const T *V = dyn_cast<T>(attr))
164 return V;
165
166 return 0;
167 }
168
169 /// setInvalidDecl - Indicates the Decl had a semantic error. This
170 /// allows for graceful error recovery.
171 void setInvalidDecl() { InvalidDecl = 1; }
172 bool isInvalidDecl() const { return (bool) InvalidDecl; }
173
174 IdentifierNamespace getIdentifierNamespace() const {
175 switch (DeclKind) {
176 default: assert(0 && "Unknown decl kind!");
Chris Lattner41110242008-06-17 18:05:57 +0000177 case ImplicitParam:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000178 case Typedef:
179 case Function:
Steve Naroff248a7532008-04-15 22:42:06 +0000180 case Var:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000181 case ParmVar:
182 case EnumConstant:
183 case ObjCInterface:
184 case ObjCCompatibleAlias:
Douglas Gregor8e9bebd2008-10-21 16:13:35 +0000185 case OverloadedFunction:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000186 case CXXField:
Argyrios Kyrtzidis1ce6ead2008-06-24 22:56:42 +0000187 case CXXMethod:
Argyrios Kyrtzidis09c31b02008-06-25 14:04:17 +0000188 case CXXClassVar:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000189 return IDNS_Ordinary;
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000190 case Record:
191 case CXXRecord:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000192 case Enum:
193 return IDNS_Tag;
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000194 case Namespace:
195 return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000196 }
197 }
Ted Kremenek792481e2008-06-20 21:39:47 +0000198
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000199 // getBody - If this Decl represents a declaration for a body of code,
Ted Kremenek792481e2008-06-20 21:39:47 +0000200 // such as a function or method definition, this method returns the top-level
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000201 // Stmt* of that body. Otherwise this method returns null.
202 virtual Stmt* getBody() const { return 0; }
Ted Kremenek792481e2008-06-20 21:39:47 +0000203
Chris Lattner0ed844b2008-04-04 06:12:32 +0000204 // global temp stats (until we have a per-module visitor)
205 static void addDeclKind(Kind k);
206 static bool CollectingStats(bool Enable = false);
207 static void PrintStats();
208
209 // Implement isa/cast/dyncast/etc.
210 static bool classof(const Decl *) { return true; }
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000211 static DeclContext *castToDeclContext(const Decl *);
212 static Decl *castFromDeclContext(const DeclContext *);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000213
214 /// Emit - Serialize this Decl to Bitcode.
215 void Emit(llvm::Serializer& S) const;
216
217 /// Create - Deserialize a Decl from Bitcode.
Sam Bishope2563ca2008-04-07 21:55:54 +0000218 static Decl* Create(llvm::Deserializer& D, ASTContext& C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000219
Sam Bishopbb45c512008-04-11 15:01:25 +0000220 /// Destroy - Call destructors and release memory.
Ted Kremenek27f8a282008-05-20 00:43:19 +0000221 virtual void Destroy(ASTContext& C);
Sam Bishopbb45c512008-04-11 15:01:25 +0000222
Chris Lattner0ed844b2008-04-04 06:12:32 +0000223protected:
224 /// EmitImpl - Provides the subclass-specific serialization logic for
225 /// serializing out a decl.
226 virtual void EmitImpl(llvm::Serializer& S) const {
227 // FIXME: This will eventually be a pure virtual function.
228 assert (false && "Not implemented.");
229 }
230
231 void EmitInRec(llvm::Serializer& S) const;
Sam Bishope2563ca2008-04-07 21:55:54 +0000232 void ReadInRec(llvm::Deserializer& D, ASTContext& C);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000233};
234
Chris Lattnerb048c982008-04-06 04:47:34 +0000235/// DeclContext - This is used only as base class of specific decl types that
Chris Lattner0ed844b2008-04-04 06:12:32 +0000236/// can act as declaration contexts. These decls are:
237///
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000238/// TranslationUnitDecl
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000239/// NamespaceDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000240/// FunctionDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000241/// CXXRecordDecl
Chris Lattnerb048c982008-04-06 04:47:34 +0000242/// EnumDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000243/// ObjCMethodDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000244/// ObjCInterfaceDecl
Steve Naroff56ee6892008-10-08 17:01:13 +0000245/// BlockDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000246///
Chris Lattnerb048c982008-04-06 04:47:34 +0000247class DeclContext {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000248 /// DeclKind - This indicates which class this is.
249 Decl::Kind DeclKind : 8;
250
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000251 /// DeclChain - Linked list of declarations that are defined inside this
252 /// declaration context.
253 ScopedDecl *DeclChain;
254
Chris Lattner0ed844b2008-04-04 06:12:32 +0000255 // Used in the CastTo template to get the DeclKind
Chris Lattnerb048c982008-04-06 04:47:34 +0000256 // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
Chris Lattner0ed844b2008-04-04 06:12:32 +0000257 // to avoid 'ambiguous access' compiler errors.
258 template<typename T> struct KindTrait {
259 static Decl::Kind getKind(const T *D) { return D->getKind(); }
260 };
261
262 // Used only by the ToDecl and FromDecl methods
263 template<typename To, typename From>
264 static To *CastTo(const From *D) {
265 Decl::Kind DK = KindTrait<From>::getKind(D);
266 switch(DK) {
Steve Naroff090276f2008-10-10 01:28:17 +0000267 case Decl::Block:
268 return static_cast<BlockDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000269 case Decl::TranslationUnit:
270 return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000271 case Decl::Namespace:
272 return static_cast<NamespaceDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000273 case Decl::Enum:
274 return static_cast<EnumDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000275 case Decl::CXXRecord:
276 return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000277 case Decl::ObjCMethod:
278 return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
279 case Decl::ObjCInterface:
280 return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
281 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000282 if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
283 return static_cast<FunctionDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000284
Chris Lattnerb048c982008-04-06 04:47:34 +0000285 assert(false && "a decl that inherits DeclContext isn't handled");
Chris Lattner0ed844b2008-04-04 06:12:32 +0000286 return 0;
287 }
288 }
289
290protected:
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000291 DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {}
Chris Lattner0ed844b2008-04-04 06:12:32 +0000292
293public:
Chris Lattnerb048c982008-04-06 04:47:34 +0000294 /// getParent - Returns the containing DeclContext if this is a ScopedDecl,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000295 /// else returns NULL.
Argyrios Kyrtzidisd2595ec2008-10-12 18:40:01 +0000296 DeclContext *getParent();
297 const DeclContext *getParent() const {
298 return const_cast<DeclContext*>(this)->getParent();
299 }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000300
301 bool isFunctionOrMethod() const {
302 switch (DeclKind) {
Steve Naroff56ee6892008-10-08 17:01:13 +0000303 case Decl::Block:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000304 case Decl::Function:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000305 case Decl::CXXMethod:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000306 case Decl::ObjCMethod:
307 return true;
308 default:
309 return false;
310 }
311 }
312
Argyrios Kyrtzidisc7ed9c62008-11-07 22:02:30 +0000313 bool isCXXRecord() const {
314 return DeclKind == Decl::CXXRecord;
315 }
316
Argyrios Kyrtzidise2ed2032008-10-12 18:45:56 +0000317 const ScopedDecl *getDeclChain() const { return DeclChain; }
318 ScopedDecl *getDeclChain() { return DeclChain; }
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000319 void setDeclChain(ScopedDecl *D) { DeclChain = D; }
320
Chris Lattner0ed844b2008-04-04 06:12:32 +0000321 static bool classof(const Decl *D) {
322 switch (D->getKind()) {
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000323 case Decl::TranslationUnit:
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000324 case Decl::Namespace:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000325 case Decl::Enum:
Argyrios Kyrtzidis35bc0822008-10-15 00:42:39 +0000326 case Decl::CXXRecord:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000327 case Decl::ObjCMethod:
328 case Decl::ObjCInterface:
Steve Naroff56ee6892008-10-08 17:01:13 +0000329 case Decl::Block:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000330 return true;
331 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000332 if (D->getKind() >= Decl::FunctionFirst &&
333 D->getKind() <= Decl::FunctionLast)
334 return true;
Chris Lattnerb048c982008-04-06 04:47:34 +0000335 return false;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000336 }
337 }
Chris Lattnerb048c982008-04-06 04:47:34 +0000338 static bool classof(const DeclContext *D) { return true; }
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000339 static bool classof(const TranslationUnitDecl *D) { return true; }
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000340 static bool classof(const NamespaceDecl *D) { return true; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000341 static bool classof(const FunctionDecl *D) { return true; }
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000342 static bool classof(const CXXRecordDecl *D) { return true; }
Chris Lattnerb048c982008-04-06 04:47:34 +0000343 static bool classof(const EnumDecl *D) { return true; }
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000344 static bool classof(const ObjCMethodDecl *D) { return true; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000345 static bool classof(const ObjCInterfaceDecl *D) { return true; }
Steve Naroff56ee6892008-10-08 17:01:13 +0000346 static bool classof(const BlockDecl *D) { return true; }
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000347
348private:
349 void EmitOutRec(llvm::Serializer& S) const;
350 void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
351
352 friend class Decl;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000353};
354
Chris Lattnerb048c982008-04-06 04:47:34 +0000355template<> struct DeclContext::KindTrait<DeclContext> {
356 static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000357};
358
359} // end clang.
360
361namespace llvm {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000362
363/// Implement a isa_impl_wrap specialization to check whether a DeclContext is
364/// a specific Decl.
365template<class ToTy>
366struct isa_impl_wrap<ToTy,
367 const ::clang::DeclContext,const ::clang::DeclContext> {
368 static bool doit(const ::clang::DeclContext &Val) {
369 return ToTy::classof(::clang::Decl::castFromDeclContext(&Val));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000370 }
371};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000372template<class ToTy>
373struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext>
374 : public isa_impl_wrap<ToTy,
375 const ::clang::DeclContext,const ::clang::DeclContext> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000376
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000377/// Implement cast_convert_val for Decl -> DeclContext conversions.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000378template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000379struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000380 static ::clang::DeclContext &doit(const FromTy &Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000381 return *FromTy::castToDeclContext(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000382 }
383};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000384
385template<class FromTy>
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000386struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> {
Chris Lattnerb048c982008-04-06 04:47:34 +0000387 static ::clang::DeclContext *doit(const FromTy *Val) {
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000388 return FromTy::castToDeclContext(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000389 }
390};
Argyrios Kyrtzidis42220c52008-10-12 16:14:48 +0000391
392/// Implement cast_convert_val for DeclContext -> Decl conversions.
393template<class ToTy>
394struct cast_convert_val<ToTy,
395 const ::clang::DeclContext,const ::clang::DeclContext> {
396 static ToTy &doit(const ::clang::DeclContext &Val) {
397 return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val));
398 }
399};
400template<class ToTy>
401struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext>
402 : public cast_convert_val<ToTy,
403 const ::clang::DeclContext,const ::clang::DeclContext> {};
404
405template<class ToTy>
406struct cast_convert_val<ToTy,
407 const ::clang::DeclContext*, const ::clang::DeclContext*> {
408 static ToTy *doit(const ::clang::DeclContext *Val) {
409 return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val));
410 }
411};
412template<class ToTy>
413struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*>
414 : public cast_convert_val<ToTy,
415 const ::clang::DeclContext*,const ::clang::DeclContext*> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000416
417} // end namespace llvm
418
419#endif