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