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