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