DeclObjC.h revision 8f36aba016c2d236a90f9ecf0a66904209202202
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 CompoundStmt *getBody(ASTContext &C) const { 246 return (CompoundStmt*) Body; 247 } 248 CompoundStmt *getBody() { return (CompoundStmt*)Body; } 249 void setBody(CompoundStmt *B) { Body = (Stmt*) 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/// ObjCContainerDecl - Represents a container for method declarations. 263/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, and 264/// ObjCProtocolDecl. 265/// FIXME: Use for ObjC implementation decls. 266/// 267class ObjCContainerDecl : public NamedDecl, public DeclContext { 268 SourceLocation AtEndLoc; // marks the end of the method container. 269public: 270 271 ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L, 272 IdentifierInfo *Id) 273 : NamedDecl(DK, DC, L, Id), DeclContext(DK) {} 274 275 virtual ~ObjCContainerDecl() {} 276 277 // Iterator access to properties. 278 typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator; 279 prop_iterator prop_begin(ASTContext &Context) const { 280 return prop_iterator(decls_begin(Context)); 281 } 282 prop_iterator prop_end(ASTContext &Context) const { 283 return prop_iterator(decls_end(Context)); 284 } 285 286 // Iterator access to instance/class methods. 287 typedef specific_decl_iterator<ObjCMethodDecl> method_iterator; 288 method_iterator meth_begin(ASTContext &Context) const { 289 return method_iterator(decls_begin(Context)); 290 } 291 method_iterator meth_end(ASTContext &Context) const { 292 return method_iterator(decls_end(Context)); 293 } 294 295 typedef filtered_decl_iterator<ObjCMethodDecl, 296 &ObjCMethodDecl::isInstanceMethod> 297 instmeth_iterator; 298 instmeth_iterator instmeth_begin(ASTContext &Context) const { 299 return instmeth_iterator(decls_begin(Context)); 300 } 301 instmeth_iterator instmeth_end(ASTContext &Context) const { 302 return instmeth_iterator(decls_end(Context)); 303 } 304 305 typedef filtered_decl_iterator<ObjCMethodDecl, 306 &ObjCMethodDecl::isClassMethod> 307 classmeth_iterator; 308 classmeth_iterator classmeth_begin(ASTContext &Context) const { 309 return classmeth_iterator(decls_begin(Context)); 310 } 311 classmeth_iterator classmeth_end(ASTContext &Context) const { 312 return classmeth_iterator(decls_end(Context)); 313 } 314 315 // Get the local instance/class method declared in this interface. 316 ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const; 317 ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const; 318 319 ObjCMethodDecl * 320 getMethod(ASTContext &Context, Selector Sel, bool isInstance) const { 321 return isInstance ? getInstanceMethod(Context, Sel) 322 : getClassMethod(Context, Sel); 323 } 324 325 ObjCPropertyDecl *FindPropertyDeclaration(ASTContext &Context, 326 IdentifierInfo *PropertyId) const; 327 328 // Marks the end of the container. 329 SourceLocation getAtEndLoc() const { return AtEndLoc; } 330 void setAtEndLoc(SourceLocation L) { AtEndLoc = L; } 331 332 // Implement isa/cast/dyncast/etc. 333 static bool classof(const Decl *D) { 334 return D->getKind() >= ObjCContainerFirst && 335 D->getKind() <= ObjCContainerLast; 336 } 337 static bool classof(const ObjCContainerDecl *D) { return true; } 338 339 static DeclContext *castToDeclContext(const ObjCContainerDecl *D) { 340 return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D)); 341 } 342 static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) { 343 return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC)); 344 } 345}; 346 347/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example: 348/// 349/// // MostPrimitive declares no super class (not particularly useful). 350/// @interface MostPrimitive 351/// // no instance variables or methods. 352/// @end 353/// 354/// // NSResponder inherits from NSObject & implements NSCoding (a protocol). 355/// @interface NSResponder : NSObject <NSCoding> 356/// { // instance variables are represented by ObjCIvarDecl. 357/// id nextResponder; // nextResponder instance variable. 358/// } 359/// - (NSResponder *)nextResponder; // return a pointer to NSResponder. 360/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer 361/// @end // to an NSEvent. 362/// 363/// Unlike C/C++, forward class declarations are accomplished with @class. 364/// Unlike C/C++, @class allows for a list of classes to be forward declared. 365/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes 366/// typically inherit from NSObject (an exception is NSProxy). 367/// 368class ObjCInterfaceDecl : public ObjCContainerDecl { 369 /// TypeForDecl - This indicates the Type object that represents this 370 /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType 371 mutable Type *TypeForDecl; 372 friend class ASTContext; 373 374 /// Class's super class. 375 ObjCInterfaceDecl *SuperClass; 376 377 /// Protocols referenced in interface header declaration 378 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 379 380 /// Instance variables in the interface. 381 ObjCList<ObjCIvarDecl> IVars; 382 383 /// List of categories defined for this class. 384 /// FIXME: Why is this a linked list?? 385 ObjCCategoryDecl *CategoryList; 386 387 bool ForwardDecl:1; // declared with @class. 388 bool InternalInterface:1; // true - no @interface for @implementation 389 390 SourceLocation ClassLoc; // location of the class identifier. 391 SourceLocation SuperClassLoc; // location of the super class identifier. 392 SourceLocation EndLoc; // marks the '>', '}', or identifier. 393 394 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, 395 SourceLocation CLoc, bool FD, bool isInternal); 396 397 virtual ~ObjCInterfaceDecl() {} 398 399public: 400 401 /// Destroy - Call destructors and release memory. 402 virtual void Destroy(ASTContext& C); 403 404 static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC, 405 SourceLocation atLoc, 406 IdentifierInfo *Id, 407 SourceLocation ClassLoc = SourceLocation(), 408 bool ForwardDecl = false, 409 bool isInternal = false); 410 const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { 411 return ReferencedProtocols; 412 } 413 414 ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; 415 416 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 417 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 418 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 419 420 typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator; 421 ivar_iterator ivar_begin() const { return IVars.begin(); } 422 ivar_iterator ivar_end() const { return IVars.end(); } 423 unsigned ivar_size() const { return IVars.size(); } 424 bool ivar_empty() const { return IVars.empty(); } 425 426 /// setProtocolList - Set the list of protocols that this interface 427 /// implements. 428 void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, 429 ASTContext &C) { 430 ReferencedProtocols.set(List, Num, C); 431 } 432 433 void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) { 434 IVars.set(List, Num, C); 435 } 436 437 bool isForwardDecl() const { return ForwardDecl; } 438 void setForwardDecl(bool val) { ForwardDecl = val; } 439 440 ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 441 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 442 443 ObjCCategoryDecl* getCategoryList() const { return CategoryList; } 444 void setCategoryList(ObjCCategoryDecl *category) { 445 CategoryList = category; 446 } 447 448 /// isSuperClassOf - Return true if this class is the specified class or is a 449 /// super class of the specified interface class. 450 bool isSuperClassOf(const ObjCInterfaceDecl *I) const { 451 // If RHS is derived from LHS it is OK; else it is not OK. 452 while (I != NULL) { 453 if (this == I) 454 return true; 455 I = I->getSuperClass(); 456 } 457 return false; 458 } 459 460 ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context, 461 IdentifierInfo *IVarName, 462 ObjCInterfaceDecl *&ClassDeclared); 463 ObjCIvarDecl *lookupInstanceVariable(ASTContext &Context, 464 IdentifierInfo *IVarName) { 465 ObjCInterfaceDecl *ClassDeclared; 466 return lookupInstanceVariable(Context, IVarName, ClassDeclared); 467 } 468 469 // Lookup a method. First, we search locally. If a method isn't 470 // found, we search referenced protocols and class categories. 471 ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel); 472 ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel); 473 474 // Location information, modeled after the Stmt API. 475 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 476 SourceLocation getLocEnd() const { return EndLoc; } 477 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 478 479 void setClassLoc(SourceLocation Loc) { ClassLoc = Loc; } 480 SourceLocation getClassLoc() const { return ClassLoc; } 481 void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; } 482 SourceLocation getSuperClassLoc() const { return SuperClassLoc; } 483 484 /// isImplicitInterfaceDecl - check that this is an implicitly declared 485 /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation 486 /// declaration without an @interface declaration. 487 bool isImplicitInterfaceDecl() const { return InternalInterface; } 488 void setImplicitInterfaceDecl(bool val) { InternalInterface = val; } 489 490 // Low-level accessor 491 Type *getTypeForDecl() const { return TypeForDecl; } 492 void setTypeForDecl(Type *TD) const { TypeForDecl = TD; } 493 494 static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; } 495 static bool classof(const ObjCInterfaceDecl *D) { return true; } 496}; 497 498/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC 499/// instance variables are identical to C. The only exception is Objective-C 500/// supports C++ style access control. For example: 501/// 502/// @interface IvarExample : NSObject 503/// { 504/// id defaultToProtected; 505/// @public: 506/// id canBePublic; // same as C++. 507/// @protected: 508/// id canBeProtected; // same as C++. 509/// @package: 510/// id canBePackage; // framework visibility (not available in C++). 511/// } 512/// 513class ObjCIvarDecl : public FieldDecl { 514public: 515 enum AccessControl { 516 None, Private, Protected, Public, Package 517 }; 518 519private: 520 ObjCIvarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 521 QualType T, AccessControl ac, Expr *BW) 522 : FieldDecl(ObjCIvar, DC, L, Id, T, BW, /*Mutable=*/false), 523 DeclAccess(ac) {} 524 525public: 526 static ObjCIvarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, 527 IdentifierInfo *Id, QualType T, 528 AccessControl ac, Expr *BW = NULL); 529 530 void setAccessControl(AccessControl ac) { DeclAccess = ac; } 531 532 AccessControl getAccessControl() const { return AccessControl(DeclAccess); } 533 534 AccessControl getCanonicalAccessControl() const { 535 return DeclAccess == None ? Protected : AccessControl(DeclAccess); 536 } 537 538 // Implement isa/cast/dyncast/etc. 539 static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; } 540 static bool classof(const ObjCIvarDecl *D) { return true; } 541private: 542 // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum 543 unsigned DeclAccess : 3; 544}; 545 546 547/// ObjCAtDefsFieldDecl - Represents a field declaration created by an 548/// @defs(...). 549class ObjCAtDefsFieldDecl : public FieldDecl { 550private: 551 ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 552 QualType T, Expr *BW) 553 : FieldDecl(ObjCAtDefsField, DC, L, Id, T, BW, /*Mutable=*/false) {} 554 555public: 556 static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, 557 SourceLocation L, 558 IdentifierInfo *Id, QualType T, 559 Expr *BW); 560 561 virtual void Destroy(ASTContext& C); 562 563 // Implement isa/cast/dyncast/etc. 564 static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; } 565 static bool classof(const ObjCAtDefsFieldDecl *D) { return true; } 566}; 567 568/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols 569/// declare a pure abstract type (i.e no instance variables are permitted). 570/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++ 571/// feature with nice semantics and lousy syntax:-). Here is an example: 572/// 573/// @protocol NSDraggingInfo <refproto1, refproto2> 574/// - (NSWindow *)draggingDestinationWindow; 575/// - (NSImage *)draggedImage; 576/// @end 577/// 578/// This says that NSDraggingInfo requires two methods and requires everything 579/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as 580/// well. 581/// 582/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo> 583/// @end 584/// 585/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and 586/// protocols are in distinct namespaces. For example, Cocoa defines both 587/// an NSObject protocol and class (which isn't allowed in Java). As a result, 588/// protocols are referenced using angle brackets as follows: 589/// 590/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; 591/// 592class ObjCProtocolDecl : public ObjCContainerDecl { 593 /// Referenced protocols 594 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 595 596 bool isForwardProtoDecl; // declared with @protocol. 597 598 SourceLocation EndLoc; // marks the '>' or identifier. 599 600 ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) 601 : ObjCContainerDecl(ObjCProtocol, DC, L, Id), 602 isForwardProtoDecl(true) { 603 } 604 605 virtual ~ObjCProtocolDecl() {} 606 607public: 608 static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, 609 SourceLocation L, IdentifierInfo *Id); 610 611 /// Destroy - Call destructors and release memory. 612 virtual void Destroy(ASTContext& C); 613 614 const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { 615 return ReferencedProtocols; 616 } 617 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 618 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 619 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 620 unsigned protocol_size() const { return ReferencedProtocols.size(); } 621 622 /// setProtocolList - Set the list of protocols that this interface 623 /// implements. 624 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 625 ASTContext &C) { 626 ReferencedProtocols.set(List, Num, C); 627 } 628 629 ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); 630 631 // Lookup a method. First, we search locally. If a method isn't 632 // found, we search referenced protocols and class categories. 633 ObjCMethodDecl *lookupInstanceMethod(ASTContext &Context, Selector Sel); 634 ObjCMethodDecl *lookupClassMethod(ASTContext &Context, Selector Sel); 635 636 bool isForwardDecl() const { return isForwardProtoDecl; } 637 void setForwardDecl(bool val) { isForwardProtoDecl = val; } 638 639 // Location information, modeled after the Stmt API. 640 SourceLocation getLocStart() const { return getLocation(); } // '@'protocol 641 SourceLocation getLocEnd() const { return EndLoc; } 642 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 643 644 static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; } 645 static bool classof(const ObjCProtocolDecl *D) { return true; } 646}; 647 648/// ObjCClassDecl - Specifies a list of forward class declarations. For example: 649/// 650/// @class NSCursor, NSImage, NSPasteboard, NSWindow; 651/// 652class ObjCClassDecl : public Decl { 653 ObjCList<ObjCInterfaceDecl> ForwardDecls; 654 655 ObjCClassDecl(DeclContext *DC, SourceLocation L, 656 ObjCInterfaceDecl *const *Elts, unsigned nElts, ASTContext &C); 657 virtual ~ObjCClassDecl() {} 658public: 659 660 /// Destroy - Call destructors and release memory. 661 virtual void Destroy(ASTContext& C); 662 663 static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, 664 ObjCInterfaceDecl *const *Elts = 0, 665 unsigned nElts = 0); 666 667 typedef ObjCList<ObjCInterfaceDecl>::iterator iterator; 668 iterator begin() const { return ForwardDecls.begin(); } 669 iterator end() const { return ForwardDecls.end(); } 670 unsigned size() const { return ForwardDecls.size(); } 671 672 /// setClassList - Set the list of forward classes. 673 void setClassList(ASTContext &C, ObjCInterfaceDecl*const*List, unsigned Num) { 674 ForwardDecls.set(List, Num, C); 675 } 676 677 static bool classof(const Decl *D) { return D->getKind() == ObjCClass; } 678 static bool classof(const ObjCClassDecl *D) { return true; } 679}; 680 681/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations. 682/// For example: 683/// 684/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo; 685/// 686class ObjCForwardProtocolDecl : public Decl { 687 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 688 689 ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L, 690 ObjCProtocolDecl *const *Elts, unsigned nElts, 691 ASTContext &C); 692 virtual ~ObjCForwardProtocolDecl() {} 693 694public: 695 static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC, 696 SourceLocation L, 697 ObjCProtocolDecl *const *Elts = 0, 698 unsigned Num = 0); 699 700 /// Destroy - Call destructors and release memory. 701 virtual void Destroy(ASTContext& C); 702 703 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 704 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 705 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 706 unsigned protocol_size() const { return ReferencedProtocols.size(); } 707 708 /// setProtocolList - Set the list of forward protocols. 709 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 710 ASTContext &C) { 711 ReferencedProtocols.set(List, Num, C); 712 } 713 static bool classof(const Decl *D) { 714 return D->getKind() == ObjCForwardProtocol; 715 } 716 static bool classof(const ObjCForwardProtocolDecl *D) { return true; } 717}; 718 719/// ObjCCategoryDecl - Represents a category declaration. A category allows 720/// you to add methods to an existing class (without subclassing or modifying 721/// the original class interface or implementation:-). Categories don't allow 722/// you to add instance data. The following example adds "myMethod" to all 723/// NSView's within a process: 724/// 725/// @interface NSView (MyViewMethods) 726/// - myMethod; 727/// @end 728/// 729/// Cateogries also allow you to split the implementation of a class across 730/// several files (a feature more naturally supported in C++). 731/// 732/// Categories were originally inspired by dynamic languages such as Common 733/// Lisp and Smalltalk. More traditional class-based languages (C++, Java) 734/// don't support this level of dynamism, which is both powerful and dangerous. 735/// 736class ObjCCategoryDecl : public ObjCContainerDecl { 737 /// Interface belonging to this category 738 ObjCInterfaceDecl *ClassInterface; 739 740 /// referenced protocols in this category. 741 ObjCList<ObjCProtocolDecl> ReferencedProtocols; 742 743 /// Next category belonging to this class. 744 /// FIXME: this should not be a singly-linked list. Move storage elsewhere. 745 ObjCCategoryDecl *NextClassCategory; 746 747 SourceLocation EndLoc; // marks the '>' or identifier. 748 749 ObjCCategoryDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id) 750 : ObjCContainerDecl(ObjCCategory, DC, L, Id), 751 ClassInterface(0), NextClassCategory(0){ 752 } 753public: 754 755 static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, 756 SourceLocation L, IdentifierInfo *Id); 757 758 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 759 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 760 void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; } 761 762 /// setProtocolList - Set the list of protocols that this interface 763 /// implements. 764 void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 765 ASTContext &C) { 766 ReferencedProtocols.set(List, Num, C); 767 } 768 769 const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const { 770 return ReferencedProtocols; 771 } 772 773 typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator; 774 protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 775 protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 776 unsigned protocol_size() const { return ReferencedProtocols.size(); } 777 778 ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 779 void setNextClassCategory(ObjCCategoryDecl *Cat) { 780 NextClassCategory = Cat; 781 } 782 void insertNextClassCategory() { 783 NextClassCategory = ClassInterface->getCategoryList(); 784 ClassInterface->setCategoryList(this); 785 } 786 // Location information, modeled after the Stmt API. 787 SourceLocation getLocStart() const { return getLocation(); } // '@'interface 788 SourceLocation getLocEnd() const { return EndLoc; } 789 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 790 791 static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; } 792 static bool classof(const ObjCCategoryDecl *D) { return true; } 793}; 794 795class ObjCImplDecl : public Decl, public DeclContext { 796 /// Class interface for this category implementation 797 ObjCInterfaceDecl *ClassInterface; 798 799 SourceLocation EndLoc; 800 801protected: 802 ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L, 803 ObjCInterfaceDecl *classInterface) 804 : Decl(DK, DC, L), DeclContext(DK), 805 ClassInterface(classInterface) {} 806 807public: 808 virtual ~ObjCImplDecl() {} 809 810 const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 811 ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 812 void setClassInterface(ObjCInterfaceDecl *IFace) { ClassInterface = IFace; } 813 814 void addInstanceMethod(ASTContext &Context, ObjCMethodDecl *method) { 815 // FIXME: Context should be set correctly before we get here. 816 method->setLexicalDeclContext(this); 817 addDecl(Context, method); 818 } 819 void addClassMethod(ASTContext &Context, ObjCMethodDecl *method) { 820 // FIXME: Context should be set correctly before we get here. 821 method->setLexicalDeclContext(this); 822 addDecl(Context, method); 823 } 824 825 // Get the local instance/class method declared in this interface. 826 ObjCMethodDecl *getInstanceMethod(ASTContext &Context, Selector Sel) const; 827 ObjCMethodDecl *getClassMethod(ASTContext &Context, Selector Sel) const; 828 ObjCMethodDecl *getMethod(ASTContext &Context, Selector Sel, 829 bool isInstance) const { 830 return isInstance ? getInstanceMethod(Context, Sel) 831 : getClassMethod(Context, Sel); 832 } 833 834 void addPropertyImplementation(ASTContext &Context, 835 ObjCPropertyImplDecl *property); 836 837 ObjCPropertyImplDecl *FindPropertyImplDecl(ASTContext &Context, 838 IdentifierInfo *propertyId) const; 839 ObjCPropertyImplDecl *FindPropertyImplIvarDecl(ASTContext &Context, 840 IdentifierInfo *ivarId) const; 841 842 // Iterator access to properties. 843 typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator; 844 propimpl_iterator propimpl_begin(ASTContext &Context) const { 845 return propimpl_iterator(decls_begin(Context)); 846 } 847 propimpl_iterator propimpl_end(ASTContext &Context) const { 848 return propimpl_iterator(decls_end(Context)); 849 } 850 851 typedef filtered_decl_iterator<ObjCMethodDecl, 852 &ObjCMethodDecl::isInstanceMethod> 853 instmeth_iterator; 854 instmeth_iterator instmeth_begin(ASTContext &Context) const { 855 return instmeth_iterator(decls_begin(Context)); 856 } 857 instmeth_iterator instmeth_end(ASTContext &Context) const { 858 return instmeth_iterator(decls_end(Context)); 859 } 860 861 typedef filtered_decl_iterator<ObjCMethodDecl, 862 &ObjCMethodDecl::isClassMethod> 863 classmeth_iterator; 864 classmeth_iterator classmeth_begin(ASTContext &Context) const { 865 return classmeth_iterator(decls_begin(Context)); 866 } 867 classmeth_iterator classmeth_end(ASTContext &Context) const { 868 return classmeth_iterator(decls_end(Context)); 869 } 870 871 // Location information, modeled after the Stmt API. 872 SourceLocation getLocStart() const { return getLocation(); } 873 SourceLocation getLocEnd() const { return EndLoc; } 874 void setLocEnd(SourceLocation LE) { EndLoc = LE; }; 875}; 876 877/// ObjCCategoryImplDecl - An object of this class encapsulates a category 878/// @implementation declaration. If a category class has declaration of a 879/// property, its implementation must be specified in the category's 880/// @implementation declaration. Example: 881/// @interface I @end 882/// @interface I(CATEGORY) 883/// @property int p1, d1; 884/// @end 885/// @implementation I(CATEGORY) 886/// @dynamic p1,d1; 887/// @end 888/// 889/// ObjCCategoryImplDecl 890class ObjCCategoryImplDecl : public ObjCImplDecl { 891 // Category name 892 IdentifierInfo *Id; 893 894 ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 895 ObjCInterfaceDecl *classInterface) 896 : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {} 897public: 898 static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, 899 SourceLocation L, IdentifierInfo *Id, 900 ObjCInterfaceDecl *classInterface); 901 902 /// getIdentifier - Get the identifier that names the class 903 /// interface associated with this implementation. 904 IdentifierInfo *getIdentifier() const { 905 return Id; 906 } 907 void setIdentifier(IdentifierInfo *II) { Id = II; } 908 909 /// getNameAsCString - Get the name of identifier for the class 910 /// interface associated with this implementation as a C string 911 /// (const char*). 912 const char *getNameAsCString() const { 913 return Id ? Id->getName() : ""; 914 } 915 916 /// @brief Get the name of the class associated with this interface. 917 std::string getNameAsString() const { 918 return Id ? Id->getName() : ""; 919 } 920 921 static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;} 922 static bool classof(const ObjCCategoryImplDecl *D) { return true; } 923 static DeclContext *castToDeclContext(const ObjCCategoryImplDecl *D) { 924 return static_cast<DeclContext *>(const_cast<ObjCCategoryImplDecl*>(D)); 925 } 926 static ObjCCategoryImplDecl *castFromDeclContext(const DeclContext *DC) { 927 return static_cast<ObjCCategoryImplDecl *>(const_cast<DeclContext*>(DC)); 928 } 929}; 930 931/// ObjCImplementationDecl - Represents a class definition - this is where 932/// method definitions are specified. For example: 933/// 934/// @code 935/// @implementation MyClass 936/// - (void)myMethod { /* do something */ } 937/// @end 938/// @endcode 939/// 940/// Typically, instance variables are specified in the class interface, 941/// *not* in the implementation. Nevertheless (for legacy reasons), we 942/// allow instance variables to be specified in the implementation. When 943/// specified, they need to be *identical* to the interface. 944/// 945class ObjCImplementationDecl : public ObjCImplDecl { 946 /// Implementation Class's super class. 947 ObjCInterfaceDecl *SuperClass; 948 949 ObjCImplementationDecl(DeclContext *DC, SourceLocation L, 950 ObjCInterfaceDecl *classInterface, 951 ObjCInterfaceDecl *superDecl) 952 : ObjCImplDecl(ObjCImplementation, DC, L, classInterface), 953 SuperClass(superDecl){} 954public: 955 static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, 956 SourceLocation L, 957 ObjCInterfaceDecl *classInterface, 958 ObjCInterfaceDecl *superDecl); 959 960 /// getIdentifier - Get the identifier that names the class 961 /// interface associated with this implementation. 962 IdentifierInfo *getIdentifier() const { 963 return getClassInterface()->getIdentifier(); 964 } 965 966 /// getNameAsCString - Get the name of identifier for the class 967 /// interface associated with this implementation as a C string 968 /// (const char*). 969 const char *getNameAsCString() const { 970 assert(getIdentifier() && "Name is not a simple identifier"); 971 return getIdentifier()->getName(); 972 } 973 974 /// @brief Get the name of the class associated with this interface. 975 std::string getNameAsString() const { 976 return getClassInterface()->getNameAsString(); 977 } 978 979 const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 980 ObjCInterfaceDecl *getSuperClass() { return SuperClass; } 981 982 void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 983 984 typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 985 ivar_iterator ivar_begin(ASTContext &Context) const { 986 return ivar_iterator(decls_begin(Context)); 987 } 988 ivar_iterator ivar_end(ASTContext &Context) const { 989 return ivar_iterator(decls_end(Context)); 990 } 991 unsigned ivar_size(ASTContext &Context) const { 992 return std::distance(ivar_begin(Context), ivar_end(Context)); 993 } 994 bool ivar_empty(ASTContext &Context) const { 995 return ivar_begin(Context) == ivar_end(Context); 996 } 997 998 static bool classof(const Decl *D) { 999 return D->getKind() == ObjCImplementation; 1000 } 1001 static bool classof(const ObjCImplementationDecl *D) { return true; } 1002 static DeclContext *castToDeclContext(const ObjCImplementationDecl *D) { 1003 return static_cast<DeclContext *>(const_cast<ObjCImplementationDecl*>(D)); 1004 } 1005 static ObjCImplementationDecl *castFromDeclContext(const DeclContext *DC) { 1006 return static_cast<ObjCImplementationDecl *>(const_cast<DeclContext*>(DC)); 1007 } 1008}; 1009 1010/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 1011/// declared as @compatibility_alias alias class. 1012class ObjCCompatibleAliasDecl : public NamedDecl { 1013 /// Class that this is an alias of. 1014 ObjCInterfaceDecl *AliasedClass; 1015 1016 ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 1017 ObjCInterfaceDecl* aliasedClass) 1018 : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {} 1019public: 1020 static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC, 1021 SourceLocation L, IdentifierInfo *Id, 1022 ObjCInterfaceDecl* aliasedClass); 1023 1024 const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } 1025 ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } 1026 void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } 1027 1028 static bool classof(const Decl *D) { 1029 return D->getKind() == ObjCCompatibleAlias; 1030 } 1031 static bool classof(const ObjCCompatibleAliasDecl *D) { return true; } 1032 1033}; 1034 1035/// ObjCPropertyDecl - Represents one property declaration in an interface. 1036/// For example: 1037/// @property (assign, readwrite) int MyProperty; 1038/// 1039class ObjCPropertyDecl : public NamedDecl { 1040public: 1041 enum PropertyAttributeKind { 1042 OBJC_PR_noattr = 0x00, 1043 OBJC_PR_readonly = 0x01, 1044 OBJC_PR_getter = 0x02, 1045 OBJC_PR_assign = 0x04, 1046 OBJC_PR_readwrite = 0x08, 1047 OBJC_PR_retain = 0x10, 1048 OBJC_PR_copy = 0x20, 1049 OBJC_PR_nonatomic = 0x40, 1050 OBJC_PR_setter = 0x80 1051 }; 1052 1053 enum SetterKind { Assign, Retain, Copy }; 1054 enum PropertyControl { None, Required, Optional }; 1055private: 1056 QualType DeclType; 1057 unsigned PropertyAttributes : 8; 1058 1059 // @required/@optional 1060 unsigned PropertyImplementation : 2; 1061 1062 Selector GetterName; // getter name of NULL if no getter 1063 Selector SetterName; // setter name of NULL if no setter 1064 1065 ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method 1066 ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method 1067 ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property 1068 1069 ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 1070 QualType T) 1071 : NamedDecl(ObjCProperty, DC, L, Id), DeclType(T), 1072 PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None), 1073 GetterName(Selector()), 1074 SetterName(Selector()), 1075 GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {} 1076public: 1077 static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, 1078 SourceLocation L, 1079 IdentifierInfo *Id, QualType T, 1080 PropertyControl propControl = None); 1081 QualType getType() const { return DeclType; } 1082 void setType(QualType T) { DeclType = T; } 1083 1084 PropertyAttributeKind getPropertyAttributes() const { 1085 return PropertyAttributeKind(PropertyAttributes); 1086 } 1087 void setPropertyAttributes(PropertyAttributeKind PRVal) { 1088 PropertyAttributes |= PRVal; 1089 } 1090 1091 void makeitReadWriteAttribute(void) { 1092 PropertyAttributes &= ~OBJC_PR_readonly; 1093 PropertyAttributes |= OBJC_PR_readwrite; 1094 } 1095 1096 // Helper methods for accessing attributes. 1097 1098 /// isReadOnly - Return true iff the property has a setter. 1099 bool isReadOnly() const { 1100 return (PropertyAttributes & OBJC_PR_readonly); 1101 } 1102 1103 /// getSetterKind - Return the method used for doing assignment in 1104 /// the property setter. This is only valid if the property has been 1105 /// defined to have a setter. 1106 SetterKind getSetterKind() const { 1107 if (PropertyAttributes & OBJC_PR_retain) 1108 return Retain; 1109 if (PropertyAttributes & OBJC_PR_copy) 1110 return Copy; 1111 return Assign; 1112 } 1113 1114 Selector getGetterName() const { return GetterName; } 1115 void setGetterName(Selector Sel) { GetterName = Sel; } 1116 1117 Selector getSetterName() const { return SetterName; } 1118 void setSetterName(Selector Sel) { SetterName = Sel; } 1119 1120 ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } 1121 void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } 1122 1123 ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } 1124 void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } 1125 1126 // Related to @optional/@required declared in @protocol 1127 void setPropertyImplementation(PropertyControl pc) { 1128 PropertyImplementation = pc; 1129 } 1130 PropertyControl getPropertyImplementation() const { 1131 return PropertyControl(PropertyImplementation); 1132 } 1133 1134 void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { 1135 PropertyIvarDecl = Ivar; 1136 } 1137 ObjCIvarDecl *getPropertyIvarDecl() const { 1138 return PropertyIvarDecl; 1139 } 1140 1141 static bool classof(const Decl *D) { 1142 return D->getKind() == ObjCProperty; 1143 } 1144 static bool classof(const ObjCPropertyDecl *D) { return true; } 1145}; 1146 1147/// ObjCPropertyImplDecl - Represents implementation declaration of a property 1148/// in a class or category implementation block. For example: 1149/// @synthesize prop1 = ivar1; 1150/// 1151class ObjCPropertyImplDecl : public Decl { 1152public: 1153 enum Kind { 1154 Synthesize, 1155 Dynamic 1156 }; 1157private: 1158 SourceLocation AtLoc; // location of @synthesize or @dynamic 1159 /// Property declaration being implemented 1160 ObjCPropertyDecl *PropertyDecl; 1161 1162 /// Null for @dynamic. Required for @synthesize. 1163 ObjCIvarDecl *PropertyIvarDecl; 1164 1165 ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, 1166 ObjCPropertyDecl *property, 1167 Kind PK, 1168 ObjCIvarDecl *ivarDecl) 1169 : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), 1170 PropertyDecl(property), PropertyIvarDecl(ivarDecl) { 1171 assert (PK == Dynamic || PropertyIvarDecl); 1172 } 1173 1174public: 1175 static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC, 1176 SourceLocation atLoc, SourceLocation L, 1177 ObjCPropertyDecl *property, 1178 Kind PK, 1179 ObjCIvarDecl *ivarDecl); 1180 1181 SourceLocation getLocStart() const { return AtLoc; } 1182 1183 ObjCPropertyDecl *getPropertyDecl() const { 1184 return PropertyDecl; 1185 } 1186 1187 Kind getPropertyImplementation() const { 1188 return PropertyIvarDecl ? Synthesize : Dynamic; 1189 } 1190 1191 ObjCIvarDecl *getPropertyIvarDecl() const { 1192 return PropertyIvarDecl; 1193 } 1194 1195 static bool classof(const Decl *D) { 1196 return D->getKind() == ObjCPropertyImpl; 1197 } 1198 static bool classof(const ObjCPropertyImplDecl *D) { return true; } 1199}; 1200 1201} // end namespace clang 1202#endif 1203