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