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