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