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