blob: 213515010c1328eb7abb5c151f0aaae275942bdf [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 Kyrtzidisef177822008-04-17 14:40:12 +000022class TranslationUnitDecl;
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +000023class NamespaceDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000024class ScopedDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000025class FunctionDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000026class CXXRecordDecl;
Chris Lattnerb048c982008-04-06 04:47:34 +000027class EnumDecl;
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000028class ObjCMethodDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000029class ObjCInterfaceDecl;
30
31/// Decl - This represents one declaration (or definition), e.g. a variable,
32/// typedef, function, struct, etc.
33///
34class Decl {
35public:
36 enum Kind {
37 // This lists the concrete classes of Decl in order of the inheritance
38 // hierarchy. This allows us to do efficient classof tests based on the
39 // enums below. The commented out names are abstract class names.
Ted Kremeneka34ea072008-08-04 22:51:42 +000040 // [DeclContext] indicates that the class also inherits from DeclContext.
Chris Lattner0ed844b2008-04-04 06:12:32 +000041
42 // Decl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000043 TranslationUnit, // [DeclContext]
Chris Lattner0ed844b2008-04-04 06:12:32 +000044 // NamedDecl
45 Field,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000046 CXXField,
Chris Lattner0ed844b2008-04-04 06:12:32 +000047 ObjCIvar,
48 ObjCCategory,
49 ObjCCategoryImpl,
50 ObjCImplementation,
51 ObjCProtocol,
Sam Bishop670aa9d2008-04-08 20:49:25 +000052 ObjCProperty,
Chris Lattner0ed844b2008-04-04 06:12:32 +000053 // ScopedDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000054 Namespace, // [DeclContext]
Chris Lattner0ed844b2008-04-04 06:12:32 +000055 // TypeDecl
56 Typedef,
57 // TagDecl
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000058 Enum, // [DeclContext]
Chris Lattner0ed844b2008-04-04 06:12:32 +000059 // RecordDecl
60 Struct,
61 Union,
62 Class,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000063 // CXXRecordDecl [DeclContext]
64 CXXStruct,
65 CXXUnion,
66 CXXClass,
Chris Lattner0ed844b2008-04-04 06:12:32 +000067 // ValueDecl
68 EnumConstant,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000069 Function, // [DeclContext]
70 CXXMethod,
Steve Naroff248a7532008-04-15 22:42:06 +000071 Var,
Chris Lattner41110242008-06-17 18:05:57 +000072 ImplicitParam,
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000073 CXXClassVar,
Chris Lattner0ed844b2008-04-04 06:12:32 +000074 ParmVar,
Daniel Dunbar226e04a2008-08-15 23:18:35 +000075 ObjCInterface, // [DeclContext]
76 ObjCCompatibleAlias,
77 ObjCMethod, // [DeclContext]
78 ObjCClass,
79 ObjCForwardProtocol,
80 ObjCPropertyImpl,
Chris Lattner0ed844b2008-04-04 06:12:32 +000081 LinkageSpec,
Daniel Dunbar226e04a2008-08-15 23:18:35 +000082 FileScopeAsm,
Chris Lattner0ed844b2008-04-04 06:12:32 +000083
84 // For each non-leaf class, we now define a mapping to the first/last member
85 // of the class, to allow efficient classof.
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +000086 NamedFirst = Field , NamedLast = ParmVar,
87 FieldFirst = Field , FieldLast = ObjCIvar,
88 ScopedFirst = Namespace , ScopedLast = ParmVar,
89 TypeFirst = Typedef , TypeLast = CXXClass,
90 TagFirst = Enum , TagLast = CXXClass,
91 RecordFirst = Struct , RecordLast = CXXClass,
92 CXXRecordFirst = CXXStruct , CXXRecordLast = CXXClass,
93 ValueFirst = EnumConstant , ValueLast = ParmVar,
94 FunctionFirst = Function , FunctionLast = CXXMethod,
95 VarFirst = Var , VarLast = ParmVar
Chris Lattner0ed844b2008-04-04 06:12:32 +000096 };
97
98 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
Douglas Gregor2ce52f32008-04-13 21:07:44 +000099 /// labels, tags, members and ordinary identifiers. These are meant
100 /// as bitmasks, so that searches in C++ can look into the "tag" namespace
101 /// during ordinary lookup.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000102 enum IdentifierNamespace {
Douglas Gregor2ce52f32008-04-13 21:07:44 +0000103 IDNS_Label = 0x1,
104 IDNS_Tag = 0x2,
105 IDNS_Member = 0x4,
106 IDNS_Ordinary = 0x8
Chris Lattner0ed844b2008-04-04 06:12:32 +0000107 };
108
109 /// ObjCDeclQualifier - Qualifier used on types in method declarations
110 /// for remote messaging. They are meant for the arguments though and
111 /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
112 enum ObjCDeclQualifier {
113 OBJC_TQ_None = 0x0,
114 OBJC_TQ_In = 0x1,
115 OBJC_TQ_Inout = 0x2,
116 OBJC_TQ_Out = 0x4,
117 OBJC_TQ_Bycopy = 0x8,
118 OBJC_TQ_Byref = 0x10,
119 OBJC_TQ_Oneway = 0x20
120 };
121
122private:
123 /// Loc - The location that this decl.
124 SourceLocation Loc;
125
126 /// 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
135 protected:
136 /// Access - Used by C++ decls for the access specifier.
137 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
138 unsigned Access : 2;
139 friend class CXXClassMemberWrapper;
140
Chris Lattner0ed844b2008-04-04 06:12:32 +0000141 Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
142 HasAttrs(false) {
143 if (Decl::CollectingStats()) addDeclKind(DK);
144 }
Sam Bishop1bb19632008-04-11 18:04:39 +0000145
Chris Lattner0ed844b2008-04-04 06:12:32 +0000146 virtual ~Decl();
Sam Bishop1bb19632008-04-11 18:04:39 +0000147
148public:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000149 SourceLocation getLocation() const { return Loc; }
150 void setLocation(SourceLocation L) { Loc = L; }
151
152 Kind getKind() const { return DeclKind; }
153 const char *getDeclKindName() const;
154
155 void addAttr(Attr *attr);
156 const Attr *getAttrs() const;
Chris Lattnera212c562008-05-04 02:29:49 +0000157 void swapAttrs(Decl *D);
Nuno Lopes9141bee2008-06-01 22:53:53 +0000158 void invalidateAttrs();
Chris Lattner0ed844b2008-04-04 06:12:32 +0000159
160 template<typename T> const T *getAttr() const {
161 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
162 if (const T *V = dyn_cast<T>(attr))
163 return V;
164
165 return 0;
166 }
167
168 /// setInvalidDecl - Indicates the Decl had a semantic error. This
169 /// allows for graceful error recovery.
170 void setInvalidDecl() { InvalidDecl = 1; }
171 bool isInvalidDecl() const { return (bool) InvalidDecl; }
172
173 IdentifierNamespace getIdentifierNamespace() const {
174 switch (DeclKind) {
175 default: assert(0 && "Unknown decl kind!");
Chris Lattner41110242008-06-17 18:05:57 +0000176 case ImplicitParam:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000177 case Typedef:
178 case Function:
Steve Naroff248a7532008-04-15 22:42:06 +0000179 case Var:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000180 case ParmVar:
181 case EnumConstant:
182 case ObjCInterface:
183 case ObjCCompatibleAlias:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000184 case CXXField:
Argyrios Kyrtzidis1ce6ead2008-06-24 22:56:42 +0000185 case CXXMethod:
Argyrios Kyrtzidis09c31b02008-06-25 14:04:17 +0000186 case CXXClassVar:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000187 return IDNS_Ordinary;
188 case Struct:
189 case Union:
190 case Class:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000191 case CXXStruct:
192 case CXXUnion:
193 case CXXClass:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000194 case Enum:
195 return IDNS_Tag;
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000196 case Namespace:
197 return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000198 }
199 }
Ted Kremenek792481e2008-06-20 21:39:47 +0000200
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000201 // getBody - If this Decl represents a declaration for a body of code,
Ted Kremenek792481e2008-06-20 21:39:47 +0000202 // such as a function or method definition, this method returns the top-level
Ted Kremenek69c8f0a2008-07-31 17:32:12 +0000203 // Stmt* of that body. Otherwise this method returns null.
204 virtual Stmt* getBody() const { return 0; }
Ted Kremenek792481e2008-06-20 21:39:47 +0000205
Chris Lattner0ed844b2008-04-04 06:12:32 +0000206 // global temp stats (until we have a per-module visitor)
207 static void addDeclKind(Kind k);
208 static bool CollectingStats(bool Enable = false);
209 static void PrintStats();
210
211 // Implement isa/cast/dyncast/etc.
212 static bool classof(const Decl *) { return true; }
213
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
245///
Chris Lattnerb048c982008-04-06 04:47:34 +0000246class DeclContext {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000247 /// DeclKind - This indicates which class this is.
248 Decl::Kind DeclKind : 8;
249
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000250 /// DeclChain - Linked list of declarations that are defined inside this
251 /// declaration context.
252 ScopedDecl *DeclChain;
253
Chris Lattner0ed844b2008-04-04 06:12:32 +0000254 // Used in the CastTo template to get the DeclKind
Chris Lattnerb048c982008-04-06 04:47:34 +0000255 // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
Chris Lattner0ed844b2008-04-04 06:12:32 +0000256 // to avoid 'ambiguous access' compiler errors.
257 template<typename T> struct KindTrait {
258 static Decl::Kind getKind(const T *D) { return D->getKind(); }
259 };
260
261 // Used only by the ToDecl and FromDecl methods
262 template<typename To, typename From>
263 static To *CastTo(const From *D) {
264 Decl::Kind DK = KindTrait<From>::getKind(D);
265 switch(DK) {
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000266 case Decl::TranslationUnit:
267 return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000268 case Decl::Namespace:
269 return static_cast<NamespaceDecl*>(const_cast<From*>(D));
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000270 case Decl::Enum:
271 return static_cast<EnumDecl*>(const_cast<From*>(D));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000272 case Decl::ObjCMethod:
273 return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
274 case Decl::ObjCInterface:
275 return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
276 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000277 if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast)
278 return static_cast<FunctionDecl*>(const_cast<From*>(D));
279 if (DK >= Decl::CXXRecordFirst && DK <= Decl::CXXRecordLast)
280 return static_cast<CXXRecordDecl*>(const_cast<From*>(D));
281
Chris Lattnerb048c982008-04-06 04:47:34 +0000282 assert(false && "a decl that inherits DeclContext isn't handled");
Chris Lattner0ed844b2008-04-04 06:12:32 +0000283 return 0;
284 }
285 }
286
287protected:
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000288 DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {}
Chris Lattner0ed844b2008-04-04 06:12:32 +0000289
290public:
Chris Lattnerb048c982008-04-06 04:47:34 +0000291 /// getParent - Returns the containing DeclContext if this is a ScopedDecl,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000292 /// else returns NULL.
Chris Lattnerb048c982008-04-06 04:47:34 +0000293 DeclContext *getParent() const;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000294
295 bool isFunctionOrMethod() const {
296 switch (DeclKind) {
297 case Decl::Function:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000298 case Decl::CXXMethod:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000299 case Decl::ObjCMethod:
300 return true;
301 default:
302 return false;
303 }
304 }
305
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000306 ScopedDecl *getDeclChain() const { return DeclChain; }
307 void setDeclChain(ScopedDecl *D) { DeclChain = D; }
308
Chris Lattnerb048c982008-04-06 04:47:34 +0000309 /// ToDecl and FromDecl make Decl <-> DeclContext castings.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000310 /// They are intended to be used by the simplify_type and cast_convert_val
311 /// templates.
Chris Lattnerb048c982008-04-06 04:47:34 +0000312 static Decl *ToDecl (const DeclContext *D);
313 static DeclContext *FromDecl (const Decl *D);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000314
315 static bool classof(const Decl *D) {
316 switch (D->getKind()) {
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000317 case Decl::TranslationUnit:
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000318 case Decl::Namespace:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000319 case Decl::Enum:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000320 case Decl::ObjCMethod:
321 case Decl::ObjCInterface:
322 return true;
323 default:
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000324 if (D->getKind() >= Decl::FunctionFirst &&
325 D->getKind() <= Decl::FunctionLast)
326 return true;
327 if (D->getKind() >= Decl::CXXRecordFirst &&
328 D->getKind() <= Decl::CXXRecordLast)
329 return true;
Chris Lattnerb048c982008-04-06 04:47:34 +0000330 return false;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000331 }
332 }
Chris Lattnerb048c982008-04-06 04:47:34 +0000333 static bool classof(const DeclContext *D) { return true; }
Argyrios Kyrtzidisef177822008-04-17 14:40:12 +0000334 static bool classof(const TranslationUnitDecl *D) { return true; }
Argyrios Kyrtzidis2d1c5d32008-04-27 13:50:30 +0000335 static bool classof(const NamespaceDecl *D) { return true; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000336 static bool classof(const FunctionDecl *D) { return true; }
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000337 static bool classof(const CXXRecordDecl *D) { return true; }
Chris Lattnerb048c982008-04-06 04:47:34 +0000338 static bool classof(const EnumDecl *D) { return true; }
Argyrios Kyrtzidisd3bb44f2008-06-09 21:05:31 +0000339 static bool classof(const ObjCMethodDecl *D) { return true; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000340 static bool classof(const ObjCInterfaceDecl *D) { return true; }
Argyrios Kyrtzidis76435362008-06-10 01:32:09 +0000341
342private:
343 void EmitOutRec(llvm::Serializer& S) const;
344 void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
345
346 friend class Decl;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000347};
348
Chris Lattnerb048c982008-04-06 04:47:34 +0000349template<> struct DeclContext::KindTrait<DeclContext> {
350 static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000351};
352
353} // end clang.
354
355namespace llvm {
Chris Lattnerb048c982008-04-06 04:47:34 +0000356/// Implement simplify_type for DeclContext, so that we can dyn_cast from
357/// DeclContext to a specific Decl class.
358 template<> struct simplify_type<const ::clang::DeclContext*> {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000359 typedef ::clang::Decl* SimpleType;
Chris Lattnerb048c982008-04-06 04:47:34 +0000360 static SimpleType getSimplifiedValue(const ::clang::DeclContext *Val) {
361 return ::clang::DeclContext::ToDecl(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000362 }
363};
Chris Lattnerb048c982008-04-06 04:47:34 +0000364template<> struct simplify_type< ::clang::DeclContext*>
365 : public simplify_type<const ::clang::DeclContext*> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000366
Chris Lattnerb048c982008-04-06 04:47:34 +0000367template<> struct simplify_type<const ::clang::DeclContext> {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000368 typedef ::clang::Decl SimpleType;
Chris Lattnerb048c982008-04-06 04:47:34 +0000369 static SimpleType &getSimplifiedValue(const ::clang::DeclContext &Val) {
370 return *::clang::DeclContext::ToDecl(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000371 }
372};
Chris Lattnerb048c982008-04-06 04:47:34 +0000373template<> struct simplify_type< ::clang::DeclContext>
374 : public simplify_type<const ::clang::DeclContext> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000375
Chris Lattnerb048c982008-04-06 04:47:34 +0000376/// Implement cast_convert_val for DeclContext, so that we can dyn_cast from
377/// a Decl class to DeclContext.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000378template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000379struct cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy> {
380 static ::clang::DeclContext &doit(const FromTy &Val) {
381 return *::clang::DeclContext::FromDecl(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000382 }
383};
384template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000385struct cast_convert_val< ::clang::DeclContext,FromTy,FromTy>
386 : public cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy>
Chris Lattner0ed844b2008-04-04 06:12:32 +0000387 {};
388
389template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000390struct cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*> {
391 static ::clang::DeclContext *doit(const FromTy *Val) {
392 return ::clang::DeclContext::FromDecl(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000393 }
394};
395template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000396struct cast_convert_val< ::clang::DeclContext,FromTy*,FromTy*>
397 : public cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*>
Chris Lattner0ed844b2008-04-04 06:12:32 +0000398 {};
399
400} // end namespace llvm
401
402#endif