blob: 4f9cc0cb661260fe9839a09ce78a238884f35bf8 [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 {
22class FunctionDecl;
23class ObjCMethodDecl;
Chris Lattnerb048c982008-04-06 04:47:34 +000024class EnumDecl;
Chris Lattner0ed844b2008-04-04 06:12:32 +000025class ObjCInterfaceDecl;
26
27/// Decl - This represents one declaration (or definition), e.g. a variable,
28/// typedef, function, struct, etc.
29///
30class Decl {
31public:
32 enum Kind {
33 // This lists the concrete classes of Decl in order of the inheritance
34 // hierarchy. This allows us to do efficient classof tests based on the
35 // enums below. The commented out names are abstract class names.
36
37 // Decl
38 // NamedDecl
39 Field,
40 ObjCIvar,
41 ObjCCategory,
42 ObjCCategoryImpl,
43 ObjCImplementation,
44 ObjCProtocol,
45 PropertyDecl,
46 // ScopedDecl
47 // TypeDecl
48 Typedef,
49 // TagDecl
50 Enum,
51 // RecordDecl
52 Struct,
53 Union,
54 Class,
55 // ValueDecl
56 EnumConstant,
57 Function,
58 // VarDecl
59 BlockVar,
60 FileVar,
61 ParmVar,
62 ObjCInterface,
63 ObjCCompatibleAlias,
64 ObjCMethod,
65 ObjCClass,
66 ObjCForwardProtocol,
67 LinkageSpec,
68 FileScopeAsm,
69
70 // For each non-leaf class, we now define a mapping to the first/last member
71 // of the class, to allow efficient classof.
72 NamedFirst = Field, NamedLast = ParmVar,
73 FieldFirst = Field, FieldLast = ObjCIvar,
74 ScopedFirst = Typedef, ScopedLast = ParmVar,
75 TypeFirst = Typedef, TypeLast = Class,
76 TagFirst = Enum , TagLast = Class,
77 RecordFirst = Struct , RecordLast = Class,
78 ValueFirst = EnumConstant , ValueLast = ParmVar,
79 VarFirst = BlockVar , VarLast = ParmVar
80 };
81
82 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
83 /// labels, tags, members and ordinary identifiers.
84 enum IdentifierNamespace {
85 IDNS_Label,
86 IDNS_Tag,
87 IDNS_Member,
88 IDNS_Ordinary
89 };
90
91 /// ObjCDeclQualifier - Qualifier used on types in method declarations
92 /// for remote messaging. They are meant for the arguments though and
93 /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
94 enum ObjCDeclQualifier {
95 OBJC_TQ_None = 0x0,
96 OBJC_TQ_In = 0x1,
97 OBJC_TQ_Inout = 0x2,
98 OBJC_TQ_Out = 0x4,
99 OBJC_TQ_Bycopy = 0x8,
100 OBJC_TQ_Byref = 0x10,
101 OBJC_TQ_Oneway = 0x20
102 };
103
104private:
105 /// Loc - The location that this decl.
106 SourceLocation Loc;
107
108 /// DeclKind - This indicates which class this is.
109 Kind DeclKind : 8;
110
111 /// InvalidDecl - This indicates a semantic error occurred.
112 unsigned int InvalidDecl : 1;
113
114 /// HasAttrs - This indicates whether the decl has attributes or not.
115 unsigned int HasAttrs : 1;
116protected:
117 Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
118 HasAttrs(false) {
119 if (Decl::CollectingStats()) addDeclKind(DK);
120 }
121
122public:
123 // TODO: This should probably be made protected once derived classes have
124 // destructors.
125 virtual ~Decl();
126
127 SourceLocation getLocation() const { return Loc; }
128 void setLocation(SourceLocation L) { Loc = L; }
129
130 Kind getKind() const { return DeclKind; }
131 const char *getDeclKindName() const;
132
133 void addAttr(Attr *attr);
134 const Attr *getAttrs() const;
135
136 template<typename T> const T *getAttr() const {
137 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
138 if (const T *V = dyn_cast<T>(attr))
139 return V;
140
141 return 0;
142 }
143
144 /// setInvalidDecl - Indicates the Decl had a semantic error. This
145 /// allows for graceful error recovery.
146 void setInvalidDecl() { InvalidDecl = 1; }
147 bool isInvalidDecl() const { return (bool) InvalidDecl; }
148
149 IdentifierNamespace getIdentifierNamespace() const {
150 switch (DeclKind) {
151 default: assert(0 && "Unknown decl kind!");
152 case Typedef:
153 case Function:
154 case BlockVar:
155 case FileVar:
156 case ParmVar:
157 case EnumConstant:
158 case ObjCInterface:
159 case ObjCCompatibleAlias:
160 return IDNS_Ordinary;
161 case Struct:
162 case Union:
163 case Class:
164 case Enum:
165 return IDNS_Tag;
166 }
167 }
168 // global temp stats (until we have a per-module visitor)
169 static void addDeclKind(Kind k);
170 static bool CollectingStats(bool Enable = false);
171 static void PrintStats();
172
173 // Implement isa/cast/dyncast/etc.
174 static bool classof(const Decl *) { return true; }
175
176 /// Emit - Serialize this Decl to Bitcode.
177 void Emit(llvm::Serializer& S) const;
178
179 /// Create - Deserialize a Decl from Bitcode.
180 static Decl* Create(llvm::Deserializer& D);
181
182protected:
183 /// EmitImpl - Provides the subclass-specific serialization logic for
184 /// serializing out a decl.
185 virtual void EmitImpl(llvm::Serializer& S) const {
186 // FIXME: This will eventually be a pure virtual function.
187 assert (false && "Not implemented.");
188 }
189
190 void EmitInRec(llvm::Serializer& S) const;
191 void ReadInRec(llvm::Deserializer& D);
192};
193
Chris Lattnerb048c982008-04-06 04:47:34 +0000194/// DeclContext - This is used only as base class of specific decl types that
Chris Lattner0ed844b2008-04-04 06:12:32 +0000195/// can act as declaration contexts. These decls are:
196///
197/// FunctionDecl
198/// ObjCMethodDecl
Chris Lattnerb048c982008-04-06 04:47:34 +0000199/// EnumDecl
Chris Lattner0ed844b2008-04-04 06:12:32 +0000200/// ObjCInterfaceDecl
201///
Chris Lattnerb048c982008-04-06 04:47:34 +0000202class DeclContext {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000203 /// DeclKind - This indicates which class this is.
204 Decl::Kind DeclKind : 8;
205
206 // Used in the CastTo template to get the DeclKind
Chris Lattnerb048c982008-04-06 04:47:34 +0000207 // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
Chris Lattner0ed844b2008-04-04 06:12:32 +0000208 // to avoid 'ambiguous access' compiler errors.
209 template<typename T> struct KindTrait {
210 static Decl::Kind getKind(const T *D) { return D->getKind(); }
211 };
212
213 // Used only by the ToDecl and FromDecl methods
214 template<typename To, typename From>
215 static To *CastTo(const From *D) {
216 Decl::Kind DK = KindTrait<From>::getKind(D);
217 switch(DK) {
218 case Decl::Function:
219 return static_cast<FunctionDecl*>(const_cast<From*>(D));
220 case Decl::ObjCMethod:
221 return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
222 case Decl::ObjCInterface:
223 return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
Chris Lattnerb048c982008-04-06 04:47:34 +0000224 case Decl::Enum:
225 return static_cast<EnumDecl*>(const_cast<From*>(D));
Chris Lattner0ed844b2008-04-04 06:12:32 +0000226 default:
Chris Lattnerb048c982008-04-06 04:47:34 +0000227 assert(false && "a decl that inherits DeclContext isn't handled");
Chris Lattner0ed844b2008-04-04 06:12:32 +0000228 return 0;
229 }
230 }
231
232protected:
Chris Lattnerb048c982008-04-06 04:47:34 +0000233 DeclContext(Decl::Kind K) : DeclKind(K) {}
Chris Lattner0ed844b2008-04-04 06:12:32 +0000234
235public:
Chris Lattnerb048c982008-04-06 04:47:34 +0000236 /// getParent - Returns the containing DeclContext if this is a ScopedDecl,
Chris Lattner0ed844b2008-04-04 06:12:32 +0000237 /// else returns NULL.
Chris Lattnerb048c982008-04-06 04:47:34 +0000238 DeclContext *getParent() const;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000239
240 bool isFunctionOrMethod() const {
241 switch (DeclKind) {
242 case Decl::Function:
243 case Decl::ObjCMethod:
244 return true;
245 default:
246 return false;
247 }
248 }
249
Chris Lattnerb048c982008-04-06 04:47:34 +0000250 /// ToDecl and FromDecl make Decl <-> DeclContext castings.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000251 /// They are intended to be used by the simplify_type and cast_convert_val
252 /// templates.
Chris Lattnerb048c982008-04-06 04:47:34 +0000253 static Decl *ToDecl (const DeclContext *D);
254 static DeclContext *FromDecl (const Decl *D);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000255
256 static bool classof(const Decl *D) {
257 switch (D->getKind()) {
258 case Decl::Function:
259 case Decl::ObjCMethod:
260 case Decl::ObjCInterface:
Chris Lattnerb048c982008-04-06 04:47:34 +0000261 case Decl::Enum:
Chris Lattner0ed844b2008-04-04 06:12:32 +0000262 return true;
263 default:
Chris Lattnerb048c982008-04-06 04:47:34 +0000264 return false;
Chris Lattner0ed844b2008-04-04 06:12:32 +0000265 }
266 }
Chris Lattnerb048c982008-04-06 04:47:34 +0000267 static bool classof(const DeclContext *D) { return true; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000268 static bool classof(const FunctionDecl *D) { return true; }
269 static bool classof(const ObjCMethodDecl *D) { return true; }
Chris Lattnerb048c982008-04-06 04:47:34 +0000270 static bool classof(const EnumDecl *D) { return true; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000271 static bool classof(const ObjCInterfaceDecl *D) { return true; }
272};
273
Chris Lattnerb048c982008-04-06 04:47:34 +0000274template<> struct DeclContext::KindTrait<DeclContext> {
275 static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; }
Chris Lattner0ed844b2008-04-04 06:12:32 +0000276};
277
278} // end clang.
279
280namespace llvm {
Chris Lattnerb048c982008-04-06 04:47:34 +0000281/// Implement simplify_type for DeclContext, so that we can dyn_cast from
282/// DeclContext to a specific Decl class.
283 template<> struct simplify_type<const ::clang::DeclContext*> {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000284 typedef ::clang::Decl* SimpleType;
Chris Lattnerb048c982008-04-06 04:47:34 +0000285 static SimpleType getSimplifiedValue(const ::clang::DeclContext *Val) {
286 return ::clang::DeclContext::ToDecl(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000287 }
288};
Chris Lattnerb048c982008-04-06 04:47:34 +0000289template<> struct simplify_type< ::clang::DeclContext*>
290 : public simplify_type<const ::clang::DeclContext*> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000291
Chris Lattnerb048c982008-04-06 04:47:34 +0000292template<> struct simplify_type<const ::clang::DeclContext> {
Chris Lattner0ed844b2008-04-04 06:12:32 +0000293 typedef ::clang::Decl SimpleType;
Chris Lattnerb048c982008-04-06 04:47:34 +0000294 static SimpleType &getSimplifiedValue(const ::clang::DeclContext &Val) {
295 return *::clang::DeclContext::ToDecl(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000296 }
297};
Chris Lattnerb048c982008-04-06 04:47:34 +0000298template<> struct simplify_type< ::clang::DeclContext>
299 : public simplify_type<const ::clang::DeclContext> {};
Chris Lattner0ed844b2008-04-04 06:12:32 +0000300
Chris Lattnerb048c982008-04-06 04:47:34 +0000301/// Implement cast_convert_val for DeclContext, so that we can dyn_cast from
302/// a Decl class to DeclContext.
Chris Lattner0ed844b2008-04-04 06:12:32 +0000303template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000304struct cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy> {
305 static ::clang::DeclContext &doit(const FromTy &Val) {
306 return *::clang::DeclContext::FromDecl(&Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000307 }
308};
309template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000310struct cast_convert_val< ::clang::DeclContext,FromTy,FromTy>
311 : public cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy>
Chris Lattner0ed844b2008-04-04 06:12:32 +0000312 {};
313
314template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000315struct cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*> {
316 static ::clang::DeclContext *doit(const FromTy *Val) {
317 return ::clang::DeclContext::FromDecl(Val);
Chris Lattner0ed844b2008-04-04 06:12:32 +0000318 }
319};
320template<class FromTy>
Chris Lattnerb048c982008-04-06 04:47:34 +0000321struct cast_convert_val< ::clang::DeclContext,FromTy*,FromTy*>
322 : public cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*>
Chris Lattner0ed844b2008-04-04 06:12:32 +0000323 {};
324
325} // end namespace llvm
326
327#endif