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