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