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