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