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