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