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