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