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