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