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" 18226633Sdim#include "clang/AST/SelectorLocationsKind.h" 19193326Sed#include "llvm/ADT/STLExtras.h" 20234353Sdim#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 { 36243830Sdim ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION; 37243830Sdim 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 88234353Sdim 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 126243830Sdim /// True if this method is the getter or setter for an explicit property. 127243830Sdim unsigned IsPropertyAccessor : 1; 128234353Sdim 129212904Sdim // Method has a definition. 130221345Sdim unsigned IsDefined : 1; 131198092Srdivacky 132226633Sdim /// \brief Method redeclaration in the same interface. 133226633Sdim unsigned IsRedeclaration : 1; 134226633Sdim 135226633Sdim /// \brief Is redeclared in the same interface. 136226633Sdim mutable unsigned HasRedeclaration : 1; 137226633Sdim 138193326Sed // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum 139239462Sdim /// \@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; 148234353Sdim 149226633Sdim /// \brief Whether the locations of the selector identifiers are in a 150226633Sdim /// "standard" position, a enum SelectorLocationsKind. 151226633Sdim unsigned SelLocsKind : 2; 152207619Srdivacky 153239462Sdim /// \brief Whether this method overrides any other in the class hierarchy. 154239462Sdim /// 155239462Sdim /// A method is said to override any method in the class's 156239462Sdim /// base classes, its protocols, or its categories' protocols, that has 157239462Sdim /// the same selector and is of the same kind (class or instance). 158239462Sdim /// A method in an implementation is not considered as overriding the same 159239462Sdim /// method in the interface or its categories. 160239462Sdim unsigned IsOverriding : 1; 161239462Sdim 162249423Sdim /// \brief Indicates if the method was a definition but its body was skipped. 163249423Sdim unsigned HasSkippedBody : 1; 164249423Sdim 165204962Srdivacky // Result type of this method. 166193326Sed QualType MethodDeclType; 167234353Sdim 168204962Srdivacky // Type source information for the result type. 169204962Srdivacky TypeSourceInfo *ResultTInfo; 170204962Srdivacky 171226633Sdim /// \brief Array of ParmVarDecls for the formal parameters of this method 172226633Sdim /// and optionally followed by selector locations. 173226633Sdim void *ParamsAndSelLocs; 174226633Sdim unsigned NumParams; 175198092Srdivacky 176193326Sed /// List of attributes for this method declaration. 177239462Sdim SourceLocation DeclEndLoc; // the location of the ';' or '{'. 178198092Srdivacky 179193326Sed // The following are only used for method definitions, null otherwise. 180243830Sdim 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 189226633Sdim SelectorLocationsKind getSelLocsKind() const { 190226633Sdim return (SelectorLocationsKind)SelLocsKind; 191226633Sdim } 192226633Sdim bool hasStandardSelLocs() const { 193226633Sdim return getSelLocsKind() != SelLoc_NonStandard; 194226633Sdim } 195226633Sdim 196226633Sdim /// \brief Get a pointer to the stored selector identifiers locations array. 197226633Sdim /// No locations will be stored if HasStandardSelLocs is true. 198226633Sdim SourceLocation *getStoredSelLocs() { 199226633Sdim return reinterpret_cast<SourceLocation*>(getParams() + NumParams); 200226633Sdim } 201226633Sdim const SourceLocation *getStoredSelLocs() const { 202226633Sdim return reinterpret_cast<const SourceLocation*>(getParams() + NumParams); 203226633Sdim } 204226633Sdim 205226633Sdim /// \brief Get a pointer to the stored selector identifiers locations array. 206226633Sdim /// No locations will be stored if HasStandardSelLocs is true. 207226633Sdim ParmVarDecl **getParams() { 208226633Sdim return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs); 209226633Sdim } 210226633Sdim const ParmVarDecl *const *getParams() const { 211226633Sdim return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs); 212226633Sdim } 213226633Sdim 214226633Sdim /// \brief Get the number of stored selector identifiers locations. 215226633Sdim /// No locations will be stored if HasStandardSelLocs is true. 216226633Sdim unsigned getNumStoredSelLocs() const { 217226633Sdim if (hasStandardSelLocs()) 218226633Sdim return 0; 219226633Sdim return getNumSelectorLocs(); 220226633Sdim } 221226633Sdim 222226633Sdim void setParamsAndSelLocs(ASTContext &C, 223226633Sdim ArrayRef<ParmVarDecl*> Params, 224226633Sdim ArrayRef<SourceLocation> SelLocs); 225226633Sdim 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, 232243830Sdim bool isPropertyAccessor = false, 233226633Sdim bool isImplicitlyDeclared = false, 234212904Sdim bool isDefined = false, 235207619Srdivacky ImplementationControl impControl = None, 236226633Sdim bool HasRelatedResultType = false) 237193326Sed : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), 238221345Sdim DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), 239193326Sed IsInstance(isInstance), IsVariadic(isVariadic), 240243830Sdim IsPropertyAccessor(isPropertyAccessor), 241226633Sdim IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0), 242193326Sed DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), 243226633Sdim RelatedResultType(HasRelatedResultType), 244249423Sdim SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0), 245223017Sdim MethodDeclType(T), ResultTInfo(ResultTInfo), 246226633Sdim ParamsAndSelLocs(0), NumParams(0), 247243830Sdim DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) { 248226633Sdim setImplicit(isImplicitlyDeclared); 249226633Sdim } 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, 259226633Sdim SourceLocation endLoc, 260226633Sdim Selector SelInfo, 261234353Sdim QualType T, 262204962Srdivacky TypeSourceInfo *ResultTInfo, 263204962Srdivacky DeclContext *contextDecl, 264193326Sed bool isInstance = true, 265193326Sed bool isVariadic = false, 266243830Sdim bool isPropertyAccessor = false, 267226633Sdim bool isImplicitlyDeclared = false, 268212904Sdim bool isDefined = false, 269207619Srdivacky ImplementationControl impControl = None, 270226633Sdim bool HasRelatedResultType = false); 271198092Srdivacky 272234353Sdim static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); 273234353Sdim 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; } 287234353Sdim 288223017Sdim /// \brief Note whether this method has a related result type. 289223017Sdim void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; } 290226633Sdim 291226633Sdim /// \brief True if this is a method redeclaration in the same interface. 292226633Sdim bool isRedeclaration() const { return IsRedeclaration; } 293226633Sdim void setAsRedeclaration(const ObjCMethodDecl *PrevMethod); 294234353Sdim 295239462Sdim /// \brief Returns the location where the declarator ends. It will be 296239462Sdim /// the location of ';' for a method declaration and the location of '{' 297239462Sdim /// for a method definition. 298239462Sdim SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; } 299239462Sdim 300193326Sed // Location information, modeled after the Stmt API. 301234353Sdim SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); } 302239462Sdim SourceLocation getLocEnd() const LLVM_READONLY; 303234353Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 304239462Sdim return SourceRange(getLocation(), getLocEnd()); 305193326Sed } 306198092Srdivacky 307234353Sdim SourceLocation getSelectorStartLoc() const { 308234353Sdim if (isImplicit()) 309234353Sdim return getLocStart(); 310234353Sdim return getSelectorLoc(0); 311234353Sdim } 312226633Sdim SourceLocation getSelectorLoc(unsigned Index) const { 313226633Sdim assert(Index < getNumSelectorLocs() && "Index out of range!"); 314226633Sdim if (hasStandardSelLocs()) 315226633Sdim return getStandardSelectorLoc(Index, getSelector(), 316226633Sdim getSelLocsKind() == SelLoc_StandardWithSpace, 317226633Sdim llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()), 318226633Sdim NumParams), 319239462Sdim DeclEndLoc); 320226633Sdim return getStoredSelLocs()[Index]; 321226633Sdim } 322226633Sdim 323226633Sdim void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; 324226633Sdim 325226633Sdim unsigned getNumSelectorLocs() const { 326226633Sdim if (isImplicit()) 327226633Sdim return 0; 328226633Sdim Selector Sel = getSelector(); 329226633Sdim if (Sel.isUnarySelector()) 330226633Sdim return 1; 331226633Sdim return Sel.getNumArgs(); 332226633Sdim } 333226633Sdim 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 344234353Sdim /// \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 } 349234353Sdim 350204962Srdivacky TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; } 351204962Srdivacky void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; } 352204962Srdivacky 353193326Sed // Iterator access to formal parameters. 354226633Sdim unsigned param_size() const { return NumParams; } 355226633Sdim typedef const ParmVarDecl *const *param_const_iterator; 356226633Sdim typedef ParmVarDecl *const *param_iterator; 357226633Sdim param_const_iterator param_begin() const { return getParams(); } 358226633Sdim param_const_iterator param_end() const { return getParams() + NumParams; } 359226633Sdim param_iterator param_begin() { return getParams(); } 360226633Sdim 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. 363234353Sdim param_const_iterator sel_param_end() const { 364234353Sdim return param_begin() + getSelector().getNumArgs(); 365207619Srdivacky } 366193326Sed 367226633Sdim /// \brief Sets the method's parameters and selector source locations. 368243830Sdim /// If the method is implicit (not coming from source) \p SelLocs is 369226633Sdim /// ignored. 370226633Sdim void setMethodParams(ASTContext &C, 371226633Sdim ArrayRef<ParmVarDecl*> Params, 372226633Sdim ArrayRef<SourceLocation> SelLocs = 373226633Sdim ArrayRef<SourceLocation>()); 374193326Sed 375193326Sed // Iterator access to parameter types. 376193326Sed typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun; 377226633Sdim typedef llvm::mapped_iterator<param_const_iterator, deref_fun> 378226633Sdim 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 408243830Sdim bool isPropertyAccessor() const { return IsPropertyAccessor; } 409243830Sdim void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; } 410234353Sdim 411212904Sdim bool isDefined() const { return IsDefined; } 412212904Sdim void setDefined(bool isDefined) { IsDefined = isDefined; } 413198092Srdivacky 414239462Sdim /// \brief Whether this method overrides any other in the class hierarchy. 415239462Sdim /// 416239462Sdim /// A method is said to override any method in the class's 417239462Sdim /// base classes, its protocols, or its categories' protocols, that has 418239462Sdim /// the same selector and is of the same kind (class or instance). 419239462Sdim /// A method in an implementation is not considered as overriding the same 420239462Sdim /// method in the interface or its categories. 421239462Sdim bool isOverriding() const { return IsOverriding; } 422239462Sdim void setOverriding(bool isOverriding) { IsOverriding = isOverriding; } 423243830Sdim 424243830Sdim /// \brief Return overridden methods for the given \p Method. 425243830Sdim /// 426243830Sdim /// An ObjC method is considered to override any method in the class's 427243830Sdim /// base classes (and base's categories), its protocols, or its categories' 428243830Sdim /// protocols, that has 429243830Sdim /// the same selector and is of the same kind (class or instance). 430243830Sdim /// A method in an implementation is not considered as overriding the same 431243830Sdim /// method in the interface or its categories. 432243830Sdim void getOverriddenMethods( 433243830Sdim SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const; 434243830Sdim 435249423Sdim /// \brief True if the method was a definition but its body was skipped. 436249423Sdim bool hasSkippedBody() const { return HasSkippedBody; } 437249423Sdim void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } 438249423Sdim 439243830Sdim /// \brief Returns the property associated with this method's selector. 440243830Sdim /// 441243830Sdim /// Note that even if this particular method is not marked as a property 442243830Sdim /// accessor, it is still possible for it to match a property declared in a 443243830Sdim /// superclass. Pass \c false if you only want to check the current class. 444243830Sdim const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const; 445243830Sdim 446239462Sdim // 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 454243830Sdim /// \brief Determine whether this method has a body. 455263508Sdim virtual bool hasBody() const { return Body.isValid(); } 456243830Sdim 457243830Sdim /// \brief Retrieve the body of this method, if it has one. 458243830Sdim virtual Stmt *getBody() const; 459243830Sdim 460243830Sdim void setLazyBody(uint64_t Offset) { Body = Offset; } 461243830Sdim 462243830Sdim CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); } 463193326Sed void setBody(Stmt *B) { Body = B; } 464193326Sed 465198092Srdivacky /// \brief Returns whether this specific method is a definition. 466263508Sdim 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 } 477226633Sdim 478226633Sdim friend class ASTDeclReader; 479226633Sdim 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 { 487234353Sdim virtual void anchor(); 488234353Sdim 489226633Sdim SourceLocation AtStart; 490226633Sdim 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 496226633Sdim ObjCContainerDecl(Kind DK, DeclContext *DC, 497226633Sdim IdentifierInfo *Id, SourceLocation nameLoc, 498226633Sdim SourceLocation atStartLoc) 499226633Sdim : 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. 540249423Sdim ObjCMethodDecl *getMethod(Selector Sel, bool isInstance, 541249423Sdim bool AllowHidden = false) const; 542249423Sdim ObjCMethodDecl *getInstanceMethod(Selector Sel, 543249423Sdim bool AllowHidden = false) const { 544249423Sdim return getMethod(Sel, true/*isInstance*/, AllowHidden); 545198092Srdivacky } 546249423Sdim ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const { 547249423Sdim return getMethod(Sel, false/*isInstance*/, AllowHidden); 548198092Srdivacky } 549249423Sdim bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const; 550195341Sed ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; 551193326Sed 552195341Sed ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; 553193326Sed 554243830Sdim typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap; 555249423Sdim 556263508Sdim typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*> 557263508Sdim ProtocolPropertyMap; 558263508Sdim 559249423Sdim typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder; 560249423Sdim 561243830Sdim /// This routine collects list of properties to be implemented in the class. 562243830Sdim /// This includes, class's and its conforming protocols' properties. 563243830Sdim /// Note, the superclass's properties are not included in the list. 564249423Sdim virtual void collectPropertiesToImplement(PropertyMap &PM, 565249423Sdim PropertyDeclOrder &PO) const {} 566243830Sdim 567226633Sdim SourceLocation getAtStartLoc() const { return AtStart; } 568226633Sdim void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } 569226633Sdim 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 578234353Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 579226633Sdim 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 597239462Sdim/// \brief Represents an ObjC class declaration. 598193326Sed/// 599239462Sdim/// For example: 600239462Sdim/// 601239462Sdim/// \code 602193326Sed/// // MostPrimitive declares no super class (not particularly useful). 603239462Sdim/// \@interface MostPrimitive 604193326Sed/// // no instance variables or methods. 605239462Sdim/// \@end 606193326Sed/// 607198092Srdivacky/// // NSResponder inherits from NSObject & implements NSCoding (a protocol). 608239462Sdim/// \@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 614239462Sdim/// \@end // to an NSEvent. 615239462Sdim/// \endcode 616193326Sed/// 617239462Sdim/// Unlike C/C++, forward class declarations are accomplished with \@class. 618239462Sdim/// 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/// 622234353Sdimclass ObjCInterfaceDecl : public ObjCContainerDecl 623234353Sdim , public Redeclarable<ObjCInterfaceDecl> { 624234353Sdim virtual void anchor(); 625234353Sdim 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; 630234353Sdim 631234353Sdim struct DefinitionData { 632234353Sdim /// \brief The definition of this class, for quick access from any 633234353Sdim /// declaration. 634234353Sdim ObjCInterfaceDecl *Definition; 635234353Sdim 636234353Sdim /// Class's super class. 637234353Sdim ObjCInterfaceDecl *SuperClass; 638198092Srdivacky 639239462Sdim /// Protocols referenced in the \@interface declaration 640234353Sdim ObjCProtocolList ReferencedProtocols; 641198092Srdivacky 642239462Sdim /// Protocols reference in both the \@interface and class extensions. 643234353Sdim ObjCList<ObjCProtocolDecl> AllReferencedProtocols; 644198092Srdivacky 645234353Sdim /// \brief List of categories and class extensions defined for this class. 646234353Sdim /// 647234353Sdim /// Categories are stored as a linked list in the AST, since the categories 648234353Sdim /// and class extensions come long after the initial interface declaration, 649234353Sdim /// and we avoid dynamically-resized arrays in the AST wherever possible. 650234353Sdim ObjCCategoryDecl *CategoryList; 651198092Srdivacky 652234353Sdim /// IvarList - List of all ivars defined by this class; including class 653234353Sdim /// extensions and implementation. This list is built lazily. 654234353Sdim ObjCIvarDecl *IvarList; 655193326Sed 656234353Sdim /// \brief Indicates that the contents of this Objective-C class will be 657234353Sdim /// completed by the external AST source when required. 658234353Sdim mutable bool ExternallyCompleted : 1; 659234353Sdim 660249423Sdim /// \brief Indicates that the ivar cache does not yet include ivars 661249423Sdim /// declared in the implementation. 662249423Sdim mutable bool IvarListMissingImplementation : 1; 663249423Sdim 664234353Sdim /// \brief The location of the superclass, if any. 665234353Sdim SourceLocation SuperClassLoc; 666234353Sdim 667234353Sdim /// \brief The location of the last location in this declaration, before 668234353Sdim /// the properties/methods. For example, this will be the '>', '}', or 669234353Sdim /// identifier, 670234353Sdim SourceLocation EndLoc; 671234353Sdim 672234353Sdim DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), 673249423Sdim ExternallyCompleted(), 674249423Sdim IvarListMissingImplementation(true) { } 675234353Sdim }; 676234353Sdim 677193326Sed ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, 678234353Sdim SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, 679234353Sdim bool isInternal); 680198092Srdivacky 681218893Sdim void LoadExternalDefinition() const; 682234353Sdim 683234353Sdim /// \brief Contains a pointer to the data associated with this class, 684234353Sdim /// which will be NULL if this class has not yet been defined. 685249423Sdim /// 686249423Sdim /// The bit indicates when we don't need to check for out-of-date 687249423Sdim /// declarations. It will be set unless modules are enabled. 688249423Sdim llvm::PointerIntPair<DefinitionData *, 1, bool> Data; 689234353Sdim 690234353Sdim DefinitionData &data() const { 691249423Sdim assert(Data.getPointer() && "Declaration has no definition!"); 692249423Sdim return *Data.getPointer(); 693234353Sdim } 694234353Sdim 695234353Sdim /// \brief Allocate the definition data for this class. 696234353Sdim void allocateDefinitionData(); 697234353Sdim 698234353Sdim typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base; 699234353Sdim virtual ObjCInterfaceDecl *getNextRedeclaration() { 700249423Sdim return RedeclLink.getNext(); 701234353Sdim } 702234353Sdim virtual ObjCInterfaceDecl *getPreviousDeclImpl() { 703234353Sdim return getPreviousDecl(); 704234353Sdim } 705234353Sdim virtual ObjCInterfaceDecl *getMostRecentDeclImpl() { 706234353Sdim return getMostRecentDecl(); 707234353Sdim } 708234353Sdim 709193326Sedpublic: 710234353Sdim static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC, 711193326Sed SourceLocation atLoc, 712198092Srdivacky IdentifierInfo *Id, 713234353Sdim ObjCInterfaceDecl *PrevDecl, 714193326Sed SourceLocation ClassLoc = SourceLocation(), 715193326Sed bool isInternal = false); 716234353Sdim 717234353Sdim static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); 718234353Sdim 719234353Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 720234353Sdim if (isThisDeclarationADefinition()) 721234353Sdim return ObjCContainerDecl::getSourceRange(); 722234353Sdim 723234353Sdim return SourceRange(getAtStartLoc(), getLocation()); 724234353Sdim } 725234353Sdim 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(); 730234353Sdim 731202879Srdivacky const ObjCProtocolList &getReferencedProtocols() const { 732234353Sdim assert(hasDefinition() && "Caller did not check for forward reference!"); 733234353Sdim if (data().ExternallyCompleted) 734218893Sdim LoadExternalDefinition(); 735234353Sdim 736234353Sdim 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; 753234353Sdim 754212904Sdim protocol_iterator protocol_begin() const { 755234353Sdim // FIXME: Should make sure no callers ever do this. 756234353Sdim if (!hasDefinition()) 757234353Sdim return protocol_iterator(); 758234353Sdim 759234353Sdim if (data().ExternallyCompleted) 760218893Sdim LoadExternalDefinition(); 761218893Sdim 762234353Sdim return data().ReferencedProtocols.begin(); 763212904Sdim } 764212904Sdim protocol_iterator protocol_end() const { 765234353Sdim // FIXME: Should make sure no callers ever do this. 766234353Sdim if (!hasDefinition()) 767234353Sdim return protocol_iterator(); 768234353Sdim 769234353Sdim if (data().ExternallyCompleted) 770218893Sdim LoadExternalDefinition(); 771218893Sdim 772234353Sdim return data().ReferencedProtocols.end(); 773212904Sdim } 774212904Sdim 775202879Srdivacky typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 776212904Sdim 777234353Sdim protocol_loc_iterator protocol_loc_begin() const { 778234353Sdim // FIXME: Should make sure no callers ever do this. 779234353Sdim if (!hasDefinition()) 780234353Sdim return protocol_loc_iterator(); 781234353Sdim 782234353Sdim if (data().ExternallyCompleted) 783218893Sdim LoadExternalDefinition(); 784218893Sdim 785234353Sdim return data().ReferencedProtocols.loc_begin(); 786202879Srdivacky } 787212904Sdim 788234353Sdim protocol_loc_iterator protocol_loc_end() const { 789234353Sdim // FIXME: Should make sure no callers ever do this. 790234353Sdim if (!hasDefinition()) 791234353Sdim return protocol_loc_iterator(); 792234353Sdim 793234353Sdim if (data().ExternallyCompleted) 794218893Sdim LoadExternalDefinition(); 795218893Sdim 796234353Sdim return data().ReferencedProtocols.loc_end(); 797202879Srdivacky } 798234353Sdim 799212904Sdim typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator; 800234353Sdim 801212904Sdim all_protocol_iterator all_referenced_protocol_begin() const { 802234353Sdim // FIXME: Should make sure no callers ever do this. 803234353Sdim if (!hasDefinition()) 804234353Sdim return all_protocol_iterator(); 805234353Sdim 806234353Sdim if (data().ExternallyCompleted) 807218893Sdim LoadExternalDefinition(); 808218893Sdim 809234353Sdim return data().AllReferencedProtocols.empty() 810234353Sdim ? protocol_begin() 811234353Sdim : data().AllReferencedProtocols.begin(); 812212904Sdim } 813212904Sdim all_protocol_iterator all_referenced_protocol_end() const { 814234353Sdim // FIXME: Should make sure no callers ever do this. 815234353Sdim if (!hasDefinition()) 816234353Sdim return all_protocol_iterator(); 817234353Sdim 818234353Sdim if (data().ExternallyCompleted) 819218893Sdim LoadExternalDefinition(); 820218893Sdim 821234353Sdim return data().AllReferencedProtocols.empty() 822234353Sdim ? protocol_end() 823234353Sdim : data().AllReferencedProtocols.end(); 824212904Sdim } 825193326Sed 826204643Srdivacky typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; 827212904Sdim 828234353Sdim ivar_iterator ivar_begin() const { 829234353Sdim if (const ObjCInterfaceDecl *Def = getDefinition()) 830234353Sdim return ivar_iterator(Def->decls_begin()); 831234353Sdim 832234353Sdim // FIXME: Should make sure no callers ever do this. 833234353Sdim return ivar_iterator(); 834234353Sdim } 835234353Sdim ivar_iterator ivar_end() const { 836234353Sdim if (const ObjCInterfaceDecl *Def = getDefinition()) 837234353Sdim return ivar_iterator(Def->decls_end()); 838212904Sdim 839234353Sdim // FIXME: Should make sure no callers ever do this. 840234353Sdim return ivar_iterator(); 841234353Sdim } 842234353Sdim 843204643Srdivacky unsigned ivar_size() const { 844204643Srdivacky return std::distance(ivar_begin(), ivar_end()); 845204643Srdivacky } 846234353Sdim 847204643Srdivacky bool ivar_empty() const { return ivar_begin() == ivar_end(); } 848234353Sdim 849226633Sdim ObjCIvarDecl *all_declared_ivar_begin(); 850226633Sdim const ObjCIvarDecl *all_declared_ivar_begin() const { 851226633Sdim // Even though this modifies IvarList, it's conceptually const: 852226633Sdim // the ivar chain is essentially a cached property of ObjCInterfaceDecl. 853226633Sdim return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin(); 854226633Sdim } 855234353Sdim void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; } 856234353Sdim 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) { 861234353Sdim 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. 866234353Sdim void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List, 867202879Srdivacky unsigned Num, 868202879Srdivacky ASTContext &C); 869198092Srdivacky 870234353Sdim /// \brief Determine whether this particular declaration of this class is 871234353Sdim /// actually also a definition. 872234353Sdim bool isThisDeclarationADefinition() const { 873249423Sdim return getDefinition() == this; 874234353Sdim } 875234353Sdim 876234353Sdim /// \brief Determine whether this class has been defined. 877249423Sdim bool hasDefinition() const { 878249423Sdim // If the name of this class is out-of-date, bring it up-to-date, which 879249423Sdim // might bring in a definition. 880249423Sdim // Note: a null value indicates that we don't have a definition and that 881249423Sdim // modules are enabled. 882249423Sdim if (!Data.getOpaqueValue()) { 883249423Sdim if (IdentifierInfo *II = getIdentifier()) { 884249423Sdim if (II->isOutOfDate()) { 885249423Sdim updateOutOfDate(*II); 886249423Sdim } 887249423Sdim } 888249423Sdim } 889249423Sdim 890249423Sdim return Data.getPointer(); 891249423Sdim } 892234353Sdim 893234353Sdim /// \brief Retrieve the definition of this class, or NULL if this class 894239462Sdim /// has been forward-declared (with \@class) but not yet defined (with 895239462Sdim /// \@interface). 896234353Sdim ObjCInterfaceDecl *getDefinition() { 897249423Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 898234353Sdim } 899198092Srdivacky 900234353Sdim /// \brief Retrieve the definition of this class, or NULL if this class 901239462Sdim /// has been forward-declared (with \@class) but not yet defined (with 902239462Sdim /// \@interface). 903234353Sdim const ObjCInterfaceDecl *getDefinition() const { 904249423Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 905234353Sdim } 906234353Sdim 907234353Sdim /// \brief Starts the definition of this Objective-C class, taking it from 908239462Sdim /// a forward declaration (\@class) to a definition (\@interface). 909234353Sdim void startDefinition(); 910234353Sdim 911234353Sdim ObjCInterfaceDecl *getSuperClass() const { 912234353Sdim // FIXME: Should make sure no callers ever do this. 913234353Sdim if (!hasDefinition()) 914234353Sdim return 0; 915234353Sdim 916234353Sdim if (data().ExternallyCompleted) 917218893Sdim LoadExternalDefinition(); 918218893Sdim 919234353Sdim return data().SuperClass; 920218893Sdim } 921198092Srdivacky 922234353Sdim void setSuperClass(ObjCInterfaceDecl * superCls) { 923234353Sdim data().SuperClass = 924234353Sdim (superCls && superCls->hasDefinition()) ? superCls->getDefinition() 925234353Sdim : superCls; 926234353Sdim } 927234353Sdim 928249423Sdim /// \brief Iterator that walks over the list of categories, filtering out 929249423Sdim /// those that do not meet specific criteria. 930249423Sdim /// 931249423Sdim /// This class template is used for the various permutations of category 932249423Sdim /// and extension iterators. 933249423Sdim template<bool (*Filter)(ObjCCategoryDecl *)> 934249423Sdim class filtered_category_iterator { 935249423Sdim ObjCCategoryDecl *Current; 936249423Sdim 937249423Sdim void findAcceptableCategory(); 938249423Sdim 939249423Sdim public: 940249423Sdim typedef ObjCCategoryDecl * value_type; 941249423Sdim typedef value_type reference; 942249423Sdim typedef value_type pointer; 943249423Sdim typedef std::ptrdiff_t difference_type; 944249423Sdim typedef std::input_iterator_tag iterator_category; 945249423Sdim 946249423Sdim filtered_category_iterator() : Current(0) { } 947249423Sdim explicit filtered_category_iterator(ObjCCategoryDecl *Current) 948249423Sdim : Current(Current) 949249423Sdim { 950249423Sdim findAcceptableCategory(); 951249423Sdim } 952249423Sdim 953249423Sdim reference operator*() const { return Current; } 954249423Sdim pointer operator->() const { return Current; } 955249423Sdim 956249423Sdim filtered_category_iterator &operator++(); 957249423Sdim 958249423Sdim filtered_category_iterator operator++(int) { 959249423Sdim filtered_category_iterator Tmp = *this; 960249423Sdim ++(*this); 961249423Sdim return Tmp; 962249423Sdim } 963249423Sdim 964249423Sdim friend bool operator==(filtered_category_iterator X, 965249423Sdim filtered_category_iterator Y) { 966249423Sdim return X.Current == Y.Current; 967249423Sdim } 968249423Sdim 969249423Sdim friend bool operator!=(filtered_category_iterator X, 970249423Sdim filtered_category_iterator Y) { 971249423Sdim return X.Current != Y.Current; 972249423Sdim } 973249423Sdim }; 974249423Sdim 975249423Sdimprivate: 976249423Sdim /// \brief Test whether the given category is visible. 977249423Sdim /// 978249423Sdim /// Used in the \c visible_categories_iterator. 979249423Sdim static bool isVisibleCategory(ObjCCategoryDecl *Cat); 980249423Sdim 981249423Sdimpublic: 982249423Sdim /// \brief Iterator that walks over the list of categories and extensions 983249423Sdim /// that are visible, i.e., not hidden in a non-imported submodule. 984249423Sdim typedef filtered_category_iterator<isVisibleCategory> 985249423Sdim visible_categories_iterator; 986249423Sdim 987249423Sdim /// \brief Retrieve an iterator to the beginning of the visible-categories 988249423Sdim /// list. 989249423Sdim visible_categories_iterator visible_categories_begin() const { 990249423Sdim return visible_categories_iterator(getCategoryListRaw()); 991249423Sdim } 992249423Sdim 993249423Sdim /// \brief Retrieve an iterator to the end of the visible-categories list. 994249423Sdim visible_categories_iterator visible_categories_end() const { 995249423Sdim return visible_categories_iterator(); 996249423Sdim } 997249423Sdim 998249423Sdim /// \brief Determine whether the visible-categories list is empty. 999249423Sdim bool visible_categories_empty() const { 1000249423Sdim return visible_categories_begin() == visible_categories_end(); 1001249423Sdim } 1002249423Sdim 1003249423Sdimprivate: 1004249423Sdim /// \brief Test whether the given category... is a category. 1005249423Sdim /// 1006249423Sdim /// Used in the \c known_categories_iterator. 1007249423Sdim static bool isKnownCategory(ObjCCategoryDecl *) { return true; } 1008249423Sdim 1009249423Sdimpublic: 1010249423Sdim /// \brief Iterator that walks over all of the known categories and 1011249423Sdim /// extensions, including those that are hidden. 1012249423Sdim typedef filtered_category_iterator<isKnownCategory> known_categories_iterator; 1013249423Sdim 1014249423Sdim /// \brief Retrieve an iterator to the beginning of the known-categories 1015249423Sdim /// list. 1016249423Sdim known_categories_iterator known_categories_begin() const { 1017249423Sdim return known_categories_iterator(getCategoryListRaw()); 1018249423Sdim } 1019249423Sdim 1020249423Sdim /// \brief Retrieve an iterator to the end of the known-categories list. 1021249423Sdim known_categories_iterator known_categories_end() const { 1022249423Sdim return known_categories_iterator(); 1023249423Sdim } 1024249423Sdim 1025249423Sdim /// \brief Determine whether the known-categories list is empty. 1026249423Sdim bool known_categories_empty() const { 1027249423Sdim return known_categories_begin() == known_categories_end(); 1028249423Sdim } 1029249423Sdim 1030249423Sdimprivate: 1031249423Sdim /// \brief Test whether the given category is a visible extension. 1032249423Sdim /// 1033249423Sdim /// Used in the \c visible_extensions_iterator. 1034249423Sdim static bool isVisibleExtension(ObjCCategoryDecl *Cat); 1035249423Sdim 1036249423Sdimpublic: 1037249423Sdim /// \brief Iterator that walks over all of the visible extensions, skipping 1038249423Sdim /// any that are known but hidden. 1039249423Sdim typedef filtered_category_iterator<isVisibleExtension> 1040249423Sdim visible_extensions_iterator; 1041249423Sdim 1042249423Sdim /// \brief Retrieve an iterator to the beginning of the visible-extensions 1043249423Sdim /// list. 1044249423Sdim visible_extensions_iterator visible_extensions_begin() const { 1045249423Sdim return visible_extensions_iterator(getCategoryListRaw()); 1046249423Sdim } 1047249423Sdim 1048249423Sdim /// \brief Retrieve an iterator to the end of the visible-extensions list. 1049249423Sdim visible_extensions_iterator visible_extensions_end() const { 1050249423Sdim return visible_extensions_iterator(); 1051249423Sdim } 1052249423Sdim 1053249423Sdim /// \brief Determine whether the visible-extensions list is empty. 1054249423Sdim bool visible_extensions_empty() const { 1055249423Sdim return visible_extensions_begin() == visible_extensions_end(); 1056249423Sdim } 1057249423Sdim 1058249423Sdimprivate: 1059249423Sdim /// \brief Test whether the given category is an extension. 1060249423Sdim /// 1061249423Sdim /// Used in the \c known_extensions_iterator. 1062249423Sdim static bool isKnownExtension(ObjCCategoryDecl *Cat); 1063249423Sdim 1064249423Sdimpublic: 1065249423Sdim /// \brief Iterator that walks over all of the known extensions. 1066249423Sdim typedef filtered_category_iterator<isKnownExtension> 1067249423Sdim known_extensions_iterator; 1068249423Sdim 1069249423Sdim /// \brief Retrieve an iterator to the beginning of the known-extensions 1070249423Sdim /// list. 1071249423Sdim known_extensions_iterator known_extensions_begin() const { 1072249423Sdim return known_extensions_iterator(getCategoryListRaw()); 1073249423Sdim } 1074249423Sdim 1075249423Sdim /// \brief Retrieve an iterator to the end of the known-extensions list. 1076249423Sdim known_extensions_iterator known_extensions_end() const { 1077249423Sdim return known_extensions_iterator(); 1078249423Sdim } 1079249423Sdim 1080249423Sdim /// \brief Determine whether the known-extensions list is empty. 1081249423Sdim bool known_extensions_empty() const { 1082249423Sdim return known_extensions_begin() == known_extensions_end(); 1083249423Sdim } 1084249423Sdim 1085249423Sdim /// \brief Retrieve the raw pointer to the start of the category/extension 1086249423Sdim /// list. 1087249423Sdim ObjCCategoryDecl* getCategoryListRaw() const { 1088234353Sdim // FIXME: Should make sure no callers ever do this. 1089234353Sdim if (!hasDefinition()) 1090234353Sdim return 0; 1091234353Sdim 1092234353Sdim if (data().ExternallyCompleted) 1093218893Sdim LoadExternalDefinition(); 1094218893Sdim 1095234353Sdim return data().CategoryList; 1096218893Sdim } 1097234353Sdim 1098249423Sdim /// \brief Set the raw pointer to the start of the category/extension 1099249423Sdim /// list. 1100249423Sdim void setCategoryListRaw(ObjCCategoryDecl *category) { 1101234353Sdim data().CategoryList = category; 1102193326Sed } 1103234353Sdim 1104205219Srdivacky ObjCPropertyDecl 1105205219Srdivacky *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; 1106205219Srdivacky 1107249423Sdim virtual void collectPropertiesToImplement(PropertyMap &PM, 1108249423Sdim PropertyDeclOrder &PO) const; 1109243830Sdim 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) { 1115234353Sdim if (declaresSameEntity(this, I)) 1116193326Sed return true; 1117234353Sdim 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. 1125249423Sdim bool isArcWeakrefUnavailable() const; 1126224145Sdim 1127234353Sdim /// isObjCRequiresPropertyDefs - Checks that a class or one of its super 1128239462Sdim /// classes must not be auto-synthesized. Returns class decl. if it must not 1129239462Sdim /// be; 0, otherwise. 1130249423Sdim const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const; 1131234353Sdim 1132195341Sed ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName, 1133193326Sed ObjCInterfaceDecl *&ClassDeclared); 1134195341Sed ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) { 1135193326Sed ObjCInterfaceDecl *ClassDeclared; 1136195341Sed return lookupInstanceVariable(IVarName, ClassDeclared); 1137193326Sed } 1138193326Sed 1139263508Sdim ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name); 1140263508Sdim 1141193326Sed // Lookup a method. First, we search locally. If a method isn't 1142193326Sed // found, we search referenced protocols and class categories. 1143234353Sdim ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, 1144251662Sdim bool shallowCategoryLookup= false, 1145251662Sdim const ObjCCategoryDecl *C= 0) const; 1146234353Sdim ObjCMethodDecl *lookupInstanceMethod(Selector Sel, 1147234353Sdim bool shallowCategoryLookup = false) const { 1148234353Sdim return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); 1149198092Srdivacky } 1150234353Sdim ObjCMethodDecl *lookupClassMethod(Selector Sel, 1151234353Sdim bool shallowCategoryLookup = false) const { 1152234353Sdim return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup); 1153198092Srdivacky } 1154193326Sed ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); 1155234353Sdim 1156239462Sdim /// \brief Lookup a method in the classes implementation hierarchy. 1157239462Sdim ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, 1158239462Sdim bool Instance=true) const; 1159193326Sed 1160239462Sdim ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) { 1161239462Sdim return lookupPrivateMethod(Sel, false); 1162239462Sdim } 1163239462Sdim 1164251662Sdim /// \brief Lookup a setter or getter in the class hierarchy, 1165251662Sdim /// including in all categories except for category passed 1166251662Sdim /// as argument. 1167251662Sdim ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, 1168251662Sdim const ObjCCategoryDecl *Cat) const { 1169251662Sdim return lookupMethod(Sel, true/*isInstance*/, 1170251662Sdim false/*shallowCategoryLookup*/, Cat); 1171251662Sdim } 1172251662Sdim 1173234353Sdim SourceLocation getEndOfDefinitionLoc() const { 1174234353Sdim if (!hasDefinition()) 1175234353Sdim return getLocation(); 1176234353Sdim 1177234353Sdim return data().EndLoc; 1178234353Sdim } 1179234353Sdim 1180234353Sdim void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; } 1181198092Srdivacky 1182234353Sdim void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; } 1183234353Sdim SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; } 1184198092Srdivacky 1185193326Sed /// isImplicitInterfaceDecl - check that this is an implicitly declared 1186239462Sdim /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation 1187239462Sdim /// declaration without an \@interface declaration. 1188234353Sdim bool isImplicitInterfaceDecl() const { 1189249423Sdim return hasDefinition() ? data().Definition->isImplicit() : isImplicit(); 1190234353Sdim } 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 1199234353Sdim typedef redeclarable_base::redecl_iterator redecl_iterator; 1200234353Sdim using redeclarable_base::redecls_begin; 1201234353Sdim using redeclarable_base::redecls_end; 1202234353Sdim using redeclarable_base::getPreviousDecl; 1203234353Sdim using redeclarable_base::getMostRecentDecl; 1204263508Sdim using redeclarable_base::isFirstDecl; 1205234353Sdim 1206234353Sdim /// Retrieves the canonical declaration of this Objective-C class. 1207263508Sdim ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); } 1208263508Sdim const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); } 1209234353Sdim 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 1217234353Sdim 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/// 1226239462Sdim/// \@interface IvarExample : NSObject 1227193326Sed/// { 1228193326Sed/// id defaultToProtected; 1229239462Sdim/// \@public: 1230193326Sed/// id canBePublic; // same as C++. 1231239462Sdim/// \@protected: 1232193326Sed/// id canBeProtected; // same as C++. 1233239462Sdim/// \@package: 1234193326Sed/// id canBePackage; // framework visibility (not available in C++). 1235193326Sed/// } 1236193326Sed/// 1237193326Sedclass ObjCIvarDecl : public FieldDecl { 1238234353Sdim virtual void anchor(); 1239234353Sdim 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, 1249263508Sdim bool synthesized, 1250263508Sdim bool backingIvarReferencedInAccessor) 1251221345Sdim : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, 1252239462Sdim /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), 1253263508Sdim NextIvar(0), DeclAccess(ac), Synthesized(synthesized), 1254263508Sdim 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, 1262263508Sdim bool synthesized=false, 1263263508Sdim bool backingIvarReferencedInAccessor=false); 1264198092Srdivacky 1265234353Sdim static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1266234353Sdim 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; 1272234353Sdim 1273212904Sdim ObjCIvarDecl *getNextIvar() { return NextIvar; } 1274226633Sdim 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 1285263508Sdim void setBackingIvarReferencedInAccessor(bool val) { 1286263508Sdim BackingIvarReferencedInAccessor = val; 1287263508Sdim } 1288263508Sdim bool getBackingIvarReferencedInAccessor() const { 1289263508Sdim return BackingIvarReferencedInAccessor; 1290263508Sdim } 1291263508Sdim 1292212904Sdim void setSynthesize(bool synth) { Synthesized = synth; } 1293212904Sdim bool getSynthesize() const { return Synthesized; } 1294234353Sdim 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: 1299234353Sdim /// NextIvar - Next Ivar in the list of ivars declared in class; class's 1300212904Sdim /// extensions and class's implementation 1301212904Sdim ObjCIvarDecl *NextIvar; 1302234353Sdim 1303193326Sed // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum 1304193326Sed unsigned DeclAccess : 3; 1305212904Sdim unsigned Synthesized : 1; 1306263508Sdim unsigned BackingIvarReferencedInAccessor : 1; 1307193326Sed}; 1308193326Sed 1309198092Srdivacky 1310239462Sdim/// \brief Represents a field declaration created by an \@defs(...). 1311193326Sedclass ObjCAtDefsFieldDecl : public FieldDecl { 1312234353Sdim 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 ? 1318239462Sdim 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 1326234353Sdim static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1327234353Sdim 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 1333239462Sdim/// \brief Represents an Objective-C protocol declaration. 1334193326Sed/// 1335239462Sdim/// Objective-C protocols declare a pure abstract type (i.e., no instance 1336239462Sdim/// variables are permitted). Protocols originally drew inspiration from 1337239462Sdim/// C++ pure virtual functions (a C++ feature with nice semantics and lousy 1338239462Sdim/// syntax:-). Here is an example: 1339239462Sdim/// 1340239462Sdim/// \code 1341239462Sdim/// \@protocol NSDraggingInfo <refproto1, refproto2> 1342193326Sed/// - (NSWindow *)draggingDestinationWindow; 1343193326Sed/// - (NSImage *)draggedImage; 1344239462Sdim/// \@end 1345239462Sdim/// \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/// 1351239462Sdim/// \code 1352239462Sdim/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo> 1353239462Sdim/// \@end 1354239462Sdim/// \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/// 1361239462Sdim/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; 1362193326Sed/// 1363234353Sdimclass ObjCProtocolDecl : public ObjCContainerDecl, 1364234353Sdim public Redeclarable<ObjCProtocolDecl> { 1365234353Sdim virtual void anchor(); 1366198092Srdivacky 1367234353Sdim struct DefinitionData { 1368234353Sdim // \brief The declaration that defines this protocol. 1369234353Sdim ObjCProtocolDecl *Definition; 1370198092Srdivacky 1371234353Sdim /// \brief Referenced protocols 1372234353Sdim ObjCProtocolList ReferencedProtocols; 1373234353Sdim }; 1374198092Srdivacky 1375249423Sdim /// \brief Contains a pointer to the data associated with this class, 1376249423Sdim /// which will be NULL if this class has not yet been defined. 1377249423Sdim /// 1378249423Sdim /// The bit indicates when we don't need to check for out-of-date 1379249423Sdim /// declarations. It will be set unless modules are enabled. 1380249423Sdim llvm::PointerIntPair<DefinitionData *, 1, bool> Data; 1381249423Sdim 1382234353Sdim DefinitionData &data() const { 1383249423Sdim assert(Data.getPointer() && "Objective-C protocol has no definition!"); 1384249423Sdim return *Data.getPointer(); 1385234353Sdim } 1386234353Sdim 1387226633Sdim ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id, 1388234353Sdim SourceLocation nameLoc, SourceLocation atStartLoc, 1389234353Sdim ObjCProtocolDecl *PrevDecl); 1390234353Sdim 1391234353Sdim void allocateDefinitionData(); 1392234353Sdim 1393234353Sdim typedef Redeclarable<ObjCProtocolDecl> redeclarable_base; 1394234353Sdim virtual ObjCProtocolDecl *getNextRedeclaration() { 1395234353Sdim return RedeclLink.getNext(); 1396193326Sed } 1397234353Sdim virtual ObjCProtocolDecl *getPreviousDeclImpl() { 1398234353Sdim return getPreviousDecl(); 1399234353Sdim } 1400234353Sdim virtual ObjCProtocolDecl *getMostRecentDeclImpl() { 1401234353Sdim return getMostRecentDecl(); 1402234353Sdim } 1403249423Sdim 1404193326Sedpublic: 1405198092Srdivacky static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, 1406226633Sdim IdentifierInfo *Id, 1407226633Sdim SourceLocation nameLoc, 1408234353Sdim SourceLocation atStartLoc, 1409234353Sdim ObjCProtocolDecl *PrevDecl); 1410193326Sed 1411234353Sdim static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1412234353Sdim 1413202879Srdivacky const ObjCProtocolList &getReferencedProtocols() const { 1414234353Sdim assert(hasDefinition() && "No definition available!"); 1415234353Sdim return data().ReferencedProtocols; 1416193326Sed } 1417202879Srdivacky typedef ObjCProtocolList::iterator protocol_iterator; 1418234353Sdim protocol_iterator protocol_begin() const { 1419234353Sdim if (!hasDefinition()) 1420234353Sdim return protocol_iterator(); 1421234353Sdim 1422234353Sdim return data().ReferencedProtocols.begin(); 1423234353Sdim } 1424234353Sdim protocol_iterator protocol_end() const { 1425234353Sdim if (!hasDefinition()) 1426234353Sdim return protocol_iterator(); 1427234353Sdim 1428234353Sdim return data().ReferencedProtocols.end(); 1429234353Sdim } 1430202879Srdivacky typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; 1431234353Sdim protocol_loc_iterator protocol_loc_begin() const { 1432234353Sdim if (!hasDefinition()) 1433234353Sdim return protocol_loc_iterator(); 1434234353Sdim 1435234353Sdim return data().ReferencedProtocols.loc_begin(); 1436202879Srdivacky } 1437234353Sdim protocol_loc_iterator protocol_loc_end() const { 1438234353Sdim if (!hasDefinition()) 1439234353Sdim return protocol_loc_iterator(); 1440234353Sdim 1441234353Sdim return data().ReferencedProtocols.loc_end(); 1442202879Srdivacky } 1443234353Sdim unsigned protocol_size() const { 1444234353Sdim if (!hasDefinition()) 1445234353Sdim return 0; 1446234353Sdim 1447234353Sdim return data().ReferencedProtocols.size(); 1448234353Sdim } 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) { 1454249423Sdim assert(hasDefinition() && "Protocol is not defined"); 1455234353Sdim 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 1470234353Sdim /// \brief Determine whether this protocol has a definition. 1471249423Sdim bool hasDefinition() const { 1472249423Sdim // If the name of this protocol is out-of-date, bring it up-to-date, which 1473249423Sdim // might bring in a definition. 1474249423Sdim // Note: a null value indicates that we don't have a definition and that 1475249423Sdim // modules are enabled. 1476249423Sdim if (!Data.getOpaqueValue()) { 1477249423Sdim if (IdentifierInfo *II = getIdentifier()) { 1478249423Sdim if (II->isOutOfDate()) { 1479249423Sdim updateOutOfDate(*II); 1480249423Sdim } 1481249423Sdim } 1482249423Sdim } 1483198092Srdivacky 1484249423Sdim return Data.getPointer(); 1485249423Sdim } 1486249423Sdim 1487234353Sdim /// \brief Retrieve the definition of this protocol, if any. 1488234353Sdim ObjCProtocolDecl *getDefinition() { 1489249423Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 1490234353Sdim } 1491198092Srdivacky 1492234353Sdim /// \brief Retrieve the definition of this protocol, if any. 1493234353Sdim const ObjCProtocolDecl *getDefinition() const { 1494249423Sdim return hasDefinition()? Data.getPointer()->Definition : 0; 1495234353Sdim } 1496198092Srdivacky 1497234353Sdim /// \brief Determine whether this particular declaration is also the 1498234353Sdim /// definition. 1499234353Sdim bool isThisDeclarationADefinition() const { 1500234353Sdim return getDefinition() == this; 1501234353Sdim } 1502199482Srdivacky 1503234353Sdim /// \brief Starts the definition of this Objective-C protocol. 1504234353Sdim void startDefinition(); 1505198092Srdivacky 1506234353Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 1507234353Sdim if (isThisDeclarationADefinition()) 1508234353Sdim return ObjCContainerDecl::getSourceRange(); 1509234353Sdim 1510234353Sdim return SourceRange(getAtStartLoc(), getLocation()); 1511202879Srdivacky } 1512234353Sdim 1513234353Sdim typedef redeclarable_base::redecl_iterator redecl_iterator; 1514234353Sdim using redeclarable_base::redecls_begin; 1515234353Sdim using redeclarable_base::redecls_end; 1516234353Sdim using redeclarable_base::getPreviousDecl; 1517234353Sdim using redeclarable_base::getMostRecentDecl; 1518263508Sdim using redeclarable_base::isFirstDecl; 1519202879Srdivacky 1520234353Sdim /// Retrieves the canonical declaration of this Objective-C protocol. 1521263508Sdim ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); } 1522263508Sdim const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); } 1523202879Srdivacky 1524249423Sdim virtual void collectPropertiesToImplement(PropertyMap &PM, 1525249423Sdim PropertyDeclOrder &PO) const; 1526263508Sdim 1527263508Sdimvoid collectInheritedProtocolProperties(const ObjCPropertyDecl *Property, 1528263508Sdim ProtocolPropertyMap &PM) const; 1529243830Sdim 1530234353Sdim static bool classof(const Decl *D) { return classofKind(D->getKind()); } 1531234353Sdim static bool classofKind(Kind K) { return K == ObjCProtocol; } 1532193326Sed 1533234353Sdim friend class ASTReader; 1534234353Sdim friend class ASTDeclReader; 1535234353Sdim 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/// 1544239462Sdim/// \@interface NSView (MyViewMethods) 1545193326Sed/// - myMethod; 1546239462Sdim/// \@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 { 1556234353Sdim virtual void anchor(); 1557234353Sdim 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 1571234353Sdim /// class extension may have private ivars. 1572234353Sdim SourceLocation IvarLBraceLoc; 1573234353Sdim SourceLocation IvarRBraceLoc; 1574234353Sdim 1575234353Sdim ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, 1576202879Srdivacky SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, 1577234353Sdim IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, 1578234353Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1579234353Sdim SourceLocation IvarRBraceLoc=SourceLocation()) 1580226633Sdim : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), 1581239462Sdim ClassInterface(IDecl), NextClassCategory(0), 1582234353Sdim CategoryNameLoc(CategoryNameLoc), 1583234353Sdim IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { 1584193326Sed } 1585249423Sdim 1586193326Sedpublic: 1587198092Srdivacky 1588193326Sed static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, 1589234353Sdim SourceLocation AtLoc, 1590202879Srdivacky SourceLocation ClassNameLoc, 1591202879Srdivacky SourceLocation CategoryNameLoc, 1592226633Sdim IdentifierInfo *Id, 1593234353Sdim ObjCInterfaceDecl *IDecl, 1594234353Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1595234353Sdim SourceLocation IvarRBraceLoc=SourceLocation()); 1596234353Sdim 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; 1620234353Sdim protocol_loc_iterator protocol_loc_begin() const { 1621234353Sdim return ReferencedProtocols.loc_begin(); 1622202879Srdivacky } 1623234353Sdim protocol_loc_iterator protocol_loc_end() const { 1624234353Sdim return ReferencedProtocols.loc_end(); 1625202879Srdivacky } 1626198092Srdivacky 1627193326Sed ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; } 1628198092Srdivacky 1629249423Sdim /// \brief Retrieve the pointer to the next stored category (or extension), 1630249423Sdim /// which may be hidden. 1631249423Sdim ObjCCategoryDecl *getNextClassCategoryRaw() const { 1632249423Sdim return NextClassCategory; 1633249423Sdim } 1634249423Sdim 1635203955Srdivacky bool IsClassExtension() const { return getIdentifier() == 0; } 1636234353Sdim 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; } 1653234353Sdim 1654234353Sdim void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } 1655234353Sdim SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } 1656234353Sdim void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } 1657234353Sdim 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; } 1661226633Sdim 1662226633Sdim friend class ASTDeclReader; 1663226633Sdim friend class ASTDeclWriter; 1664193326Sed}; 1665193326Sed 1666198092Srdivackyclass ObjCImplDecl : public ObjCContainerDecl { 1667234353Sdim virtual void anchor(); 1668234353Sdim 1669198893Srdivacky /// Class interface for this class/category implementation 1670193326Sed ObjCInterfaceDecl *ClassInterface; 1671198092Srdivacky 1672193326Sedprotected: 1673226633Sdim ObjCImplDecl(Kind DK, DeclContext *DC, 1674226633Sdim ObjCInterfaceDecl *classInterface, 1675226633Sdim SourceLocation nameLoc, SourceLocation atStartLoc) 1676226633Sdim : ObjCContainerDecl(DK, DC, 1677226633Sdim classInterface? classInterface->getIdentifier() : 0, 1678226633Sdim 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 1718239462Sdim/// \@implementation declaration. If a category class has declaration of a 1719198092Srdivacky/// property, its implementation must be specified in the category's 1720239462Sdim/// \@implementation declaration. Example: 1721239462Sdim/// \@interface I \@end 1722239462Sdim/// \@interface I(CATEGORY) 1723239462Sdim/// \@property int p1, d1; 1724239462Sdim/// \@end 1725239462Sdim/// \@implementation I(CATEGORY) 1726239462Sdim/// \@dynamic p1,d1; 1727239462Sdim/// \@end 1728193326Sed/// 1729193326Sed/// ObjCCategoryImplDecl 1730193326Sedclass ObjCCategoryImplDecl : public ObjCImplDecl { 1731234353Sdim virtual void anchor(); 1732234353Sdim 1733193326Sed // Category name 1734193326Sed IdentifierInfo *Id; 1735193326Sed 1736234353Sdim // Category name location 1737234353Sdim SourceLocation CategoryNameLoc; 1738234353Sdim 1739226633Sdim ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id, 1740226633Sdim ObjCInterfaceDecl *classInterface, 1741234353Sdim SourceLocation nameLoc, SourceLocation atStartLoc, 1742234353Sdim SourceLocation CategoryNameLoc) 1743226633Sdim : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc), 1744234353Sdim Id(Id), CategoryNameLoc(CategoryNameLoc) {} 1745193326Sedpublic: 1746193326Sed static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, 1747226633Sdim IdentifierInfo *Id, 1748226633Sdim ObjCInterfaceDecl *classInterface, 1749226633Sdim SourceLocation nameLoc, 1750234353Sdim SourceLocation atStartLoc, 1751234353Sdim SourceLocation CategoryNameLoc); 1752234353Sdim 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: 1758234353Sdim /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier() 1759234353Sdim /// returns the class interface name, whereas 1760234353Sdim /// ((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 1769234353Sdim SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } 1770234353Sdim 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. 1776226633Sdim 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;} 1789234353Sdim 1790234353Sdim friend class ASTDeclReader; 1791234353Sdim friend class ASTDeclWriter; 1792193326Sed}; 1793193326Sed 1794234353Sdimraw_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 1800239462Sdim/// \@implementation MyClass 1801193326Sed/// - (void)myMethod { /* do something */ } 1802239462Sdim/// \@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 { 1811234353Sdim virtual void anchor(); 1812193326Sed /// Implementation Class's super class. 1813193326Sed ObjCInterfaceDecl *SuperClass; 1814251662Sdim SourceLocation SuperLoc; 1815251662Sdim 1816239462Sdim /// \@implementation may have private ivars. 1817234353Sdim SourceLocation IvarLBraceLoc; 1818234353Sdim SourceLocation IvarRBraceLoc; 1819234353Sdim 1820207619Srdivacky /// Support for ivar initialization. 1821207619Srdivacky /// IvarInitializers - The arguments used to initialize the ivars 1822218893Sdim CXXCtorInitializer **IvarInitializers; 1823207619Srdivacky unsigned NumIvarInitializers; 1824224145Sdim 1825243830Sdim /// Do the ivars of this class require initialization other than 1826243830Sdim /// zero-initialization? 1827243830Sdim bool HasNonZeroConstructors : 1; 1828234353Sdim 1829243830Sdim /// Do the ivars of this class require non-trivial destruction? 1830243830Sdim bool HasDestructors : 1; 1831243830Sdim 1832226633Sdim ObjCImplementationDecl(DeclContext *DC, 1833193326Sed ObjCInterfaceDecl *classInterface, 1834226633Sdim ObjCInterfaceDecl *superDecl, 1835234353Sdim SourceLocation nameLoc, SourceLocation atStartLoc, 1836251662Sdim SourceLocation superLoc = SourceLocation(), 1837234353Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1838234353Sdim SourceLocation IvarRBraceLoc=SourceLocation()) 1839226633Sdim : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), 1840251662Sdim SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc), 1841234353Sdim IvarRBraceLoc(IvarRBraceLoc), 1842234353Sdim IvarInitializers(0), NumIvarInitializers(0), 1843243830Sdim HasNonZeroConstructors(false), HasDestructors(false) {} 1844198092Srdivackypublic: 1845198092Srdivacky static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, 1846193326Sed ObjCInterfaceDecl *classInterface, 1847226633Sdim ObjCInterfaceDecl *superDecl, 1848226633Sdim SourceLocation nameLoc, 1849234353Sdim SourceLocation atStartLoc, 1850251662Sdim SourceLocation superLoc = SourceLocation(), 1851234353Sdim SourceLocation IvarLBraceLoc=SourceLocation(), 1852234353Sdim SourceLocation IvarRBraceLoc=SourceLocation()); 1853234353Sdim 1854234353Sdim static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); 1855234353Sdim 1856207619Srdivacky /// init_iterator - Iterates through the ivar initializer list. 1857218893Sdim typedef CXXCtorInitializer **init_iterator; 1858234353Sdim 1859207619Srdivacky /// init_const_iterator - Iterates through the ivar initializer list. 1860218893Sdim typedef CXXCtorInitializer * const * init_const_iterator; 1861234353Sdim 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; } 1866234353Sdim 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 } 1879234353Sdim 1880207619Srdivacky void setNumIvarInitializers(unsigned numNumIvarInitializers) { 1881207619Srdivacky NumIvarInitializers = numNumIvarInitializers; 1882207619Srdivacky } 1883234353Sdim 1884207619Srdivacky void setIvarInitializers(ASTContext &C, 1885218893Sdim CXXCtorInitializer ** initializers, 1886207619Srdivacky unsigned numInitializers); 1887224145Sdim 1888243830Sdim /// Do any of the ivars of this class (not counting its base classes) 1889243830Sdim /// require construction other than zero-initialization? 1890243830Sdim bool hasNonZeroConstructors() const { return HasNonZeroConstructors; } 1891243830Sdim void setHasNonZeroConstructors(bool val) { HasNonZeroConstructors = val; } 1892234353Sdim 1893243830Sdim /// Do any of the ivars of this class (not counting its base classes) 1894243830Sdim /// require non-trivial destruction? 1895243830Sdim bool hasDestructors() const { return HasDestructors; } 1896243830Sdim void setHasDestructors(bool val) { HasDestructors = val; } 1897243830Sdim 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. 1909226633Sdim 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; } 1923251662Sdim SourceLocation getSuperClassLoc() const { return SuperLoc; } 1924198092Srdivacky 1925193326Sed void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } 1926198092Srdivacky 1927234353Sdim void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } 1928234353Sdim SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } 1929234353Sdim void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } 1930234353Sdim SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } 1931234353Sdim 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 1953234353Sdimraw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID); 1954207619Srdivacky 1955198092Srdivacky/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is 1956239462Sdim/// declared as \@compatibility_alias alias class. 1957193326Sedclass ObjCCompatibleAliasDecl : public NamedDecl { 1958234353Sdim 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 1970234353Sdim static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, 1971234353Sdim unsigned ID); 1972234353Sdim 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 1982239462Sdim/// \brief Represents one property declaration in an Objective-C interface. 1983239462Sdim/// 1984193326Sed/// For example: 1985239462Sdim/// \code{.mm} 1986239462Sdim/// \@property (assign, readwrite) int MyProperty; 1987239462Sdim/// \endcode 1988193326Sedclass ObjCPropertyDecl : public NamedDecl { 1989234353Sdim 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 2013226633Sdim enum SetterKind { Assign, Retain, Copy, Weak }; 2014193326Sed enum PropertyControl { None, Required, Optional }; 2015193326Sedprivate: 2016239462Sdim SourceLocation AtLoc; // location of \@property 2017234353Sdim SourceLocation LParenLoc; // location of '(' starting attribute list or null. 2018210299Sed TypeSourceInfo *DeclType; 2019224145Sdim unsigned PropertyAttributes : NumPropertyAttrsBits; 2020224145Sdim unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; 2021239462Sdim // \@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, 2032234353Sdim SourceLocation AtLocation, SourceLocation LParenLocation, 2033234353Sdim TypeSourceInfo *T) 2034234353Sdim : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), 2035234353Sdim LParenLoc(LParenLocation), DeclType(T), 2036234353Sdim 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, 2046234353Sdim SourceLocation LParenLocation, 2047210299Sed TypeSourceInfo *T, 2048193326Sed PropertyControl propControl = None); 2049234353Sdim 2050234353Sdim static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); 2051234353Sdim 2052202879Srdivacky SourceLocation getAtLoc() const { return AtLoc; } 2053202879Srdivacky void setAtLoc(SourceLocation L) { AtLoc = L; } 2054202879Srdivacky 2055234353Sdim SourceLocation getLParenLoc() const { return LParenLoc; } 2056234353Sdim void setLParenLoc(SourceLocation L) { LParenLoc = L; } 2057234353Sdim 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 } 2078234353Sdim 2079210299Sed void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { 2080210299Sed PropertyAttributesAsWritten = PRVal; 2081210299Sed } 2082234353Sdim 2083249423Sdim 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 2095226633Sdim /// isAtomic - Return true if the property is atomic. 2096226633Sdim bool isAtomic() const { 2097226633Sdim return (PropertyAttributes & OBJC_PR_atomic); 2098226633Sdim } 2099226633Sdim 2100226633Sdim /// isRetaining - Return true if the property retains its value. 2101226633Sdim bool isRetaining() const { 2102226633Sdim return (PropertyAttributes & 2103226633Sdim (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); 2104226633Sdim } 2105226633Sdim 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 { 2110226633Sdim if (PropertyAttributes & OBJC_PR_strong) 2111226633Sdim return getType()->isBlockPointerType() ? Copy : Retain; 2112226633Sdim if (PropertyAttributes & OBJC_PR_retain) 2113193326Sed return Retain; 2114193326Sed if (PropertyAttributes & OBJC_PR_copy) 2115193326Sed return Copy; 2116226633Sdim if (PropertyAttributes & OBJC_PR_weak) 2117226633Sdim 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 2133239462Sdim // 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 2148234353Sdim virtual SourceRange getSourceRange() const LLVM_READONLY { 2149218893Sdim return SourceRange(AtLoc, getLocation()); 2150218893Sdim } 2151243830Sdim 2152243830Sdim /// Get the default name of the synthesized ivar. 2153243830Sdim 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: 2165239462Sdim/// \@synthesize prop1 = ivar1; 2166193326Sed/// 2167193326Sedclass ObjCPropertyImplDecl : public Decl { 2168193326Sedpublic: 2169193326Sed enum Kind { 2170193326Sed Synthesize, 2171193326Sed Dynamic 2172193326Sed }; 2173193326Sedprivate: 2174239462Sdim SourceLocation AtLoc; // location of \@synthesize or \@dynamic 2175234353Sdim 2176239462Sdim /// \brief For \@synthesize, the location of the ivar, if it was written in 2177218893Sdim /// the source code. 2178218893Sdim /// 2179218893Sdim /// \code 2180239462Sdim /// \@synthesize int a = b 2181218893Sdim /// \endcode 2182218893Sdim SourceLocation IvarLoc; 2183234353Sdim 2184193326Sed /// Property declaration being implemented 2185193326Sed ObjCPropertyDecl *PropertyDecl; 2186193326Sed 2187239462Sdim /// Null for \@dynamic. Required for \@synthesize. 2188193326Sed ObjCIvarDecl *PropertyIvarDecl; 2189234353Sdim 2190239462Sdim /// Null for \@dynamic. Non-null if property must be copy-constructed in 2191239462Sdim /// getter. 2192208600Srdivacky Expr *GetterCXXConstructor; 2193234353Sdim 2194239462Sdim /// 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), 2204234353Sdim 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 2217234353Sdim static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); 2218218893Sdim 2219234353Sdim virtual SourceRange getSourceRange() const LLVM_READONLY; 2220234353Sdim 2221234353Sdim 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; } 2237234353Sdim 2238218893Sdim void setPropertyIvarDecl(ObjCIvarDecl *Ivar, 2239234353Sdim SourceLocation IvarLoc) { 2240234353Sdim PropertyIvarDecl = Ivar; 2241218893Sdim this->IvarLoc = IvarLoc; 2242218893Sdim } 2243234353Sdim 2244239462Sdim /// \brief For \@synthesize, returns true if an ivar name was explicitly 2245239462Sdim /// specified. 2246239462Sdim /// 2247239462Sdim /// \code 2248239462Sdim /// \@synthesize int a = b; // true 2249239462Sdim /// \@synthesize int a; // false 2250239462Sdim /// \endcode 2251239462Sdim bool isIvarNameSpecified() const { 2252239462Sdim return IvarLoc.isValid() && IvarLoc != getLocation(); 2253239462Sdim } 2254239462Sdim 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 } 2268234353Sdim 2269203955Srdivacky static bool classof(const Decl *D) { return classofKind(D->getKind()); } 2270203955Srdivacky static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } 2271234353Sdim 2272218893Sdim friend class ASTDeclReader; 2273193326Sed}; 2274193326Sed 2275249423Sdimtemplate<bool (*Filter)(ObjCCategoryDecl *)> 2276249423Sdimvoid 2277249423SdimObjCInterfaceDecl::filtered_category_iterator<Filter>:: 2278249423SdimfindAcceptableCategory() { 2279249423Sdim while (Current && !Filter(Current)) 2280249423Sdim Current = Current->getNextClassCategoryRaw(); 2281249423Sdim} 2282249423Sdim 2283249423Sdimtemplate<bool (*Filter)(ObjCCategoryDecl *)> 2284249423Sdiminline ObjCInterfaceDecl::filtered_category_iterator<Filter> & 2285249423SdimObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() { 2286249423Sdim Current = Current->getNextClassCategoryRaw(); 2287249423Sdim findAcceptableCategory(); 2288249423Sdim return *this; 2289249423Sdim} 2290249423Sdim 2291249423Sdiminline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) { 2292249423Sdim return !Cat->isHidden(); 2293249423Sdim} 2294249423Sdim 2295249423Sdiminline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) { 2296249423Sdim return Cat->IsClassExtension() && !Cat->isHidden(); 2297249423Sdim} 2298249423Sdim 2299249423Sdiminline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { 2300249423Sdim return Cat->IsClassExtension(); 2301249423Sdim} 2302249423Sdim 2303193326Sed} // end namespace clang 2304193326Sed#endif 2305