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