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