DeclObjC.h revision b718b407db1f921c5a2dc0164a23582c322f8ce0
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/Basic/IdentifierTable.h"
19#include "llvm/ADT/DenseMap.h"
20
21namespace clang {
22class Expr;
23class Stmt;
24class FunctionDecl;
25class AttributeList;
26class RecordDecl;
27class ObjCIvarDecl;
28class ObjCMethodDecl;
29class ObjCProtocolDecl;
30class ObjCCategoryDecl;
31class ObjCPropertyDecl;
32class ObjCPropertyImplDecl;
33
34
35/// ObjCList - This is a simple template class used to hold various lists of
36/// decls etc, which is heavily used by the ObjC front-end.  This only use case
37/// this supports is setting the list all at once and then reading elements out
38/// of it.
39template <typename T>
40class ObjCList {
41  /// List is a new[]'d array of pointers to objects that are not owned by this
42  /// list.
43  T **List;
44  unsigned NumElts;
45
46  void operator=(const ObjCList &); // DO NOT IMPLEMENT
47  ObjCList(const ObjCList&);        // DO NOT IMPLEMENT
48public:
49  ObjCList() : List(0), NumElts(0) {}
50  ~ObjCList() {
51    delete[] List;
52  }
53
54  void set(T* const* InList, unsigned Elts) {
55    assert(List == 0 && "Elements already set!");
56    List = new T*[Elts];
57    NumElts = Elts;
58    memcpy(List, InList, sizeof(T*)*Elts);
59  }
60
61  typedef T* const * iterator;
62  iterator begin() const { return List; }
63  iterator end() const { return List+NumElts; }
64
65  unsigned size() const { return NumElts; }
66  bool empty() const { return NumElts == 0; }
67
68  T* operator[](unsigned idx) const {
69    assert(idx < NumElts && "Invalid access");
70    return List[idx];
71  }
72};
73
74
75
76/// ObjCMethodDecl - Represents an instance or class method declaration.
77/// ObjC methods can be declared within 4 contexts: class interfaces,
78/// categories, protocols, and class implementations. While C++ member
79/// functions leverage C syntax, Objective-C method syntax is modeled after
80/// Smalltalk (using colons to specify argument types/expressions).
81/// Here are some brief examples:
82///
83/// Setter/getter instance methods:
84/// - (void)setMenu:(NSMenu *)menu;
85/// - (NSMenu *)menu;
86///
87/// Instance method that takes 2 NSView arguments:
88/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
89///
90/// Getter class method:
91/// + (NSMenu *)defaultMenu;
92///
93/// A selector represents a unique name for a method. The selector names for
94/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
95///
96class ObjCMethodDecl : public ScopedDecl, public DeclContext {
97public:
98  enum ImplementationControl { None, Required, Optional };
99private:
100  /// Bitfields must be first fields in this class so they pack with those
101  /// declared in class Decl.
102  /// instance (true) or class (false) method.
103  bool IsInstance : 1;
104  bool IsVariadic : 1;
105
106  // Synthesized declaration method for a property setter/getter
107  bool IsSynthesized : 1;
108
109  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
110  /// @required/@optional
111  unsigned DeclImplementation : 2;
112
113  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
114  /// in, inout, etc.
115  unsigned objcDeclQualifier : 6;
116
117  // Type of this method.
118  QualType MethodDeclType;
119  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
120  /// parameters of this Method.  This is null if there are no formals.
121  ParmVarDecl **ParamInfo;
122  unsigned NumMethodParams;
123
124  /// List of attributes for this method declaration.
125  SourceLocation EndLoc; // the location of the ';' or '{'.
126
127  // The following are only used for method definitions, null otherwise.
128  // FIXME: space savings opportunity, consider a sub-class.
129  Stmt *Body;
130
131  /// SelfDecl - Decl for the implicit self parameter. This is lazily
132  /// constructed by createImplicitParams.
133  ImplicitParamDecl *SelfDecl;
134  /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
135  /// constructed by createImplicitParams.
136  ImplicitParamDecl *CmdDecl;
137
138  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
139                 Selector SelInfo, QualType T,
140                 DeclContext *contextDecl,
141                 bool isInstance = true,
142                 bool isVariadic = false,
143                 bool isSynthesized = false,
144                 ImplementationControl impControl = None)
145  : ScopedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo, 0),
146    DeclContext(ObjCMethod),
147    IsInstance(isInstance), IsVariadic(isVariadic),
148    IsSynthesized(isSynthesized),
149    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
150    MethodDeclType(T),
151    ParamInfo(0), NumMethodParams(0),
152    EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
153
154  virtual ~ObjCMethodDecl();
155
156public:
157
158  /// Destroy - Call destructors and release memory.
159  virtual void Destroy(ASTContext& C);
160
161  static ObjCMethodDecl *Create(ASTContext &C,
162                                SourceLocation beginLoc,
163                                SourceLocation endLoc, Selector SelInfo,
164                                QualType T, DeclContext *contextDecl,
165                                bool isInstance = true,
166                                bool isVariadic = false,
167                                bool isSynthesized = false,
168                                ImplementationControl impControl = None);
169
170  ObjCDeclQualifier getObjCDeclQualifier() const {
171    return ObjCDeclQualifier(objcDeclQualifier);
172  }
173  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
174
175  // Location information, modeled after the Stmt API.
176  SourceLocation getLocStart() const { return getLocation(); }
177  SourceLocation getLocEnd() const { return EndLoc; }
178  SourceRange getSourceRange() const {
179    return SourceRange(getLocation(), EndLoc);
180  }
181
182  ObjCInterfaceDecl *getClassInterface();
183  const ObjCInterfaceDecl *getClassInterface() const {
184    return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
185  }
186
187  Selector getSelector() const { return getDeclName().getObjCSelector(); }
188  unsigned getSynthesizedMethodSize() const;
189  QualType getResultType() const { return MethodDeclType; }
190
191  // Iterator access to formal parameters.
192  unsigned param_size() const { return NumMethodParams; }
193  typedef ParmVarDecl **param_iterator;
194  typedef ParmVarDecl * const *param_const_iterator;
195  param_iterator param_begin() { return ParamInfo; }
196  param_iterator param_end() { return ParamInfo+param_size(); }
197  param_const_iterator param_begin() const { return ParamInfo; }
198  param_const_iterator param_end() const { return ParamInfo+param_size(); }
199
200  unsigned getNumParams() const { return NumMethodParams; }
201  ParmVarDecl *getParamDecl(unsigned i) const {
202    assert(i < getNumParams() && "Illegal param #");
203    return ParamInfo[i];
204  }
205  void setParamDecl(int i, ParmVarDecl *pDecl) {
206    ParamInfo[i] = pDecl;
207  }
208  void setMethodParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
209
210  /// createImplicitParams - Used to lazily create the self and cmd
211  /// implict parameters. This must be called prior to using getSelfDecl()
212  /// or getCmdDecl(). The call is ignored if the implicit paramters
213  /// have already been created.
214  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
215
216  ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
217  ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
218
219  bool isInstance() const { return IsInstance; }
220  bool isVariadic() const { return IsVariadic; }
221
222  bool isSynthesized() const { return IsSynthesized; }
223  void setIsSynthesized() { IsSynthesized = true; }
224
225  // Related to protocols declared in  @protocol
226  void setDeclImplementation(ImplementationControl ic) {
227    DeclImplementation = ic;
228  }
229  ImplementationControl getImplementationControl() const {
230    return ImplementationControl(DeclImplementation);
231  }
232
233  virtual Stmt *getBody() const { return Body; }
234  void setBody(Stmt *B) { Body = B; }
235
236  // Implement isa/cast/dyncast/etc.
237  static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
238  static bool classof(const ObjCMethodDecl *D) { return true; }
239  static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
240    return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
241  }
242  static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
243    return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
244  }
245};
246
247/// ObjCContainerDecl - Represents a container for method declarations.
248/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, and
249/// ObjCProtocolDecl.
250/// FIXME: Use for ObjC implementation decls.
251/// FIXME: Consider properties.
252/// FIXME: It would be nice to reduce amount of "boilerplate" iterator code
253/// below. For now, the iterators are modeled after RecordDecl::field_iterator().
254/// If DeclContext ends up providing some support for creating more strongly
255/// typed iterators, the code below should be reduced considerably.
256///
257class ObjCContainerDecl : public NamedDecl, public DeclContext {
258  SourceLocation AtEndLoc; // marks the end of the method container.
259public:
260
261  ObjCContainerDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
262    : NamedDecl(DK, L, Id), DeclContext(DK) {}
263
264  virtual ~ObjCContainerDecl();
265
266  // Iterator access to instance/class methods.
267  class method_iterator {
268  protected:
269    /// Current - Current position within the sequence of declarations
270    /// in this record.
271    DeclContext::decl_iterator Current;
272
273    /// End - Last position in the sequence of declarations in this
274    /// record.
275    DeclContext::decl_iterator End;
276
277    /// IsInstance - If true, we are iterating through instance methods.
278    /// If false, we are iteratring through class methods.
279    bool IsInstance;
280
281    /// SkipToNextMethod - Advances the current position up to the next
282    /// ObjCMethodDecl.
283    void SkipToNextMethod() {
284      while (Current != End) {
285        ObjCMethodDecl *M = dyn_cast<ObjCMethodDecl>(*Current);
286        if (M &&
287            (IsInstance && M->isInstance() || !IsInstance && !M->isInstance()))
288          return;
289        ++Current;
290      }
291    }
292
293  public:
294    typedef ObjCMethodDecl const *    value_type;
295    typedef ObjCMethodDecl const *    reference;
296    typedef ObjCMethodDecl const *    pointer;
297    typedef std::ptrdiff_t            difference_type;
298    typedef std::forward_iterator_tag iterator_category;
299
300    method_iterator() : Current(), End(), IsInstance(true) { }
301
302    method_iterator(DeclContext::decl_iterator C,
303                    DeclContext::decl_iterator E, bool I)
304      : Current(C), End(E), IsInstance(I) {
305      SkipToNextMethod();
306    }
307
308    reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
309
310    pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
311
312    method_iterator& operator++() {
313      ++Current;
314      SkipToNextMethod();
315      return *this;
316    }
317
318    method_iterator operator++(int) {
319      method_iterator tmp(*this);
320      ++(*this);
321      return tmp;
322    }
323
324    friend bool
325    operator==(const method_iterator& x, const method_iterator& y) {
326      return x.Current == y.Current;
327    }
328
329    friend bool
330    operator!=(const method_iterator& x, const method_iterator& y) {
331      return x.Current != y.Current;
332    }
333  };
334
335  class instmeth_iterator : public method_iterator {
336  public:
337    typedef ObjCMethodDecl*           value_type;
338    typedef ObjCMethodDecl*           reference;
339    typedef ObjCMethodDecl*           pointer;
340
341    instmeth_iterator() : method_iterator() { }
342
343    instmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
344      : method_iterator(C, E, true) { }
345
346    reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
347
348    pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
349
350    instmeth_iterator& operator++() {
351      ++Current;
352      SkipToNextMethod();
353      return *this;
354    }
355
356    instmeth_iterator operator++(int) {
357      instmeth_iterator tmp(*this);
358      ++(*this);
359      return tmp;
360    }
361  };
362
363  instmeth_iterator instmeth_begin() const {
364    return instmeth_iterator(decls_begin(), decls_end());
365  }
366  instmeth_iterator instmeth_end() const {
367    return instmeth_iterator(decls_end(), decls_end());
368  }
369
370  class classmeth_iterator : public method_iterator {
371  public:
372    typedef ObjCMethodDecl*           value_type;
373    typedef ObjCMethodDecl*           reference;
374    typedef ObjCMethodDecl*           pointer;
375
376    classmeth_iterator() : method_iterator() { }
377
378    classmeth_iterator(DeclContext::decl_iterator C, DeclContext::decl_iterator E)
379      : method_iterator(C, E, false) { }
380
381    reference operator*() const { return cast<ObjCMethodDecl>(*Current); }
382
383    pointer operator->() const { return cast<ObjCMethodDecl>(*Current); }
384
385    classmeth_iterator& operator++() {
386      ++Current;
387      SkipToNextMethod();
388      return *this;
389    }
390
391    classmeth_iterator operator++(int) {
392      classmeth_iterator tmp(*this);
393      ++(*this);
394      return tmp;
395    }
396  };
397  classmeth_iterator classmeth_begin() const {
398    return classmeth_iterator(decls_begin(), decls_end());
399  }
400  classmeth_iterator classmeth_end() const {
401    return classmeth_iterator(decls_end(), decls_end());
402  }
403
404  // Get the local instance/class method declared in this interface.
405  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
406  ObjCMethodDecl *getClassMethod(Selector Sel) const;
407
408  // Get the number of instance/class methods.
409  unsigned getNumInstanceMethods() const;
410  unsigned getNumClassMethods() const;
411
412  // Marks the end of the container.
413  SourceLocation getAtEndLoc() const { return AtEndLoc; }
414  void setAtEndLoc(SourceLocation L) { AtEndLoc = L; }
415};
416
417/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
418///
419///   // MostPrimitive declares no super class (not particularly useful).
420///   @interface MostPrimitive
421///     // no instance variables or methods.
422///   @end
423///
424///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
425///   @interface NSResponder : NSObject <NSCoding>
426///   { // instance variables are represented by ObjCIvarDecl.
427///     id nextResponder; // nextResponder instance variable.
428///   }
429///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
430///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
431///   @end                                    // to an NSEvent.
432///
433///   Unlike C/C++, forward class declarations are accomplished with @class.
434///   Unlike C/C++, @class allows for a list of classes to be forward declared.
435///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
436///   typically inherit from NSObject (an exception is NSProxy).
437///
438class ObjCInterfaceDecl : public ObjCContainerDecl {
439  /// TypeForDecl - This indicates the Type object that represents this
440  /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
441  Type *TypeForDecl;
442  friend class ASTContext;
443
444  /// Class's super class.
445  ObjCInterfaceDecl *SuperClass;
446
447  /// Protocols referenced in interface header declaration
448  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
449
450  /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
451  ObjCIvarDecl **Ivars;   // Null if not defined.
452  unsigned NumIvars;      // 0 if none.
453
454  /// List of categories defined for this class.
455  ObjCCategoryDecl *CategoryList;
456
457  /// class properties
458  ObjCPropertyDecl **PropertyDecl;  // Null if no property
459  unsigned NumPropertyDecl;  // 0 if none.
460
461  bool ForwardDecl:1; // declared with @class.
462  bool InternalInterface:1; // true - no @interface for @implementation
463
464  SourceLocation ClassLoc; // location of the class identifier.
465  SourceLocation SuperClassLoc; // location of the super class identifier.
466  SourceLocation EndLoc; // marks the '>', '}', or identifier.
467
468  ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id,
469                    SourceLocation CLoc, bool FD, bool isInternal)
470    : ObjCContainerDecl(ObjCInterface, atLoc, Id),
471      TypeForDecl(0), SuperClass(0),
472      Ivars(0), NumIvars(0),
473      CategoryList(0), PropertyDecl(0), NumPropertyDecl(0),
474      ForwardDecl(FD), InternalInterface(isInternal),
475      ClassLoc(CLoc) {
476      }
477
478  virtual ~ObjCInterfaceDecl();
479
480public:
481
482  /// Destroy - Call destructors and release memory.
483  virtual void Destroy(ASTContext& C);
484
485  static ObjCInterfaceDecl *Create(ASTContext &C,
486                                   SourceLocation atLoc,
487                                   IdentifierInfo *Id,
488                                   SourceLocation ClassLoc = SourceLocation(),
489                                   bool ForwardDecl = false,
490                                   bool isInternal = false);
491  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
492    return ReferencedProtocols;
493  }
494
495  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
496  ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
497  ObjCIvarDecl *FindIvarDeclaration(IdentifierInfo *IvarId) const;
498  bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl) const;
499
500  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
501  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
502  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
503
504  typedef ObjCIvarDecl * const *ivar_iterator;
505  ivar_iterator ivar_begin() const { return Ivars; }
506  ivar_iterator ivar_end() const { return Ivars + ivar_size();}
507  unsigned ivar_size() const { return NumIvars; }
508  bool ivar_empty() const { return NumIvars == 0; }
509
510  /// addReferencedProtocols - Set the list of protocols that this interface
511  /// implements.
512  void addReferencedProtocols(ObjCProtocolDecl *const*List, unsigned NumRPs) {
513    ReferencedProtocols.set(List, NumRPs);
514  }
515
516  void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars,
517                                   SourceLocation RBracLoc);
518  FieldDecl *lookupFieldDeclForIvar(ASTContext &Context,
519                                    const ObjCIvarDecl *ivar);
520
521  void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
522
523  void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
524
525  typedef ObjCPropertyDecl * const * classprop_iterator;
526  classprop_iterator classprop_begin() const { return PropertyDecl; }
527  classprop_iterator classprop_end() const {
528    return PropertyDecl+NumPropertyDecl;
529  }
530
531  bool isForwardDecl() const { return ForwardDecl; }
532  void setForwardDecl(bool val) { ForwardDecl = val; }
533
534  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
535  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
536
537  ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
538  void setCategoryList(ObjCCategoryDecl *category) {
539    CategoryList = category;
540  }
541
542  /// isSuperClassOf - Return true if this class is the specified class or is a
543  /// super class of the specified interface class.
544  bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
545    // If RHS is derived from LHS it is OK; else it is not OK.
546    while (I != NULL) {
547      if (this == I)
548        return true;
549      I = I->getSuperClass();
550    }
551    return false;
552  }
553
554  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
555                                       ObjCInterfaceDecl *&ClassDeclared);
556  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
557    ObjCInterfaceDecl *ClassDeclared;
558    return lookupInstanceVariable(IVarName, ClassDeclared);
559  }
560
561  // Lookup a method. First, we search locally. If a method isn't
562  // found, we search referenced protocols and class categories.
563  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
564  ObjCMethodDecl *lookupClassMethod(Selector Sel);
565
566  // Location information, modeled after the Stmt API.
567  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
568  SourceLocation getLocEnd() const { return EndLoc; }
569  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
570
571  SourceLocation getClassLoc() const { return ClassLoc; }
572  void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
573  SourceLocation getSuperClassLoc() const { return SuperClassLoc; }
574
575  unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
576
577  ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
578  ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
579
580  /// ImplicitInterfaceDecl - check that this is an implicitely declared
581  /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
582  /// declaration without an @interface declaration.
583  bool ImplicitInterfaceDecl() const { return InternalInterface; }
584
585  static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
586  static bool classof(const ObjCInterfaceDecl *D) { return true; }
587  static DeclContext *castToDeclContext(const ObjCInterfaceDecl *D) {
588    return static_cast<DeclContext *>(const_cast<ObjCInterfaceDecl*>(D));
589  }
590  static ObjCInterfaceDecl *castFromDeclContext(const DeclContext *DC) {
591    return static_cast<ObjCInterfaceDecl *>(const_cast<DeclContext*>(DC));
592  }
593};
594
595/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
596/// instance variables are identical to C. The only exception is Objective-C
597/// supports C++ style access control. For example:
598///
599///   @interface IvarExample : NSObject
600///   {
601///     id defaultToProtected;
602///   @public:
603///     id canBePublic; // same as C++.
604///   @protected:
605///     id canBeProtected; // same as C++.
606///   @package:
607///     id canBePackage; // framework visibility (not available in C++).
608///   }
609///
610class ObjCIvarDecl : public FieldDecl {
611public:
612  enum AccessControl {
613    None, Private, Protected, Public, Package
614  };
615
616private:
617  ObjCIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
618               AccessControl ac, Expr *BW)
619    : FieldDecl(ObjCIvar, 0, L, Id, T, BW, /*Mutable=*/false, 0),
620      DeclAccess(ac) {}
621
622public:
623  static ObjCIvarDecl *Create(ASTContext &C, SourceLocation L,
624                              IdentifierInfo *Id, QualType T,
625                              AccessControl ac, Expr *BW = NULL);
626
627  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
628
629  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
630
631  AccessControl getCanonicalAccessControl() const {
632    return DeclAccess == None ? Protected : AccessControl(DeclAccess);
633  }
634
635  // Implement isa/cast/dyncast/etc.
636  static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
637  static bool classof(const ObjCIvarDecl *D) { return true; }
638private:
639  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
640  unsigned DeclAccess : 3;
641};
642
643
644/// ObjCAtDefsFieldDecl - Represents a field declaration created by an
645///  @defs(...).
646class ObjCAtDefsFieldDecl : public FieldDecl {
647private:
648  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
649                      QualType T, Expr *BW)
650    : FieldDecl(ObjCAtDefsField, DC, L, Id, T, BW, /*Mutable=*/false, 0) {}
651
652public:
653  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
654                                     SourceLocation L,
655                                     IdentifierInfo *Id, QualType T,
656                                     Expr *BW);
657
658  virtual void Destroy(ASTContext& C);
659
660  // Implement isa/cast/dyncast/etc.
661  static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
662  static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
663};
664
665/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
666/// declare a pure abstract type (i.e no instance variables are permitted).
667/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
668/// feature with nice semantics and lousy syntax:-). Here is an example:
669///
670/// @protocol NSDraggingInfo <refproto1, refproto2>
671/// - (NSWindow *)draggingDestinationWindow;
672/// - (NSImage *)draggedImage;
673/// @end
674///
675/// This says that NSDraggingInfo requires two methods and requires everything
676/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
677/// well.
678///
679/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
680/// @end
681///
682/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
683/// protocols are in distinct namespaces. For example, Cocoa defines both
684/// an NSObject protocol and class (which isn't allowed in Java). As a result,
685/// protocols are referenced using angle brackets as follows:
686///
687/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
688///
689class ObjCProtocolDecl : public ObjCContainerDecl {
690  /// Referenced protocols
691  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
692
693  /// protocol properties
694  ObjCPropertyDecl **PropertyDecl;  // Null if no property
695  unsigned NumPropertyDecl;  // 0 if none
696
697  bool isForwardProtoDecl; // declared with @protocol.
698
699  SourceLocation EndLoc; // marks the '>' or identifier.
700  SourceLocation AtEndLoc; // marks the end of the entire interface.
701
702  ObjCProtocolDecl(SourceLocation L, IdentifierInfo *Id)
703    : ObjCContainerDecl(ObjCProtocol, L, Id),
704      PropertyDecl(0), NumPropertyDecl(0),
705      isForwardProtoDecl(true) {
706  }
707
708  virtual ~ObjCProtocolDecl();
709
710public:
711
712  /// Destroy - Call destructors and release memory.
713  virtual void Destroy(ASTContext& C);
714
715  static ObjCProtocolDecl *Create(ASTContext &C, SourceLocation L,
716                                  IdentifierInfo *Id);
717
718  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
719    return ReferencedProtocols;
720  }
721  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
722  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
723  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
724
725  /// addReferencedProtocols - Set the list of protocols that this interface
726  /// implements.
727  void addReferencedProtocols(ObjCProtocolDecl *const*List, unsigned NumRPs) {
728    ReferencedProtocols.set(List, NumRPs);
729  }
730
731  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
732
733  unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
734
735  ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
736  ObjCPropertyDecl **getPropertyDecl() { return PropertyDecl; }
737
738  void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
739
740  typedef ObjCPropertyDecl * const * classprop_iterator;
741  classprop_iterator classprop_begin() const { return PropertyDecl; }
742  classprop_iterator classprop_end() const {
743    return PropertyDecl+NumPropertyDecl;
744  }
745
746  // Lookup a method. First, we search locally. If a method isn't
747  // found, we search referenced protocols and class categories.
748  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
749  ObjCMethodDecl *lookupClassMethod(Selector Sel);
750
751  bool isForwardDecl() const { return isForwardProtoDecl; }
752  void setForwardDecl(bool val) { isForwardProtoDecl = val; }
753
754  // Location information, modeled after the Stmt API.
755  SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
756  SourceLocation getLocEnd() const { return EndLoc; }
757  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
758
759  static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
760  static bool classof(const ObjCProtocolDecl *D) { return true; }
761  static DeclContext *castToDeclContext(const ObjCProtocolDecl *D) {
762    return static_cast<DeclContext *>(const_cast<ObjCProtocolDecl*>(D));
763  }
764  static ObjCProtocolDecl *castFromDeclContext(const DeclContext *DC) {
765    return static_cast<ObjCProtocolDecl *>(const_cast<DeclContext*>(DC));
766  }
767};
768
769/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
770///
771/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
772///
773class ObjCClassDecl : public Decl {
774  ObjCInterfaceDecl **ForwardDecls;
775  unsigned NumForwardDecls;
776
777  ObjCClassDecl(SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts)
778    : Decl(ObjCClass, L) {
779    if (nElts) {
780      ForwardDecls = new ObjCInterfaceDecl*[nElts];
781      memcpy(ForwardDecls, Elts, nElts*sizeof(ObjCInterfaceDecl*));
782    } else {
783      ForwardDecls = 0;
784    }
785    NumForwardDecls = nElts;
786  }
787
788  virtual ~ObjCClassDecl();
789
790public:
791
792  /// Destroy - Call destructors and release memory.
793  virtual void Destroy(ASTContext& C);
794
795  static ObjCClassDecl *Create(ASTContext &C, SourceLocation L,
796                               ObjCInterfaceDecl **Elts, unsigned nElts);
797
798  void setInterfaceDecl(unsigned idx, ObjCInterfaceDecl *OID) {
799    assert(idx < NumForwardDecls && "index out of range");
800    ForwardDecls[idx] = OID;
801  }
802  ObjCInterfaceDecl** getForwardDecls() const { return ForwardDecls; }
803  int getNumForwardDecls() const { return NumForwardDecls; }
804
805  typedef ObjCInterfaceDecl * const * iterator;
806  iterator begin() const { return ForwardDecls; }
807  iterator end() const { return ForwardDecls+NumForwardDecls; }
808
809  static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
810  static bool classof(const ObjCClassDecl *D) { return true; }
811};
812
813/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
814/// For example:
815///
816/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
817///
818class ObjCForwardProtocolDecl : public Decl {
819  ObjCProtocolDecl **ReferencedProtocols;
820  unsigned NumReferencedProtocols;
821
822  ObjCForwardProtocolDecl(SourceLocation L,
823                          ObjCProtocolDecl **Elts, unsigned nElts)
824  : Decl(ObjCForwardProtocol, L) {
825    NumReferencedProtocols = nElts;
826    if (nElts) {
827      ReferencedProtocols = new ObjCProtocolDecl*[nElts];
828      memcpy(ReferencedProtocols, Elts, nElts*sizeof(ObjCProtocolDecl*));
829    } else {
830      ReferencedProtocols = 0;
831    }
832  }
833
834  virtual ~ObjCForwardProtocolDecl();
835
836public:
837  static ObjCForwardProtocolDecl *Create(ASTContext &C, SourceLocation L,
838                                         ObjCProtocolDecl **Elts, unsigned Num);
839
840
841  void setForwardProtocolDecl(unsigned idx, ObjCProtocolDecl *OID) {
842    assert(idx < NumReferencedProtocols && "index out of range");
843    ReferencedProtocols[idx] = OID;
844  }
845
846  unsigned getNumForwardDecls() const { return NumReferencedProtocols; }
847
848  ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) {
849    assert(idx < NumReferencedProtocols && "index out of range");
850    return ReferencedProtocols[idx];
851  }
852  const ObjCProtocolDecl *getForwardProtocolDecl(unsigned idx) const {
853    assert(idx < NumReferencedProtocols && "index out of range");
854    return ReferencedProtocols[idx];
855  }
856
857  typedef ObjCProtocolDecl * const * iterator;
858  iterator begin() const { return ReferencedProtocols; }
859  iterator end() const { return ReferencedProtocols+NumReferencedProtocols; }
860
861  static bool classof(const Decl *D) {
862    return D->getKind() == ObjCForwardProtocol;
863  }
864  static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
865};
866
867/// ObjCCategoryDecl - Represents a category declaration. A category allows
868/// you to add methods to an existing class (without subclassing or modifying
869/// the original class interface or implementation:-). Categories don't allow
870/// you to add instance data. The following example adds "myMethod" to all
871/// NSView's within a process:
872///
873/// @interface NSView (MyViewMethods)
874/// - myMethod;
875/// @end
876///
877/// Cateogries also allow you to split the implementation of a class across
878/// several files (a feature more naturally supported in C++).
879///
880/// Categories were originally inspired by dynamic languages such as Common
881/// Lisp and Smalltalk.  More traditional class-based languages (C++, Java)
882/// don't support this level of dynamism, which is both powerful and dangerous.
883///
884class ObjCCategoryDecl : public ObjCContainerDecl {
885  /// Interface belonging to this category
886  ObjCInterfaceDecl *ClassInterface;
887
888  /// referenced protocols in this category.
889  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
890
891  /// Next category belonging to this class
892  ObjCCategoryDecl *NextClassCategory;
893
894  /// category properties
895  ObjCPropertyDecl **PropertyDecl;  // Null if no property
896  unsigned NumPropertyDecl;  // 0 if none
897
898  SourceLocation EndLoc; // marks the '>' or identifier.
899
900  ObjCCategoryDecl(SourceLocation L, IdentifierInfo *Id)
901    : ObjCContainerDecl(ObjCCategory, L, Id),
902      ClassInterface(0),
903      NextClassCategory(0), PropertyDecl(0),  NumPropertyDecl(0) {
904  }
905public:
906
907  static ObjCCategoryDecl *Create(ASTContext &C,
908                                  SourceLocation L, IdentifierInfo *Id);
909
910  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
911  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
912  void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
913
914  /// addReferencedProtocols - Set the list of protocols that this interface
915  /// implements.
916  void addReferencedProtocols(ObjCProtocolDecl *const*List, unsigned NumRPs) {
917    ReferencedProtocols.set(List, NumRPs);
918  }
919
920  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
921    return ReferencedProtocols;
922  }
923
924  typedef ObjCProtocolDecl * const * protocol_iterator;
925  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
926  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
927
928  unsigned getNumPropertyDecl() const { return NumPropertyDecl; }
929
930  ObjCPropertyDecl * const * getPropertyDecl() const { return PropertyDecl; }
931
932  void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
933
934  void mergeProperties(ObjCPropertyDecl **Properties, unsigned NumProperties);
935
936  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
937
938  typedef ObjCPropertyDecl * const * classprop_iterator;
939  classprop_iterator classprop_begin() const { return PropertyDecl; }
940  classprop_iterator classprop_end() const {
941    return PropertyDecl+NumPropertyDecl;
942  }
943
944  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
945  void insertNextClassCategory() {
946    NextClassCategory = ClassInterface->getCategoryList();
947    ClassInterface->setCategoryList(this);
948  }
949  // Location information, modeled after the Stmt API.
950  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
951  SourceLocation getLocEnd() const { return EndLoc; }
952  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
953
954  static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
955  static bool classof(const ObjCCategoryDecl *D) { return true; }
956  static DeclContext *castToDeclContext(const ObjCCategoryDecl *D) {
957    return static_cast<DeclContext *>(const_cast<ObjCCategoryDecl*>(D));
958  }
959  static ObjCCategoryDecl *castFromDeclContext(const DeclContext *DC) {
960    return static_cast<ObjCCategoryDecl *>(const_cast<DeclContext*>(DC));
961  }
962};
963
964/// ObjCCategoryImplDecl - An object of this class encapsulates a category
965/// @implementation declaration. If a category class has declaration of a
966/// property, its implementation must be specified in the category's
967/// @implementation declaration. Example:
968/// @interface I @end
969/// @interface I(CATEGORY)
970///    @property int p1, d1;
971/// @end
972/// @implementation I(CATEGORY)
973///  @dynamic p1,d1;
974/// @end
975///
976class ObjCCategoryImplDecl : public NamedDecl, public DeclContext {
977  /// Class interface for this category implementation
978  ObjCInterfaceDecl *ClassInterface;
979
980  /// implemented instance methods
981  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
982
983  /// implemented class methods
984  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
985
986  /// Property Implementations in this category
987  llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
988
989  SourceLocation EndLoc;
990
991  ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
992                       ObjCInterfaceDecl *classInterface)
993    : NamedDecl(ObjCCategoryImpl, L, Id), DeclContext(ObjCCategoryImpl),
994      ClassInterface(classInterface) {}
995public:
996  static ObjCCategoryImplDecl *Create(ASTContext &C,
997                                      SourceLocation L, IdentifierInfo *Id,
998                                      ObjCInterfaceDecl *classInterface);
999
1000  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1001  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1002
1003  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
1004  unsigned getNumClassMethods() const { return ClassMethods.size(); }
1005
1006  void addInstanceMethod(ObjCMethodDecl *method) {
1007    InstanceMethods.push_back(method);
1008  }
1009  void addClassMethod(ObjCMethodDecl *method) {
1010    ClassMethods.push_back(method);
1011  }
1012  // Get the instance method definition for this implementation.
1013  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
1014
1015  // Get the class method definition for this implementation.
1016  ObjCMethodDecl *getClassMethod(Selector Sel) const;
1017
1018  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
1019    PropertyImplementations.push_back(property);
1020  }
1021
1022  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1023  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1024
1025  unsigned getNumPropertyImplementations() const
1026  { return PropertyImplementations.size(); }
1027
1028
1029  typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
1030    propimpl_iterator;
1031  propimpl_iterator propimpl_begin() const {
1032    return PropertyImplementations.begin();
1033  }
1034  propimpl_iterator propimpl_end() const {
1035    return PropertyImplementations.end();
1036  }
1037
1038  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1039    instmeth_iterator;
1040  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
1041  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
1042
1043  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1044    classmeth_iterator;
1045  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
1046  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
1047
1048
1049  // Location information, modeled after the Stmt API.
1050  SourceLocation getLocStart() const { return getLocation(); }
1051  SourceLocation getLocEnd() const { return EndLoc; }
1052  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
1053
1054  static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
1055  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
1056  static DeclContext *castToDeclContext(const ObjCCategoryImplDecl *D) {
1057    return static_cast<DeclContext *>(const_cast<ObjCCategoryImplDecl*>(D));
1058  }
1059  static ObjCCategoryImplDecl *castFromDeclContext(const DeclContext *DC) {
1060    return static_cast<ObjCCategoryImplDecl *>(const_cast<DeclContext*>(DC));
1061  }
1062};
1063
1064/// ObjCImplementationDecl - Represents a class definition - this is where
1065/// method definitions are specified. For example:
1066///
1067/// @implementation MyClass
1068/// - (void)myMethod { /* do something */ }
1069/// @end
1070///
1071/// Typically, instance variables are specified in the class interface,
1072/// *not* in the implemenentation. Nevertheless (for legacy reasons), we
1073/// allow instance variables to be specified in the implementation. When
1074/// specified, they need to be *identical* to the interface. Now that we
1075/// have support for non-fragile ivars in ObjC 2.0, we can consider removing
1076/// the legacy semantics and allow developers to move private ivar declarations
1077/// from the class interface to the class implementation (but I digress:-)
1078///
1079class ObjCImplementationDecl : public NamedDecl, public DeclContext {
1080  /// Class interface for this implementation
1081  ObjCInterfaceDecl *ClassInterface;
1082
1083  /// Implementation Class's super class.
1084  ObjCInterfaceDecl *SuperClass;
1085
1086  /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
1087  ObjCIvarDecl **Ivars;   // Null if not specified
1088  unsigned NumIvars;      // 0 if none.
1089
1090  /// implemented instance methods
1091  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
1092
1093  /// implemented class methods
1094  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
1095
1096  /// Propertys' being implemented
1097  llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
1098
1099  SourceLocation EndLoc;
1100
1101  ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
1102                         ObjCInterfaceDecl *classInterface,
1103                         ObjCInterfaceDecl *superDecl)
1104    : NamedDecl(ObjCImplementation, L, Id), DeclContext(ObjCImplementation),
1105      ClassInterface(classInterface), SuperClass(superDecl),
1106      Ivars(0), NumIvars(0) {}
1107public:
1108  static ObjCImplementationDecl *Create(ASTContext &C,
1109                                        SourceLocation L, IdentifierInfo *Id,
1110                                        ObjCInterfaceDecl *classInterface,
1111                                        ObjCInterfaceDecl *superDecl);
1112
1113
1114  void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars,
1115                                           unsigned numIvars);
1116
1117  void addInstanceMethod(ObjCMethodDecl *method) {
1118    InstanceMethods.push_back(method);
1119  }
1120  void addClassMethod(ObjCMethodDecl *method) {
1121    ClassMethods.push_back(method);
1122  }
1123
1124  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
1125    PropertyImplementations.push_back(property);
1126  }
1127
1128  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1129  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1130
1131  typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
1132  propimpl_iterator;
1133  propimpl_iterator propimpl_begin() const {
1134    return PropertyImplementations.begin();
1135  }
1136  propimpl_iterator propimpl_end() const {
1137    return PropertyImplementations.end();
1138  }
1139
1140  // Location information, modeled after the Stmt API.
1141  SourceLocation getLocStart() const { return getLocation(); }
1142  SourceLocation getLocEnd() const { return EndLoc; }
1143  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
1144
1145  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1146  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1147  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1148  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
1149
1150  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
1151
1152  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
1153  unsigned getNumClassMethods() const { return ClassMethods.size(); }
1154
1155  unsigned getNumPropertyImplementations() const
1156    { return PropertyImplementations.size(); }
1157
1158  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1159       instmeth_iterator;
1160  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
1161  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
1162
1163  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1164    classmeth_iterator;
1165  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
1166  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
1167
1168  // Get the instance method definition for this implementation.
1169  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
1170
1171  // Get the class method definition for this implementation.
1172  ObjCMethodDecl *getClassMethod(Selector Sel) const;
1173
1174  typedef ObjCIvarDecl * const *ivar_iterator;
1175  ivar_iterator ivar_begin() const { return Ivars; }
1176  ivar_iterator ivar_end() const { return Ivars+NumIvars; }
1177  unsigned ivar_size() const { return NumIvars; }
1178  bool ivar_empty() const { return NumIvars == 0; }
1179
1180  static bool classof(const Decl *D) {
1181    return D->getKind() == ObjCImplementation;
1182  }
1183  static bool classof(const ObjCImplementationDecl *D) { return true; }
1184  static DeclContext *castToDeclContext(const ObjCImplementationDecl *D) {
1185    return static_cast<DeclContext *>(const_cast<ObjCImplementationDecl*>(D));
1186  }
1187  static ObjCImplementationDecl *castFromDeclContext(const DeclContext *DC) {
1188    return static_cast<ObjCImplementationDecl *>(const_cast<DeclContext*>(DC));
1189  }
1190};
1191
1192/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1193/// declared as @compatibility_alias alias class.
1194class ObjCCompatibleAliasDecl : public NamedDecl {
1195  /// Class that this is an alias of.
1196  ObjCInterfaceDecl *AliasedClass;
1197
1198  ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id,
1199                          ObjCInterfaceDecl* aliasedClass)
1200    : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {}
1201public:
1202  static ObjCCompatibleAliasDecl *Create(ASTContext &C,
1203                                         SourceLocation L, IdentifierInfo *Id,
1204                                         ObjCInterfaceDecl* aliasedClass);
1205
1206  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1207  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
1208
1209  static bool classof(const Decl *D) {
1210    return D->getKind() == ObjCCompatibleAlias;
1211  }
1212  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
1213
1214};
1215
1216/// ObjCPropertyDecl - Represents one property declaration in an interface.
1217/// For example:
1218/// @property (assign, readwrite) int MyProperty;
1219///
1220class ObjCPropertyDecl : public NamedDecl {
1221public:
1222  enum PropertyAttributeKind {
1223    OBJC_PR_noattr    = 0x00,
1224    OBJC_PR_readonly  = 0x01,
1225    OBJC_PR_getter    = 0x02,
1226    OBJC_PR_assign    = 0x04,
1227    OBJC_PR_readwrite = 0x08,
1228    OBJC_PR_retain    = 0x10,
1229    OBJC_PR_copy      = 0x20,
1230    OBJC_PR_nonatomic = 0x40,
1231    OBJC_PR_setter    = 0x80
1232  };
1233
1234  enum SetterKind { Assign, Retain, Copy };
1235  enum PropertyControl { None, Required, Optional };
1236private:
1237  QualType DeclType;
1238  unsigned PropertyAttributes : 8;
1239
1240  // @required/@optional
1241  unsigned PropertyImplementation : 2;
1242
1243  Selector GetterName;    // getter name of NULL if no getter
1244  Selector SetterName;    // setter name of NULL if no setter
1245
1246  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
1247  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1248
1249  ObjCPropertyDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
1250    : NamedDecl(ObjCProperty, L, Id), DeclType(T),
1251      PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
1252      GetterName(Selector()),
1253      SetterName(Selector()),
1254      GetterMethodDecl(0), SetterMethodDecl(0) {}
1255public:
1256  static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L,
1257                                  IdentifierInfo *Id, QualType T,
1258                                  PropertyControl propControl = None);
1259  QualType getType() const { return DeclType; }
1260
1261  PropertyAttributeKind getPropertyAttributes() const {
1262    return PropertyAttributeKind(PropertyAttributes);
1263  }
1264  void setPropertyAttributes(PropertyAttributeKind PRVal) {
1265    PropertyAttributes |= PRVal;
1266  }
1267
1268 void makeitReadWriteAttribute(void) {
1269    PropertyAttributes &= ~OBJC_PR_readonly;
1270    PropertyAttributes |= OBJC_PR_readwrite;
1271 }
1272
1273  // Helper methods for accessing attributes.
1274
1275  /// isReadOnly - Return true iff the property has a setter.
1276  bool isReadOnly() const {
1277    return (PropertyAttributes & OBJC_PR_readonly);
1278  }
1279
1280  /// getSetterKind - Return the method used for doing assignment in
1281  /// the property setter. This is only valid if the property has been
1282  /// defined to have a setter.
1283  SetterKind getSetterKind() const {
1284    if (PropertyAttributes & OBJC_PR_retain)
1285      return Retain;
1286    if (PropertyAttributes & OBJC_PR_copy)
1287      return Copy;
1288    return Assign;
1289  }
1290
1291  Selector getGetterName() const { return GetterName; }
1292  void setGetterName(Selector Sel) { GetterName = Sel; }
1293
1294  Selector getSetterName() const { return SetterName; }
1295  void setSetterName(Selector Sel) { SetterName = Sel; }
1296
1297  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1298  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1299
1300  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1301  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1302
1303  // Related to @optional/@required declared in @protocol
1304  void setPropertyImplementation(PropertyControl pc) {
1305    PropertyImplementation = pc;
1306  }
1307  PropertyControl getPropertyImplementation() const {
1308    return PropertyControl(PropertyImplementation);
1309  }
1310
1311  static bool classof(const Decl *D) {
1312    return D->getKind() == ObjCProperty;
1313  }
1314  static bool classof(const ObjCPropertyDecl *D) { return true; }
1315};
1316
1317/// ObjCPropertyImplDecl - Represents implementation declaration of a property
1318/// in a class or category implementation block. For example:
1319/// @synthesize prop1 = ivar1;
1320///
1321class ObjCPropertyImplDecl : public Decl {
1322public:
1323  enum Kind {
1324    Synthesize,
1325    Dynamic
1326  };
1327private:
1328  SourceLocation AtLoc;   // location of @synthesize or @dynamic
1329  /// Property declaration being implemented
1330  ObjCPropertyDecl *PropertyDecl;
1331
1332  /// Null for @dynamic. Required for @synthesize.
1333  ObjCIvarDecl *PropertyIvarDecl;
1334
1335  ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L,
1336                       ObjCPropertyDecl *property,
1337                       Kind PK,
1338                       ObjCIvarDecl *ivarDecl)
1339    : Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(property),
1340      PropertyIvarDecl(ivarDecl) {
1341    assert (PK == Dynamic || PropertyIvarDecl);
1342  }
1343
1344public:
1345  static ObjCPropertyImplDecl *Create(ASTContext &C, SourceLocation atLoc,
1346                                      SourceLocation L,
1347                                      ObjCPropertyDecl *property,
1348                                      Kind PK,
1349                                      ObjCIvarDecl *ivarDecl);
1350
1351  SourceLocation getLocStart() const { return AtLoc; }
1352
1353  ObjCPropertyDecl *getPropertyDecl() const {
1354    return PropertyDecl;
1355  }
1356
1357  Kind getPropertyImplementation() const {
1358    return PropertyIvarDecl ? Synthesize : Dynamic;
1359  }
1360
1361  ObjCIvarDecl *getPropertyIvarDecl() const {
1362    return PropertyIvarDecl;
1363  }
1364
1365  static bool classof(const Decl *D) {
1366    return D->getKind() == ObjCPropertyImpl;
1367  }
1368  static bool classof(const ObjCPropertyImplDecl *D) { return true; }
1369};
1370
1371}  // end namespace clang
1372#endif
1373