DeclObjC.h revision ae6f6fd1527a1da84679a6f0439dec3bbbd6ca7b
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 addPropertyMethods(ASTContext &Context, 887 ObjCPropertyDecl* Property, 888 llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods, 889 llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap); 890 891 ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; 892 893 typedef ObjCPropertyDecl * const * classprop_iterator; 894 classprop_iterator classprop_begin() const { return PropertyDecl; } 895 classprop_iterator classprop_end() const { 896 return PropertyDecl+NumPropertyDecl; 897 } 898 899 typedef ObjCMethodDecl * const * instmeth_iterator; 900 instmeth_iterator instmeth_begin() const { return InstanceMethods; } 901 instmeth_iterator instmeth_end() const { 902 return InstanceMethods+NumInstanceMethods; 903 } 904 905 typedef ObjCMethodDecl * const * classmeth_iterator; 906 classmeth_iterator classmeth_begin() const { return ClassMethods; } 907 classmeth_iterator classmeth_end() const { 908 return ClassMethods+NumClassMethods; 909 } 910 911 // Get the local instance method declared in this interface. 912 ObjCMethodDecl *getInstanceMethod(Selector Sel) const { 913 for (instmeth_iterator I = instmeth_begin(), E = instmeth_end(); 914 I != E; ++I) { 915 if ((*I)->getSelector() == Sel) 916 return *I; 917 } 918 return 0; 919 } 920 // Get the local class method declared in this interface. 921 ObjCMethodDecl *getClassMethod(Selector Sel) const { 922 for (classmeth_iterator I = classmeth_begin(), E = classmeth_end(); 923 I != E; ++I) { 924 if ((*I)->getSelector() == Sel) 925 return *I; 926 } 927 return 0; 928 } 929 930 void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers, 931 ObjCMethodDecl **clsMethods, unsigned numClsMembers, 932 SourceLocation AtEndLoc); 933 934 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 935 void insertNextClassCategory() { 936 NextClassCategory = ClassInterface->getCategoryList(); 937 ClassInterface->setCategoryList(this); 938 } 939 // Location information, modeled after the Stmt API. 940 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 941 SourceLocation getLocEnd() const { return EndLoc; } 942 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 943 944 // We also need to record the @end location. 945 SourceLocation getAtEndLoc() const { return AtEndLoc; } 946 947 static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; } 948 static bool classof(const ObjCCategoryDecl *D) { return true; } 949}; 950 951/// ObjCCategoryImplDecl - An object of this class encapsulates a category 952/// @implementation declaration. If a category class has declaration of a 953/// property, its implementation must be specified in the category's 954/// @implementation declaration. Example: 955/// @interface I @end 956/// @interface I(CATEGORY) 957/// @property int p1, d1; 958/// @end 959/// @implementation I(CATEGORY) 960/// @dynamic p1,d1; 961/// @end 962/// 963class ObjCCategoryImplDecl : public NamedDecl { 964 /// Class interface for this category implementation 965 ObjCInterfaceDecl *ClassInterface; 966 967 /// implemented instance methods 968 llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods; 969 970 /// implemented class methods 971 llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods; 972 973 /// Property Implementations in this category 974 llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations; 975 976 SourceLocation EndLoc; 977 978 ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id, 979 ObjCInterfaceDecl *classInterface) 980 : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {} 981public: 982 static ObjCCategoryImplDecl *Create(ASTContext &C, 983 SourceLocation L, IdentifierInfo *Id, 984 ObjCInterfaceDecl *classInterface); 985 986 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 987 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 988 989 unsigned getNumInstanceMethods() const { return InstanceMethods.size(); } 990 unsigned getNumClassMethods() const { return ClassMethods.size(); } 991 992 void addInstanceMethod(ObjCMethodDecl *method) { 993 InstanceMethods.push_back(method); 994 } 995 void addClassMethod(ObjCMethodDecl *method) { 996 ClassMethods.push_back(method); 997 } 998 // Get the instance method definition for this implementation. 999 ObjCMethodDecl *getInstanceMethod(Selector Sel) const; 1000 1001 // Get the class method definition for this implementation. 1002 ObjCMethodDecl *getClassMethod(Selector Sel) const; 1003 1004 void addPropertyImplementation(ObjCPropertyImplDecl *property) { 1005 PropertyImplementations.push_back(property); 1006 } 1007 1008 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; 1009 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 1010 1011 unsigned getNumPropertyImplementations() const 1012 { return PropertyImplementations.size(); } 1013 1014 1015 typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator 1016 propimpl_iterator; 1017 propimpl_iterator propimpl_begin() const { 1018 return PropertyImplementations.begin(); 1019 } 1020 propimpl_iterator propimpl_end() const { 1021 return PropertyImplementations.end(); 1022 } 1023 1024 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1025 instmeth_iterator; 1026 instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); } 1027 instmeth_iterator instmeth_end() const { return InstanceMethods.end(); } 1028 1029 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1030 classmeth_iterator; 1031 classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); } 1032 classmeth_iterator classmeth_end() const { return ClassMethods.end(); } 1033 1034 1035 // Location information, modeled after the Stmt API. 1036 SourceLocation getLocStart() const { return getLocation(); } 1037 SourceLocation getLocEnd() const { return EndLoc; } 1038 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 1039 1040 static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;} 1041 static bool classof(const ObjCCategoryImplDecl *D) { return true; } 1042}; 1043 1044/// ObjCImplementationDecl - Represents a class definition - this is where 1045/// method definitions are specified. For example: 1046/// 1047/// @implementation MyClass 1048/// - (void)myMethod { /* do something */ } 1049/// @end 1050/// 1051/// Typically, instance variables are specified in the class interface, 1052/// *not* in the implemenentation. Nevertheless (for legacy reasons), we 1053/// allow instance variables to be specified in the implementation. When 1054/// specified, they need to be *identical* to the interface. Now that we 1055/// have support for non-fragile ivars in ObjC 2.0, we can consider removing 1056/// the legacy semantics and allow developers to move private ivar declarations 1057/// from the class interface to the class implementation (but I digress:-) 1058/// 1059class ObjCImplementationDecl : public NamedDecl { 1060 /// Class interface for this implementation 1061 ObjCInterfaceDecl *ClassInterface; 1062 1063 /// Implementation Class's super class. 1064 ObjCInterfaceDecl *SuperClass; 1065 1066 /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 1067 ObjCIvarDecl **Ivars; // Null if not specified 1068 unsigned NumIvars; // 0 if none. 1069 1070 /// implemented instance methods 1071 llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods; 1072 1073 /// implemented class methods 1074 llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods; 1075 1076 /// Propertys' being implemented 1077 llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations; 1078 1079 SourceLocation EndLoc; 1080 1081 ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id, 1082 ObjCInterfaceDecl *classInterface, 1083 ObjCInterfaceDecl *superDecl) 1084 : NamedDecl(ObjCImplementation, L, Id), 1085 ClassInterface(classInterface), SuperClass(superDecl), 1086 Ivars(0), NumIvars(0) {} 1087public: 1088 static ObjCImplementationDecl *Create(ASTContext &C, 1089 SourceLocation L, IdentifierInfo *Id, 1090 ObjCInterfaceDecl *classInterface, 1091 ObjCInterfaceDecl *superDecl); 1092 1093 1094 void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars, 1095 unsigned numIvars); 1096 1097 void addInstanceMethod(ObjCMethodDecl *method) { 1098 InstanceMethods.push_back(method); 1099 } 1100 void addClassMethod(ObjCMethodDecl *method) { 1101 ClassMethods.push_back(method); 1102 } 1103 1104 void addPropertyImplementation(ObjCPropertyImplDecl *property) { 1105 PropertyImplementations.push_back(property); 1106 } 1107 1108 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; 1109 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 1110 1111 typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator 1112 propimpl_iterator; 1113 propimpl_iterator propimpl_begin() const { 1114 return PropertyImplementations.begin(); 1115 } 1116 propimpl_iterator propimpl_end() const { 1117 return PropertyImplementations.end(); 1118 } 1119 1120 // Location information, modeled after the Stmt API. 1121 SourceLocation getLocStart() const { return getLocation(); } 1122 SourceLocation getLocEnd() const { return EndLoc; } 1123 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 1124 1125 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 1126 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 1127 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 1128 ObjCInterfaceDecl *getSuperClass() { return SuperClass; } 1129 1130 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 1131 1132 unsigned getNumInstanceMethods() const { return InstanceMethods.size(); } 1133 unsigned getNumClassMethods() const { return ClassMethods.size(); } 1134 1135 unsigned getNumPropertyImplementations() const 1136 { return PropertyImplementations.size(); } 1137 1138 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1139 instmeth_iterator; 1140 instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); } 1141 instmeth_iterator instmeth_end() const { return InstanceMethods.end(); } 1142 1143 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1144 classmeth_iterator; 1145 classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); } 1146 classmeth_iterator classmeth_end() const { return ClassMethods.end(); } 1147 1148 // Get the instance method definition for this implementation. 1149 ObjCMethodDecl *getInstanceMethod(Selector Sel) const; 1150 1151 // Get the class method definition for this implementation. 1152 ObjCMethodDecl *getClassMethod(Selector Sel) const; 1153 1154 typedef ObjCIvarDecl * const *ivar_iterator; 1155 ivar_iterator ivar_begin() const { return Ivars; } 1156 ivar_iterator ivar_end() const { return Ivars+NumIvars; } 1157 unsigned ivar_size() const { return NumIvars; } 1158 bool ivar_empty() const { return NumIvars == 0; } 1159 1160 static bool classof(const Decl *D) { 1161 return D->getKind() == ObjCImplementation; 1162 } 1163 static bool classof(const ObjCImplementationDecl *D) { return true; } 1164}; 1165 1166/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 1167/// declared as @compatibility_alias alias class. 1168class ObjCCompatibleAliasDecl : public NamedDecl { 1169 /// Class that this is an alias of. 1170 ObjCInterfaceDecl *AliasedClass; 1171 1172 ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id, 1173 ObjCInterfaceDecl* aliasedClass) 1174 : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {} 1175public: 1176 static ObjCCompatibleAliasDecl *Create(ASTContext &C, 1177 SourceLocation L, IdentifierInfo *Id, 1178 ObjCInterfaceDecl* aliasedClass); 1179 1180 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } 1181 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } 1182 1183 static bool classof(const Decl *D) { 1184 return D->getKind() == ObjCCompatibleAlias; 1185 } 1186 static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } 1187 1188}; 1189 1190/// ObjCPropertyDecl - Represents one property declaration in an interface. 1191/// For example: 1192/// @property (assign, readwrite) int MyProperty; 1193/// 1194class ObjCPropertyDecl : public NamedDecl { 1195public: 1196 enum PropertyAttributeKind { 1197 OBJC_PR_noattr = 0x00, 1198 OBJC_PR_readonly = 0x01, 1199 OBJC_PR_getter = 0x02, 1200 OBJC_PR_assign = 0x04, 1201 OBJC_PR_readwrite = 0x08, 1202 OBJC_PR_retain = 0x10, 1203 OBJC_PR_copy = 0x20, 1204 OBJC_PR_nonatomic = 0x40, 1205 OBJC_PR_setter = 0x80 1206 }; 1207 1208 enum SetterKind { Assign, Retain, Copy }; 1209 enum PropertyControl { None, Required, Optional }; 1210private: 1211 QualType DeclType; 1212 unsigned PropertyAttributes : 8; 1213 1214 // @required/@optional 1215 unsigned PropertyImplementation : 2; 1216 1217 Selector GetterName; // getter name of NULL if no getter 1218 Selector SetterName; // setter name of NULL if no setter 1219 1220 ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method 1221 ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method 1222 1223 ObjCPropertyDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 1224 : NamedDecl(ObjCProperty, L, Id), DeclType(T), 1225 PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None), 1226 GetterName(Selector()), 1227 SetterName(Selector()), 1228 GetterMethodDecl(0), SetterMethodDecl(0) {} 1229public: 1230 static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L, 1231 IdentifierInfo *Id, QualType T, 1232 PropertyControl propControl = None); 1233 QualType getType() const { return DeclType; } 1234 1235 PropertyAttributeKind getPropertyAttributes() const { 1236 return PropertyAttributeKind(PropertyAttributes); 1237 } 1238 void setPropertyAttributes(PropertyAttributeKind PRVal) { 1239 PropertyAttributes |= PRVal; 1240 } 1241 1242 void makeitReadWriteAttribute(void) { 1243 PropertyAttributes &= ~OBJC_PR_readonly; 1244 PropertyAttributes |= OBJC_PR_readwrite; 1245 } 1246 1247 // Helper methods for accessing attributes. 1248 1249 /// isReadOnly - Return true iff the property has a setter. 1250 bool isReadOnly() const { 1251 return (PropertyAttributes & OBJC_PR_readonly); 1252 } 1253 1254 /// getSetterKind - Return the method used for doing assignment in 1255 /// the property setter. This is only valid if the property has been 1256 /// defined to have a setter. 1257 SetterKind getSetterKind() const { 1258 if (PropertyAttributes & OBJC_PR_retain) 1259 return Retain; 1260 if (PropertyAttributes & OBJC_PR_copy) 1261 return Copy; 1262 return Assign; 1263 } 1264 1265 Selector getGetterName() const { return GetterName; } 1266 void setGetterName(Selector Sel) { GetterName = Sel; } 1267 1268 Selector getSetterName() const { return SetterName; } 1269 void setSetterName(Selector Sel) { SetterName = Sel; } 1270 1271 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } 1272 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } 1273 1274 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } 1275 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } 1276 1277 // Related to @optional/@required declared in @protocol 1278 void setPropertyImplementation(PropertyControl pc) { 1279 PropertyImplementation = pc; 1280 } 1281 PropertyControl getPropertyImplementation() const { 1282 return PropertyControl(PropertyImplementation); 1283 } 1284 1285 static bool classof(const Decl *D) { 1286 return D->getKind() == ObjCProperty; 1287 } 1288 static bool classof(const ObjCPropertyDecl *D) { return true; } 1289}; 1290 1291/// ObjCPropertyImplDecl - Represents implementation declaration of a property 1292/// in a class or category implementation block. For example: 1293/// @synthesize prop1 = ivar1; 1294/// 1295class ObjCPropertyImplDecl : public Decl { 1296public: 1297 enum Kind { 1298 Synthesize, 1299 Dynamic 1300 }; 1301private: 1302 SourceLocation AtLoc; // location of @synthesize or @dynamic 1303 /// Property declaration being implemented 1304 ObjCPropertyDecl *PropertyDecl; 1305 1306 /// Null for @dynamic. Required for @synthesize. 1307 ObjCIvarDecl *PropertyIvarDecl; 1308 1309 ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L, 1310 ObjCPropertyDecl *property, 1311 Kind PK, 1312 ObjCIvarDecl *ivarDecl) 1313 : Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(property), 1314 PropertyIvarDecl(ivarDecl) { 1315 assert (PK == Dynamic || PropertyIvarDecl); 1316 } 1317 1318public: 1319 static ObjCPropertyImplDecl *Create(ASTContext &C, SourceLocation atLoc, 1320 SourceLocation L, 1321 ObjCPropertyDecl *property, 1322 Kind PK, 1323 ObjCIvarDecl *ivarDecl); 1324 1325 SourceLocation getLocStart() const { return AtLoc; } 1326 1327 ObjCPropertyDecl *getPropertyDecl() const { 1328 return PropertyDecl; 1329 } 1330 1331 Kind getPropertyImplementation() const { 1332 return PropertyIvarDecl ? Synthesize : Dynamic; 1333 } 1334 1335 ObjCIvarDecl *getPropertyIvarDecl() const { 1336 return PropertyIvarDecl; 1337 } 1338 1339 static bool classof(const Decl *D) { 1340 return D->getKind() == ObjCPropertyImpl; 1341 } 1342 static bool classof(const ObjCPropertyImplDecl *D) { return true; } 1343}; 1344 1345} // end namespace clang 1346#endif 1347