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