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