DeclBase.h revision 0ed844b04ea4387caa4e1cf3dc375d269657536b
1//===-- 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// 10// This file defines the Decl and ContextDecl interfaces. 11// 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; 24class TagDecl; 25class 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 194/// ContextDecl - This is used only as base class of specific decl types that 195/// can act as declaration contexts. These decls are: 196/// 197/// FunctionDecl 198/// ObjCMethodDecl 199/// TagDecl 200/// ObjCInterfaceDecl 201/// 202class ContextDecl { 203 /// DeclKind - This indicates which class this is. 204 Decl::Kind DeclKind : 8; 205 206 // Used in the CastTo template to get the DeclKind 207 // from a Decl or a ContextDecl. ContextDecl doesn't have a getKind() method 208 // 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)); 224 default: 225 // check for TagDecl 226 if (DK >= Decl::TagFirst && DK <= Decl::TagLast) 227 return static_cast<TagDecl*>(const_cast<From*>(D)); 228 229 assert(false && "a decl that inherits ContextDecl isn't handled"); 230 return 0; 231 } 232 } 233 234protected: 235 ContextDecl(Decl::Kind K) : DeclKind(K) {} 236 237public: 238 /// getParent - Returns the containing ContextDecl if this is a ScopedDecl, 239 /// else returns NULL. 240 ContextDecl *getParent() const; 241 242 bool isFunctionOrMethod() const { 243 switch (DeclKind) { 244 case Decl::Function: 245 case Decl::ObjCMethod: 246 return true; 247 default: 248 return false; 249 } 250 } 251 252 /// ToDecl and FromDecl make Decl <-> ContextDecl castings. 253 /// They are intended to be used by the simplify_type and cast_convert_val 254 /// templates. 255 static Decl *ToDecl (const ContextDecl *D); 256 static ContextDecl *FromDecl (const Decl *D); 257 258 static bool classof(const Decl *D) { 259 switch (D->getKind()) { 260 case Decl::Function: 261 case Decl::ObjCMethod: 262 case Decl::ObjCInterface: 263 return true; 264 default: 265 // check for TagDecl 266 return D->getKind() >= Decl::TagFirst && 267 D->getKind() <= Decl::TagLast; 268 } 269 } 270 static bool classof(const ContextDecl *D) { return true; } 271 static bool classof(const FunctionDecl *D) { return true; } 272 static bool classof(const ObjCMethodDecl *D) { return true; } 273 static bool classof(const TagDecl *D) { return true; } 274 static bool classof(const ObjCInterfaceDecl *D) { return true; } 275}; 276 277template<> struct ContextDecl::KindTrait<ContextDecl> { 278 static Decl::Kind getKind(const ContextDecl *D) { return D->DeclKind; } 279}; 280 281} // end clang. 282 283namespace llvm { 284/// Implement simplify_type for ContextDecl, so that we can dyn_cast from 285/// ContextDecl to a specific Decl class. 286 template<> struct simplify_type<const ::clang::ContextDecl*> { 287 typedef ::clang::Decl* SimpleType; 288 static SimpleType getSimplifiedValue(const ::clang::ContextDecl *Val) { 289 return ::clang::ContextDecl::ToDecl(Val); 290 } 291}; 292template<> struct simplify_type< ::clang::ContextDecl*> 293 : public simplify_type<const ::clang::ContextDecl*> {}; 294 295template<> struct simplify_type<const ::clang::ContextDecl> { 296 typedef ::clang::Decl SimpleType; 297 static SimpleType &getSimplifiedValue(const ::clang::ContextDecl &Val) { 298 return *::clang::ContextDecl::ToDecl(&Val); 299 } 300}; 301template<> struct simplify_type< ::clang::ContextDecl> 302 : public simplify_type<const ::clang::ContextDecl> {}; 303 304/// Implement cast_convert_val for ContextDecl, so that we can dyn_cast from 305/// a Decl class to ContextDecl. 306template<class FromTy> 307struct cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy> { 308 static ::clang::ContextDecl &doit(const FromTy &Val) { 309 return *::clang::ContextDecl::FromDecl(&Val); 310 } 311}; 312template<class FromTy> 313struct cast_convert_val< ::clang::ContextDecl,FromTy,FromTy> 314 : public cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy> 315 {}; 316 317template<class FromTy> 318struct cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*> { 319 static ::clang::ContextDecl *doit(const FromTy *Val) { 320 return ::clang::ContextDecl::FromDecl(Val); 321 } 322}; 323template<class FromTy> 324struct cast_convert_val< ::clang::ContextDecl,FromTy*,FromTy*> 325 : public cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*> 326 {}; 327 328} // end namespace llvm 329 330#endif 331