DeclBase.h revision 1bb19638f2ec0d63ed131b51ca8d9542d1a9afee
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 DeclContext 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 EnumDecl; 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 ObjCProperty, 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 122 virtual ~Decl(); 123 124public: 125 SourceLocation getLocation() const { return Loc; } 126 void setLocation(SourceLocation L) { Loc = L; } 127 128 Kind getKind() const { return DeclKind; } 129 const char *getDeclKindName() const; 130 131 void addAttr(Attr *attr); 132 const Attr *getAttrs() const; 133 134 template<typename T> const T *getAttr() const { 135 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) 136 if (const T *V = dyn_cast<T>(attr)) 137 return V; 138 139 return 0; 140 } 141 142 /// setInvalidDecl - Indicates the Decl had a semantic error. This 143 /// allows for graceful error recovery. 144 void setInvalidDecl() { InvalidDecl = 1; } 145 bool isInvalidDecl() const { return (bool) InvalidDecl; } 146 147 IdentifierNamespace getIdentifierNamespace() const { 148 switch (DeclKind) { 149 default: assert(0 && "Unknown decl kind!"); 150 case Typedef: 151 case Function: 152 case BlockVar: 153 case FileVar: 154 case ParmVar: 155 case EnumConstant: 156 case ObjCInterface: 157 case ObjCCompatibleAlias: 158 return IDNS_Ordinary; 159 case Struct: 160 case Union: 161 case Class: 162 case Enum: 163 return IDNS_Tag; 164 } 165 } 166 // global temp stats (until we have a per-module visitor) 167 static void addDeclKind(Kind k); 168 static bool CollectingStats(bool Enable = false); 169 static void PrintStats(); 170 171 // Implement isa/cast/dyncast/etc. 172 static bool classof(const Decl *) { return true; } 173 174 /// Emit - Serialize this Decl to Bitcode. 175 void Emit(llvm::Serializer& S) const; 176 177 /// Create - Deserialize a Decl from Bitcode. 178 static Decl* Create(llvm::Deserializer& D, ASTContext& C); 179 180 /// Destroy - Call destructors and release memory. 181 void Destroy(ASTContext& C) const; 182 183protected: 184 /// EmitImpl - Provides the subclass-specific serialization logic for 185 /// serializing out a decl. 186 virtual void EmitImpl(llvm::Serializer& S) const { 187 // FIXME: This will eventually be a pure virtual function. 188 assert (false && "Not implemented."); 189 } 190 191 void EmitInRec(llvm::Serializer& S) const; 192 void ReadInRec(llvm::Deserializer& D, ASTContext& C); 193}; 194 195/// DeclContext - This is used only as base class of specific decl types that 196/// can act as declaration contexts. These decls are: 197/// 198/// FunctionDecl 199/// ObjCMethodDecl 200/// EnumDecl 201/// ObjCInterfaceDecl 202/// 203class DeclContext { 204 /// DeclKind - This indicates which class this is. 205 Decl::Kind DeclKind : 8; 206 207 // Used in the CastTo template to get the DeclKind 208 // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method 209 // to avoid 'ambiguous access' compiler errors. 210 template<typename T> struct KindTrait { 211 static Decl::Kind getKind(const T *D) { return D->getKind(); } 212 }; 213 214 // Used only by the ToDecl and FromDecl methods 215 template<typename To, typename From> 216 static To *CastTo(const From *D) { 217 Decl::Kind DK = KindTrait<From>::getKind(D); 218 switch(DK) { 219 case Decl::Function: 220 return static_cast<FunctionDecl*>(const_cast<From*>(D)); 221 case Decl::ObjCMethod: 222 return static_cast<ObjCMethodDecl*>(const_cast<From*>(D)); 223 case Decl::ObjCInterface: 224 return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D)); 225 case Decl::Enum: 226 return static_cast<EnumDecl*>(const_cast<From*>(D)); 227 default: 228 assert(false && "a decl that inherits DeclContext isn't handled"); 229 return 0; 230 } 231 } 232 233protected: 234 DeclContext(Decl::Kind K) : DeclKind(K) {} 235 236public: 237 /// getParent - Returns the containing DeclContext if this is a ScopedDecl, 238 /// else returns NULL. 239 DeclContext *getParent() const; 240 241 bool isFunctionOrMethod() const { 242 switch (DeclKind) { 243 case Decl::Function: 244 case Decl::ObjCMethod: 245 return true; 246 default: 247 return false; 248 } 249 } 250 251 /// ToDecl and FromDecl make Decl <-> DeclContext castings. 252 /// They are intended to be used by the simplify_type and cast_convert_val 253 /// templates. 254 static Decl *ToDecl (const DeclContext *D); 255 static DeclContext *FromDecl (const Decl *D); 256 257 static bool classof(const Decl *D) { 258 switch (D->getKind()) { 259 case Decl::Function: 260 case Decl::ObjCMethod: 261 case Decl::ObjCInterface: 262 case Decl::Enum: 263 return true; 264 default: 265 return false; 266 } 267 } 268 static bool classof(const DeclContext *D) { return true; } 269 static bool classof(const FunctionDecl *D) { return true; } 270 static bool classof(const ObjCMethodDecl *D) { return true; } 271 static bool classof(const EnumDecl *D) { return true; } 272 static bool classof(const ObjCInterfaceDecl *D) { return true; } 273}; 274 275template<> struct DeclContext::KindTrait<DeclContext> { 276 static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; } 277}; 278 279} // end clang. 280 281namespace llvm { 282/// Implement simplify_type for DeclContext, so that we can dyn_cast from 283/// DeclContext to a specific Decl class. 284 template<> struct simplify_type<const ::clang::DeclContext*> { 285 typedef ::clang::Decl* SimpleType; 286 static SimpleType getSimplifiedValue(const ::clang::DeclContext *Val) { 287 return ::clang::DeclContext::ToDecl(Val); 288 } 289}; 290template<> struct simplify_type< ::clang::DeclContext*> 291 : public simplify_type<const ::clang::DeclContext*> {}; 292 293template<> struct simplify_type<const ::clang::DeclContext> { 294 typedef ::clang::Decl SimpleType; 295 static SimpleType &getSimplifiedValue(const ::clang::DeclContext &Val) { 296 return *::clang::DeclContext::ToDecl(&Val); 297 } 298}; 299template<> struct simplify_type< ::clang::DeclContext> 300 : public simplify_type<const ::clang::DeclContext> {}; 301 302/// Implement cast_convert_val for DeclContext, so that we can dyn_cast from 303/// a Decl class to DeclContext. 304template<class FromTy> 305struct cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy> { 306 static ::clang::DeclContext &doit(const FromTy &Val) { 307 return *::clang::DeclContext::FromDecl(&Val); 308 } 309}; 310template<class FromTy> 311struct cast_convert_val< ::clang::DeclContext,FromTy,FromTy> 312 : public cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy> 313 {}; 314 315template<class FromTy> 316struct cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*> { 317 static ::clang::DeclContext *doit(const FromTy *Val) { 318 return ::clang::DeclContext::FromDecl(Val); 319 } 320}; 321template<class FromTy> 322struct cast_convert_val< ::clang::DeclContext,FromTy*,FromTy*> 323 : public cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*> 324 {}; 325 326} // end namespace llvm 327 328#endif 329