DeclBase.h revision b48fe3812047e84164925c8938ce82be0624c40c
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 DeclContext; 23class TranslationUnitDecl; 24class NamespaceDecl; 25class ScopedDecl; 26class FunctionDecl; 27class CXXRecordDecl; 28class EnumDecl; 29class ObjCMethodDecl; 30class ObjCInterfaceDecl; 31class BlockDecl; 32 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. 42 // [DeclContext] indicates that the class also inherits from DeclContext. 43 44 // Decl 45 TranslationUnit, // [DeclContext] 46 // NamedDecl 47 Field, 48 CXXField, 49 ObjCIvar, 50 ObjCAtDefsField, 51 OverloadedFunction, 52 ObjCCategory, 53 ObjCCategoryImpl, 54 ObjCImplementation, 55 ObjCProtocol, 56 ObjCProperty, 57 // ScopedDecl 58 Namespace, // [DeclContext] 59 // TypeDecl 60 Typedef, 61 // TagDecl 62 Enum, // [DeclContext] 63 Record, 64 CXXRecord, // [DeclContext] 65 // ValueDecl 66 EnumConstant, 67 Function, // [DeclContext] 68 CXXMethod, 69 CXXConstructor, 70 Var, 71 ImplicitParam, 72 CXXClassVar, 73 ParmVar, 74 ObjCInterface, // [DeclContext] 75 ObjCCompatibleAlias, 76 ObjCMethod, // [DeclContext] 77 ObjCClass, 78 ObjCForwardProtocol, 79 ObjCPropertyImpl, 80 LinkageSpec, 81 FileScopeAsm, 82 Block, // [DeclContext] 83 84 // For each non-leaf class, we now define a mapping to the first/last member 85 // of the class, to allow efficient classof. 86 NamedFirst = Field , NamedLast = ParmVar, 87 FieldFirst = Field , FieldLast = ObjCAtDefsField, 88 ScopedFirst = Namespace , ScopedLast = ParmVar, 89 TypeFirst = Typedef , TypeLast = CXXRecord, 90 TagFirst = Enum , TagLast = CXXRecord, 91 RecordFirst = Record , RecordLast = CXXRecord, 92 ValueFirst = EnumConstant , ValueLast = ParmVar, 93 FunctionFirst = Function , FunctionLast = CXXConstructor, 94 VarFirst = Var , VarLast = ParmVar 95 }; 96 97 /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces, 98 /// labels, tags, members and ordinary identifiers. These are meant 99 /// as bitmasks, so that searches in C++ can look into the "tag" namespace 100 /// during ordinary lookup. 101 enum IdentifierNamespace { 102 IDNS_Label = 0x1, 103 IDNS_Tag = 0x2, 104 IDNS_Member = 0x4, 105 IDNS_Ordinary = 0x8 106 }; 107 108 /// ObjCDeclQualifier - Qualifier used on types in method declarations 109 /// for remote messaging. They are meant for the arguments though and 110 /// applied to the Decls (ObjCMethodDecl and ParmVarDecl). 111 enum ObjCDeclQualifier { 112 OBJC_TQ_None = 0x0, 113 OBJC_TQ_In = 0x1, 114 OBJC_TQ_Inout = 0x2, 115 OBJC_TQ_Out = 0x4, 116 OBJC_TQ_Bycopy = 0x8, 117 OBJC_TQ_Byref = 0x10, 118 OBJC_TQ_Oneway = 0x20 119 }; 120 121private: 122 /// Loc - The location that this decl. 123 SourceLocation Loc; 124 125 /// DeclKind - This indicates which class this is. 126 Kind DeclKind : 8; 127 128 /// InvalidDecl - This indicates a semantic error occurred. 129 unsigned int InvalidDecl : 1; 130 131 /// HasAttrs - This indicates whether the decl has attributes or not. 132 unsigned int HasAttrs : 1; 133 134 protected: 135 /// Access - Used by C++ decls for the access specifier. 136 // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum 137 unsigned Access : 2; 138 friend class CXXClassMemberWrapper; 139 140 Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0), 141 HasAttrs(false) { 142 if (Decl::CollectingStats()) addDeclKind(DK); 143 } 144 145 virtual ~Decl(); 146 147public: 148 SourceLocation getLocation() const { return Loc; } 149 void setLocation(SourceLocation L) { Loc = L; } 150 151 Kind getKind() const { return DeclKind; } 152 const char *getDeclKindName() const; 153 154 void addAttr(Attr *attr); 155 const Attr *getAttrs() const; 156 void swapAttrs(Decl *D); 157 void invalidateAttrs(); 158 159 template<typename T> const T *getAttr() const { 160 for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) 161 if (const T *V = dyn_cast<T>(attr)) 162 return V; 163 164 return 0; 165 } 166 167 /// setInvalidDecl - Indicates the Decl had a semantic error. This 168 /// allows for graceful error recovery. 169 void setInvalidDecl() { InvalidDecl = 1; } 170 bool isInvalidDecl() const { return (bool) InvalidDecl; } 171 172 IdentifierNamespace getIdentifierNamespace() const { 173 switch (DeclKind) { 174 default: assert(0 && "Unknown decl kind!"); 175 case ImplicitParam: 176 case Typedef: 177 case Function: 178 case Var: 179 case ParmVar: 180 case EnumConstant: 181 case ObjCInterface: 182 case ObjCCompatibleAlias: 183 case OverloadedFunction: 184 case CXXField: 185 case CXXMethod: 186 case CXXClassVar: 187 return IDNS_Ordinary; 188 case Record: 189 case CXXRecord: 190 case Enum: 191 return IDNS_Tag; 192 case Namespace: 193 return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary); 194 } 195 } 196 197 // getBody - If this Decl represents a declaration for a body of code, 198 // such as a function or method definition, this method returns the top-level 199 // Stmt* of that body. Otherwise this method returns null. 200 virtual Stmt* getBody() const { return 0; } 201 202 // global temp stats (until we have a per-module visitor) 203 static void addDeclKind(Kind k); 204 static bool CollectingStats(bool Enable = false); 205 static void PrintStats(); 206 207 // Implement isa/cast/dyncast/etc. 208 static bool classof(const Decl *) { return true; } 209 static DeclContext *castToDeclContext(const Decl *); 210 static Decl *castFromDeclContext(const DeclContext *); 211 212 /// Emit - Serialize this Decl to Bitcode. 213 void Emit(llvm::Serializer& S) const; 214 215 /// Create - Deserialize a Decl from Bitcode. 216 static Decl* Create(llvm::Deserializer& D, ASTContext& C); 217 218 /// Destroy - Call destructors and release memory. 219 virtual void Destroy(ASTContext& C); 220 221protected: 222 /// EmitImpl - Provides the subclass-specific serialization logic for 223 /// serializing out a decl. 224 virtual void EmitImpl(llvm::Serializer& S) const { 225 // FIXME: This will eventually be a pure virtual function. 226 assert (false && "Not implemented."); 227 } 228 229 void EmitInRec(llvm::Serializer& S) const; 230 void ReadInRec(llvm::Deserializer& D, ASTContext& C); 231}; 232 233/// DeclContext - This is used only as base class of specific decl types that 234/// can act as declaration contexts. These decls are: 235/// 236/// TranslationUnitDecl 237/// NamespaceDecl 238/// FunctionDecl 239/// CXXRecordDecl 240/// EnumDecl 241/// ObjCMethodDecl 242/// ObjCInterfaceDecl 243/// BlockDecl 244/// 245class DeclContext { 246 /// DeclKind - This indicates which class this is. 247 Decl::Kind DeclKind : 8; 248 249 /// DeclChain - Linked list of declarations that are defined inside this 250 /// declaration context. 251 ScopedDecl *DeclChain; 252 253 // Used in the CastTo template to get the DeclKind 254 // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method 255 // to avoid 'ambiguous access' compiler errors. 256 template<typename T> struct KindTrait { 257 static Decl::Kind getKind(const T *D) { return D->getKind(); } 258 }; 259 260 // Used only by the ToDecl and FromDecl methods 261 template<typename To, typename From> 262 static To *CastTo(const From *D) { 263 Decl::Kind DK = KindTrait<From>::getKind(D); 264 switch(DK) { 265 case Decl::Block: 266 return static_cast<BlockDecl*>(const_cast<From*>(D)); 267 case Decl::TranslationUnit: 268 return static_cast<TranslationUnitDecl*>(const_cast<From*>(D)); 269 case Decl::Namespace: 270 return static_cast<NamespaceDecl*>(const_cast<From*>(D)); 271 case Decl::Enum: 272 return static_cast<EnumDecl*>(const_cast<From*>(D)); 273 case Decl::CXXRecord: 274 return static_cast<CXXRecordDecl*>(const_cast<From*>(D)); 275 case Decl::ObjCMethod: 276 return static_cast<ObjCMethodDecl*>(const_cast<From*>(D)); 277 case Decl::ObjCInterface: 278 return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D)); 279 default: 280 if (DK >= Decl::FunctionFirst && DK <= Decl::FunctionLast) 281 return static_cast<FunctionDecl*>(const_cast<From*>(D)); 282 283 assert(false && "a decl that inherits DeclContext isn't handled"); 284 return 0; 285 } 286 } 287 288protected: 289 DeclContext(Decl::Kind K) : DeclKind(K), DeclChain(0) {} 290 291public: 292 /// getParent - Returns the containing DeclContext if this is a ScopedDecl, 293 /// else returns NULL. 294 DeclContext *getParent(); 295 const DeclContext *getParent() const { 296 return const_cast<DeclContext*>(this)->getParent(); 297 } 298 299 bool isFunctionOrMethod() const { 300 switch (DeclKind) { 301 case Decl::Block: 302 case Decl::Function: 303 case Decl::CXXMethod: 304 case Decl::ObjCMethod: 305 return true; 306 default: 307 return false; 308 } 309 } 310 311 const ScopedDecl *getDeclChain() const { return DeclChain; } 312 ScopedDecl *getDeclChain() { return DeclChain; } 313 void setDeclChain(ScopedDecl *D) { DeclChain = D; } 314 315 static bool classof(const Decl *D) { 316 switch (D->getKind()) { 317 case Decl::TranslationUnit: 318 case Decl::Namespace: 319 case Decl::Enum: 320 case Decl::CXXRecord: 321 case Decl::ObjCMethod: 322 case Decl::ObjCInterface: 323 case Decl::Block: 324 return true; 325 default: 326 if (D->getKind() >= Decl::FunctionFirst && 327 D->getKind() <= Decl::FunctionLast) 328 return true; 329 return false; 330 } 331 } 332 static bool classof(const DeclContext *D) { return true; } 333 static bool classof(const TranslationUnitDecl *D) { return true; } 334 static bool classof(const NamespaceDecl *D) { return true; } 335 static bool classof(const FunctionDecl *D) { return true; } 336 static bool classof(const CXXRecordDecl *D) { return true; } 337 static bool classof(const EnumDecl *D) { return true; } 338 static bool classof(const ObjCMethodDecl *D) { return true; } 339 static bool classof(const ObjCInterfaceDecl *D) { return true; } 340 static bool classof(const BlockDecl *D) { return true; } 341 342private: 343 void EmitOutRec(llvm::Serializer& S) const; 344 void ReadOutRec(llvm::Deserializer& D, ASTContext& C); 345 346 friend class Decl; 347}; 348 349template<> struct DeclContext::KindTrait<DeclContext> { 350 static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; } 351}; 352 353} // end clang. 354 355namespace llvm { 356 357/// Implement a isa_impl_wrap specialization to check whether a DeclContext is 358/// a specific Decl. 359template<class ToTy> 360struct isa_impl_wrap<ToTy, 361 const ::clang::DeclContext,const ::clang::DeclContext> { 362 static bool doit(const ::clang::DeclContext &Val) { 363 return ToTy::classof(::clang::Decl::castFromDeclContext(&Val)); 364 } 365}; 366template<class ToTy> 367struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext> 368 : public isa_impl_wrap<ToTy, 369 const ::clang::DeclContext,const ::clang::DeclContext> {}; 370 371/// Implement cast_convert_val for Decl -> DeclContext conversions. 372template<class FromTy> 373struct cast_convert_val< ::clang::DeclContext, FromTy, FromTy> { 374 static ::clang::DeclContext &doit(const FromTy &Val) { 375 return *FromTy::castToDeclContext(&Val); 376 } 377}; 378 379template<class FromTy> 380struct cast_convert_val< ::clang::DeclContext, FromTy*, FromTy*> { 381 static ::clang::DeclContext *doit(const FromTy *Val) { 382 return FromTy::castToDeclContext(Val); 383 } 384}; 385 386/// Implement cast_convert_val for DeclContext -> Decl conversions. 387template<class ToTy> 388struct cast_convert_val<ToTy, 389 const ::clang::DeclContext,const ::clang::DeclContext> { 390 static ToTy &doit(const ::clang::DeclContext &Val) { 391 return *reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(&Val)); 392 } 393}; 394template<class ToTy> 395struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> 396 : public cast_convert_val<ToTy, 397 const ::clang::DeclContext,const ::clang::DeclContext> {}; 398 399template<class ToTy> 400struct cast_convert_val<ToTy, 401 const ::clang::DeclContext*, const ::clang::DeclContext*> { 402 static ToTy *doit(const ::clang::DeclContext *Val) { 403 return reinterpret_cast<ToTy*>(ToTy::castFromDeclContext(Val)); 404 } 405}; 406template<class ToTy> 407struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> 408 : public cast_convert_val<ToTy, 409 const ::clang::DeclContext*,const ::clang::DeclContext*> {}; 410 411} // end namespace llvm 412 413#endif 414