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