DeclObjC.h revision 3a082d81006e7a2e01a6e431a22e21c78490ff8f
1//===--- DeclObjC.h - 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 DeclObjC interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_DECLOBJC_H 15#define LLVM_CLANG_AST_DECLOBJC_H 16 17#include "clang/AST/Decl.h" 18#include "llvm/ADT/STLExtras.h" 19 20namespace clang { 21class Expr; 22class Stmt; 23class FunctionDecl; 24class AttributeList; 25class RecordDecl; 26class ObjCIvarDecl; 27class ObjCMethodDecl; 28class ObjCProtocolDecl; 29class ObjCCategoryDecl; 30class ObjCPropertyDecl; 31class ObjCPropertyImplDecl; 32 33class ObjCListBase { 34 void operator=(const ObjCListBase &); // DO NOT IMPLEMENT 35 ObjCListBase(const ObjCListBase&); // DO NOT IMPLEMENT 36protected: 37 /// List is an array of pointers to objects that are not owned by this object. 38 void **List; 39 unsigned NumElts; 40 41public: 42 ObjCListBase() : List(0), NumElts(0) {} 43 ~ObjCListBase() { 44 assert(List == 0 && "Destroy should have been called before dtor"); 45 } 46 47 void Destroy(ASTContext &Ctx); 48 49 unsigned size() const { return NumElts; } 50 bool empty() const { return NumElts == 0; } 51 52protected: 53 void set(void *const* InList, unsigned Elts, ASTContext &Ctx); 54}; 55 56 57/// ObjCList - This is a simple template class used to hold various lists of 58/// decls etc, which is heavily used by the ObjC front-end. This only use case 59/// this supports is setting the list all at once and then reading elements out 60/// of it. 61template <typename T> 62class ObjCList : public ObjCListBase { 63public: 64 void set(T* const* InList, unsigned Elts, ASTContext &Ctx) { 65 ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx); 66 } 67 68 typedef T* const * iterator; 69 iterator begin() const { return (iterator)List; } 70 iterator end() const { return (iterator)List+NumElts; } 71 72 T* operator[](unsigned Idx) const { 73 assert(Idx < NumElts && "Invalid access"); 74 return (T*)List[Idx]; 75 } 76}; 77 78 79 80/// ObjCMethodDecl - Represents an instance or class method declaration. 81/// ObjC methods can be declared within 4 contexts: class interfaces, 82/// categories, protocols, and class implementations. While C++ member 83/// functions leverage C syntax, Objective-C method syntax is modeled after 84/// Smalltalk (using colons to specify argument types/expressions). 85/// Here are some brief examples: 86/// 87/// Setter/getter instance methods: 88/// - (void)setMenu:(NSMenu *)menu; 89/// - (NSMenu *)menu; 90/// 91/// Instance method that takes 2 NSView arguments: 92/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; 93/// 94/// Getter class method: 95/// + (NSMenu *)defaultMenu; 96/// 97/// A selector represents a unique name for a method. The selector names for 98/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. 99/// 100class ObjCMethodDecl : public NamedDecl, public DeclContext { 101public: 102 enum ImplementationControl { None, Required, Optional }; 103private: 104 /// Bitfields must be first fields in this class so they pack with those 105 /// declared in class Decl. 106 /// instance (true) or class (false) method. 107 bool IsInstance : 1; 108 bool IsVariadic : 1; 109 110 // Synthesized declaration method for a property setter/getter 111 bool IsSynthesized : 1; 112 113 // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum 114 /// @required/@optional 115 unsigned DeclImplementation : 2; 116 117 // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum 118 /// in, inout, etc. 119 unsigned objcDeclQualifier : 6; 120 121 // Type of this method. 122 QualType MethodDeclType; 123 /// ParamInfo - List of pointers to VarDecls for the formal parameters of this 124 /// Method. 125 ObjCList<ParmVarDecl> ParamInfo; 126 127 /// List of attributes for this method declaration. 128 SourceLocation EndLoc; // the location of the ';' or '}'. 129 130 // The following are only used for method definitions, null otherwise. 131 // FIXME: space savings opportunity, consider a sub-class. 132 Stmt *Body; 133 134 /// SelfDecl - Decl for the implicit self parameter. This is lazily 135 /// constructed by createImplicitParams. 136 ImplicitParamDecl *SelfDecl; 137 /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily 138 /// constructed by createImplicitParams. 139 ImplicitParamDecl *CmdDecl; 140 141 ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, 142 Selector SelInfo, QualType T, 143 DeclContext *contextDecl, 144 bool isInstance = true, 145 bool isVariadic = false, 146 bool isSynthesized = false, 147 ImplementationControl impControl = None) 148 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), 149 DeclContext(ObjCMethod), 150 IsInstance(isInstance), IsVariadic(isVariadic), 151 IsSynthesized(isSynthesized), 152 DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), 153 MethodDeclType(T), 154 EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {} 155 156 virtual ~ObjCMethodDecl() {} 157 158 /// \brief A definition will return its interface declaration. 159 /// An interface declaration will return its definition. 160 /// Otherwise it will return itself. 161 virtual ObjCMethodDecl *getNextRedeclaration(); 162 163public: 164 165 /// Destroy - Call destructors and release memory. 166 virtual void Destroy(ASTContext& C); 167 168 static ObjCMethodDecl *Create(ASTContext &C, 169 SourceLocation beginLoc, 170 SourceLocation endLoc, Selector SelInfo, 171 QualType T, DeclContext *contextDecl, 172 bool isInstance = true, 173 bool isVariadic = false, 174 bool isSynthesized = false, 175 ImplementationControl impControl = None); 176 177 virtual ObjCMethodDecl *getCanonicalDecl(); 178 179 ObjCDeclQualifier getObjCDeclQualifier() const { 180 return ObjCDeclQualifier(objcDeclQualifier); 181 } 182 void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; } 183 184 // Location information, modeled after the Stmt API. 185 SourceLocation getLocStart() const { return getLocation(); } 186 SourceLocation getLocEnd() const { return EndLoc; } 187 void setEndLoc(SourceLocation Loc) { EndLoc = Loc; } 188 virtual SourceRange getSourceRange() const { 189 return SourceRange(getLocation(), EndLoc); 190 } 191 192 ObjCInterfaceDecl *getClassInterface(); 193 const ObjCInterfaceDecl *getClassInterface() const { 194 return const_cast<ObjCMethodDecl*>(this)->getClassInterface(); 195 } 196 197 Selector getSelector() const { return getDeclName().getObjCSelector(); } 198 199 QualType getResultType() const { return MethodDeclType; } 200 void setResultType(QualType T) { MethodDeclType = T; } 201 202 // Iterator access to formal parameters. 203 unsigned param_size() const { return ParamInfo.size(); } 204 typedef ObjCList<ParmVarDecl>::iterator param_iterator; 205 param_iterator param_begin() const { return ParamInfo.begin(); } 206 param_iterator param_end() const { return ParamInfo.end(); } 207 208 void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num) { 209 ParamInfo.set(List, Num, C); 210 } 211 212 // Iterator access to parameter types. 213 typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun; 214 typedef llvm::mapped_iterator<param_iterator, deref_fun> arg_type_iterator; 215 216 arg_type_iterator arg_type_begin() const { 217 return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType)); 218 } 219 arg_type_iterator arg_type_end() const { 220 return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType)); 221 } 222 223 /// createImplicitParams - Used to lazily create the self and cmd 224 /// implict parameters. This must be called prior to using getSelfDecl() 225 /// or getCmdDecl(). The call is ignored if the implicit paramters 226 /// have already been created. 227 void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID); 228 229 ImplicitParamDecl * getSelfDecl() const { return SelfDecl; } 230 void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; } 231 ImplicitParamDecl * getCmdDecl() const { return CmdDecl; } 232 void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; } 233 234 bool isInstanceMethod() const { return IsInstance; } 235 void setInstanceMethod(bool isInst) { IsInstance = isInst; } 236 bool isVariadic() const { return IsVariadic; } 237 void setVariadic(bool isVar) { IsVariadic = isVar; } 238 239 bool isClassMethod() const { return !IsInstance; } 240 241 bool isSynthesized() const { return IsSynthesized; } 242 void setSynthesized(bool isSynth) { IsSynthesized = isSynth; } 243 244 // Related to protocols declared in @protocol 245 void setDeclImplementation(ImplementationControl ic) { 246 DeclImplementation = ic; 247 } 248 ImplementationControl getImplementationControl() const { 249 return ImplementationControl(DeclImplementation); 250 } 251 252 virtual Stmt *getBody() const { 253 return (Stmt*) Body; 254 } 255 CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; } 256 void setBody(Stmt *B) { Body = B; } 257 258 /// \brief Returns whether this specific method is a definition. 259 bool isThisDeclarationADefinition() const { return Body; } 260 261 // Implement isa/cast/dyncast/etc. 262 static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; } 263 static bool classof(const ObjCMethodDecl *D) { return true; } 264 static DeclContext *castToDeclContext(const ObjCMethodDecl *D) { 265 return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D)); 266 } 267 static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) { 268 return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC)); 269 } 270}; 271 272/// ObjCMethodList - a linked list of methods with different signatures. 273struct ObjCMethodList { 274 ObjCMethodDecl *Method; 275 ObjCMethodList *Next; 276 277 ObjCMethodList() { 278 Method = 0; 279 Next = 0; 280 } 281 ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) { 282 Method = M; 283 Next = C; 284 } 285}; 286 287/// ObjCContainerDecl - Represents a container for method declarations. 288/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, 289/// ObjCProtocolDecl, and ObjCImplDecl. 290/// 291class ObjCContainerDecl : public NamedDecl, public DeclContext { 292 SourceLocation AtEndLoc; // marks the end of the method container. 293public: 294 295 ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L, 296 IdentifierInfo *Id) 297 : NamedDecl(DK, DC, L, Id), DeclContext(DK) {} 298 299 virtual ~ObjCContainerDecl() {} 300 301 // Iterator access to properties. 302 typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator; 303 prop_iterator prop_begin() const { 304 return prop_iterator(decls_begin()); 305 } 306 prop_iterator prop_end() const { 307 return prop_iterator(decls_end()); 308 } 309 310 // Iterator access to instance/class methods. 311 typedef specific_decl_iterator<ObjCMethodDecl> method_iterator; 312 method_iterator meth_begin() const { 313 return method_iterator(decls_begin()); 314 } 315 method_iterator meth_end() const { 316 return method_iterator(decls_end()); 317 } 318 319 typedef filtered_decl_iterator<ObjCMethodDecl, 320 &ObjCMethodDecl::isInstanceMethod> 321 instmeth_iterator; 322 instmeth_iterator instmeth_begin() const { 323 return instmeth_iterator(decls_begin()); 324 } 325 instmeth_iterator instmeth_end() const { 326 return instmeth_iterator(decls_end()); 327 } 328 329 typedef filtered_decl_iterator<ObjCMethodDecl, 330 &ObjCMethodDecl::isClassMethod> 331 classmeth_iterator; 332 classmeth_iterator classmeth_begin() const { 333 return classmeth_iterator(decls_begin()); 334 } 335 classmeth_iterator classmeth_end() const { 336 return classmeth_iterator(decls_end()); 337 } 338 339 // Get the local instance/class method declared in this interface. 340 ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const; 341 ObjCMethodDecl *getInstanceMethod(Selector Sel) const { 342 return getMethod(Sel, true/*isInstance*/); 343 } 344 ObjCMethodDecl *getClassMethod(Selector Sel) const { 345 return getMethod(Sel, false/*isInstance*/); 346 } 347 ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; 348 349 ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; 350 351 // Marks the end of the container. 352 SourceLocation getAtEndLoc() const { return AtEndLoc; } 353 void setAtEndLoc(SourceLocation L) { AtEndLoc = L; } 354 355 virtual SourceRange getSourceRange() const { 356 return SourceRange(getLocation(), getAtEndLoc()); 357 } 358 359 // Implement isa/cast/dyncast/etc. 360 static bool classof(const Decl *D) { 361 return D->getKind() >= ObjCContainerFirst && 362 D->getKind() <= ObjCContainerLast; 363 } 364 static bool classof(const ObjCContainerDecl *D) { return true; } 365 366 static DeclContext *castToDeclContext(const ObjCContainerDecl *D) { 367 return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D)); 368 } 369 static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) { 370 return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC)); 371 } 372}; 373 374/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example: 375/// 376/// // MostPrimitive declares no super class (not particularly useful). 377/// @interface MostPrimitive 378/// // no instance variables or methods. 379/// @end 380/// 381/// // NSResponder inherits from NSObject & implements NSCoding (a protocol). 382/// @interface NSResponder : NSObject <NSCoding> 383/// { // instance variables are represented by ObjCIvarDecl. 384/// id nextResponder; // nextResponder instance variable. 385/// } 386/// - (NSResponder *)nextResponder; // return a pointer to NSResponder. 387/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer 388/// @end // to an NSEvent. 389/// 390/// Unlike C/C++, forward class declarations are accomplished with @class. 391/// Unlike C/C++, @class allows for a list of classes to be forward declared. 392/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes 393/// typically inherit from NSObject (an exception is NSProxy). 394/// 395class ObjCInterfaceDecl : public ObjCContainerDecl { 396 /// TypeForDecl - This indicates the Type object that represents this 397 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType 398 mutable Type *TypeForDecl; 399 friend class ASTContext; 400 401 /// Class's super class. 402 ObjCInterfaceDecl *SuperClass; 403 404 /// Protocols referenced in interface header declaration 405 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 406 407 /// Instance variables in the interface. 408 ObjCList<ObjCIvarDecl> IVars; 409 410 /// List of categories defined for this class. 411 /// FIXME: Why is this a linked list?? 412 ObjCCategoryDecl *CategoryList; 413 414 bool ForwardDecl:1; // declared with @class. 415 bool InternalInterface:1; // true - no @interface for @implementation 416 417 SourceLocation ClassLoc; // location of the class identifier. 418 SourceLocation SuperClassLoc; // location of the super class identifier. 419 SourceLocation EndLoc; // marks the '>', '}', or identifier. 420 421 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, 422 SourceLocation CLoc, bool FD, bool isInternal); 423 424 virtual ~ObjCInterfaceDecl() {} 425 426public: 427 428 /// Destroy - Call destructors and release memory. 429 virtual void Destroy(ASTContext& C); 430 431 static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC, 432 SourceLocation atLoc, 433 IdentifierInfo *Id, 434 SourceLocation ClassLoc = SourceLocation(), 435 bool ForwardDecl = false, 436 bool isInternal = false); 437 const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { 438 return ReferencedProtocols; 439 } 440 441 ObjCImplementationDecl *getImplementation() const; 442 void setImplementation(ObjCImplementationDecl *ImplD); 443 444 ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; 445 446 // Get the local instance/class method declared in a category. 447 ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; 448 ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const; 449 ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const { 450 return isInstance ? getInstanceMethod(Sel) 451 : getClassMethod(Sel); 452 } 453 454 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 455 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 456 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 457 unsigned protocol_size() const { return ReferencedProtocols.size(); } 458 459 typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator; 460 ivar_iterator ivar_begin() const { return IVars.begin(); } 461 ivar_iterator ivar_end() const { return IVars.end(); } 462 unsigned ivar_size() const { return IVars.size(); } 463 bool ivar_empty() const { return IVars.empty(); } 464 465 /// setProtocolList - Set the list of protocols that this interface 466 /// implements. 467 void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, 468 ASTContext &C) { 469 ReferencedProtocols.set(List, Num, C); 470 } 471 472 void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) { 473 IVars.set(List, Num, C); 474 } 475 476 bool isForwardDecl() const { return ForwardDecl; } 477 void setForwardDecl(bool val) { ForwardDecl = val; } 478 479 ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 480 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 481 482 ObjCCategoryDecl* getCategoryList() const { return CategoryList; } 483 void setCategoryList(ObjCCategoryDecl *category) { 484 CategoryList = category; 485 } 486 487 /// isSuperClassOf - Return true if this class is the specified class or is a 488 /// super class of the specified interface class. 489 bool isSuperClassOf(const ObjCInterfaceDecl *I) const { 490 // If RHS is derived from LHS it is OK; else it is not OK. 491 while (I != NULL) { 492 if (this == I) 493 return true; 494 I = I->getSuperClass(); 495 } 496 return false; 497 } 498 499 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName, 500 ObjCInterfaceDecl *&ClassDeclared); 501 ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) { 502 ObjCInterfaceDecl *ClassDeclared; 503 return lookupInstanceVariable(IVarName, ClassDeclared); 504 } 505 506 // Lookup a method. First, we search locally. If a method isn't 507 // found, we search referenced protocols and class categories. 508 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const; 509 ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { 510 return lookupMethod(Sel, true/*isInstance*/); 511 } 512 ObjCMethodDecl *lookupClassMethod(Selector Sel) const { 513 return lookupMethod(Sel, false/*isInstance*/); 514 } 515 ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); 516 517 // Location information, modeled after the Stmt API. 518 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 519 SourceLocation getLocEnd() const { return EndLoc; } 520 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 521 522 void setClassLoc(SourceLocation Loc) { ClassLoc = Loc; } 523 SourceLocation getClassLoc() const { return ClassLoc; } 524 void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; } 525 SourceLocation getSuperClassLoc() const { return SuperClassLoc; } 526 527 /// isImplicitInterfaceDecl - check that this is an implicitly declared 528 /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation 529 /// declaration without an @interface declaration. 530 bool isImplicitInterfaceDecl() const { return InternalInterface; } 531 void setImplicitInterfaceDecl(bool val) { InternalInterface = val; } 532 533 /// ClassImplementsProtocol - Checks that 'lProto' protocol 534 /// has been implemented in IDecl class, its super class or categories (if 535 /// lookupCategory is true). 536 bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, 537 bool lookupCategory, 538 bool RHSIsQualifiedID = false); 539 540 // Low-level accessor 541 Type *getTypeForDecl() const { return TypeForDecl; } 542 void setTypeForDecl(Type *TD) const { TypeForDecl = TD; } 543 544 static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; } 545 static bool classof(const ObjCInterfaceDecl *D) { return true; } 546}; 547 548/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC 549/// instance variables are identical to C. The only exception is Objective-C 550/// supports C++ style access control. For example: 551/// 552/// @interface IvarExample : NSObject 553/// { 554/// id defaultToProtected; 555/// @public: 556/// id canBePublic; // same as C++. 557/// @protected: 558/// id canBeProtected; // same as C++. 559/// @package: 560/// id canBePackage; // framework visibility (not available in C++). 561/// } 562/// 563class ObjCIvarDecl : public FieldDecl { 564public: 565 enum AccessControl { 566 None, Private, Protected, Public, Package 567 }; 568 569private: 570 ObjCIvarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 571 QualType T, DeclaratorInfo *DInfo, AccessControl ac, Expr *BW) 572 : FieldDecl(ObjCIvar, DC, L, Id, T, DInfo, BW, /*Mutable=*/false), 573 DeclAccess(ac) {} 574 575public: 576 static ObjCIvarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, 577 IdentifierInfo *Id, QualType T, 578 DeclaratorInfo *DInfo, 579 AccessControl ac, Expr *BW = NULL); 580 581 void setAccessControl(AccessControl ac) { DeclAccess = ac; } 582 583 AccessControl getAccessControl() const { return AccessControl(DeclAccess); } 584 585 AccessControl getCanonicalAccessControl() const { 586 return DeclAccess == None ? Protected : AccessControl(DeclAccess); 587 } 588 589 // Implement isa/cast/dyncast/etc. 590 static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; } 591 static bool classof(const ObjCIvarDecl *D) { return true; } 592private: 593 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum 594 unsigned DeclAccess : 3; 595}; 596 597 598/// ObjCAtDefsFieldDecl - Represents a field declaration created by an 599/// @defs(...). 600class ObjCAtDefsFieldDecl : public FieldDecl { 601private: 602 ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 603 QualType T, Expr *BW) 604 : FieldDecl(ObjCAtDefsField, DC, L, Id, T, 605 /*DInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? 606 BW, /*Mutable=*/false) {} 607 608public: 609 static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, 610 SourceLocation L, 611 IdentifierInfo *Id, QualType T, 612 Expr *BW); 613 614 virtual void Destroy(ASTContext& C); 615 616 // Implement isa/cast/dyncast/etc. 617 static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; } 618 static bool classof(const ObjCAtDefsFieldDecl *D) { return true; } 619}; 620 621/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols 622/// declare a pure abstract type (i.e no instance variables are permitted). 623/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++ 624/// feature with nice semantics and lousy syntax:-). Here is an example: 625/// 626/// @protocol NSDraggingInfo <refproto1, refproto2> 627/// - (NSWindow *)draggingDestinationWindow; 628/// - (NSImage *)draggedImage; 629/// @end 630/// 631/// This says that NSDraggingInfo requires two methods and requires everything 632/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as 633/// well. 634/// 635/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo> 636/// @end 637/// 638/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and 639/// protocols are in distinct namespaces. For example, Cocoa defines both 640/// an NSObject protocol and class (which isn't allowed in Java). As a result, 641/// protocols are referenced using angle brackets as follows: 642/// 643/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; 644/// 645class ObjCProtocolDecl : public ObjCContainerDecl { 646 /// Referenced protocols 647 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 648 649 bool isForwardProtoDecl; // declared with @protocol. 650 651 SourceLocation EndLoc; // marks the '>' or identifier. 652 653 ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) 654 : ObjCContainerDecl(ObjCProtocol, DC, L, Id), 655 isForwardProtoDecl(true) { 656 } 657 658 virtual ~ObjCProtocolDecl() {} 659 660public: 661 static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, 662 SourceLocation L, IdentifierInfo *Id); 663 664 /// Destroy - Call destructors and release memory. 665 virtual void Destroy(ASTContext& C); 666 667 const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { 668 return ReferencedProtocols; 669 } 670 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 671 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 672 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 673 unsigned protocol_size() const { return ReferencedProtocols.size(); } 674 675 /// setProtocolList - Set the list of protocols that this interface 676 /// implements. 677 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 678 ASTContext &C) { 679 ReferencedProtocols.set(List, Num, C); 680 } 681 682 ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); 683 684 // Lookup a method. First, we search locally. If a method isn't 685 // found, we search referenced protocols and class categories. 686 ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const; 687 ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { 688 return lookupMethod(Sel, true/*isInstance*/); 689 } 690 ObjCMethodDecl *lookupClassMethod(Selector Sel) const { 691 return lookupMethod(Sel, false/*isInstance*/); 692 } 693 694 bool isForwardDecl() const { return isForwardProtoDecl; } 695 void setForwardDecl(bool val) { isForwardProtoDecl = val; } 696 697 // Location information, modeled after the Stmt API. 698 SourceLocation getLocStart() const { return getLocation(); } // '@'protocol 699 SourceLocation getLocEnd() const { return EndLoc; } 700 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 701 702 static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; } 703 static bool classof(const ObjCProtocolDecl *D) { return true; } 704}; 705 706/// ObjCClassDecl - Specifies a list of forward class declarations. For example: 707/// 708/// @class NSCursor, NSImage, NSPasteboard, NSWindow; 709/// 710class ObjCClassDecl : public Decl { 711 ObjCList<ObjCInterfaceDecl> ForwardDecls; 712 713 ObjCClassDecl(DeclContext *DC, SourceLocation L, 714 ObjCInterfaceDecl *const *Elts, unsigned nElts, ASTContext &C); 715 virtual ~ObjCClassDecl() {} 716public: 717 718 /// Destroy - Call destructors and release memory. 719 virtual void Destroy(ASTContext& C); 720 721 static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, 722 ObjCInterfaceDecl *const *Elts = 0, 723 unsigned nElts = 0); 724 725 typedef ObjCList<ObjCInterfaceDecl>::iterator iterator; 726 iterator begin() const { return ForwardDecls.begin(); } 727 iterator end() const { return ForwardDecls.end(); } 728 unsigned size() const { return ForwardDecls.size(); } 729 730 /// setClassList - Set the list of forward classes. 731 void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, unsigned Num) { 732 ForwardDecls.set(List, Num, C); 733 } 734 735 static bool classof(const Decl *D) { return D->getKind() == ObjCClass; } 736 static bool classof(const ObjCClassDecl *D) { return true; } 737}; 738 739/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations. 740/// For example: 741/// 742/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; 743/// 744class ObjCForwardProtocolDecl : public Decl { 745 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 746 747 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, 748 ObjCProtocolDecl *const *Elts, unsigned nElts, 749 ASTContext &C); 750 virtual ~ObjCForwardProtocolDecl() {} 751 752public: 753 static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, 754 SourceLocation L, 755 ObjCProtocolDecl *const *Elts = 0, 756 unsigned Num = 0); 757 758 /// Destroy - Call destructors and release memory. 759 virtual void Destroy(ASTContext& C); 760 761 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 762 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 763 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 764 unsigned protocol_size() const { return ReferencedProtocols.size(); } 765 766 /// setProtocolList - Set the list of forward protocols. 767 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 768 ASTContext &C) { 769 ReferencedProtocols.set(List, Num, C); 770 } 771 static bool classof(const Decl *D) { 772 return D->getKind() == ObjCForwardProtocol; 773 } 774 static bool classof(const ObjCForwardProtocolDecl *D) { return true; } 775}; 776 777/// ObjCCategoryDecl - Represents a category declaration. A category allows 778/// you to add methods to an existing class (without subclassing or modifying 779/// the original class interface or implementation:-). Categories don't allow 780/// you to add instance data. The following example adds "myMethod" to all 781/// NSView's within a process: 782/// 783/// @interface NSView (MyViewMethods) 784/// - myMethod; 785/// @end 786/// 787/// Cateogries also allow you to split the implementation of a class across 788/// several files (a feature more naturally supported in C++). 789/// 790/// Categories were originally inspired by dynamic languages such as Common 791/// Lisp and Smalltalk. More traditional class-based languages (C++, Java) 792/// don't support this level of dynamism, which is both powerful and dangerous. 793/// 794class ObjCCategoryDecl : public ObjCContainerDecl { 795 /// Interface belonging to this category 796 ObjCInterfaceDecl *ClassInterface; 797 798 /// referenced protocols in this category. 799 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 800 801 /// Next category belonging to this class. 802 /// FIXME: this should not be a singly-linked list. Move storage elsewhere. 803 ObjCCategoryDecl *NextClassCategory; 804 805 SourceLocation EndLoc; // marks the '>' or identifier. 806 807 ObjCCategoryDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) 808 : ObjCContainerDecl(ObjCCategory, DC, L, Id), 809 ClassInterface(0), NextClassCategory(0){ 810 } 811public: 812 813 static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, 814 SourceLocation L, IdentifierInfo *Id); 815 816 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 817 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 818 void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; } 819 820 ObjCCategoryImplDecl *getImplementation() const; 821 void setImplementation(ObjCCategoryImplDecl *ImplD); 822 823 /// setProtocolList - Set the list of protocols that this interface 824 /// implements. 825 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 826 ASTContext &C) { 827 ReferencedProtocols.set(List, Num, C); 828 } 829 830 const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { 831 return ReferencedProtocols; 832 } 833 834 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 835 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 836 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 837 unsigned protocol_size() const { return ReferencedProtocols.size(); } 838 839 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 840 void setNextClassCategory(ObjCCategoryDecl *Cat) { 841 NextClassCategory = Cat; 842 } 843 void insertNextClassCategory() { 844 NextClassCategory = ClassInterface->getCategoryList(); 845 ClassInterface->setCategoryList(this); 846 } 847 // Location information, modeled after the Stmt API. 848 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 849 SourceLocation getLocEnd() const { return EndLoc; } 850 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 851 852 static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; } 853 static bool classof(const ObjCCategoryDecl *D) { return true; } 854}; 855 856class ObjCImplDecl : public ObjCContainerDecl { 857 /// Class interface for this category implementation 858 ObjCInterfaceDecl *ClassInterface; 859 860protected: 861 ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L, 862 ObjCInterfaceDecl *classInterface) 863 : ObjCContainerDecl(DK, DC, L, 864 classInterface? classInterface->getIdentifier() : 0), 865 ClassInterface(classInterface) {} 866 867public: 868 virtual ~ObjCImplDecl() {} 869 870 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 871 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 872 void setClassInterface(ObjCInterfaceDecl *IFace); 873 874 void addInstanceMethod(ObjCMethodDecl *method) { 875 // FIXME: Context should be set correctly before we get here. 876 method->setLexicalDeclContext(this); 877 addDecl(method); 878 } 879 void addClassMethod(ObjCMethodDecl *method) { 880 // FIXME: Context should be set correctly before we get here. 881 method->setLexicalDeclContext(this); 882 addDecl(method); 883 } 884 885 void addPropertyImplementation(ObjCPropertyImplDecl *property); 886 887 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; 888 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 889 890 // Iterator access to properties. 891 typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator; 892 propimpl_iterator propimpl_begin() const { 893 return propimpl_iterator(decls_begin()); 894 } 895 propimpl_iterator propimpl_end() const { 896 return propimpl_iterator(decls_end()); 897 } 898 899 static bool classof(const Decl *D) { 900 return D->getKind() >= ObjCImplFirst && D->getKind() <= ObjCImplLast; 901 } 902 static bool classof(const ObjCImplDecl *D) { return true; } 903}; 904 905/// ObjCCategoryImplDecl - An object of this class encapsulates a category 906/// @implementation declaration. If a category class has declaration of a 907/// property, its implementation must be specified in the category's 908/// @implementation declaration. Example: 909/// @interface I @end 910/// @interface I(CATEGORY) 911/// @property int p1, d1; 912/// @end 913/// @implementation I(CATEGORY) 914/// @dynamic p1,d1; 915/// @end 916/// 917/// ObjCCategoryImplDecl 918class ObjCCategoryImplDecl : public ObjCImplDecl { 919 // Category name 920 IdentifierInfo *Id; 921 922 ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 923 ObjCInterfaceDecl *classInterface) 924 : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {} 925public: 926 static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, 927 SourceLocation L, IdentifierInfo *Id, 928 ObjCInterfaceDecl *classInterface); 929 930 /// getIdentifier - Get the identifier that names the class 931 /// interface associated with this implementation. 932 IdentifierInfo *getIdentifier() const { 933 return Id; 934 } 935 void setIdentifier(IdentifierInfo *II) { Id = II; } 936 937 ObjCCategoryDecl *getCategoryClass() const; 938 939 /// getNameAsCString - Get the name of identifier for the class 940 /// interface associated with this implementation as a C string 941 /// (const char*). 942 const char *getNameAsCString() const { 943 return Id ? Id->getName() : ""; 944 } 945 946 /// @brief Get the name of the class associated with this interface. 947 std::string getNameAsString() const { 948 return Id ? Id->getName() : ""; 949 } 950 951 static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;} 952 static bool classof(const ObjCCategoryImplDecl *D) { return true; } 953}; 954 955/// ObjCImplementationDecl - Represents a class definition - this is where 956/// method definitions are specified. For example: 957/// 958/// @code 959/// @implementation MyClass 960/// - (void)myMethod { /* do something */ } 961/// @end 962/// @endcode 963/// 964/// Typically, instance variables are specified in the class interface, 965/// *not* in the implementation. Nevertheless (for legacy reasons), we 966/// allow instance variables to be specified in the implementation. When 967/// specified, they need to be *identical* to the interface. 968/// 969class ObjCImplementationDecl : public ObjCImplDecl { 970 /// Implementation Class's super class. 971 ObjCInterfaceDecl *SuperClass; 972 973 ObjCImplementationDecl(DeclContext *DC, SourceLocation L, 974 ObjCInterfaceDecl *classInterface, 975 ObjCInterfaceDecl *superDecl) 976 : ObjCImplDecl(ObjCImplementation, DC, L, classInterface), 977 SuperClass(superDecl){} 978public: 979 static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, 980 SourceLocation L, 981 ObjCInterfaceDecl *classInterface, 982 ObjCInterfaceDecl *superDecl); 983 984 /// getIdentifier - Get the identifier that names the class 985 /// interface associated with this implementation. 986 IdentifierInfo *getIdentifier() const { 987 return getClassInterface()->getIdentifier(); 988 } 989 990 /// getNameAsCString - Get the name of identifier for the class 991 /// interface associated with this implementation as a C string 992 /// (const char*). 993 const char *getNameAsCString() const { 994 assert(getIdentifier() && "Name is not a simple identifier"); 995 return getIdentifier()->getName(); 996 } 997 998 /// @brief Get the name of the class associated with this interface. 999 std::string getNameAsString() const { 1000 return getClassInterface()->getNameAsString(); 1001 } 1002 1003 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 1004 ObjCInterfaceDecl *getSuperClass() { return SuperClass; } 1005 1006 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 1007 1008 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 1009 ivar_iterator ivar_begin() const { 1010 return ivar_iterator(decls_begin()); 1011 } 1012 ivar_iterator ivar_end() const { 1013 return ivar_iterator(decls_end()); 1014 } 1015 unsigned ivar_size() const { 1016 return std::distance(ivar_begin(), ivar_end()); 1017 } 1018 bool ivar_empty() const { 1019 return ivar_begin() == ivar_end(); 1020 } 1021 1022 static bool classof(const Decl *D) { 1023 return D->getKind() == ObjCImplementation; 1024 } 1025 static bool classof(const ObjCImplementationDecl *D) { return true; } 1026}; 1027 1028/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 1029/// declared as @compatibility_alias alias class. 1030class ObjCCompatibleAliasDecl : public NamedDecl { 1031 /// Class that this is an alias of. 1032 ObjCInterfaceDecl *AliasedClass; 1033 1034 ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 1035 ObjCInterfaceDecl* aliasedClass) 1036 : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {} 1037public: 1038 static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC, 1039 SourceLocation L, IdentifierInfo *Id, 1040 ObjCInterfaceDecl* aliasedClass); 1041 1042 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } 1043 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } 1044 void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } 1045 1046 static bool classof(const Decl *D) { 1047 return D->getKind() == ObjCCompatibleAlias; 1048 } 1049 static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } 1050 1051}; 1052 1053/// ObjCPropertyDecl - Represents one property declaration in an interface. 1054/// For example: 1055/// @property (assign, readwrite) int MyProperty; 1056/// 1057class ObjCPropertyDecl : public NamedDecl { 1058public: 1059 enum PropertyAttributeKind { 1060 OBJC_PR_noattr = 0x00, 1061 OBJC_PR_readonly = 0x01, 1062 OBJC_PR_getter = 0x02, 1063 OBJC_PR_assign = 0x04, 1064 OBJC_PR_readwrite = 0x08, 1065 OBJC_PR_retain = 0x10, 1066 OBJC_PR_copy = 0x20, 1067 OBJC_PR_nonatomic = 0x40, 1068 OBJC_PR_setter = 0x80 1069 }; 1070 1071 enum SetterKind { Assign, Retain, Copy }; 1072 enum PropertyControl { None, Required, Optional }; 1073private: 1074 QualType DeclType; 1075 unsigned PropertyAttributes : 8; 1076 1077 // @required/@optional 1078 unsigned PropertyImplementation : 2; 1079 1080 Selector GetterName; // getter name of NULL if no getter 1081 Selector SetterName; // setter name of NULL if no setter 1082 1083 ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method 1084 ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method 1085 ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property 1086 1087 ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 1088 QualType T) 1089 : NamedDecl(ObjCProperty, DC, L, Id), DeclType(T), 1090 PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None), 1091 GetterName(Selector()), 1092 SetterName(Selector()), 1093 GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {} 1094public: 1095 static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, 1096 SourceLocation L, 1097 IdentifierInfo *Id, QualType T, 1098 PropertyControl propControl = None); 1099 QualType getType() const { return DeclType; } 1100 void setType(QualType T) { DeclType = T; } 1101 1102 PropertyAttributeKind getPropertyAttributes() const { 1103 return PropertyAttributeKind(PropertyAttributes); 1104 } 1105 void setPropertyAttributes(PropertyAttributeKind PRVal) { 1106 PropertyAttributes |= PRVal; 1107 } 1108 1109 void makeitReadWriteAttribute(void) { 1110 PropertyAttributes &= ~OBJC_PR_readonly; 1111 PropertyAttributes |= OBJC_PR_readwrite; 1112 } 1113 1114 // Helper methods for accessing attributes. 1115 1116 /// isReadOnly - Return true iff the property has a setter. 1117 bool isReadOnly() const { 1118 return (PropertyAttributes & OBJC_PR_readonly); 1119 } 1120 1121 /// getSetterKind - Return the method used for doing assignment in 1122 /// the property setter. This is only valid if the property has been 1123 /// defined to have a setter. 1124 SetterKind getSetterKind() const { 1125 if (PropertyAttributes & OBJC_PR_retain) 1126 return Retain; 1127 if (PropertyAttributes & OBJC_PR_copy) 1128 return Copy; 1129 return Assign; 1130 } 1131 1132 Selector getGetterName() const { return GetterName; } 1133 void setGetterName(Selector Sel) { GetterName = Sel; } 1134 1135 Selector getSetterName() const { return SetterName; } 1136 void setSetterName(Selector Sel) { SetterName = Sel; } 1137 1138 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } 1139 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } 1140 1141 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } 1142 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } 1143 1144 // Related to @optional/@required declared in @protocol 1145 void setPropertyImplementation(PropertyControl pc) { 1146 PropertyImplementation = pc; 1147 } 1148 PropertyControl getPropertyImplementation() const { 1149 return PropertyControl(PropertyImplementation); 1150 } 1151 1152 void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { 1153 PropertyIvarDecl = Ivar; 1154 } 1155 ObjCIvarDecl *getPropertyIvarDecl() const { 1156 return PropertyIvarDecl; 1157 } 1158 1159 static bool classof(const Decl *D) { 1160 return D->getKind() == ObjCProperty; 1161 } 1162 static bool classof(const ObjCPropertyDecl *D) { return true; } 1163}; 1164 1165/// ObjCPropertyImplDecl - Represents implementation declaration of a property 1166/// in a class or category implementation block. For example: 1167/// @synthesize prop1 = ivar1; 1168/// 1169class ObjCPropertyImplDecl : public Decl { 1170public: 1171 enum Kind { 1172 Synthesize, 1173 Dynamic 1174 }; 1175private: 1176 SourceLocation AtLoc; // location of @synthesize or @dynamic 1177 /// Property declaration being implemented 1178 ObjCPropertyDecl *PropertyDecl; 1179 1180 /// Null for @dynamic. Required for @synthesize. 1181 ObjCIvarDecl *PropertyIvarDecl; 1182 1183 ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, 1184 ObjCPropertyDecl *property, 1185 Kind PK, 1186 ObjCIvarDecl *ivarDecl) 1187 : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), 1188 PropertyDecl(property), PropertyIvarDecl(ivarDecl) { 1189 assert (PK == Dynamic || PropertyIvarDecl); 1190 } 1191 1192public: 1193 static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC, 1194 SourceLocation atLoc, SourceLocation L, 1195 ObjCPropertyDecl *property, 1196 Kind PK, 1197 ObjCIvarDecl *ivarDecl); 1198 1199 virtual SourceRange getSourceRange() const { 1200 return SourceRange(AtLoc, getLocation()); 1201 } 1202 SourceLocation getLocStart() const { return AtLoc; } 1203 void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } 1204 1205 ObjCPropertyDecl *getPropertyDecl() const { 1206 return PropertyDecl; 1207 } 1208 void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; } 1209 1210 Kind getPropertyImplementation() const { 1211 return PropertyIvarDecl ? Synthesize : Dynamic; 1212 } 1213 1214 ObjCIvarDecl *getPropertyIvarDecl() const { 1215 return PropertyIvarDecl; 1216 } 1217 void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; } 1218 1219 static bool classof(const Decl *D) { 1220 return D->getKind() == ObjCPropertyImpl; 1221 } 1222 static bool classof(const ObjCPropertyImplDecl *D) { return true; } 1223}; 1224 1225} // end namespace clang 1226#endif 1227