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