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