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