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