DeclObjC.h revision 6804461f7f154b38130e421b16daf7f2890feb49
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}; 762 763/// ObjCClassDecl - Specifies a list of forward class declarations. For example: 764/// 765/// @class NSCursor, NSImage, NSPasteboard, NSWindow; 766/// 767class ObjCClassDecl : public Decl { 768 ObjCInterfaceDecl **ForwardDecls; 769 unsigned NumForwardDecls; 770 771 ObjCClassDecl(SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts) 772 : Decl(ObjCClass, L) { 773 if (nElts) { 774 ForwardDecls = new ObjCInterfaceDecl*[nElts]; 775 memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*)); 776 } else { 777 ForwardDecls = 0; 778 } 779 NumForwardDecls = nElts; 780 } 781 782 virtual ~ObjCClassDecl(); 783 784public: 785 786 /// Destroy - Call destructors and release memory. 787 virtual void Destroy(ASTContext& C); 788 789 static ObjCClassDecl *Create(ASTContext &C, SourceLocation L, 790 ObjCInterfaceDecl **Elts, unsigned nElts); 791 792 void setInterfaceDecl(unsigned idx, ObjCInterfaceDecl *OID) { 793 assert(idx < NumForwardDecls && "index out of range"); 794 ForwardDecls[idx] = OID; 795 } 796 ObjCInterfaceDecl** getForwardDecls() const { return ForwardDecls; } 797 int getNumForwardDecls() const { return NumForwardDecls; } 798 799 typedef ObjCInterfaceDecl * const * iterator; 800 iterator begin() const { return ForwardDecls; } 801 iterator end() const { return ForwardDecls+NumForwardDecls; } 802 803 static bool classof(const Decl *D) { return D->getKind() == ObjCClass; } 804 static bool classof(const ObjCClassDecl *D) { return true; } 805}; 806 807/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations. 808/// For example: 809/// 810/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; 811/// 812class ObjCForwardProtocolDecl : public Decl { 813 ObjCProtocolDecl **ReferencedProtocols; 814 unsigned NumReferencedProtocols; 815 816 ObjCForwardProtocolDecl(SourceLocation L, 817 ObjCProtocolDecl **Elts, unsigned nElts) 818 : Decl(ObjCForwardProtocol, L) { 819 NumReferencedProtocols = nElts; 820 if (nElts) { 821 ReferencedProtocols = new ObjCProtocolDecl*[nElts]; 822 memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*)); 823 } else { 824 ReferencedProtocols = 0; 825 } 826 } 827 828 virtual ~ObjCForwardProtocolDecl(); 829 830public: 831 static ObjCForwardProtocolDecl *Create(ASTContext &C, SourceLocation L, 832 ObjCProtocolDecl **Elts, unsigned Num); 833 834 835 void setForwardProtocolDecl(unsigned idx, ObjCProtocolDecl *OID) { 836 assert(idx < NumReferencedProtocols && "index out of range"); 837 ReferencedProtocols[idx] = OID; 838 } 839 840 unsigned getNumForwardDecls() const { return NumReferencedProtocols; } 841 842 ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) { 843 assert(idx < NumReferencedProtocols && "index out of range"); 844 return ReferencedProtocols[idx]; 845 } 846 const ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) const { 847 assert(idx < NumReferencedProtocols && "index out of range"); 848 return ReferencedProtocols[idx]; 849 } 850 851 typedef ObjCProtocolDecl * const * iterator; 852 iterator begin() const { return ReferencedProtocols; } 853 iterator end() const { return ReferencedProtocols+NumReferencedProtocols; } 854 855 static bool classof(const Decl *D) { 856 return D->getKind() == ObjCForwardProtocol; 857 } 858 static bool classof(const ObjCForwardProtocolDecl *D) { return true; } 859}; 860 861/// ObjCCategoryDecl - Represents a category declaration. A category allows 862/// you to add methods to an existing class (without subclassing or modifying 863/// the original class interface or implementation:-). Categories don't allow 864/// you to add instance data. The following example adds "myMethod" to all 865/// NSView's within a process: 866/// 867/// @interface NSView (MyViewMethods) 868/// - myMethod; 869/// @end 870/// 871/// Cateogries also allow you to split the implementation of a class across 872/// several files (a feature more naturally supported in C++). 873/// 874/// Categories were originally inspired by dynamic languages such as Common 875/// Lisp and Smalltalk. More traditional class-based languages (C++, Java) 876/// don't support this level of dynamism, which is both powerful and dangerous. 877/// 878class ObjCCategoryDecl : public ObjCContainerDecl { 879 /// Interface belonging to this category 880 ObjCInterfaceDecl *ClassInterface; 881 882 /// referenced protocols in this category. 883 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 884 885 /// Next category belonging to this class 886 ObjCCategoryDecl *NextClassCategory; 887 888 /// category properties 889 ObjCPropertyDecl **PropertyDecl; // Null if no property 890 unsigned NumPropertyDecl; // 0 if none 891 892 SourceLocation EndLoc; // marks the '>' or identifier. 893 894 ObjCCategoryDecl(SourceLocation L, IdentifierInfo *Id) 895 : ObjCContainerDecl(ObjCCategory, L, Id), 896 ClassInterface(0), 897 NextClassCategory(0), PropertyDecl(0), NumPropertyDecl(0) { 898 } 899public: 900 901 static ObjCCategoryDecl *Create(ASTContext &C, 902 SourceLocation L, IdentifierInfo *Id); 903 904 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 905 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 906 void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; } 907 908 /// addReferencedProtocols - Set the list of protocols that this interface 909 /// implements. 910 void addReferencedProtocols(ObjCProtocolDecl *const*List, unsigned NumRPs) { 911 ReferencedProtocols.set(List, NumRPs); 912 } 913 914 const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { 915 return ReferencedProtocols; 916 } 917 918 typedef ObjCProtocolDecl * const * protocol_iterator; 919 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 920 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 921 922 unsigned getNumPropertyDecl() const { return NumPropertyDecl; } 923 924 ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; } 925 926 void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); 927 928 void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); 929 930 ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; 931 932 typedef ObjCPropertyDecl * const * classprop_iterator; 933 classprop_iterator classprop_begin() const { return PropertyDecl; } 934 classprop_iterator classprop_end() const { 935 return PropertyDecl+NumPropertyDecl; 936 } 937 938 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 939 void insertNextClassCategory() { 940 NextClassCategory = ClassInterface->getCategoryList(); 941 ClassInterface->setCategoryList(this); 942 } 943 // Location information, modeled after the Stmt API. 944 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 945 SourceLocation getLocEnd() const { return EndLoc; } 946 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 947 948 static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; } 949 static bool classof(const ObjCCategoryDecl *D) { return true; } 950}; 951 952/// ObjCCategoryImplDecl - An object of this class encapsulates a category 953/// @implementation declaration. If a category class has declaration of a 954/// property, its implementation must be specified in the category's 955/// @implementation declaration. Example: 956/// @interface I @end 957/// @interface I(CATEGORY) 958/// @property int p1, d1; 959/// @end 960/// @implementation I(CATEGORY) 961/// @dynamic p1,d1; 962/// @end 963/// 964class ObjCCategoryImplDecl : public NamedDecl, public DeclContext { 965 /// Class interface for this category implementation 966 ObjCInterfaceDecl *ClassInterface; 967 968 /// implemented instance methods 969 llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods; 970 971 /// implemented class methods 972 llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods; 973 974 /// Property Implementations in this category 975 llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations; 976 977 SourceLocation EndLoc; 978 979 ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id, 980 ObjCInterfaceDecl *classInterface) 981 : NamedDecl(ObjCCategoryImpl, L, Id), DeclContext(ObjCCategoryImpl), 982 ClassInterface(classInterface) {} 983public: 984 static ObjCCategoryImplDecl *Create(ASTContext &C, 985 SourceLocation L, IdentifierInfo *Id, 986 ObjCInterfaceDecl *classInterface); 987 988 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 989 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 990 991 unsigned getNumInstanceMethods() const { return InstanceMethods.size(); } 992 unsigned getNumClassMethods() const { return ClassMethods.size(); } 993 994 void addInstanceMethod(ObjCMethodDecl *method) { 995 InstanceMethods.push_back(method); 996 } 997 void addClassMethod(ObjCMethodDecl *method) { 998 ClassMethods.push_back(method); 999 } 1000 // Get the instance method definition for this implementation. 1001 ObjCMethodDecl *getInstanceMethod(Selector Sel) const; 1002 1003 // Get the class method definition for this implementation. 1004 ObjCMethodDecl *getClassMethod(Selector Sel) const; 1005 1006 void addPropertyImplementation(ObjCPropertyImplDecl *property) { 1007 PropertyImplementations.push_back(property); 1008 } 1009 1010 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; 1011 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 1012 1013 unsigned getNumPropertyImplementations() const 1014 { return PropertyImplementations.size(); } 1015 1016 1017 typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator 1018 propimpl_iterator; 1019 propimpl_iterator propimpl_begin() const { 1020 return PropertyImplementations.begin(); 1021 } 1022 propimpl_iterator propimpl_end() const { 1023 return PropertyImplementations.end(); 1024 } 1025 1026 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1027 instmeth_iterator; 1028 instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); } 1029 instmeth_iterator instmeth_end() const { return InstanceMethods.end(); } 1030 1031 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1032 classmeth_iterator; 1033 classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); } 1034 classmeth_iterator classmeth_end() const { return ClassMethods.end(); } 1035 1036 1037 // Location information, modeled after the Stmt API. 1038 SourceLocation getLocStart() const { return getLocation(); } 1039 SourceLocation getLocEnd() const { return EndLoc; } 1040 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 1041 1042 static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;} 1043 static bool classof(const ObjCCategoryImplDecl *D) { return true; } 1044}; 1045 1046/// ObjCImplementationDecl - Represents a class definition - this is where 1047/// method definitions are specified. For example: 1048/// 1049/// @implementation MyClass 1050/// - (void)myMethod { /* do something */ } 1051/// @end 1052/// 1053/// Typically, instance variables are specified in the class interface, 1054/// *not* in the implemenentation. Nevertheless (for legacy reasons), we 1055/// allow instance variables to be specified in the implementation. When 1056/// specified, they need to be *identical* to the interface. Now that we 1057/// have support for non-fragile ivars in ObjC 2.0, we can consider removing 1058/// the legacy semantics and allow developers to move private ivar declarations 1059/// from the class interface to the class implementation (but I digress:-) 1060/// 1061class ObjCImplementationDecl : public NamedDecl, public DeclContext { 1062 /// Class interface for this implementation 1063 ObjCInterfaceDecl *ClassInterface; 1064 1065 /// Implementation Class's super class. 1066 ObjCInterfaceDecl *SuperClass; 1067 1068 /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls. 1069 ObjCIvarDecl **Ivars; // Null if not specified 1070 unsigned NumIvars; // 0 if none. 1071 1072 /// implemented instance methods 1073 llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods; 1074 1075 /// implemented class methods 1076 llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods; 1077 1078 /// Propertys' being implemented 1079 llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations; 1080 1081 SourceLocation EndLoc; 1082 1083 ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id, 1084 ObjCInterfaceDecl *classInterface, 1085 ObjCInterfaceDecl *superDecl) 1086 : NamedDecl(ObjCImplementation, L, Id), DeclContext(ObjCImplementation), 1087 ClassInterface(classInterface), SuperClass(superDecl), 1088 Ivars(0), NumIvars(0) {} 1089public: 1090 static ObjCImplementationDecl *Create(ASTContext &C, 1091 SourceLocation L, IdentifierInfo *Id, 1092 ObjCInterfaceDecl *classInterface, 1093 ObjCInterfaceDecl *superDecl); 1094 1095 1096 void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars, 1097 unsigned numIvars); 1098 1099 void addInstanceMethod(ObjCMethodDecl *method) { 1100 InstanceMethods.push_back(method); 1101 } 1102 void addClassMethod(ObjCMethodDecl *method) { 1103 ClassMethods.push_back(method); 1104 } 1105 1106 void addPropertyImplementation(ObjCPropertyImplDecl *property) { 1107 PropertyImplementations.push_back(property); 1108 } 1109 1110 ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; 1111 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 1112 1113 typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator 1114 propimpl_iterator; 1115 propimpl_iterator propimpl_begin() const { 1116 return PropertyImplementations.begin(); 1117 } 1118 propimpl_iterator propimpl_end() const { 1119 return PropertyImplementations.end(); 1120 } 1121 1122 // Location information, modeled after the Stmt API. 1123 SourceLocation getLocStart() const { return getLocation(); } 1124 SourceLocation getLocEnd() const { return EndLoc; } 1125 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 1126 1127 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 1128 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 1129 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 1130 ObjCInterfaceDecl *getSuperClass() { return SuperClass; } 1131 1132 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 1133 1134 unsigned getNumInstanceMethods() const { return InstanceMethods.size(); } 1135 unsigned getNumClassMethods() const { return ClassMethods.size(); } 1136 1137 unsigned getNumPropertyImplementations() const 1138 { return PropertyImplementations.size(); } 1139 1140 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1141 instmeth_iterator; 1142 instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); } 1143 instmeth_iterator instmeth_end() const { return InstanceMethods.end(); } 1144 1145 typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator 1146 classmeth_iterator; 1147 classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); } 1148 classmeth_iterator classmeth_end() const { return ClassMethods.end(); } 1149 1150 // Get the instance method definition for this implementation. 1151 ObjCMethodDecl *getInstanceMethod(Selector Sel) const; 1152 1153 // Get the class method definition for this implementation. 1154 ObjCMethodDecl *getClassMethod(Selector Sel) const; 1155 1156 typedef ObjCIvarDecl * const *ivar_iterator; 1157 ivar_iterator ivar_begin() const { return Ivars; } 1158 ivar_iterator ivar_end() const { return Ivars+NumIvars; } 1159 unsigned ivar_size() const { return NumIvars; } 1160 bool ivar_empty() const { return NumIvars == 0; } 1161 1162 static bool classof(const Decl *D) { 1163 return D->getKind() == ObjCImplementation; 1164 } 1165 static bool classof(const ObjCImplementationDecl *D) { return true; } 1166}; 1167 1168/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 1169/// declared as @compatibility_alias alias class. 1170class ObjCCompatibleAliasDecl : public NamedDecl { 1171 /// Class that this is an alias of. 1172 ObjCInterfaceDecl *AliasedClass; 1173 1174 ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id, 1175 ObjCInterfaceDecl* aliasedClass) 1176 : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {} 1177public: 1178 static ObjCCompatibleAliasDecl *Create(ASTContext &C, 1179 SourceLocation L, IdentifierInfo *Id, 1180 ObjCInterfaceDecl* aliasedClass); 1181 1182 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } 1183 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } 1184 1185 static bool classof(const Decl *D) { 1186 return D->getKind() == ObjCCompatibleAlias; 1187 } 1188 static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } 1189 1190}; 1191 1192/// ObjCPropertyDecl - Represents one property declaration in an interface. 1193/// For example: 1194/// @property (assign, readwrite) int MyProperty; 1195/// 1196class ObjCPropertyDecl : public NamedDecl { 1197public: 1198 enum PropertyAttributeKind { 1199 OBJC_PR_noattr = 0x00, 1200 OBJC_PR_readonly = 0x01, 1201 OBJC_PR_getter = 0x02, 1202 OBJC_PR_assign = 0x04, 1203 OBJC_PR_readwrite = 0x08, 1204 OBJC_PR_retain = 0x10, 1205 OBJC_PR_copy = 0x20, 1206 OBJC_PR_nonatomic = 0x40, 1207 OBJC_PR_setter = 0x80 1208 }; 1209 1210 enum SetterKind { Assign, Retain, Copy }; 1211 enum PropertyControl { None, Required, Optional }; 1212private: 1213 QualType DeclType; 1214 unsigned PropertyAttributes : 8; 1215 1216 // @required/@optional 1217 unsigned PropertyImplementation : 2; 1218 1219 Selector GetterName; // getter name of NULL if no getter 1220 Selector SetterName; // setter name of NULL if no setter 1221 1222 ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method 1223 ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method 1224 1225 ObjCPropertyDecl(SourceLocation L, IdentifierInfo *Id, QualType T) 1226 : NamedDecl(ObjCProperty, L, Id), DeclType(T), 1227 PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None), 1228 GetterName(Selector()), 1229 SetterName(Selector()), 1230 GetterMethodDecl(0), SetterMethodDecl(0) {} 1231public: 1232 static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L, 1233 IdentifierInfo *Id, QualType T, 1234 PropertyControl propControl = None); 1235 QualType getType() const { return DeclType; } 1236 1237 PropertyAttributeKind getPropertyAttributes() const { 1238 return PropertyAttributeKind(PropertyAttributes); 1239 } 1240 void setPropertyAttributes(PropertyAttributeKind PRVal) { 1241 PropertyAttributes |= PRVal; 1242 } 1243 1244 void makeitReadWriteAttribute(void) { 1245 PropertyAttributes &= ~OBJC_PR_readonly; 1246 PropertyAttributes |= OBJC_PR_readwrite; 1247 } 1248 1249 // Helper methods for accessing attributes. 1250 1251 /// isReadOnly - Return true iff the property has a setter. 1252 bool isReadOnly() const { 1253 return (PropertyAttributes & OBJC_PR_readonly); 1254 } 1255 1256 /// getSetterKind - Return the method used for doing assignment in 1257 /// the property setter. This is only valid if the property has been 1258 /// defined to have a setter. 1259 SetterKind getSetterKind() const { 1260 if (PropertyAttributes & OBJC_PR_retain) 1261 return Retain; 1262 if (PropertyAttributes & OBJC_PR_copy) 1263 return Copy; 1264 return Assign; 1265 } 1266 1267 Selector getGetterName() const { return GetterName; } 1268 void setGetterName(Selector Sel) { GetterName = Sel; } 1269 1270 Selector getSetterName() const { return SetterName; } 1271 void setSetterName(Selector Sel) { SetterName = Sel; } 1272 1273 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } 1274 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } 1275 1276 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } 1277 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } 1278 1279 // Related to @optional/@required declared in @protocol 1280 void setPropertyImplementation(PropertyControl pc) { 1281 PropertyImplementation = pc; 1282 } 1283 PropertyControl getPropertyImplementation() const { 1284 return PropertyControl(PropertyImplementation); 1285 } 1286 1287 static bool classof(const Decl *D) { 1288 return D->getKind() == ObjCProperty; 1289 } 1290 static bool classof(const ObjCPropertyDecl *D) { return true; } 1291}; 1292 1293/// ObjCPropertyImplDecl - Represents implementation declaration of a property 1294/// in a class or category implementation block. For example: 1295/// @synthesize prop1 = ivar1; 1296/// 1297class ObjCPropertyImplDecl : public Decl { 1298public: 1299 enum Kind { 1300 Synthesize, 1301 Dynamic 1302 }; 1303private: 1304 SourceLocation AtLoc; // location of @synthesize or @dynamic 1305 /// Property declaration being implemented 1306 ObjCPropertyDecl *PropertyDecl; 1307 1308 /// Null for @dynamic. Required for @synthesize. 1309 ObjCIvarDecl *PropertyIvarDecl; 1310 1311 ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L, 1312 ObjCPropertyDecl *property, 1313 Kind PK, 1314 ObjCIvarDecl *ivarDecl) 1315 : Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(property), 1316 PropertyIvarDecl(ivarDecl) { 1317 assert (PK == Dynamic || PropertyIvarDecl); 1318 } 1319 1320public: 1321 static ObjCPropertyImplDecl *Create(ASTContext &C, SourceLocation atLoc, 1322 SourceLocation L, 1323 ObjCPropertyDecl *property, 1324 Kind PK, 1325 ObjCIvarDecl *ivarDecl); 1326 1327 SourceLocation getLocStart() const { return AtLoc; } 1328 1329 ObjCPropertyDecl *getPropertyDecl() const { 1330 return PropertyDecl; 1331 } 1332 1333 Kind getPropertyImplementation() const { 1334 return PropertyIvarDecl ? Synthesize : Dynamic; 1335 } 1336 1337 ObjCIvarDecl *getPropertyIvarDecl() const { 1338 return PropertyIvarDecl; 1339 } 1340 1341 static bool classof(const Decl *D) { 1342 return D->getKind() == ObjCPropertyImpl; 1343 } 1344 static bool classof(const ObjCPropertyImplDecl *D) { return true; } 1345}; 1346 1347} // end namespace clang 1348#endif 1349