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