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