DeclObjC.h revision ae6f6fd1527a1da84679a6f0439dec3bbbd6ca7b
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 addPropertyMethods(ASTContext &Context,
887                          ObjCPropertyDecl* Property,
888                          llvm::SmallVector<ObjCMethodDecl*, 32> &insMethods,
889                          llvm::DenseMap<Selector, const ObjCMethodDecl*> &InsMap);
890
891  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
892
893  typedef ObjCPropertyDecl * const * classprop_iterator;
894  classprop_iterator classprop_begin() const { return PropertyDecl; }
895  classprop_iterator classprop_end() const {
896    return PropertyDecl+NumPropertyDecl;
897  }
898
899  typedef ObjCMethodDecl * const * instmeth_iterator;
900  instmeth_iterator instmeth_begin() const { return InstanceMethods; }
901  instmeth_iterator instmeth_end() const {
902    return InstanceMethods+NumInstanceMethods;
903  }
904
905  typedef ObjCMethodDecl * const * classmeth_iterator;
906  classmeth_iterator classmeth_begin() const { return ClassMethods; }
907  classmeth_iterator classmeth_end() const {
908    return ClassMethods+NumClassMethods;
909  }
910
911  // Get the local instance method declared in this interface.
912  ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
913    for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
914         I != E; ++I) {
915      if ((*I)->getSelector() == Sel)
916        return *I;
917    }
918    return 0;
919  }
920  // Get the local class method declared in this interface.
921  ObjCMethodDecl *getClassMethod(Selector Sel) const {
922    for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
923         I != E; ++I) {
924      if ((*I)->getSelector() == Sel)
925        return *I;
926    }
927    return 0;
928  }
929
930  void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
931                  ObjCMethodDecl **clsMethods, unsigned numClsMembers,
932                  SourceLocation AtEndLoc);
933
934  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
935  void insertNextClassCategory() {
936    NextClassCategory = ClassInterface->getCategoryList();
937    ClassInterface->setCategoryList(this);
938  }
939  // Location information, modeled after the Stmt API.
940  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
941  SourceLocation getLocEnd() const { return EndLoc; }
942  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
943
944  // We also need to record the @end location.
945  SourceLocation getAtEndLoc() const { return AtEndLoc; }
946
947  static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
948  static bool classof(const ObjCCategoryDecl *D) { return true; }
949};
950
951/// ObjCCategoryImplDecl - An object of this class encapsulates a category
952/// @implementation declaration. If a category class has declaration of a
953/// property, its implementation must be specified in the category's
954/// @implementation declaration. Example:
955/// @interface I @end
956/// @interface I(CATEGORY)
957///    @property int p1, d1;
958/// @end
959/// @implementation I(CATEGORY)
960///  @dynamic p1,d1;
961/// @end
962///
963class ObjCCategoryImplDecl : public NamedDecl {
964  /// Class interface for this category implementation
965  ObjCInterfaceDecl *ClassInterface;
966
967  /// implemented instance methods
968  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
969
970  /// implemented class methods
971  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
972
973  /// Property Implementations in this category
974  llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
975
976  SourceLocation EndLoc;
977
978  ObjCCategoryImplDecl(SourceLocation L, IdentifierInfo *Id,
979                       ObjCInterfaceDecl *classInterface)
980    : NamedDecl(ObjCCategoryImpl, L, Id), ClassInterface(classInterface) {}
981public:
982  static ObjCCategoryImplDecl *Create(ASTContext &C,
983                                      SourceLocation L, IdentifierInfo *Id,
984                                      ObjCInterfaceDecl *classInterface);
985
986  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
987  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
988
989  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
990  unsigned getNumClassMethods() const { return ClassMethods.size(); }
991
992  void addInstanceMethod(ObjCMethodDecl *method) {
993    InstanceMethods.push_back(method);
994  }
995  void addClassMethod(ObjCMethodDecl *method) {
996    ClassMethods.push_back(method);
997  }
998  // Get the instance method definition for this implementation.
999  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
1000
1001  // Get the class method definition for this implementation.
1002  ObjCMethodDecl *getClassMethod(Selector Sel) const;
1003
1004  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
1005    PropertyImplementations.push_back(property);
1006  }
1007
1008  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1009  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1010
1011  unsigned getNumPropertyImplementations() const
1012  { return PropertyImplementations.size(); }
1013
1014
1015  typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
1016    propimpl_iterator;
1017  propimpl_iterator propimpl_begin() const {
1018    return PropertyImplementations.begin();
1019  }
1020  propimpl_iterator propimpl_end() const {
1021    return PropertyImplementations.end();
1022  }
1023
1024  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1025    instmeth_iterator;
1026  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
1027  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
1028
1029  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1030    classmeth_iterator;
1031  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
1032  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
1033
1034
1035  // Location information, modeled after the Stmt API.
1036  SourceLocation getLocStart() const { return getLocation(); }
1037  SourceLocation getLocEnd() const { return EndLoc; }
1038  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
1039
1040  static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
1041  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
1042};
1043
1044/// ObjCImplementationDecl - Represents a class definition - this is where
1045/// method definitions are specified. For example:
1046///
1047/// @implementation MyClass
1048/// - (void)myMethod { /* do something */ }
1049/// @end
1050///
1051/// Typically, instance variables are specified in the class interface,
1052/// *not* in the implemenentation. Nevertheless (for legacy reasons), we
1053/// allow instance variables to be specified in the implementation. When
1054/// specified, they need to be *identical* to the interface. Now that we
1055/// have support for non-fragile ivars in ObjC 2.0, we can consider removing
1056/// the legacy semantics and allow developers to move private ivar declarations
1057/// from the class interface to the class implementation (but I digress:-)
1058///
1059class ObjCImplementationDecl : public NamedDecl {
1060  /// Class interface for this implementation
1061  ObjCInterfaceDecl *ClassInterface;
1062
1063  /// Implementation Class's super class.
1064  ObjCInterfaceDecl *SuperClass;
1065
1066  /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
1067  ObjCIvarDecl **Ivars;   // Null if not specified
1068  unsigned NumIvars;      // 0 if none.
1069
1070  /// implemented instance methods
1071  llvm::SmallVector<ObjCMethodDecl*, 32> InstanceMethods;
1072
1073  /// implemented class methods
1074  llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
1075
1076  /// Propertys' being implemented
1077  llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
1078
1079  SourceLocation EndLoc;
1080
1081  ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
1082                         ObjCInterfaceDecl *classInterface,
1083                         ObjCInterfaceDecl *superDecl)
1084    : NamedDecl(ObjCImplementation, L, Id),
1085      ClassInterface(classInterface), SuperClass(superDecl),
1086      Ivars(0), NumIvars(0) {}
1087public:
1088  static ObjCImplementationDecl *Create(ASTContext &C,
1089                                        SourceLocation L, IdentifierInfo *Id,
1090                                        ObjCInterfaceDecl *classInterface,
1091                                        ObjCInterfaceDecl *superDecl);
1092
1093
1094  void ObjCAddInstanceVariablesToClassImpl(ObjCIvarDecl **ivars,
1095                                           unsigned numIvars);
1096
1097  void addInstanceMethod(ObjCMethodDecl *method) {
1098    InstanceMethods.push_back(method);
1099  }
1100  void addClassMethod(ObjCMethodDecl *method) {
1101    ClassMethods.push_back(method);
1102  }
1103
1104  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
1105    PropertyImplementations.push_back(property);
1106  }
1107
1108  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1109  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1110
1111  typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
1112  propimpl_iterator;
1113  propimpl_iterator propimpl_begin() const {
1114    return PropertyImplementations.begin();
1115  }
1116  propimpl_iterator propimpl_end() const {
1117    return PropertyImplementations.end();
1118  }
1119
1120  // Location information, modeled after the Stmt API.
1121  SourceLocation getLocStart() const { return getLocation(); }
1122  SourceLocation getLocEnd() const { return EndLoc; }
1123  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
1124
1125  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1126  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1127  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1128  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
1129
1130  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
1131
1132  unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
1133  unsigned getNumClassMethods() const { return ClassMethods.size(); }
1134
1135  unsigned getNumPropertyImplementations() const
1136    { return PropertyImplementations.size(); }
1137
1138  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1139       instmeth_iterator;
1140  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
1141  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
1142
1143  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
1144    classmeth_iterator;
1145  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
1146  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
1147
1148  // Get the instance method definition for this implementation.
1149  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
1150
1151  // Get the class method definition for this implementation.
1152  ObjCMethodDecl *getClassMethod(Selector Sel) const;
1153
1154  typedef ObjCIvarDecl * const *ivar_iterator;
1155  ivar_iterator ivar_begin() const { return Ivars; }
1156  ivar_iterator ivar_end() const { return Ivars+NumIvars; }
1157  unsigned ivar_size() const { return NumIvars; }
1158  bool ivar_empty() const { return NumIvars == 0; }
1159
1160  static bool classof(const Decl *D) {
1161    return D->getKind() == ObjCImplementation;
1162  }
1163  static bool classof(const ObjCImplementationDecl *D) { return true; }
1164};
1165
1166/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1167/// declared as @compatibility_alias alias class.
1168class ObjCCompatibleAliasDecl : public NamedDecl {
1169  /// Class that this is an alias of.
1170  ObjCInterfaceDecl *AliasedClass;
1171
1172  ObjCCompatibleAliasDecl(SourceLocation L, IdentifierInfo *Id,
1173                          ObjCInterfaceDecl* aliasedClass)
1174    : NamedDecl(ObjCCompatibleAlias, L, Id), AliasedClass(aliasedClass) {}
1175public:
1176  static ObjCCompatibleAliasDecl *Create(ASTContext &C,
1177                                         SourceLocation L, IdentifierInfo *Id,
1178                                         ObjCInterfaceDecl* aliasedClass);
1179
1180  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1181  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
1182
1183  static bool classof(const Decl *D) {
1184    return D->getKind() == ObjCCompatibleAlias;
1185  }
1186  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
1187
1188};
1189
1190/// ObjCPropertyDecl - Represents one property declaration in an interface.
1191/// For example:
1192/// @property (assign, readwrite) int MyProperty;
1193///
1194class ObjCPropertyDecl : public NamedDecl {
1195public:
1196  enum PropertyAttributeKind {
1197    OBJC_PR_noattr    = 0x00,
1198    OBJC_PR_readonly  = 0x01,
1199    OBJC_PR_getter    = 0x02,
1200    OBJC_PR_assign    = 0x04,
1201    OBJC_PR_readwrite = 0x08,
1202    OBJC_PR_retain    = 0x10,
1203    OBJC_PR_copy      = 0x20,
1204    OBJC_PR_nonatomic = 0x40,
1205    OBJC_PR_setter    = 0x80
1206  };
1207
1208  enum SetterKind { Assign, Retain, Copy };
1209  enum PropertyControl { None, Required, Optional };
1210private:
1211  QualType DeclType;
1212  unsigned PropertyAttributes : 8;
1213
1214  // @required/@optional
1215  unsigned PropertyImplementation : 2;
1216
1217  Selector GetterName;    // getter name of NULL if no getter
1218  Selector SetterName;    // setter name of NULL if no setter
1219
1220  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
1221  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1222
1223  ObjCPropertyDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
1224    : NamedDecl(ObjCProperty, L, Id), DeclType(T),
1225      PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
1226      GetterName(Selector()),
1227      SetterName(Selector()),
1228      GetterMethodDecl(0), SetterMethodDecl(0) {}
1229public:
1230  static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L,
1231                                  IdentifierInfo *Id, QualType T,
1232                                  PropertyControl propControl = None);
1233  QualType getType() const { return DeclType; }
1234
1235  PropertyAttributeKind getPropertyAttributes() const {
1236    return PropertyAttributeKind(PropertyAttributes);
1237  }
1238  void setPropertyAttributes(PropertyAttributeKind PRVal) {
1239    PropertyAttributes |= PRVal;
1240  }
1241
1242 void makeitReadWriteAttribute(void) {
1243    PropertyAttributes &= ~OBJC_PR_readonly;
1244    PropertyAttributes |= OBJC_PR_readwrite;
1245 }
1246
1247  // Helper methods for accessing attributes.
1248
1249  /// isReadOnly - Return true iff the property has a setter.
1250  bool isReadOnly() const {
1251    return (PropertyAttributes & OBJC_PR_readonly);
1252  }
1253
1254  /// getSetterKind - Return the method used for doing assignment in
1255  /// the property setter. This is only valid if the property has been
1256  /// defined to have a setter.
1257  SetterKind getSetterKind() const {
1258    if (PropertyAttributes & OBJC_PR_retain)
1259      return Retain;
1260    if (PropertyAttributes & OBJC_PR_copy)
1261      return Copy;
1262    return Assign;
1263  }
1264
1265  Selector getGetterName() const { return GetterName; }
1266  void setGetterName(Selector Sel) { GetterName = Sel; }
1267
1268  Selector getSetterName() const { return SetterName; }
1269  void setSetterName(Selector Sel) { SetterName = Sel; }
1270
1271  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1272  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1273
1274  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1275  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1276
1277  // Related to @optional/@required declared in @protocol
1278  void setPropertyImplementation(PropertyControl pc) {
1279    PropertyImplementation = pc;
1280  }
1281  PropertyControl getPropertyImplementation() const {
1282    return PropertyControl(PropertyImplementation);
1283  }
1284
1285  static bool classof(const Decl *D) {
1286    return D->getKind() == ObjCProperty;
1287  }
1288  static bool classof(const ObjCPropertyDecl *D) { return true; }
1289};
1290
1291/// ObjCPropertyImplDecl - Represents implementation declaration of a property
1292/// in a class or category implementation block. For example:
1293/// @synthesize prop1 = ivar1;
1294///
1295class ObjCPropertyImplDecl : public Decl {
1296public:
1297  enum Kind {
1298    Synthesize,
1299    Dynamic
1300  };
1301private:
1302  SourceLocation AtLoc;   // location of @synthesize or @dynamic
1303  /// Property declaration being implemented
1304  ObjCPropertyDecl *PropertyDecl;
1305
1306  /// Null for @dynamic. Required for @synthesize.
1307  ObjCIvarDecl *PropertyIvarDecl;
1308
1309  ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L,
1310                       ObjCPropertyDecl *property,
1311                       Kind PK,
1312                       ObjCIvarDecl *ivarDecl)
1313    : Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(property),
1314      PropertyIvarDecl(ivarDecl) {
1315    assert (PK == Dynamic || PropertyIvarDecl);
1316  }
1317
1318public:
1319  static ObjCPropertyImplDecl *Create(ASTContext &C, SourceLocation atLoc,
1320                                      SourceLocation L,
1321                                      ObjCPropertyDecl *property,
1322                                      Kind PK,
1323                                      ObjCIvarDecl *ivarDecl);
1324
1325  SourceLocation getLocStart() const { return AtLoc; }
1326
1327  ObjCPropertyDecl *getPropertyDecl() const {
1328    return PropertyDecl;
1329  }
1330
1331  Kind getPropertyImplementation() const {
1332    return PropertyIvarDecl ? Synthesize : Dynamic;
1333  }
1334
1335  ObjCIvarDecl *getPropertyIvarDecl() const {
1336    return PropertyIvarDecl;
1337  }
1338
1339  static bool classof(const Decl *D) {
1340    return D->getKind() == ObjCPropertyImpl;
1341  }
1342  static bool classof(const ObjCPropertyImplDecl *D) { return true; }
1343};
1344
1345}  // end namespace clang
1346#endif
1347