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