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