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