1193326Sed//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines the DeclObjC interface and subclasses. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14193326Sed#ifndef LLVM_CLANG_AST_DECLOBJC_H 15193326Sed#define LLVM_CLANG_AST_DECLOBJC_H 16193326Sed 17193326Sed#include "clang/AST/Decl.h" 18226890Sdim#include "clang/AST/SelectorLocationsKind.h" 19193326Sed#include "llvm/ADT/STLExtras.h" 20235633Sdim#include "llvm/Support/Compiler.h" 21193326Sed 22193326Sednamespace clang { 23193326Sedclass Expr; 24193326Sedclass Stmt; 25193326Sedclass FunctionDecl; 26193326Sedclass RecordDecl; 27193326Sedclass ObjCIvarDecl; 28193326Sedclass ObjCMethodDecl; 29193326Sedclass ObjCProtocolDecl; 30193326Sedclass ObjCCategoryDecl; 31193326Sedclass ObjCPropertyDecl; 32193326Sedclass ObjCPropertyImplDecl; 33218893Sdimclass CXXCtorInitializer; 34193326Sed 35193326Sedclass ObjCListBase { 36245431Sdim ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION; 37245431Sdim void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION; 38193326Sedprotected: 39193326Sed /// List is an array of pointers to objects that are not owned by this object. 40193326Sed void **List; 41193326Sed unsigned NumElts; 42193326Sed 43193326Sedpublic: 44193326Sed ObjCListBase() : List(0), NumElts(0) {} 45193326Sed unsigned size() const { return NumElts; } 46193326Sed bool empty() const { return NumElts == 0; } 47198092Srdivacky 48193326Sedprotected: 49193326Sed void set(void *const* InList, unsigned Elts, ASTContext &Ctx); 50193326Sed}; 51198092Srdivacky 52198092Srdivacky 53193326Sed/// ObjCList - This is a simple template class used to hold various lists of 54193326Sed/// decls etc, which is heavily used by the ObjC front-end. This only use case 55193326Sed/// this supports is setting the list all at once and then reading elements out 56193326Sed/// of it. 57193326Sedtemplate <typename T> 58193326Sedclass ObjCList : public ObjCListBase { 59193326Sedpublic: 60193326Sed void set(T* const* InList, unsigned Elts, ASTContext &Ctx) { 61193326Sed ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx); 62193326Sed } 63198092Srdivacky 64193326Sed typedef T* const * iterator; 65193326Sed iterator begin() const { return (iterator)List; } 66193326Sed iterator end() const { return (iterator)List+NumElts; } 67198092Srdivacky 68193326Sed T* operator[](unsigned Idx) const { 69193326Sed assert(Idx < NumElts && "Invalid access"); 70193326Sed return (T*)List[Idx]; 71193326Sed } 72193326Sed}; 73193326Sed 74202879Srdivacky/// \brief A list of Objective-C protocols, along with the source 75202879Srdivacky/// locations at which they were referenced. 76202879Srdivackyclass ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { 77202879Srdivacky SourceLocation *Locations; 78193326Sed 79202879Srdivacky using ObjCList<ObjCProtocolDecl>::set; 80198092Srdivacky 81202879Srdivackypublic: 82202879Srdivacky ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { } 83202879Srdivacky 84202879Srdivacky typedef const SourceLocation *loc_iterator; 85202879Srdivacky loc_iterator loc_begin() const { return Locations; } 86202879Srdivacky loc_iterator loc_end() const { return Locations + size(); } 87202879Srdivacky 88235633Sdim void set(ObjCProtocolDecl* const* InList, unsigned Elts, 89202879Srdivacky const SourceLocation *Locs, ASTContext &Ctx); 90202879Srdivacky}; 91202879Srdivacky 92202879Srdivacky 93193326Sed/// ObjCMethodDecl - Represents an instance or class method declaration. 94193326Sed/// ObjC methods can be declared within 4 contexts: class interfaces, 95193326Sed/// categories, protocols, and class implementations. While C++ member 96198092Srdivacky/// functions leverage C syntax, Objective-C method syntax is modeled after 97198092Srdivacky/// Smalltalk (using colons to specify argument types/expressions). 98193326Sed/// Here are some brief examples: 99193326Sed/// 100193326Sed/// Setter/getter instance methods: 101193326Sed/// - (void)setMenu:(NSMenu *)menu; 102198092Srdivacky/// - (NSMenu *)menu; 103198092Srdivacky/// 104193326Sed/// Instance method that takes 2 NSView arguments: 105193326Sed/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView; 106193326Sed/// 107193326Sed/// Getter class method: 108193326Sed/// + (NSMenu *)defaultMenu; 109193326Sed/// 110193326Sed/// A selector represents a unique name for a method. The selector names for 111193326Sed/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. 112193326Sed/// 113193326Sedclass ObjCMethodDecl : public NamedDecl, public DeclContext { 114193326Sedpublic: 115193326Sed enum ImplementationControl { None, Required, Optional }; 116193326Sedprivate: 117221345Sdim // The conventional meaning of this method; an ObjCMethodFamily. 118221345Sdim // This is not serialized; instead, it is computed on demand and 119221345Sdim // cached. 120221345Sdim mutable unsigned Family : ObjCMethodFamilyBitWidth; 121221345Sdim 122193326Sed /// instance (true) or class (false) method. 123221345Sdim unsigned IsInstance : 1; 124221345Sdim unsigned IsVariadic : 1; 125198092Srdivacky 126245431Sdim /// True if this method is the getter or setter for an explicit property. 127245431Sdim unsigned IsPropertyAccessor : 1; 128235633Sdim 129212904Sdim // Method has a definition. 130221345Sdim unsigned IsDefined : 1; 131198092Srdivacky 132226890Sdim /// \brief Method redeclaration in the same interface. 133226890Sdim unsigned IsRedeclaration : 1; 134226890Sdim 135226890Sdim /// \brief Is redeclared in the same interface. 136226890Sdim mutable unsigned HasRedeclaration : 1; 137226890Sdim 138193326Sed // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum 139245431Sdim /// \@required/\@optional 140193326Sed unsigned DeclImplementation : 2; 141198092Srdivacky 142193326Sed // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum 143193326Sed /// in, inout, etc. 144193326Sed unsigned objcDeclQualifier : 6; 145198092Srdivacky 146223017Sdim /// \brief Indicates whether this method has a related result type. 147223017Sdim unsigned RelatedResultType : 1; 148235633Sdim 149226890Sdim /// \brief Whether the locations of the selector identifiers are in a 150226890Sdim /// "standard" position, a enum SelectorLocationsKind. 151226890Sdim unsigned SelLocsKind : 2; 152207619Srdivacky 153245431Sdim /// \brief Whether this method overrides any other in the class hierarchy. 154245431Sdim /// 155245431Sdim /// A method is said to override any method in the class's 156245431Sdim /// base classes, its protocols, or its categories' protocols, that has 157245431Sdim /// the same selector and is of the same kind (class or instance). 158245431Sdim /// A method in an implementation is not considered as overriding the same 159245431Sdim /// method in the interface or its categories. 160245431Sdim unsigned IsOverriding : 1; 161245431Sdim 162252723Sdim /// \brief Indicates if the method was a definition but its body was skipped. 163252723Sdim unsigned HasSkippedBody : 1; 164252723Sdim 165204962Srdivacky // Result type of this method. 166193326Sed QualType MethodDeclType; 167235633Sdim 168204962Srdivacky // Type source information for the result type. 169204962Srdivacky TypeSourceInfo *ResultTInfo; 170204962Srdivacky 171226890Sdim /// \brief Array of ParmVarDecls for the formal parameters of this method 172226890Sdim /// and optionally followed by selector locations. 173226890Sdim void *ParamsAndSelLocs; 174226890Sdim unsigned NumParams; 175198092Srdivacky 176193326Sed /// List of attributes for this method declaration. 177245431Sdim SourceLocation DeclEndLoc; // the location of the ';' or '{'. 178198092Srdivacky 179193326Sed // The following are only used for method definitions, null otherwise. 180245431Sdim LazyDeclStmtPtr Body; 181193326Sed 182193326Sed /// SelfDecl - Decl for the implicit self parameter. This is lazily 183193326Sed /// constructed by createImplicitParams. 184193326Sed ImplicitParamDecl *SelfDecl; 185193326Sed /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily 186193326Sed /// constructed by createImplicitParams. 187193326Sed ImplicitParamDecl *CmdDecl; 188198092Srdivacky 189226890Sdim SelectorLocationsKind getSelLocsKind() const { 190226890Sdim return (SelectorLocationsKind)SelLocsKind; 191226890Sdim } 192226890Sdim bool hasStandardSelLocs() const { 193226890Sdim return getSelLocsKind() != SelLoc_NonStandard; 194226890Sdim } 195226890Sdim 196226890Sdim /// \brief Get a pointer to the stored selector identifiers locations array. 197226890Sdim /// No locations will be stored if HasStandardSelLocs is true. 198226890Sdim SourceLocation *getStoredSelLocs() { 199226890Sdim return reinterpret_cast<SourceLocation*>(getParams() + NumParams); 200226890Sdim } 201226890Sdim const SourceLocation *getStoredSelLocs() const { 202226890Sdim return reinterpret_cast<const SourceLocation*>(getParams() + NumParams); 203226890Sdim } 204226890Sdim 205226890Sdim /// \brief Get a pointer to the stored selector identifiers locations array. 206226890Sdim /// No locations will be stored if HasStandardSelLocs is true. 207226890Sdim ParmVarDecl **getParams() { 208226890Sdim return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs); 209226890Sdim } 210226890Sdim const ParmVarDecl *const *getParams() const { 211226890Sdim return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs); 212226890Sdim } 213226890Sdim 214226890Sdim /// \brief Get the number of stored selector identifiers locations. 215226890Sdim /// No locations will be stored if HasStandardSelLocs is true. 216226890Sdim unsigned getNumStoredSelLocs() const { 217226890Sdim if (hasStandardSelLocs()) 218226890Sdim return 0; 219226890Sdim return getNumSelectorLocs(); 220226890Sdim } 221226890Sdim 222226890Sdim void setParamsAndSelLocs(ASTContext &C, 223226890Sdim ArrayRef<ParmVarDecl*> Params, 224226890Sdim ArrayRef<SourceLocation> SelLocs); 225226890Sdim 226193326Sed ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, 227193326Sed Selector SelInfo, QualType T, 228204962Srdivacky TypeSourceInfo *ResultTInfo, 229193326Sed DeclContext *contextDecl, 230193326Sed bool isInstance = true, 231193326Sed bool isVariadic = false, 232245431Sdim bool isPropertyAccessor = false, 233226890Sdim bool isImplicitlyDeclared = false, 234212904Sdim bool isDefined = false, 235207619Srdivacky ImplementationControl impControl = None, 236226890Sdim bool HasRelatedResultType = false) 237193326Sed : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), 238221345Sdim DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), 239193326Sed IsInstance(isInstance), IsVariadic(isVariadic), 240245431Sdim IsPropertyAccessor(isPropertyAccessor), 241226890Sdim IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), 242193326Sed DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), 243226890Sdim RelatedResultType(HasRelatedResultType), 244252723Sdim SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0), 245223017Sdim MethodDeclType(T), ResultTInfo(ResultTInfo), 246226890Sdim ParamsAndSelLocs(0), NumParams(0), 247245431Sdim DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) { 248226890Sdim setImplicit(isImplicitlyDeclared); 249226890Sdim } 250193326Sed 251198092Srdivacky /// \brief A definition will return its interface declaration. 252198092Srdivacky /// An interface declaration will return its definition. 253198092Srdivacky /// Otherwise it will return itself. 254198092Srdivacky virtual ObjCMethodDecl *getNextRedeclaration(); 255198092Srdivacky 256193326Sedpublic: 257193326Sed static ObjCMethodDecl *Create(ASTContext &C, 258198092Srdivacky SourceLocation beginLoc, 259226890Sdim SourceLocation endLoc, 260226890Sdim Selector SelInfo, 261235633Sdim QualType T, 262204962Srdivacky TypeSourceInfo *ResultTInfo, 263204962Srdivacky DeclContext *contextDecl, 264193326Sed bool isInstance = true, 265193326Sed bool isVariadic = false, 266245431Sdim bool isPropertyAccessor = false, 267226890Sdim bool isImplicitlyDeclared = false, 268212904Sdim bool isDefined = false, 269207619Srdivacky ImplementationControl impControl = None, 270226890Sdim bool HasRelatedResultType = false); 271198092Srdivacky 272235633Sdim static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); 273235633Sdim 274198092Srdivacky virtual ObjCMethodDecl *getCanonicalDecl(); 275203955Srdivacky const ObjCMethodDecl *getCanonicalDecl() const { 276203955Srdivacky return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl(); 277203955Srdivacky } 278198092Srdivacky 279193326Sed ObjCDeclQualifier getObjCDeclQualifier() const { 280193326Sed return ObjCDeclQualifier(objcDeclQualifier); 281193326Sed } 282193326Sed void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; } 283198092Srdivacky 284223017Sdim /// \brief Determine whether this method has a result type that is related 285223017Sdim /// to the message receiver's type. 286223017Sdim bool hasRelatedResultType() const { return RelatedResultType; } 287235633Sdim 288223017Sdim /// \brief Note whether this method has a related result type. 289223017Sdim void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; } 290226890Sdim 291226890Sdim /// \brief True if this is a method redeclaration in the same interface. 292226890Sdim bool isRedeclaration() const { return IsRedeclaration; } 293226890Sdim void setAsRedeclaration(const ObjCMethodDecl *PrevMethod); 294235633Sdim 295245431Sdim /// \brief Returns the location where the declarator ends. It will be 296245431Sdim /// the location of ';' for a method declaration and the location of '{' 297245431Sdim /// for a method definition. 298245431Sdim SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; } 299245431Sdim 300193326Sed // Location information, modeled after the Stmt API. 301235633Sdim SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); } 302245431Sdim SourceLocation getLocEnd() const LLVM_READONLY; 303235633Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 304245431Sdim return SourceRange(getLocation(), getLocEnd()); 305193326Sed } 306198092Srdivacky 307235633Sdim SourceLocation getSelectorStartLoc() const { 308235633Sdim if (isImplicit()) 309235633Sdim return getLocStart(); 310235633Sdim return getSelectorLoc(0); 311235633Sdim } 312226890Sdim SourceLocation getSelectorLoc(unsigned Index) const { 313226890Sdim assert(Index < getNumSelectorLocs() && "Index out of range!"); 314226890Sdim if (hasStandardSelLocs()) 315226890Sdim return getStandardSelectorLoc(Index, getSelector(), 316226890Sdim getSelLocsKind() == SelLoc_StandardWithSpace, 317226890Sdim llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()), 318226890Sdim NumParams), 319245431Sdim DeclEndLoc); 320226890Sdim return getStoredSelLocs()[Index]; 321226890Sdim } 322226890Sdim 323226890Sdim void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; 324226890Sdim 325226890Sdim unsigned getNumSelectorLocs() const { 326226890Sdim if (isImplicit()) 327226890Sdim return 0; 328226890Sdim Selector Sel = getSelector(); 329226890Sdim if (Sel.isUnarySelector()) 330226890Sdim return 1; 331226890Sdim return Sel.getNumArgs(); 332226890Sdim } 333226890Sdim 334193326Sed ObjCInterfaceDecl *getClassInterface(); 335193326Sed const ObjCInterfaceDecl *getClassInterface() const { 336193326Sed return const_cast<ObjCMethodDecl*>(this)->getClassInterface(); 337193326Sed } 338198092Srdivacky 339193326Sed Selector getSelector() const { return getDeclName().getObjCSelector(); } 340198092Srdivacky 341193326Sed QualType getResultType() const { return MethodDeclType; } 342193326Sed void setResultType(QualType T) { MethodDeclType = T; } 343198092Srdivacky 344235633Sdim /// \brief Determine the type of an expression that sends a message to this 345210299Sed /// function. 346210299Sed QualType getSendResultType() const { 347210299Sed return getResultType().getNonLValueExprType(getASTContext()); 348210299Sed } 349235633Sdim 350204962Srdivacky TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; } 351204962Srdivacky void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; } 352204962Srdivacky 353193326Sed // Iterator access to formal parameters. 354226890Sdim unsigned param_size() const { return NumParams; } 355226890Sdim typedef const ParmVarDecl *const *param_const_iterator; 356226890Sdim typedef ParmVarDecl *const *param_iterator; 357226890Sdim param_const_iterator param_begin() const { return getParams(); } 358226890Sdim param_const_iterator param_end() const { return getParams() + NumParams; } 359226890Sdim param_iterator param_begin() { return getParams(); } 360226890Sdim param_iterator param_end() { return getParams() + NumParams; } 361207619Srdivacky // This method returns and of the parameters which are part of the selector 362207619Srdivacky // name mangling requirements. 363235633Sdim param_const_iterator sel_param_end() const { 364235633Sdim return param_begin() + getSelector().getNumArgs(); 365207619Srdivacky } 366193326Sed 367226890Sdim /// \brief Sets the method's parameters and selector source locations. 368245431Sdim /// If the method is implicit (not coming from source) \p SelLocs is 369226890Sdim /// ignored. 370226890Sdim void setMethodParams(ASTContext &C, 371226890Sdim ArrayRef<ParmVarDecl*> Params, 372226890Sdim ArrayRef<SourceLocation> SelLocs = 373226890Sdim ArrayRef<SourceLocation>()); 374193326Sed 375193326Sed // Iterator access to parameter types. 376193326Sed typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun; 377226890Sdim typedef llvm::mapped_iterator<param_const_iterator, deref_fun> 378226890Sdim arg_type_iterator; 379193326Sed 380193326Sed arg_type_iterator arg_type_begin() const { 381193326Sed return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType)); 382193326Sed } 383193326Sed arg_type_iterator arg_type_end() const { 384193326Sed return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType)); 385193326Sed } 386198092Srdivacky 387193326Sed /// createImplicitParams - Used to lazily create the self and cmd 388193326Sed /// implict parameters. This must be called prior to using getSelfDecl() 389193326Sed /// or getCmdDecl(). The call is ignored if the implicit paramters 390193326Sed /// have already been created. 391193326Sed void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID); 392193326Sed 393193326Sed ImplicitParamDecl * getSelfDecl() const { return SelfDecl; } 394193326Sed void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; } 395193326Sed ImplicitParamDecl * getCmdDecl() const { return CmdDecl; } 396193326Sed void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; } 397198092Srdivacky 398221345Sdim /// Determines the family of this method. 399221345Sdim ObjCMethodFamily getMethodFamily() const; 400221345Sdim 401193326Sed bool isInstanceMethod() const { return IsInstance; } 402193326Sed void setInstanceMethod(bool isInst) { IsInstance = isInst; } 403193326Sed bool isVariadic() const { return IsVariadic; } 404193326Sed void setVariadic(bool isVar) { IsVariadic = isVar; } 405198092Srdivacky 406193326Sed bool isClassMethod() const { return !IsInstance; } 407193326Sed 408245431Sdim bool isPropertyAccessor() const { return IsPropertyAccessor; } 409245431Sdim void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; } 410235633Sdim 411212904Sdim bool isDefined() const { return IsDefined; } 412212904Sdim void setDefined(bool isDefined) { IsDefined = isDefined; } 413198092Srdivacky 414245431Sdim /// \brief Whether this method overrides any other in the class hierarchy. 415245431Sdim /// 416245431Sdim /// A method is said to override any method in the class's 417245431Sdim /// base classes, its protocols, or its categories' protocols, that has 418245431Sdim /// the same selector and is of the same kind (class or instance). 419245431Sdim /// A method in an implementation is not considered as overriding the same 420245431Sdim /// method in the interface or its categories. 421245431Sdim bool isOverriding() const { return IsOverriding; } 422245431Sdim void setOverriding(bool isOverriding) { IsOverriding = isOverriding; } 423245431Sdim 424245431Sdim /// \brief Return overridden methods for the given \p Method. 425245431Sdim /// 426245431Sdim /// An ObjC method is considered to override any method in the class's 427245431Sdim /// base classes (and base's categories), its protocols, or its categories' 428245431Sdim /// protocols, that has 429245431Sdim /// the same selector and is of the same kind (class or instance). 430245431Sdim /// A method in an implementation is not considered as overriding the same 431245431Sdim /// method in the interface or its categories. 432245431Sdim void getOverriddenMethods( 433245431Sdim SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const; 434245431Sdim 435252723Sdim /// \brief True if the method was a definition but its body was skipped. 436252723Sdim bool hasSkippedBody() const { return HasSkippedBody; } 437252723Sdim void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } 438252723Sdim 439245431Sdim /// \brief Returns the property associated with this method's selector. 440245431Sdim /// 441245431Sdim /// Note that even if this particular method is not marked as a property 442245431Sdim /// accessor, it is still possible for it to match a property declared in a 443245431Sdim /// superclass. Pass \c false if you only want to check the current class. 444245431Sdim const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const; 445245431Sdim 446245431Sdim // Related to protocols declared in \@protocol 447198092Srdivacky void setDeclImplementation(ImplementationControl ic) { 448198092Srdivacky DeclImplementation = ic; 449193326Sed } 450198092Srdivacky ImplementationControl getImplementationControl() const { 451198092Srdivacky return ImplementationControl(DeclImplementation); 452193326Sed } 453193326Sed 454245431Sdim /// \brief Determine whether this method has a body. 455263509Sdim virtual bool hasBody() const { return Body.isValid(); } 456245431Sdim 457245431Sdim /// \brief Retrieve the body of this method, if it has one. 458245431Sdim virtual Stmt *getBody() const; 459245431Sdim 460245431Sdim void setLazyBody(uint64_t Offset) { Body = Offset; } 461245431Sdim 462245431Sdim CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); } 463193326Sed void setBody(Stmt *B) { Body = B; } 464193326Sed 465198092Srdivacky /// \brief Returns whether this specific method is a definition. 466263509Sdim bool isThisDeclarationADefinition() const { return hasBody(); } 467198092Srdivacky 468193326Sed // Implement isa/cast/dyncast/etc. 469203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 470203955Srdivacky static bool classofKind(Kind K) { return K == ObjCMethod; } 471193326Sed static DeclContext *castToDeclContext(const ObjCMethodDecl *D) { 472193326Sed return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D)); 473193326Sed } 474193326Sed static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) { 475193326Sed return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC)); 476193326Sed } 477226890Sdim 478226890Sdim friend class ASTDeclReader; 479226890Sdim friend class ASTDeclWriter; 480193326Sed}; 481193326Sed 482193326Sed/// ObjCContainerDecl - Represents a container for method declarations. 483198092Srdivacky/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, 484198092Srdivacky/// ObjCProtocolDecl, and ObjCImplDecl. 485193326Sed/// 486193326Sedclass ObjCContainerDecl : public NamedDecl, public DeclContext { 487235633Sdim virtual void anchor(); 488235633Sdim 489226890Sdim SourceLocation AtStart; 490226890Sdim 491202379Srdivacky // These two locations in the range mark the end of the method container. 492202379Srdivacky // The first points to the '@' token, and the second to the 'end' token. 493202379Srdivacky SourceRange AtEnd; 494193326Sedpublic: 495193326Sed 496226890Sdim ObjCContainerDecl(Kind DK, DeclContext *DC, 497226890Sdim IdentifierInfo *Id, SourceLocation nameLoc, 498226890Sdim SourceLocation atStartLoc) 499226890Sdim : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} 500193326Sed 501193326Sed // Iterator access to properties. 502193326Sed typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator; 503198092Srdivacky prop_iterator prop_begin() const { 504195341Sed return prop_iterator(decls_begin()); 505193326Sed } 506198092Srdivacky prop_iterator prop_end() const { 507195341Sed return prop_iterator(decls_end()); 508193326Sed } 509198092Srdivacky 510193326Sed // Iterator access to instance/class methods. 511193326Sed typedef specific_decl_iterator<ObjCMethodDecl> method_iterator; 512198092Srdivacky method_iterator meth_begin() const { 513195341Sed return method_iterator(decls_begin()); 514193326Sed } 515198092Srdivacky method_iterator meth_end() const { 516195341Sed return method_iterator(decls_end()); 517193326Sed } 518193326Sed 519198092Srdivacky typedef filtered_decl_iterator<ObjCMethodDecl, 520198092Srdivacky &ObjCMethodDecl::isInstanceMethod> 521193326Sed instmeth_iterator; 522195341Sed instmeth_iterator instmeth_begin() const { 523195341Sed return instmeth_iterator(decls_begin()); 524193326Sed } 525195341Sed instmeth_iterator instmeth_end() const { 526195341Sed return instmeth_iterator(decls_end()); 527193326Sed } 528193326Sed 529198092Srdivacky typedef filtered_decl_iterator<ObjCMethodDecl, 530198092Srdivacky &ObjCMethodDecl::isClassMethod> 531193326Sed classmeth_iterator; 532195341Sed classmeth_iterator classmeth_begin() const { 533195341Sed return classmeth_iterator(decls_begin()); 534193326Sed } 535195341Sed classmeth_iterator classmeth_end() const { 536195341Sed return classmeth_iterator(decls_end()); 537193326Sed } 538193326Sed 539193326Sed // Get the local instance/class method declared in this interface. 540252723Sdim ObjCMethodDecl *getMethod(Selector Sel, bool isInstance, 541252723Sdim bool AllowHidden = false) const; 542252723Sdim ObjCMethodDecl *getInstanceMethod(Selector Sel, 543252723Sdim bool AllowHidden = false) const { 544252723Sdim return getMethod(Sel, true/*isInstance*/, AllowHidden); 545198092Srdivacky } 546252723Sdim ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const { 547252723Sdim return getMethod(Sel, false/*isInstance*/, AllowHidden); 548198092Srdivacky } 549252723Sdim bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const; 550195341Sed ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; 551193326Sed 552195341Sed ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; 553193326Sed 554245431Sdim typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap; 555252723Sdim 556263509Sdim typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*> 557263509Sdim ProtocolPropertyMap; 558263509Sdim 559252723Sdim typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder; 560252723Sdim 561245431Sdim /// This routine collects list of properties to be implemented in the class. 562245431Sdim /// This includes, class's and its conforming protocols' properties. 563245431Sdim /// Note, the superclass's properties are not included in the list. 564252723Sdim virtual void collectPropertiesToImplement(PropertyMap &PM, 565252723Sdim PropertyDeclOrder &PO) const {} 566245431Sdim 567226890Sdim SourceLocation getAtStartLoc() const { return AtStart; } 568226890Sdim void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } 569226890Sdim 570193326Sed // Marks the end of the container. 571202379Srdivacky SourceRange getAtEndRange() const { 572202379Srdivacky return AtEnd; 573202379Srdivacky } 574202379Srdivacky void setAtEndRange(SourceRange atEnd) { 575202379Srdivacky AtEnd = atEnd; 576202379Srdivacky } 577198092Srdivacky 578235633Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 579226890Sdim return SourceRange(AtStart, getAtEndRange().getEnd()); 580198092Srdivacky } 581198092Srdivacky 582193326Sed // Implement isa/cast/dyncast/etc. 583203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 584203955Srdivacky static bool classofKind(Kind K) { 585210299Sed return K >= firstObjCContainer && 586210299Sed K <= lastObjCContainer; 587193326Sed } 588193326Sed 589193326Sed static DeclContext *castToDeclContext(const ObjCContainerDecl *D) { 590193326Sed return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D)); 591193326Sed } 592193326Sed static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) { 593193326Sed return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC)); 594193326Sed } 595193326Sed}; 596193326Sed 597245431Sdim/// \brief Represents an ObjC class declaration. 598193326Sed/// 599245431Sdim/// For example: 600245431Sdim/// 601245431Sdim/// \code 602193326Sed/// // MostPrimitive declares no super class (not particularly useful). 603245431Sdim/// \@interface MostPrimitive 604193326Sed/// // no instance variables or methods. 605245431Sdim/// \@end 606193326Sed/// 607198092Srdivacky/// // NSResponder inherits from NSObject & implements NSCoding (a protocol). 608245431Sdim/// \@interface NSResponder : NSObject \<NSCoding> 609193326Sed/// { // instance variables are represented by ObjCIvarDecl. 610193326Sed/// id nextResponder; // nextResponder instance variable. 611193326Sed/// } 612193326Sed/// - (NSResponder *)nextResponder; // return a pointer to NSResponder. 613193326Sed/// - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer 614245431Sdim/// \@end // to an NSEvent. 615245431Sdim/// \endcode 616193326Sed/// 617245431Sdim/// Unlike C/C++, forward class declarations are accomplished with \@class. 618245431Sdim/// Unlike C/C++, \@class allows for a list of classes to be forward declared. 619193326Sed/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes 620193326Sed/// typically inherit from NSObject (an exception is NSProxy). 621193326Sed/// 622235633Sdimclass ObjCInterfaceDecl : public ObjCContainerDecl 623235633Sdim , public Redeclarable<ObjCInterfaceDecl> { 624235633Sdim virtual void anchor(); 625235633Sdim 626193326Sed /// TypeForDecl - This indicates the Type object that represents this 627193326Sed /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType 628218893Sdim mutable const Type *TypeForDecl; 629193326Sed friend class ASTContext; 630235633Sdim 631235633Sdim struct DefinitionData { 632235633Sdim /// \brief The definition of this class, for quick access from any 633235633Sdim /// declaration. 634235633Sdim ObjCInterfaceDecl *Definition; 635235633Sdim 636235633Sdim /// Class's super class. 637235633Sdim ObjCInterfaceDecl *SuperClass; 638198092Srdivacky 639245431Sdim /// Protocols referenced in the \@interface declaration 640235633Sdim ObjCProtocolList ReferencedProtocols; 641198092Srdivacky 642245431Sdim /// Protocols reference in both the \@interface and class extensions. 643235633Sdim ObjCList<ObjCProtocolDecl> AllReferencedProtocols; 644198092Srdivacky 645235633Sdim /// \brief List of categories and class extensions defined for this class. 646235633Sdim /// 647235633Sdim /// Categories are stored as a linked list in the AST, since the categories 648235633Sdim /// and class extensions come long after the initial interface declaration, 649235633Sdim /// and we avoid dynamically-resized arrays in the AST wherever possible. 650235633Sdim ObjCCategoryDecl *CategoryList; 651198092Srdivacky 652235633Sdim /// IvarList - List of all ivars defined by this class; including class 653235633Sdim /// extensions and implementation. This list is built lazily. 654235633Sdim ObjCIvarDecl *IvarList; 655193326Sed 656235633Sdim /// \brief Indicates that the contents of this Objective-C class will be 657235633Sdim /// completed by the external AST source when required. 658235633Sdim mutable bool ExternallyCompleted : 1; 659235633Sdim 660252723Sdim /// \brief Indicates that the ivar cache does not yet include ivars 661252723Sdim /// declared in the implementation. 662252723Sdim mutable bool IvarListMissingImplementation : 1; 663252723Sdim 664235633Sdim /// \brief The location of the superclass, if any. 665235633Sdim SourceLocation SuperClassLoc; 666235633Sdim 667235633Sdim /// \brief The location of the last location in this declaration, before 668235633Sdim /// the properties/methods. For example, this will be the '>', '}', or 669235633Sdim /// identifier, 670235633Sdim SourceLocation EndLoc; 671235633Sdim 672235633Sdim DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), 673252723Sdim ExternallyCompleted(), 674252723Sdim IvarListMissingImplementation(true) { } 675235633Sdim }; 676235633Sdim 677193326Sed ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, 678235633Sdim SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, 679235633Sdim bool isInternal); 680198092Srdivacky 681218893Sdim void LoadExternalDefinition() const; 682235633Sdim 683235633Sdim /// \brief Contains a pointer to the data associated with this class, 684235633Sdim /// which will be NULL if this class has not yet been defined. 685252723Sdim /// 686252723Sdim /// The bit indicates when we don't need to check for out-of-date 687252723Sdim /// declarations. It will be set unless modules are enabled. 688252723Sdim llvm::PointerIntPair<DefinitionData *, 1, bool> Data; 689235633Sdim 690235633Sdim DefinitionData &data() const { 691252723Sdim assert(Data.getPointer() && "Declaration has no definition!"); 692252723Sdim return *Data.getPointer(); 693235633Sdim } 694235633Sdim 695235633Sdim /// \brief Allocate the definition data for this class. 696235633Sdim void allocateDefinitionData(); 697235633Sdim 698235633Sdim typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base; 699235633Sdim virtual ObjCInterfaceDecl *getNextRedeclaration() { 700252723Sdim return RedeclLink.getNext(); 701235633Sdim } 702235633Sdim virtual ObjCInterfaceDecl *getPreviousDeclImpl() { 703235633Sdim return getPreviousDecl(); 704235633Sdim } 705235633Sdim virtual ObjCInterfaceDecl *getMostRecentDeclImpl() { 706235633Sdim return getMostRecentDecl(); 707235633Sdim } 708235633Sdim 709193326Sedpublic: 710235633Sdim static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC, 711193326Sed SourceLocation atLoc, 712198092Srdivacky IdentifierInfo *Id, 713235633Sdim ObjCInterfaceDecl *PrevDecl, 714193326Sed SourceLocation ClassLoc = SourceLocation(), 715193326Sed bool isInternal = false); 716235633Sdim 717235633Sdim static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); 718235633Sdim 719235633Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 720235633Sdim if (isThisDeclarationADefinition()) 721235633Sdim return ObjCContainerDecl::getSourceRange(); 722235633Sdim 723235633Sdim return SourceRange(getAtStartLoc(), getLocation()); 724235633Sdim } 725235633Sdim 726218893Sdim /// \brief Indicate that this Objective-C class is complete, but that 727218893Sdim /// the external AST source will be responsible for filling in its contents 728218893Sdim /// when a complete class is required. 729218893Sdim void setExternallyCompleted(); 730235633Sdim 731202879Srdivacky const ObjCProtocolList &getReferencedProtocols() const { 732235633Sdim assert(hasDefinition() && "Caller did not check for forward reference!"); 733235633Sdim if (data().ExternallyCompleted) 734218893Sdim LoadExternalDefinition(); 735235633Sdim 736235633Sdim return data().ReferencedProtocols; 737193326Sed } 738198092Srdivacky 739198092Srdivacky ObjCImplementationDecl *getImplementation() const; 740198092Srdivacky void setImplementation(ObjCImplementationDecl *ImplD); 741198092Srdivacky 742193326Sed ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; 743193326Sed 744198092Srdivacky // Get the local instance/class method declared in a category. 745198092Srdivacky ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; 746198092Srdivacky ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const; 747198092Srdivacky ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const { 748198092Srdivacky return isInstance ? getInstanceMethod(Sel) 749198092Srdivacky : getClassMethod(Sel); 750198092Srdivacky } 751198092Srdivacky 752202879Srdivacky typedef ObjCProtocolList::iterator protocol_iterator; 753235633Sdim 754212904Sdim protocol_iterator protocol_begin() const { 755235633Sdim // FIXME: Should make sure no callers ever do this. 756235633Sdim if (!hasDefinition()) 757235633Sdim return protocol_iterator(); 758235633Sdim 759235633Sdim if (data().ExternallyCompleted) 760218893Sdim LoadExternalDefinition(); 761218893Sdim 762235633Sdim return data().ReferencedProtocols.begin(); 763212904Sdim } 764212904Sdim protocol_iterator protocol_end() const { 765235633Sdim // FIXME: Should make sure no callers ever do this. 766235633Sdim if (!hasDefinition()) 767235633Sdim return protocol_iterator(); 768235633Sdim 769235633Sdim if (data().ExternallyCompleted) 770218893Sdim LoadExternalDefinition(); 771218893Sdim 772235633Sdim return data().ReferencedProtocols.end(); 773212904Sdim } 774212904Sdim 775202879Srdivacky typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 776212904Sdim 777235633Sdim protocol_loc_iterator protocol_loc_begin() const { 778235633Sdim // FIXME: Should make sure no callers ever do this. 779235633Sdim if (!hasDefinition()) 780235633Sdim return protocol_loc_iterator(); 781235633Sdim 782235633Sdim if (data().ExternallyCompleted) 783218893Sdim LoadExternalDefinition(); 784218893Sdim 785235633Sdim return data().ReferencedProtocols.loc_begin(); 786202879Srdivacky } 787212904Sdim 788235633Sdim protocol_loc_iterator protocol_loc_end() const { 789235633Sdim // FIXME: Should make sure no callers ever do this. 790235633Sdim if (!hasDefinition()) 791235633Sdim return protocol_loc_iterator(); 792235633Sdim 793235633Sdim if (data().ExternallyCompleted) 794218893Sdim LoadExternalDefinition(); 795218893Sdim 796235633Sdim return data().ReferencedProtocols.loc_end(); 797202879Srdivacky } 798235633Sdim 799212904Sdim typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator; 800235633Sdim 801212904Sdim all_protocol_iterator all_referenced_protocol_begin() const { 802235633Sdim // FIXME: Should make sure no callers ever do this. 803235633Sdim if (!hasDefinition()) 804235633Sdim return all_protocol_iterator(); 805235633Sdim 806235633Sdim if (data().ExternallyCompleted) 807218893Sdim LoadExternalDefinition(); 808218893Sdim 809235633Sdim return data().AllReferencedProtocols.empty() 810235633Sdim ? protocol_begin() 811235633Sdim : data().AllReferencedProtocols.begin(); 812212904Sdim } 813212904Sdim all_protocol_iterator all_referenced_protocol_end() const { 814235633Sdim // FIXME: Should make sure no callers ever do this. 815235633Sdim if (!hasDefinition()) 816235633Sdim return all_protocol_iterator(); 817235633Sdim 818235633Sdim if (data().ExternallyCompleted) 819218893Sdim LoadExternalDefinition(); 820218893Sdim 821235633Sdim return data().AllReferencedProtocols.empty() 822235633Sdim ? protocol_end() 823235633Sdim : data().AllReferencedProtocols.end(); 824212904Sdim } 825193326Sed 826204643Srdivacky typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 827212904Sdim 828235633Sdim ivar_iterator ivar_begin() const { 829235633Sdim if (const ObjCInterfaceDecl *Def = getDefinition()) 830235633Sdim return ivar_iterator(Def->decls_begin()); 831235633Sdim 832235633Sdim // FIXME: Should make sure no callers ever do this. 833235633Sdim return ivar_iterator(); 834235633Sdim } 835235633Sdim ivar_iterator ivar_end() const { 836235633Sdim if (const ObjCInterfaceDecl *Def = getDefinition()) 837235633Sdim return ivar_iterator(Def->decls_end()); 838212904Sdim 839235633Sdim // FIXME: Should make sure no callers ever do this. 840235633Sdim return ivar_iterator(); 841235633Sdim } 842235633Sdim 843204643Srdivacky unsigned ivar_size() const { 844204643Srdivacky return std::distance(ivar_begin(), ivar_end()); 845204643Srdivacky } 846235633Sdim 847204643Srdivacky bool ivar_empty() const { return ivar_begin() == ivar_end(); } 848235633Sdim 849226890Sdim ObjCIvarDecl *all_declared_ivar_begin(); 850226890Sdim const ObjCIvarDecl *all_declared_ivar_begin() const { 851226890Sdim // Even though this modifies IvarList, it's conceptually const: 852226890Sdim // the ivar chain is essentially a cached property of ObjCInterfaceDecl. 853226890Sdim return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin(); 854226890Sdim } 855235633Sdim void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; } 856235633Sdim 857193326Sed /// setProtocolList - Set the list of protocols that this interface 858193326Sed /// implements. 859193326Sed void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num, 860202879Srdivacky const SourceLocation *Locs, ASTContext &C) { 861235633Sdim data().ReferencedProtocols.set(List, Num, Locs, C); 862193326Sed } 863198092Srdivacky 864198092Srdivacky /// mergeClassExtensionProtocolList - Merge class extension's protocol list 865198092Srdivacky /// into the protocol list for this class. 866235633Sdim void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, 867202879Srdivacky unsigned Num, 868202879Srdivacky ASTContext &C); 869198092Srdivacky 870235633Sdim /// \brief Determine whether this particular declaration of this class is 871235633Sdim /// actually also a definition. 872235633Sdim bool isThisDeclarationADefinition() const { 873252723Sdim return getDefinition() == this; 874235633Sdim } 875235633Sdim 876235633Sdim /// \brief Determine whether this class has been defined. 877252723Sdim bool hasDefinition() const { 878252723Sdim // If the name of this class is out-of-date, bring it up-to-date, which 879252723Sdim // might bring in a definition. 880252723Sdim // Note: a null value indicates that we don't have a definition and that 881252723Sdim // modules are enabled. 882252723Sdim if (!Data.getOpaqueValue()) { 883252723Sdim if (IdentifierInfo *II = getIdentifier()) { 884252723Sdim if (II->isOutOfDate()) { 885252723Sdim updateOutOfDate(*II); 886252723Sdim } 887252723Sdim } 888252723Sdim } 889252723Sdim 890252723Sdim return Data.getPointer(); 891252723Sdim } 892235633Sdim 893235633Sdim /// \brief Retrieve the definition of this class, or NULL if this class 894245431Sdim /// has been forward-declared (with \@class) but not yet defined (with 895245431Sdim /// \@interface). 896235633Sdim ObjCInterfaceDecl *getDefinition() { 897252723Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 898235633Sdim } 899198092Srdivacky 900235633Sdim /// \brief Retrieve the definition of this class, or NULL if this class 901245431Sdim /// has been forward-declared (with \@class) but not yet defined (with 902245431Sdim /// \@interface). 903235633Sdim const ObjCInterfaceDecl *getDefinition() const { 904252723Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 905235633Sdim } 906235633Sdim 907235633Sdim /// \brief Starts the definition of this Objective-C class, taking it from 908245431Sdim /// a forward declaration (\@class) to a definition (\@interface). 909235633Sdim void startDefinition(); 910235633Sdim 911235633Sdim ObjCInterfaceDecl *getSuperClass() const { 912235633Sdim // FIXME: Should make sure no callers ever do this. 913235633Sdim if (!hasDefinition()) 914235633Sdim return 0; 915235633Sdim 916235633Sdim if (data().ExternallyCompleted) 917218893Sdim LoadExternalDefinition(); 918218893Sdim 919235633Sdim return data().SuperClass; 920218893Sdim } 921198092Srdivacky 922235633Sdim void setSuperClass(ObjCInterfaceDecl * superCls) { 923235633Sdim data().SuperClass = 924235633Sdim (superCls && superCls->hasDefinition()) ? superCls->getDefinition() 925235633Sdim : superCls; 926235633Sdim } 927235633Sdim 928252723Sdim /// \brief Iterator that walks over the list of categories, filtering out 929252723Sdim /// those that do not meet specific criteria. 930252723Sdim /// 931252723Sdim /// This class template is used for the various permutations of category 932252723Sdim /// and extension iterators. 933252723Sdim template<bool (*Filter)(ObjCCategoryDecl *)> 934252723Sdim class filtered_category_iterator { 935252723Sdim ObjCCategoryDecl *Current; 936252723Sdim 937252723Sdim void findAcceptableCategory(); 938252723Sdim 939252723Sdim public: 940252723Sdim typedef ObjCCategoryDecl * value_type; 941252723Sdim typedef value_type reference; 942252723Sdim typedef value_type pointer; 943252723Sdim typedef std::ptrdiff_t difference_type; 944252723Sdim typedef std::input_iterator_tag iterator_category; 945252723Sdim 946252723Sdim filtered_category_iterator() : Current(0) { } 947252723Sdim explicit filtered_category_iterator(ObjCCategoryDecl *Current) 948252723Sdim : Current(Current) 949252723Sdim { 950252723Sdim findAcceptableCategory(); 951252723Sdim } 952252723Sdim 953252723Sdim reference operator*() const { return Current; } 954252723Sdim pointer operator->() const { return Current; } 955252723Sdim 956252723Sdim filtered_category_iterator &operator++(); 957252723Sdim 958252723Sdim filtered_category_iterator operator++(int) { 959252723Sdim filtered_category_iterator Tmp = *this; 960252723Sdim ++(*this); 961252723Sdim return Tmp; 962252723Sdim } 963252723Sdim 964252723Sdim friend bool operator==(filtered_category_iterator X, 965252723Sdim filtered_category_iterator Y) { 966252723Sdim return X.Current == Y.Current; 967252723Sdim } 968252723Sdim 969252723Sdim friend bool operator!=(filtered_category_iterator X, 970252723Sdim filtered_category_iterator Y) { 971252723Sdim return X.Current != Y.Current; 972252723Sdim } 973252723Sdim }; 974252723Sdim 975252723Sdimprivate: 976252723Sdim /// \brief Test whether the given category is visible. 977252723Sdim /// 978252723Sdim /// Used in the \c visible_categories_iterator. 979252723Sdim static bool isVisibleCategory(ObjCCategoryDecl *Cat); 980252723Sdim 981252723Sdimpublic: 982252723Sdim /// \brief Iterator that walks over the list of categories and extensions 983252723Sdim /// that are visible, i.e., not hidden in a non-imported submodule. 984252723Sdim typedef filtered_category_iterator<isVisibleCategory> 985252723Sdim visible_categories_iterator; 986252723Sdim 987252723Sdim /// \brief Retrieve an iterator to the beginning of the visible-categories 988252723Sdim /// list. 989252723Sdim visible_categories_iterator visible_categories_begin() const { 990252723Sdim return visible_categories_iterator(getCategoryListRaw()); 991252723Sdim } 992252723Sdim 993252723Sdim /// \brief Retrieve an iterator to the end of the visible-categories list. 994252723Sdim visible_categories_iterator visible_categories_end() const { 995252723Sdim return visible_categories_iterator(); 996252723Sdim } 997252723Sdim 998252723Sdim /// \brief Determine whether the visible-categories list is empty. 999252723Sdim bool visible_categories_empty() const { 1000252723Sdim return visible_categories_begin() == visible_categories_end(); 1001252723Sdim } 1002252723Sdim 1003252723Sdimprivate: 1004252723Sdim /// \brief Test whether the given category... is a category. 1005252723Sdim /// 1006252723Sdim /// Used in the \c known_categories_iterator. 1007252723Sdim static bool isKnownCategory(ObjCCategoryDecl *) { return true; } 1008252723Sdim 1009252723Sdimpublic: 1010252723Sdim /// \brief Iterator that walks over all of the known categories and 1011252723Sdim /// extensions, including those that are hidden. 1012252723Sdim typedef filtered_category_iterator<isKnownCategory> known_categories_iterator; 1013252723Sdim 1014252723Sdim /// \brief Retrieve an iterator to the beginning of the known-categories 1015252723Sdim /// list. 1016252723Sdim known_categories_iterator known_categories_begin() const { 1017252723Sdim return known_categories_iterator(getCategoryListRaw()); 1018252723Sdim } 1019252723Sdim 1020252723Sdim /// \brief Retrieve an iterator to the end of the known-categories list. 1021252723Sdim known_categories_iterator known_categories_end() const { 1022252723Sdim return known_categories_iterator(); 1023252723Sdim } 1024252723Sdim 1025252723Sdim /// \brief Determine whether the known-categories list is empty. 1026252723Sdim bool known_categories_empty() const { 1027252723Sdim return known_categories_begin() == known_categories_end(); 1028252723Sdim } 1029252723Sdim 1030252723Sdimprivate: 1031252723Sdim /// \brief Test whether the given category is a visible extension. 1032252723Sdim /// 1033252723Sdim /// Used in the \c visible_extensions_iterator. 1034252723Sdim static bool isVisibleExtension(ObjCCategoryDecl *Cat); 1035252723Sdim 1036252723Sdimpublic: 1037252723Sdim /// \brief Iterator that walks over all of the visible extensions, skipping 1038252723Sdim /// any that are known but hidden. 1039252723Sdim typedef filtered_category_iterator<isVisibleExtension> 1040252723Sdim visible_extensions_iterator; 1041252723Sdim 1042252723Sdim /// \brief Retrieve an iterator to the beginning of the visible-extensions 1043252723Sdim /// list. 1044252723Sdim visible_extensions_iterator visible_extensions_begin() const { 1045252723Sdim return visible_extensions_iterator(getCategoryListRaw()); 1046252723Sdim } 1047252723Sdim 1048252723Sdim /// \brief Retrieve an iterator to the end of the visible-extensions list. 1049252723Sdim visible_extensions_iterator visible_extensions_end() const { 1050252723Sdim return visible_extensions_iterator(); 1051252723Sdim } 1052252723Sdim 1053252723Sdim /// \brief Determine whether the visible-extensions list is empty. 1054252723Sdim bool visible_extensions_empty() const { 1055252723Sdim return visible_extensions_begin() == visible_extensions_end(); 1056252723Sdim } 1057252723Sdim 1058252723Sdimprivate: 1059252723Sdim /// \brief Test whether the given category is an extension. 1060252723Sdim /// 1061252723Sdim /// Used in the \c known_extensions_iterator. 1062252723Sdim static bool isKnownExtension(ObjCCategoryDecl *Cat); 1063252723Sdim 1064252723Sdimpublic: 1065252723Sdim /// \brief Iterator that walks over all of the known extensions. 1066252723Sdim typedef filtered_category_iterator<isKnownExtension> 1067252723Sdim known_extensions_iterator; 1068252723Sdim 1069252723Sdim /// \brief Retrieve an iterator to the beginning of the known-extensions 1070252723Sdim /// list. 1071252723Sdim known_extensions_iterator known_extensions_begin() const { 1072252723Sdim return known_extensions_iterator(getCategoryListRaw()); 1073252723Sdim } 1074252723Sdim 1075252723Sdim /// \brief Retrieve an iterator to the end of the known-extensions list. 1076252723Sdim known_extensions_iterator known_extensions_end() const { 1077252723Sdim return known_extensions_iterator(); 1078252723Sdim } 1079252723Sdim 1080252723Sdim /// \brief Determine whether the known-extensions list is empty. 1081252723Sdim bool known_extensions_empty() const { 1082252723Sdim return known_extensions_begin() == known_extensions_end(); 1083252723Sdim } 1084252723Sdim 1085252723Sdim /// \brief Retrieve the raw pointer to the start of the category/extension 1086252723Sdim /// list. 1087252723Sdim ObjCCategoryDecl* getCategoryListRaw() const { 1088235633Sdim // FIXME: Should make sure no callers ever do this. 1089235633Sdim if (!hasDefinition()) 1090235633Sdim return 0; 1091235633Sdim 1092235633Sdim if (data().ExternallyCompleted) 1093218893Sdim LoadExternalDefinition(); 1094218893Sdim 1095235633Sdim return data().CategoryList; 1096218893Sdim } 1097235633Sdim 1098252723Sdim /// \brief Set the raw pointer to the start of the category/extension 1099252723Sdim /// list. 1100252723Sdim void setCategoryListRaw(ObjCCategoryDecl *category) { 1101235633Sdim data().CategoryList = category; 1102193326Sed } 1103235633Sdim 1104205219Srdivacky ObjCPropertyDecl 1105205219Srdivacky *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; 1106205219Srdivacky 1107252723Sdim virtual void collectPropertiesToImplement(PropertyMap &PM, 1108252723Sdim PropertyDeclOrder &PO) const; 1109245431Sdim 1110193326Sed /// isSuperClassOf - Return true if this class is the specified class or is a 1111193326Sed /// super class of the specified interface class. 1112193326Sed bool isSuperClassOf(const ObjCInterfaceDecl *I) const { 1113193326Sed // If RHS is derived from LHS it is OK; else it is not OK. 1114193326Sed while (I != NULL) { 1115235633Sdim if (declaresSameEntity(this, I)) 1116193326Sed return true; 1117235633Sdim 1118193326Sed I = I->getSuperClass(); 1119193326Sed } 1120193326Sed return false; 1121193326Sed } 1122198092Srdivacky 1123224145Sdim /// isArcWeakrefUnavailable - Checks for a class or one of its super classes 1124224145Sdim /// to be incompatible with __weak references. Returns true if it is. 1125252723Sdim bool isArcWeakrefUnavailable() const; 1126224145Sdim 1127235633Sdim /// isObjCRequiresPropertyDefs - Checks that a class or one of its super 1128245431Sdim /// classes must not be auto-synthesized. Returns class decl. if it must not 1129245431Sdim /// be; 0, otherwise. 1130252723Sdim const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const; 1131235633Sdim 1132195341Sed ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName, 1133193326Sed ObjCInterfaceDecl *&ClassDeclared); 1134195341Sed ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) { 1135193326Sed ObjCInterfaceDecl *ClassDeclared; 1136195341Sed return lookupInstanceVariable(IVarName, ClassDeclared); 1137193326Sed } 1138193326Sed 1139263509Sdim ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name); 1140263509Sdim 1141193326Sed // Lookup a method. First, we search locally. If a method isn't 1142193326Sed // found, we search referenced protocols and class categories. 1143235633Sdim ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, 1144252723Sdim bool shallowCategoryLookup= false, 1145252723Sdim const ObjCCategoryDecl *C= 0) const; 1146235633Sdim ObjCMethodDecl *lookupInstanceMethod(Selector Sel, 1147235633Sdim bool shallowCategoryLookup = false) const { 1148235633Sdim return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); 1149198092Srdivacky } 1150235633Sdim ObjCMethodDecl *lookupClassMethod(Selector Sel, 1151235633Sdim bool shallowCategoryLookup = false) const { 1152235633Sdim return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup); 1153198092Srdivacky } 1154193326Sed ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); 1155235633Sdim 1156245431Sdim /// \brief Lookup a method in the classes implementation hierarchy. 1157245431Sdim ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, 1158245431Sdim bool Instance=true) const; 1159193326Sed 1160245431Sdim ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) { 1161245431Sdim return lookupPrivateMethod(Sel, false); 1162245431Sdim } 1163245431Sdim 1164252723Sdim /// \brief Lookup a setter or getter in the class hierarchy, 1165252723Sdim /// including in all categories except for category passed 1166252723Sdim /// as argument. 1167252723Sdim ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, 1168252723Sdim const ObjCCategoryDecl *Cat) const { 1169252723Sdim return lookupMethod(Sel, true/*isInstance*/, 1170252723Sdim false/*shallowCategoryLookup*/, Cat); 1171252723Sdim } 1172252723Sdim 1173235633Sdim SourceLocation getEndOfDefinitionLoc() const { 1174235633Sdim if (!hasDefinition()) 1175235633Sdim return getLocation(); 1176235633Sdim 1177235633Sdim return data().EndLoc; 1178235633Sdim } 1179235633Sdim 1180235633Sdim void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; } 1181198092Srdivacky 1182235633Sdim void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; } 1183235633Sdim SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; } 1184198092Srdivacky 1185193326Sed /// isImplicitInterfaceDecl - check that this is an implicitly declared 1186245431Sdim /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation 1187245431Sdim /// declaration without an \@interface declaration. 1188235633Sdim bool isImplicitInterfaceDecl() const { 1189252723Sdim return hasDefinition() ? data().Definition->isImplicit() : isImplicit(); 1190235633Sdim } 1191198092Srdivacky 1192198092Srdivacky /// ClassImplementsProtocol - Checks that 'lProto' protocol 1193198092Srdivacky /// has been implemented in IDecl class, its super class or categories (if 1194198092Srdivacky /// lookupCategory is true). 1195198092Srdivacky bool ClassImplementsProtocol(ObjCProtocolDecl *lProto, 1196198092Srdivacky bool lookupCategory, 1197198092Srdivacky bool RHSIsQualifiedID = false); 1198198092Srdivacky 1199235633Sdim typedef redeclarable_base::redecl_iterator redecl_iterator; 1200235633Sdim using redeclarable_base::redecls_begin; 1201235633Sdim using redeclarable_base::redecls_end; 1202235633Sdim using redeclarable_base::getPreviousDecl; 1203235633Sdim using redeclarable_base::getMostRecentDecl; 1204263509Sdim using redeclarable_base::isFirstDecl; 1205235633Sdim 1206235633Sdim /// Retrieves the canonical declaration of this Objective-C class. 1207263509Sdim ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); } 1208263509Sdim const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); } 1209235633Sdim 1210193326Sed // Low-level accessor 1211218893Sdim const Type *getTypeForDecl() const { return TypeForDecl; } 1212218893Sdim void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; } 1213193326Sed 1214203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1215203955Srdivacky static bool classofKind(Kind K) { return K == ObjCInterface; } 1216212904Sdim 1217235633Sdim friend class ASTReader; 1218212904Sdim friend class ASTDeclReader; 1219212904Sdim friend class ASTDeclWriter; 1220193326Sed}; 1221193326Sed 1222193326Sed/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC 1223193326Sed/// instance variables are identical to C. The only exception is Objective-C 1224193326Sed/// supports C++ style access control. For example: 1225193326Sed/// 1226245431Sdim/// \@interface IvarExample : NSObject 1227193326Sed/// { 1228193326Sed/// id defaultToProtected; 1229245431Sdim/// \@public: 1230193326Sed/// id canBePublic; // same as C++. 1231245431Sdim/// \@protected: 1232193326Sed/// id canBeProtected; // same as C++. 1233245431Sdim/// \@package: 1234193326Sed/// id canBePackage; // framework visibility (not available in C++). 1235193326Sed/// } 1236193326Sed/// 1237193326Sedclass ObjCIvarDecl : public FieldDecl { 1238235633Sdim virtual void anchor(); 1239235633Sdim 1240193326Sedpublic: 1241193326Sed enum AccessControl { 1242193326Sed None, Private, Protected, Public, Package 1243193326Sed }; 1244198092Srdivacky 1245193326Sedprivate: 1246221345Sdim ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, 1247221345Sdim SourceLocation IdLoc, IdentifierInfo *Id, 1248212904Sdim QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, 1249263509Sdim bool synthesized, 1250263509Sdim bool backingIvarReferencedInAccessor) 1251221345Sdim : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, 1252245431Sdim /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), 1253263509Sdim NextIvar(0), DeclAccess(ac), Synthesized(synthesized), 1254263509Sdim BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {} 1255198092Srdivacky 1256193326Sedpublic: 1257206125Srdivacky static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC, 1258221345Sdim SourceLocation StartLoc, SourceLocation IdLoc, 1259221345Sdim IdentifierInfo *Id, QualType T, 1260200583Srdivacky TypeSourceInfo *TInfo, 1261212904Sdim AccessControl ac, Expr *BW = NULL, 1262263509Sdim bool synthesized=false, 1263263509Sdim bool backingIvarReferencedInAccessor=false); 1264198092Srdivacky 1265235633Sdim static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1266235633Sdim 1267206125Srdivacky /// \brief Return the class interface that this ivar is logically contained 1268206125Srdivacky /// in; this is either the interface where the ivar was declared, or the 1269206125Srdivacky /// interface the ivar is conceptually a part of in the case of synthesized 1270206125Srdivacky /// ivars. 1271206125Srdivacky const ObjCInterfaceDecl *getContainingInterface() const; 1272235633Sdim 1273212904Sdim ObjCIvarDecl *getNextIvar() { return NextIvar; } 1274226890Sdim const ObjCIvarDecl *getNextIvar() const { return NextIvar; } 1275212904Sdim void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; } 1276206125Srdivacky 1277193326Sed void setAccessControl(AccessControl ac) { DeclAccess = ac; } 1278193326Sed 1279193326Sed AccessControl getAccessControl() const { return AccessControl(DeclAccess); } 1280193326Sed 1281193326Sed AccessControl getCanonicalAccessControl() const { 1282193326Sed return DeclAccess == None ? Protected : AccessControl(DeclAccess); 1283193326Sed } 1284198092Srdivacky 1285263509Sdim void setBackingIvarReferencedInAccessor(bool val) { 1286263509Sdim BackingIvarReferencedInAccessor = val; 1287263509Sdim } 1288263509Sdim bool getBackingIvarReferencedInAccessor() const { 1289263509Sdim return BackingIvarReferencedInAccessor; 1290263509Sdim } 1291263509Sdim 1292212904Sdim void setSynthesize(bool synth) { Synthesized = synth; } 1293212904Sdim bool getSynthesize() const { return Synthesized; } 1294235633Sdim 1295193326Sed // Implement isa/cast/dyncast/etc. 1296203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1297203955Srdivacky static bool classofKind(Kind K) { return K == ObjCIvar; } 1298193326Sedprivate: 1299235633Sdim /// NextIvar - Next Ivar in the list of ivars declared in class; class's 1300212904Sdim /// extensions and class's implementation 1301212904Sdim ObjCIvarDecl *NextIvar; 1302235633Sdim 1303193326Sed // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum 1304193326Sed unsigned DeclAccess : 3; 1305212904Sdim unsigned Synthesized : 1; 1306263509Sdim unsigned BackingIvarReferencedInAccessor : 1; 1307193326Sed}; 1308193326Sed 1309198092Srdivacky 1310245431Sdim/// \brief Represents a field declaration created by an \@defs(...). 1311193326Sedclass ObjCAtDefsFieldDecl : public FieldDecl { 1312235633Sdim virtual void anchor(); 1313221345Sdim ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc, 1314221345Sdim SourceLocation IdLoc, IdentifierInfo *Id, 1315193326Sed QualType T, Expr *BW) 1316221345Sdim : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, 1317200583Srdivacky /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? 1318245431Sdim BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {} 1319198092Srdivacky 1320193326Sedpublic: 1321193326Sed static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, 1322221345Sdim SourceLocation StartLoc, 1323221345Sdim SourceLocation IdLoc, IdentifierInfo *Id, 1324221345Sdim QualType T, Expr *BW); 1325198092Srdivacky 1326235633Sdim static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1327235633Sdim 1328193326Sed // Implement isa/cast/dyncast/etc. 1329203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1330203955Srdivacky static bool classofKind(Kind K) { return K == ObjCAtDefsField; } 1331193326Sed}; 1332193326Sed 1333245431Sdim/// \brief Represents an Objective-C protocol declaration. 1334193326Sed/// 1335245431Sdim/// Objective-C protocols declare a pure abstract type (i.e., no instance 1336245431Sdim/// variables are permitted). Protocols originally drew inspiration from 1337245431Sdim/// C++ pure virtual functions (a C++ feature with nice semantics and lousy 1338245431Sdim/// syntax:-). Here is an example: 1339245431Sdim/// 1340245431Sdim/// \code 1341245431Sdim/// \@protocol NSDraggingInfo <refproto1, refproto2> 1342193326Sed/// - (NSWindow *)draggingDestinationWindow; 1343193326Sed/// - (NSImage *)draggedImage; 1344245431Sdim/// \@end 1345245431Sdim/// \endcode 1346193326Sed/// 1347193326Sed/// This says that NSDraggingInfo requires two methods and requires everything 1348193326Sed/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as 1349193326Sed/// well. 1350193326Sed/// 1351245431Sdim/// \code 1352245431Sdim/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo> 1353245431Sdim/// \@end 1354245431Sdim/// \endcode 1355193326Sed/// 1356193326Sed/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and 1357193326Sed/// protocols are in distinct namespaces. For example, Cocoa defines both 1358198092Srdivacky/// an NSObject protocol and class (which isn't allowed in Java). As a result, 1359193326Sed/// protocols are referenced using angle brackets as follows: 1360193326Sed/// 1361245431Sdim/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; 1362193326Sed/// 1363235633Sdimclass ObjCProtocolDecl : public ObjCContainerDecl, 1364235633Sdim public Redeclarable<ObjCProtocolDecl> { 1365235633Sdim virtual void anchor(); 1366198092Srdivacky 1367235633Sdim struct DefinitionData { 1368235633Sdim // \brief The declaration that defines this protocol. 1369235633Sdim ObjCProtocolDecl *Definition; 1370198092Srdivacky 1371235633Sdim /// \brief Referenced protocols 1372235633Sdim ObjCProtocolList ReferencedProtocols; 1373235633Sdim }; 1374198092Srdivacky 1375252723Sdim /// \brief Contains a pointer to the data associated with this class, 1376252723Sdim /// which will be NULL if this class has not yet been defined. 1377252723Sdim /// 1378252723Sdim /// The bit indicates when we don't need to check for out-of-date 1379252723Sdim /// declarations. It will be set unless modules are enabled. 1380252723Sdim llvm::PointerIntPair<DefinitionData *, 1, bool> Data; 1381252723Sdim 1382235633Sdim DefinitionData &data() const { 1383252723Sdim assert(Data.getPointer() && "Objective-C protocol has no definition!"); 1384252723Sdim return *Data.getPointer(); 1385235633Sdim } 1386235633Sdim 1387226890Sdim ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, 1388235633Sdim SourceLocation nameLoc, SourceLocation atStartLoc, 1389235633Sdim ObjCProtocolDecl *PrevDecl); 1390235633Sdim 1391235633Sdim void allocateDefinitionData(); 1392235633Sdim 1393235633Sdim typedef Redeclarable<ObjCProtocolDecl> redeclarable_base; 1394235633Sdim virtual ObjCProtocolDecl *getNextRedeclaration() { 1395235633Sdim return RedeclLink.getNext(); 1396193326Sed } 1397235633Sdim virtual ObjCProtocolDecl *getPreviousDeclImpl() { 1398235633Sdim return getPreviousDecl(); 1399235633Sdim } 1400235633Sdim virtual ObjCProtocolDecl *getMostRecentDeclImpl() { 1401235633Sdim return getMostRecentDecl(); 1402235633Sdim } 1403252723Sdim 1404193326Sedpublic: 1405198092Srdivacky static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, 1406226890Sdim IdentifierInfo *Id, 1407226890Sdim SourceLocation nameLoc, 1408235633Sdim SourceLocation atStartLoc, 1409235633Sdim ObjCProtocolDecl *PrevDecl); 1410193326Sed 1411235633Sdim static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1412235633Sdim 1413202879Srdivacky const ObjCProtocolList &getReferencedProtocols() const { 1414235633Sdim assert(hasDefinition() && "No definition available!"); 1415235633Sdim return data().ReferencedProtocols; 1416193326Sed } 1417202879Srdivacky typedef ObjCProtocolList::iterator protocol_iterator; 1418235633Sdim protocol_iterator protocol_begin() const { 1419235633Sdim if (!hasDefinition()) 1420235633Sdim return protocol_iterator(); 1421235633Sdim 1422235633Sdim return data().ReferencedProtocols.begin(); 1423235633Sdim } 1424235633Sdim protocol_iterator protocol_end() const { 1425235633Sdim if (!hasDefinition()) 1426235633Sdim return protocol_iterator(); 1427235633Sdim 1428235633Sdim return data().ReferencedProtocols.end(); 1429235633Sdim } 1430202879Srdivacky typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 1431235633Sdim protocol_loc_iterator protocol_loc_begin() const { 1432235633Sdim if (!hasDefinition()) 1433235633Sdim return protocol_loc_iterator(); 1434235633Sdim 1435235633Sdim return data().ReferencedProtocols.loc_begin(); 1436202879Srdivacky } 1437235633Sdim protocol_loc_iterator protocol_loc_end() const { 1438235633Sdim if (!hasDefinition()) 1439235633Sdim return protocol_loc_iterator(); 1440235633Sdim 1441235633Sdim return data().ReferencedProtocols.loc_end(); 1442202879Srdivacky } 1443235633Sdim unsigned protocol_size() const { 1444235633Sdim if (!hasDefinition()) 1445235633Sdim return 0; 1446235633Sdim 1447235633Sdim return data().ReferencedProtocols.size(); 1448235633Sdim } 1449198092Srdivacky 1450193326Sed /// setProtocolList - Set the list of protocols that this interface 1451193326Sed /// implements. 1452193326Sed void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 1453202879Srdivacky const SourceLocation *Locs, ASTContext &C) { 1454252723Sdim assert(hasDefinition() && "Protocol is not defined"); 1455235633Sdim data().ReferencedProtocols.set(List, Num, Locs, C); 1456193326Sed } 1457198092Srdivacky 1458193326Sed ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName); 1459198092Srdivacky 1460193326Sed // Lookup a method. First, we search locally. If a method isn't 1461193326Sed // found, we search referenced protocols and class categories. 1462198092Srdivacky ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const; 1463198092Srdivacky ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { 1464198092Srdivacky return lookupMethod(Sel, true/*isInstance*/); 1465198092Srdivacky } 1466198092Srdivacky ObjCMethodDecl *lookupClassMethod(Selector Sel) const { 1467198092Srdivacky return lookupMethod(Sel, false/*isInstance*/); 1468198092Srdivacky } 1469193326Sed 1470235633Sdim /// \brief Determine whether this protocol has a definition. 1471252723Sdim bool hasDefinition() const { 1472252723Sdim // If the name of this protocol is out-of-date, bring it up-to-date, which 1473252723Sdim // might bring in a definition. 1474252723Sdim // Note: a null value indicates that we don't have a definition and that 1475252723Sdim // modules are enabled. 1476252723Sdim if (!Data.getOpaqueValue()) { 1477252723Sdim if (IdentifierInfo *II = getIdentifier()) { 1478252723Sdim if (II->isOutOfDate()) { 1479252723Sdim updateOutOfDate(*II); 1480252723Sdim } 1481252723Sdim } 1482252723Sdim } 1483198092Srdivacky 1484252723Sdim return Data.getPointer(); 1485252723Sdim } 1486252723Sdim 1487235633Sdim /// \brief Retrieve the definition of this protocol, if any. 1488235633Sdim ObjCProtocolDecl *getDefinition() { 1489252723Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 1490235633Sdim } 1491198092Srdivacky 1492235633Sdim /// \brief Retrieve the definition of this protocol, if any. 1493235633Sdim const ObjCProtocolDecl *getDefinition() const { 1494252723Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 1495235633Sdim } 1496198092Srdivacky 1497235633Sdim /// \brief Determine whether this particular declaration is also the 1498235633Sdim /// definition. 1499235633Sdim bool isThisDeclarationADefinition() const { 1500235633Sdim return getDefinition() == this; 1501235633Sdim } 1502199482Srdivacky 1503235633Sdim /// \brief Starts the definition of this Objective-C protocol. 1504235633Sdim void startDefinition(); 1505198092Srdivacky 1506235633Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 1507235633Sdim if (isThisDeclarationADefinition()) 1508235633Sdim return ObjCContainerDecl::getSourceRange(); 1509235633Sdim 1510235633Sdim return SourceRange(getAtStartLoc(), getLocation()); 1511202879Srdivacky } 1512235633Sdim 1513235633Sdim typedef redeclarable_base::redecl_iterator redecl_iterator; 1514235633Sdim using redeclarable_base::redecls_begin; 1515235633Sdim using redeclarable_base::redecls_end; 1516235633Sdim using redeclarable_base::getPreviousDecl; 1517235633Sdim using redeclarable_base::getMostRecentDecl; 1518263509Sdim using redeclarable_base::isFirstDecl; 1519202879Srdivacky 1520235633Sdim /// Retrieves the canonical declaration of this Objective-C protocol. 1521263509Sdim ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); } 1522263509Sdim const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); } 1523202879Srdivacky 1524252723Sdim virtual void collectPropertiesToImplement(PropertyMap &PM, 1525252723Sdim PropertyDeclOrder &PO) const; 1526263509Sdim 1527263509Sdimvoid collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, 1528263509Sdim ProtocolPropertyMap &PM) const; 1529245431Sdim 1530235633Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1531235633Sdim static bool classofKind(Kind K) { return K == ObjCProtocol; } 1532193326Sed 1533235633Sdim friend class ASTReader; 1534235633Sdim friend class ASTDeclReader; 1535235633Sdim friend class ASTDeclWriter; 1536193326Sed}; 1537193326Sed 1538193326Sed/// ObjCCategoryDecl - Represents a category declaration. A category allows 1539193326Sed/// you to add methods to an existing class (without subclassing or modifying 1540198092Srdivacky/// the original class interface or implementation:-). Categories don't allow 1541193326Sed/// you to add instance data. The following example adds "myMethod" to all 1542193326Sed/// NSView's within a process: 1543193326Sed/// 1544245431Sdim/// \@interface NSView (MyViewMethods) 1545193326Sed/// - myMethod; 1546245431Sdim/// \@end 1547193326Sed/// 1548199512Srdivacky/// Categories also allow you to split the implementation of a class across 1549193326Sed/// several files (a feature more naturally supported in C++). 1550193326Sed/// 1551193326Sed/// Categories were originally inspired by dynamic languages such as Common 1552198092Srdivacky/// Lisp and Smalltalk. More traditional class-based languages (C++, Java) 1553193326Sed/// don't support this level of dynamism, which is both powerful and dangerous. 1554193326Sed/// 1555193326Sedclass ObjCCategoryDecl : public ObjCContainerDecl { 1556235633Sdim virtual void anchor(); 1557235633Sdim 1558193326Sed /// Interface belonging to this category 1559193326Sed ObjCInterfaceDecl *ClassInterface; 1560198092Srdivacky 1561193326Sed /// referenced protocols in this category. 1562202879Srdivacky ObjCProtocolList ReferencedProtocols; 1563198092Srdivacky 1564193326Sed /// Next category belonging to this class. 1565193326Sed /// FIXME: this should not be a singly-linked list. Move storage elsewhere. 1566193326Sed ObjCCategoryDecl *NextClassCategory; 1567198092Srdivacky 1568202879Srdivacky /// \brief The location of the category name in this declaration. 1569202879Srdivacky SourceLocation CategoryNameLoc; 1570202879Srdivacky 1571235633Sdim /// class extension may have private ivars. 1572235633Sdim SourceLocation IvarLBraceLoc; 1573235633Sdim SourceLocation IvarRBraceLoc; 1574235633Sdim 1575235633Sdim ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, 1576202879Srdivacky SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, 1577235633Sdim IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, 1578235633Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1579235633Sdim SourceLocation IvarRBraceLoc=SourceLocation()) 1580226890Sdim : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), 1581245431Sdim ClassInterface(IDecl), NextClassCategory(0), 1582235633Sdim CategoryNameLoc(CategoryNameLoc), 1583235633Sdim IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { 1584193326Sed } 1585252723Sdim 1586193326Sedpublic: 1587198092Srdivacky 1588193326Sed static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, 1589235633Sdim SourceLocation AtLoc, 1590202879Srdivacky SourceLocation ClassNameLoc, 1591202879Srdivacky SourceLocation CategoryNameLoc, 1592226890Sdim IdentifierInfo *Id, 1593235633Sdim ObjCInterfaceDecl *IDecl, 1594235633Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1595235633Sdim SourceLocation IvarRBraceLoc=SourceLocation()); 1596235633Sdim static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1597198092Srdivacky 1598193326Sed ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 1599193326Sed const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 1600198092Srdivacky 1601198092Srdivacky ObjCCategoryImplDecl *getImplementation() const; 1602198092Srdivacky void setImplementation(ObjCCategoryImplDecl *ImplD); 1603198092Srdivacky 1604193326Sed /// setProtocolList - Set the list of protocols that this interface 1605193326Sed /// implements. 1606193326Sed void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num, 1607202879Srdivacky const SourceLocation *Locs, ASTContext &C) { 1608202879Srdivacky ReferencedProtocols.set(List, Num, Locs, C); 1609193326Sed } 1610198092Srdivacky 1611202879Srdivacky const ObjCProtocolList &getReferencedProtocols() const { 1612193326Sed return ReferencedProtocols; 1613193326Sed } 1614198092Srdivacky 1615202879Srdivacky typedef ObjCProtocolList::iterator protocol_iterator; 1616193326Sed protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();} 1617193326Sed protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } 1618193326Sed unsigned protocol_size() const { return ReferencedProtocols.size(); } 1619202879Srdivacky typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 1620235633Sdim protocol_loc_iterator protocol_loc_begin() const { 1621235633Sdim return ReferencedProtocols.loc_begin(); 1622202879Srdivacky } 1623235633Sdim protocol_loc_iterator protocol_loc_end() const { 1624235633Sdim return ReferencedProtocols.loc_end(); 1625202879Srdivacky } 1626198092Srdivacky 1627193326Sed ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 1628198092Srdivacky 1629252723Sdim /// \brief Retrieve the pointer to the next stored category (or extension), 1630252723Sdim /// which may be hidden. 1631252723Sdim ObjCCategoryDecl *getNextClassCategoryRaw() const { 1632252723Sdim return NextClassCategory; 1633252723Sdim } 1634252723Sdim 1635203955Srdivacky bool IsClassExtension() const { return getIdentifier() == 0; } 1636235633Sdim 1637204643Srdivacky typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 1638204643Srdivacky ivar_iterator ivar_begin() const { 1639204643Srdivacky return ivar_iterator(decls_begin()); 1640204643Srdivacky } 1641204643Srdivacky ivar_iterator ivar_end() const { 1642204643Srdivacky return ivar_iterator(decls_end()); 1643204643Srdivacky } 1644204643Srdivacky unsigned ivar_size() const { 1645204643Srdivacky return std::distance(ivar_begin(), ivar_end()); 1646204643Srdivacky } 1647204643Srdivacky bool ivar_empty() const { 1648204643Srdivacky return ivar_begin() == ivar_end(); 1649204643Srdivacky } 1650202879Srdivacky 1651202879Srdivacky SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } 1652202879Srdivacky void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } 1653235633Sdim 1654235633Sdim void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } 1655235633Sdim SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } 1656235633Sdim void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } 1657235633Sdim SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } 1658202879Srdivacky 1659203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1660203955Srdivacky static bool classofKind(Kind K) { return K == ObjCCategory; } 1661226890Sdim 1662226890Sdim friend class ASTDeclReader; 1663226890Sdim friend class ASTDeclWriter; 1664193326Sed}; 1665193326Sed 1666198092Srdivackyclass ObjCImplDecl : public ObjCContainerDecl { 1667235633Sdim virtual void anchor(); 1668235633Sdim 1669198893Srdivacky /// Class interface for this class/category implementation 1670193326Sed ObjCInterfaceDecl *ClassInterface; 1671198092Srdivacky 1672193326Sedprotected: 1673226890Sdim ObjCImplDecl(Kind DK, DeclContext *DC, 1674226890Sdim ObjCInterfaceDecl *classInterface, 1675226890Sdim SourceLocation nameLoc, SourceLocation atStartLoc) 1676226890Sdim : ObjCContainerDecl(DK, DC, 1677226890Sdim classInterface? classInterface->getIdentifier() : 0, 1678226890Sdim nameLoc, atStartLoc), 1679198092Srdivacky ClassInterface(classInterface) {} 1680198092Srdivacky 1681193326Sedpublic: 1682193326Sed const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } 1683193326Sed ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } 1684198092Srdivacky void setClassInterface(ObjCInterfaceDecl *IFace); 1685193326Sed 1686198092Srdivacky void addInstanceMethod(ObjCMethodDecl *method) { 1687193326Sed // FIXME: Context should be set correctly before we get here. 1688193326Sed method->setLexicalDeclContext(this); 1689198092Srdivacky addDecl(method); 1690193326Sed } 1691198092Srdivacky void addClassMethod(ObjCMethodDecl *method) { 1692193326Sed // FIXME: Context should be set correctly before we get here. 1693193326Sed method->setLexicalDeclContext(this); 1694198092Srdivacky addDecl(method); 1695193326Sed } 1696198092Srdivacky 1697195341Sed void addPropertyImplementation(ObjCPropertyImplDecl *property); 1698198092Srdivacky 1699195341Sed ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; 1700195341Sed ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; 1701193326Sed 1702193326Sed // Iterator access to properties. 1703193326Sed typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator; 1704198092Srdivacky propimpl_iterator propimpl_begin() const { 1705195341Sed return propimpl_iterator(decls_begin()); 1706193326Sed } 1707198092Srdivacky propimpl_iterator propimpl_end() const { 1708195341Sed return propimpl_iterator(decls_end()); 1709193326Sed } 1710193326Sed 1711203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1712203955Srdivacky static bool classofKind(Kind K) { 1713210299Sed return K >= firstObjCImpl && K <= lastObjCImpl; 1714193326Sed } 1715198092Srdivacky}; 1716193326Sed 1717198092Srdivacky/// ObjCCategoryImplDecl - An object of this class encapsulates a category 1718245431Sdim/// \@implementation declaration. If a category class has declaration of a 1719198092Srdivacky/// property, its implementation must be specified in the category's 1720245431Sdim/// \@implementation declaration. Example: 1721245431Sdim/// \@interface I \@end 1722245431Sdim/// \@interface I(CATEGORY) 1723245431Sdim/// \@property int p1, d1; 1724245431Sdim/// \@end 1725245431Sdim/// \@implementation I(CATEGORY) 1726245431Sdim/// \@dynamic p1,d1; 1727245431Sdim/// \@end 1728193326Sed/// 1729193326Sed/// ObjCCategoryImplDecl 1730193326Sedclass ObjCCategoryImplDecl : public ObjCImplDecl { 1731235633Sdim virtual void anchor(); 1732235633Sdim 1733193326Sed // Category name 1734193326Sed IdentifierInfo *Id; 1735193326Sed 1736235633Sdim // Category name location 1737235633Sdim SourceLocation CategoryNameLoc; 1738235633Sdim 1739226890Sdim ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id, 1740226890Sdim ObjCInterfaceDecl *classInterface, 1741235633Sdim SourceLocation nameLoc, SourceLocation atStartLoc, 1742235633Sdim SourceLocation CategoryNameLoc) 1743226890Sdim : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc), 1744235633Sdim Id(Id), CategoryNameLoc(CategoryNameLoc) {} 1745193326Sedpublic: 1746193326Sed static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, 1747226890Sdim IdentifierInfo *Id, 1748226890Sdim ObjCInterfaceDecl *classInterface, 1749226890Sdim SourceLocation nameLoc, 1750235633Sdim SourceLocation atStartLoc, 1751235633Sdim SourceLocation CategoryNameLoc); 1752235633Sdim static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1753198092Srdivacky 1754198893Srdivacky /// getIdentifier - Get the identifier that names the category 1755193326Sed /// interface associated with this implementation. 1756198893Srdivacky /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier() 1757198893Srdivacky /// to mean something different. For example: 1758235633Sdim /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier() 1759235633Sdim /// returns the class interface name, whereas 1760235633Sdim /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier() 1761198893Srdivacky /// returns the category name. 1762198092Srdivacky IdentifierInfo *getIdentifier() const { 1763198092Srdivacky return Id; 1764193326Sed } 1765193326Sed void setIdentifier(IdentifierInfo *II) { Id = II; } 1766193326Sed 1767198893Srdivacky ObjCCategoryDecl *getCategoryDecl() const; 1768198092Srdivacky 1769235633Sdim SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } 1770235633Sdim 1771198398Srdivacky /// getName - Get the name of identifier for the class interface associated 1772198398Srdivacky /// with this implementation as a StringRef. 1773198398Srdivacky // 1774198398Srdivacky // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean 1775198398Srdivacky // something different. 1776226890Sdim StringRef getName() const { 1777198398Srdivacky return Id ? Id->getNameStart() : ""; 1778198398Srdivacky } 1779198398Srdivacky 1780193326Sed /// @brief Get the name of the class associated with this interface. 1781198398Srdivacky // 1782198398Srdivacky // FIXME: Deprecated, move clients to getName(). 1783193326Sed std::string getNameAsString() const { 1784198398Srdivacky return getName(); 1785193326Sed } 1786198092Srdivacky 1787203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1788203955Srdivacky static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} 1789235633Sdim 1790235633Sdim friend class ASTDeclReader; 1791235633Sdim friend class ASTDeclWriter; 1792193326Sed}; 1793193326Sed 1794235633Sdimraw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID); 1795207619Srdivacky 1796193326Sed/// ObjCImplementationDecl - Represents a class definition - this is where 1797193326Sed/// method definitions are specified. For example: 1798193326Sed/// 1799193326Sed/// @code 1800245431Sdim/// \@implementation MyClass 1801193326Sed/// - (void)myMethod { /* do something */ } 1802245431Sdim/// \@end 1803193326Sed/// @endcode 1804193326Sed/// 1805198092Srdivacky/// Typically, instance variables are specified in the class interface, 1806193326Sed/// *not* in the implementation. Nevertheless (for legacy reasons), we 1807193326Sed/// allow instance variables to be specified in the implementation. When 1808193326Sed/// specified, they need to be *identical* to the interface. 1809193326Sed/// 1810198092Srdivackyclass ObjCImplementationDecl : public ObjCImplDecl { 1811235633Sdim virtual void anchor(); 1812193326Sed /// Implementation Class's super class. 1813193326Sed ObjCInterfaceDecl *SuperClass; 1814252723Sdim SourceLocation SuperLoc; 1815252723Sdim 1816245431Sdim /// \@implementation may have private ivars. 1817235633Sdim SourceLocation IvarLBraceLoc; 1818235633Sdim SourceLocation IvarRBraceLoc; 1819235633Sdim 1820207619Srdivacky /// Support for ivar initialization. 1821207619Srdivacky /// IvarInitializers - The arguments used to initialize the ivars 1822218893Sdim CXXCtorInitializer **IvarInitializers; 1823207619Srdivacky unsigned NumIvarInitializers; 1824224145Sdim 1825245431Sdim /// Do the ivars of this class require initialization other than 1826245431Sdim /// zero-initialization? 1827245431Sdim bool HasNonZeroConstructors : 1; 1828235633Sdim 1829245431Sdim /// Do the ivars of this class require non-trivial destruction? 1830245431Sdim bool HasDestructors : 1; 1831235633Sdim 1832226890Sdim ObjCImplementationDecl(DeclContext *DC, 1833193326Sed ObjCInterfaceDecl *classInterface, 1834226890Sdim ObjCInterfaceDecl *superDecl, 1835235633Sdim SourceLocation nameLoc, SourceLocation atStartLoc, 1836252723Sdim SourceLocation superLoc = SourceLocation(), 1837235633Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1838235633Sdim SourceLocation IvarRBraceLoc=SourceLocation()) 1839226890Sdim : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), 1840252723Sdim SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc), 1841235633Sdim IvarRBraceLoc(IvarRBraceLoc), 1842235633Sdim IvarInitializers(0), NumIvarInitializers(0), 1843245431Sdim HasNonZeroConstructors(false), HasDestructors(false) {} 1844198092Srdivackypublic: 1845198092Srdivacky static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, 1846193326Sed ObjCInterfaceDecl *classInterface, 1847226890Sdim ObjCInterfaceDecl *superDecl, 1848226890Sdim SourceLocation nameLoc, 1849235633Sdim SourceLocation atStartLoc, 1850252723Sdim SourceLocation superLoc = SourceLocation(), 1851235633Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1852235633Sdim SourceLocation IvarRBraceLoc=SourceLocation()); 1853235633Sdim 1854235633Sdim static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1855235633Sdim 1856207619Srdivacky /// init_iterator - Iterates through the ivar initializer list. 1857218893Sdim typedef CXXCtorInitializer **init_iterator; 1858235633Sdim 1859207619Srdivacky /// init_const_iterator - Iterates through the ivar initializer list. 1860218893Sdim typedef CXXCtorInitializer * const * init_const_iterator; 1861235633Sdim 1862207619Srdivacky /// init_begin() - Retrieve an iterator to the first initializer. 1863207619Srdivacky init_iterator init_begin() { return IvarInitializers; } 1864207619Srdivacky /// begin() - Retrieve an iterator to the first initializer. 1865207619Srdivacky init_const_iterator init_begin() const { return IvarInitializers; } 1866235633Sdim 1867207619Srdivacky /// init_end() - Retrieve an iterator past the last initializer. 1868207619Srdivacky init_iterator init_end() { 1869207619Srdivacky return IvarInitializers + NumIvarInitializers; 1870207619Srdivacky } 1871207619Srdivacky /// end() - Retrieve an iterator past the last initializer. 1872207619Srdivacky init_const_iterator init_end() const { 1873207619Srdivacky return IvarInitializers + NumIvarInitializers; 1874207619Srdivacky } 1875207619Srdivacky /// getNumArgs - Number of ivars which must be initialized. 1876207619Srdivacky unsigned getNumIvarInitializers() const { 1877207619Srdivacky return NumIvarInitializers; 1878207619Srdivacky } 1879235633Sdim 1880207619Srdivacky void setNumIvarInitializers(unsigned numNumIvarInitializers) { 1881207619Srdivacky NumIvarInitializers = numNumIvarInitializers; 1882207619Srdivacky } 1883235633Sdim 1884207619Srdivacky void setIvarInitializers(ASTContext &C, 1885218893Sdim CXXCtorInitializer ** initializers, 1886207619Srdivacky unsigned numInitializers); 1887224145Sdim 1888245431Sdim /// Do any of the ivars of this class (not counting its base classes) 1889245431Sdim /// require construction other than zero-initialization? 1890245431Sdim bool hasNonZeroConstructors() const { return HasNonZeroConstructors; } 1891245431Sdim void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; } 1892235633Sdim 1893245431Sdim /// Do any of the ivars of this class (not counting its base classes) 1894245431Sdim /// require non-trivial destruction? 1895245431Sdim bool hasDestructors() const { return HasDestructors; } 1896245431Sdim void setHasDestructors(bool val) { HasDestructors = val; } 1897235633Sdim 1898193326Sed /// getIdentifier - Get the identifier that names the class 1899193326Sed /// interface associated with this implementation. 1900198092Srdivacky IdentifierInfo *getIdentifier() const { 1901198092Srdivacky return getClassInterface()->getIdentifier(); 1902193326Sed } 1903193326Sed 1904198398Srdivacky /// getName - Get the name of identifier for the class interface associated 1905198398Srdivacky /// with this implementation as a StringRef. 1906198398Srdivacky // 1907198398Srdivacky // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean 1908198398Srdivacky // something different. 1909226890Sdim StringRef getName() const { 1910198398Srdivacky assert(getIdentifier() && "Name is not a simple identifier"); 1911198398Srdivacky return getIdentifier()->getName(); 1912198398Srdivacky } 1913198398Srdivacky 1914193326Sed /// @brief Get the name of the class associated with this interface. 1915198398Srdivacky // 1916198398Srdivacky // FIXME: Move to StringRef API. 1917193326Sed std::string getNameAsString() const { 1918198398Srdivacky return getName(); 1919193326Sed } 1920193326Sed 1921193326Sed const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } 1922193326Sed ObjCInterfaceDecl *getSuperClass() { return SuperClass; } 1923252723Sdim SourceLocation getSuperClassLoc() const { return SuperLoc; } 1924198092Srdivacky 1925193326Sed void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 1926198092Srdivacky 1927235633Sdim void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } 1928235633Sdim SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } 1929235633Sdim void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } 1930235633Sdim SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } 1931235633Sdim 1932193326Sed typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 1933198092Srdivacky ivar_iterator ivar_begin() const { 1934198092Srdivacky return ivar_iterator(decls_begin()); 1935193326Sed } 1936198092Srdivacky ivar_iterator ivar_end() const { 1937195341Sed return ivar_iterator(decls_end()); 1938193326Sed } 1939198092Srdivacky unsigned ivar_size() const { 1940195341Sed return std::distance(ivar_begin(), ivar_end()); 1941193326Sed } 1942198092Srdivacky bool ivar_empty() const { 1943195341Sed return ivar_begin() == ivar_end(); 1944193326Sed } 1945198092Srdivacky 1946203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1947203955Srdivacky static bool classofKind(Kind K) { return K == ObjCImplementation; } 1948212904Sdim 1949212904Sdim friend class ASTDeclReader; 1950212904Sdim friend class ASTDeclWriter; 1951193326Sed}; 1952193326Sed 1953235633Sdimraw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID); 1954207619Srdivacky 1955198092Srdivacky/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 1956245431Sdim/// declared as \@compatibility_alias alias class. 1957193326Sedclass ObjCCompatibleAliasDecl : public NamedDecl { 1958235633Sdim virtual void anchor(); 1959193326Sed /// Class that this is an alias of. 1960193326Sed ObjCInterfaceDecl *AliasedClass; 1961198092Srdivacky 1962193326Sed ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 1963193326Sed ObjCInterfaceDecl* aliasedClass) 1964193326Sed : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {} 1965193326Sedpublic: 1966193326Sed static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC, 1967193326Sed SourceLocation L, IdentifierInfo *Id, 1968193326Sed ObjCInterfaceDecl* aliasedClass); 1969193326Sed 1970235633Sdim static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, 1971235633Sdim unsigned ID); 1972235633Sdim 1973193326Sed const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } 1974193326Sed ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } 1975193326Sed void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } 1976198092Srdivacky 1977203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1978203955Srdivacky static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; } 1979198092Srdivacky 1980193326Sed}; 1981193326Sed 1982245431Sdim/// \brief Represents one property declaration in an Objective-C interface. 1983245431Sdim/// 1984193326Sed/// For example: 1985245431Sdim/// \code{.mm} 1986245431Sdim/// \@property (assign, readwrite) int MyProperty; 1987245431Sdim/// \endcode 1988193326Sedclass ObjCPropertyDecl : public NamedDecl { 1989235633Sdim virtual void anchor(); 1990193326Sedpublic: 1991193326Sed enum PropertyAttributeKind { 1992198092Srdivacky OBJC_PR_noattr = 0x00, 1993198092Srdivacky OBJC_PR_readonly = 0x01, 1994193326Sed OBJC_PR_getter = 0x02, 1995198092Srdivacky OBJC_PR_assign = 0x04, 1996198092Srdivacky OBJC_PR_readwrite = 0x08, 1997193326Sed OBJC_PR_retain = 0x10, 1998198092Srdivacky OBJC_PR_copy = 0x20, 1999193326Sed OBJC_PR_nonatomic = 0x40, 2000218893Sdim OBJC_PR_setter = 0x80, 2001224145Sdim OBJC_PR_atomic = 0x100, 2002224145Sdim OBJC_PR_weak = 0x200, 2003224145Sdim OBJC_PR_strong = 0x400, 2004224145Sdim OBJC_PR_unsafe_unretained = 0x800 2005224145Sdim // Adding a property should change NumPropertyAttrsBits 2006193326Sed }; 2007193326Sed 2008224145Sdim enum { 2009224145Sdim /// \brief Number of bits fitting all the property attributes. 2010224145Sdim NumPropertyAttrsBits = 12 2011224145Sdim }; 2012224145Sdim 2013226890Sdim enum SetterKind { Assign, Retain, Copy, Weak }; 2014193326Sed enum PropertyControl { None, Required, Optional }; 2015193326Sedprivate: 2016245431Sdim SourceLocation AtLoc; // location of \@property 2017235633Sdim SourceLocation LParenLoc; // location of '(' starting attribute list or null. 2018210299Sed TypeSourceInfo *DeclType; 2019224145Sdim unsigned PropertyAttributes : NumPropertyAttrsBits; 2020224145Sdim unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; 2021245431Sdim // \@required/\@optional 2022193326Sed unsigned PropertyImplementation : 2; 2023198092Srdivacky 2024193326Sed Selector GetterName; // getter name of NULL if no getter 2025193326Sed Selector SetterName; // setter name of NULL if no setter 2026198092Srdivacky 2027193326Sed ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method 2028193326Sed ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method 2029193326Sed ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property 2030193326Sed 2031198092Srdivacky ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, 2032235633Sdim SourceLocation AtLocation, SourceLocation LParenLocation, 2033235633Sdim TypeSourceInfo *T) 2034235633Sdim : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), 2035235633Sdim LParenLoc(LParenLocation), DeclType(T), 2036235633Sdim PropertyAttributes(OBJC_PR_noattr), 2037210299Sed PropertyAttributesAsWritten(OBJC_PR_noattr), 2038210299Sed PropertyImplementation(None), 2039198092Srdivacky GetterName(Selector()), 2040193326Sed SetterName(Selector()), 2041193326Sed GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {} 2042193326Sedpublic: 2043198092Srdivacky static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, 2044198092Srdivacky SourceLocation L, 2045202879Srdivacky IdentifierInfo *Id, SourceLocation AtLocation, 2046235633Sdim SourceLocation LParenLocation, 2047210299Sed TypeSourceInfo *T, 2048193326Sed PropertyControl propControl = None); 2049235633Sdim 2050235633Sdim static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); 2051235633Sdim 2052202879Srdivacky SourceLocation getAtLoc() const { return AtLoc; } 2053202879Srdivacky void setAtLoc(SourceLocation L) { AtLoc = L; } 2054202879Srdivacky 2055235633Sdim SourceLocation getLParenLoc() const { return LParenLoc; } 2056235633Sdim void setLParenLoc(SourceLocation L) { LParenLoc = L; } 2057235633Sdim 2058210299Sed TypeSourceInfo *getTypeSourceInfo() const { return DeclType; } 2059210299Sed QualType getType() const { return DeclType->getType(); } 2060210299Sed void setType(TypeSourceInfo *T) { DeclType = T; } 2061193326Sed 2062193326Sed PropertyAttributeKind getPropertyAttributes() const { 2063193326Sed return PropertyAttributeKind(PropertyAttributes); 2064193326Sed } 2065198092Srdivacky void setPropertyAttributes(PropertyAttributeKind PRVal) { 2066193326Sed PropertyAttributes |= PRVal; 2067193326Sed } 2068193326Sed 2069210299Sed PropertyAttributeKind getPropertyAttributesAsWritten() const { 2070210299Sed return PropertyAttributeKind(PropertyAttributesAsWritten); 2071210299Sed } 2072224145Sdim 2073224145Sdim bool hasWrittenStorageAttribute() const { 2074224145Sdim return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy | 2075224145Sdim OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong | 2076224145Sdim OBJC_PR_weak); 2077224145Sdim } 2078235633Sdim 2079210299Sed void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { 2080210299Sed PropertyAttributesAsWritten = PRVal; 2081210299Sed } 2082235633Sdim 2083252723Sdim void makeitReadWriteAttribute() { 2084193326Sed PropertyAttributes &= ~OBJC_PR_readonly; 2085193326Sed PropertyAttributes |= OBJC_PR_readwrite; 2086198092Srdivacky } 2087193326Sed 2088193326Sed // Helper methods for accessing attributes. 2089193326Sed 2090193326Sed /// isReadOnly - Return true iff the property has a setter. 2091193326Sed bool isReadOnly() const { 2092193326Sed return (PropertyAttributes & OBJC_PR_readonly); 2093193326Sed } 2094193326Sed 2095226890Sdim /// isAtomic - Return true if the property is atomic. 2096226890Sdim bool isAtomic() const { 2097226890Sdim return (PropertyAttributes & OBJC_PR_atomic); 2098226890Sdim } 2099226890Sdim 2100226890Sdim /// isRetaining - Return true if the property retains its value. 2101226890Sdim bool isRetaining() const { 2102226890Sdim return (PropertyAttributes & 2103226890Sdim (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); 2104226890Sdim } 2105226890Sdim 2106193326Sed /// getSetterKind - Return the method used for doing assignment in 2107193326Sed /// the property setter. This is only valid if the property has been 2108193326Sed /// defined to have a setter. 2109193326Sed SetterKind getSetterKind() const { 2110226890Sdim if (PropertyAttributes & OBJC_PR_strong) 2111226890Sdim return getType()->isBlockPointerType() ? Copy : Retain; 2112226890Sdim if (PropertyAttributes & OBJC_PR_retain) 2113193326Sed return Retain; 2114193326Sed if (PropertyAttributes & OBJC_PR_copy) 2115193326Sed return Copy; 2116226890Sdim if (PropertyAttributes & OBJC_PR_weak) 2117226890Sdim return Weak; 2118193326Sed return Assign; 2119193326Sed } 2120193326Sed 2121193326Sed Selector getGetterName() const { return GetterName; } 2122193326Sed void setGetterName(Selector Sel) { GetterName = Sel; } 2123198092Srdivacky 2124193326Sed Selector getSetterName() const { return SetterName; } 2125193326Sed void setSetterName(Selector Sel) { SetterName = Sel; } 2126198092Srdivacky 2127193326Sed ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } 2128193326Sed void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } 2129193326Sed 2130193326Sed ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } 2131193326Sed void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } 2132198092Srdivacky 2133245431Sdim // Related to \@optional/\@required declared in \@protocol 2134193326Sed void setPropertyImplementation(PropertyControl pc) { 2135193326Sed PropertyImplementation = pc; 2136193326Sed } 2137193326Sed PropertyControl getPropertyImplementation() const { 2138193326Sed return PropertyControl(PropertyImplementation); 2139198092Srdivacky } 2140198092Srdivacky 2141193326Sed void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { 2142193326Sed PropertyIvarDecl = Ivar; 2143193326Sed } 2144193326Sed ObjCIvarDecl *getPropertyIvarDecl() const { 2145193326Sed return PropertyIvarDecl; 2146193326Sed } 2147198092Srdivacky 2148235633Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 2149218893Sdim return SourceRange(AtLoc, getLocation()); 2150218893Sdim } 2151245431Sdim 2152245431Sdim /// Get the default name of the synthesized ivar. 2153245431Sdim IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const; 2154218893Sdim 2155205219Srdivacky /// Lookup a property by name in the specified DeclContext. 2156205219Srdivacky static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, 2157205219Srdivacky IdentifierInfo *propertyID); 2158205219Srdivacky 2159203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2160203955Srdivacky static bool classofKind(Kind K) { return K == ObjCProperty; } 2161193326Sed}; 2162193326Sed 2163198092Srdivacky/// ObjCPropertyImplDecl - Represents implementation declaration of a property 2164193326Sed/// in a class or category implementation block. For example: 2165245431Sdim/// \@synthesize prop1 = ivar1; 2166193326Sed/// 2167193326Sedclass ObjCPropertyImplDecl : public Decl { 2168193326Sedpublic: 2169193326Sed enum Kind { 2170193326Sed Synthesize, 2171193326Sed Dynamic 2172193326Sed }; 2173193326Sedprivate: 2174245431Sdim SourceLocation AtLoc; // location of \@synthesize or \@dynamic 2175235633Sdim 2176245431Sdim /// \brief For \@synthesize, the location of the ivar, if it was written in 2177218893Sdim /// the source code. 2178218893Sdim /// 2179218893Sdim /// \code 2180245431Sdim /// \@synthesize int a = b 2181218893Sdim /// \endcode 2182218893Sdim SourceLocation IvarLoc; 2183235633Sdim 2184193326Sed /// Property declaration being implemented 2185193326Sed ObjCPropertyDecl *PropertyDecl; 2186193326Sed 2187245431Sdim /// Null for \@dynamic. Required for \@synthesize. 2188193326Sed ObjCIvarDecl *PropertyIvarDecl; 2189235633Sdim 2190245431Sdim /// Null for \@dynamic. Non-null if property must be copy-constructed in 2191245431Sdim /// getter. 2192208600Srdivacky Expr *GetterCXXConstructor; 2193235633Sdim 2194245431Sdim /// Null for \@dynamic. Non-null if property has assignment operator to call 2195208600Srdivacky /// in Setter synthesis. 2196208600Srdivacky Expr *SetterCXXAssignment; 2197193326Sed 2198193326Sed ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, 2199198092Srdivacky ObjCPropertyDecl *property, 2200198092Srdivacky Kind PK, 2201218893Sdim ObjCIvarDecl *ivarDecl, 2202218893Sdim SourceLocation ivarLoc) 2203198092Srdivacky : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), 2204235633Sdim IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl), 2205208600Srdivacky GetterCXXConstructor(0), SetterCXXAssignment(0) { 2206193326Sed assert (PK == Dynamic || PropertyIvarDecl); 2207193326Sed } 2208198092Srdivacky 2209193326Sedpublic: 2210193326Sed static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC, 2211198092Srdivacky SourceLocation atLoc, SourceLocation L, 2212198092Srdivacky ObjCPropertyDecl *property, 2213198092Srdivacky Kind PK, 2214218893Sdim ObjCIvarDecl *ivarDecl, 2215218893Sdim SourceLocation ivarLoc); 2216193326Sed 2217235633Sdim static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); 2218218893Sdim 2219235633Sdim virtual SourceRange getSourceRange() const LLVM_READONLY; 2220235633Sdim 2221235633Sdim SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } 2222193326Sed void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } 2223193326Sed 2224193326Sed ObjCPropertyDecl *getPropertyDecl() const { 2225193326Sed return PropertyDecl; 2226193326Sed } 2227193326Sed void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; } 2228193326Sed 2229193326Sed Kind getPropertyImplementation() const { 2230193326Sed return PropertyIvarDecl ? Synthesize : Dynamic; 2231193326Sed } 2232198092Srdivacky 2233193326Sed ObjCIvarDecl *getPropertyIvarDecl() const { 2234193326Sed return PropertyIvarDecl; 2235193326Sed } 2236218893Sdim SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; } 2237235633Sdim 2238218893Sdim void setPropertyIvarDecl(ObjCIvarDecl *Ivar, 2239235633Sdim SourceLocation IvarLoc) { 2240235633Sdim PropertyIvarDecl = Ivar; 2241218893Sdim this->IvarLoc = IvarLoc; 2242218893Sdim } 2243235633Sdim 2244245431Sdim /// \brief For \@synthesize, returns true if an ivar name was explicitly 2245245431Sdim /// specified. 2246245431Sdim /// 2247245431Sdim /// \code 2248245431Sdim /// \@synthesize int a = b; // true 2249245431Sdim /// \@synthesize int a; // false 2250245431Sdim /// \endcode 2251245431Sdim bool isIvarNameSpecified() const { 2252245431Sdim return IvarLoc.isValid() && IvarLoc != getLocation(); 2253245431Sdim } 2254245431Sdim 2255208600Srdivacky Expr *getGetterCXXConstructor() const { 2256208600Srdivacky return GetterCXXConstructor; 2257208600Srdivacky } 2258208600Srdivacky void setGetterCXXConstructor(Expr *getterCXXConstructor) { 2259208600Srdivacky GetterCXXConstructor = getterCXXConstructor; 2260208600Srdivacky } 2261193326Sed 2262208600Srdivacky Expr *getSetterCXXAssignment() const { 2263208600Srdivacky return SetterCXXAssignment; 2264208600Srdivacky } 2265208600Srdivacky void setSetterCXXAssignment(Expr *setterCXXAssignment) { 2266208600Srdivacky SetterCXXAssignment = setterCXXAssignment; 2267208600Srdivacky } 2268235633Sdim 2269203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2270203955Srdivacky static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } 2271235633Sdim 2272218893Sdim friend class ASTDeclReader; 2273193326Sed}; 2274193326Sed 2275252723Sdimtemplate<bool (*Filter)(ObjCCategoryDecl *)> 2276252723Sdimvoid 2277252723SdimObjCInterfaceDecl::filtered_category_iterator<Filter>:: 2278252723SdimfindAcceptableCategory() { 2279252723Sdim while (Current && !Filter(Current)) 2280252723Sdim Current = Current->getNextClassCategoryRaw(); 2281252723Sdim} 2282252723Sdim 2283252723Sdimtemplate<bool (*Filter)(ObjCCategoryDecl *)> 2284252723Sdiminline ObjCInterfaceDecl::filtered_category_iterator<Filter> & 2285252723SdimObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() { 2286252723Sdim Current = Current->getNextClassCategoryRaw(); 2287252723Sdim findAcceptableCategory(); 2288252723Sdim return *this; 2289252723Sdim} 2290252723Sdim 2291252723Sdiminline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) { 2292252723Sdim return !Cat->isHidden(); 2293252723Sdim} 2294252723Sdim 2295252723Sdiminline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) { 2296252723Sdim return Cat->IsClassExtension() && !Cat->isHidden(); 2297252723Sdim} 2298252723Sdim 2299252723Sdiminline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { 2300252723Sdim return Cat->IsClassExtension(); 2301252723Sdim} 2302252723Sdim 2303193326Sed} // end namespace clang 2304193326Sed#endif 2305