DeclObjC.h revision 53b9441b5a81a24fa1f66f3f6416f1e36baa9c2f
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  }
995
996  bool IsClassExtension() const { return getIdentifier() == 0; }
997  const ObjCCategoryDecl *getNextClassExtension() const;
998
999  bool hasSynthBitfield() const { return HasSynthBitfield; }
1000  void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
1001
1002  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1003  ivar_iterator ivar_begin() const {
1004    return ivar_iterator(decls_begin());
1005  }
1006  ivar_iterator ivar_end() const {
1007    return ivar_iterator(decls_end());
1008  }
1009  unsigned ivar_size() const {
1010    return std::distance(ivar_begin(), ivar_end());
1011  }
1012  bool ivar_empty() const {
1013    return ivar_begin() == ivar_end();
1014  }
1015
1016  SourceLocation getAtLoc() const { return AtLoc; }
1017  void setAtLoc(SourceLocation At) { AtLoc = At; }
1018
1019  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1020  void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
1021
1022  virtual SourceRange getSourceRange() const {
1023    return SourceRange(AtLoc, getAtEndRange().getEnd());
1024  }
1025
1026  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1027  static bool classof(const ObjCCategoryDecl *D) { return true; }
1028  static bool classofKind(Kind K) { return K == ObjCCategory; }
1029};
1030
1031class ObjCImplDecl : public ObjCContainerDecl {
1032  /// Class interface for this class/category implementation
1033  ObjCInterfaceDecl *ClassInterface;
1034
1035protected:
1036  ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L,
1037               ObjCInterfaceDecl *classInterface)
1038    : ObjCContainerDecl(DK, DC, L,
1039                        classInterface? classInterface->getIdentifier() : 0),
1040      ClassInterface(classInterface) {}
1041
1042public:
1043  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1044  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1045  void setClassInterface(ObjCInterfaceDecl *IFace);
1046
1047  void addInstanceMethod(ObjCMethodDecl *method) {
1048    // FIXME: Context should be set correctly before we get here.
1049    method->setLexicalDeclContext(this);
1050    addDecl(method);
1051  }
1052  void addClassMethod(ObjCMethodDecl *method) {
1053    // FIXME: Context should be set correctly before we get here.
1054    method->setLexicalDeclContext(this);
1055    addDecl(method);
1056  }
1057
1058  void addPropertyImplementation(ObjCPropertyImplDecl *property);
1059
1060  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1061  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1062
1063  // Iterator access to properties.
1064  typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
1065  propimpl_iterator propimpl_begin() const {
1066    return propimpl_iterator(decls_begin());
1067  }
1068  propimpl_iterator propimpl_end() const {
1069    return propimpl_iterator(decls_end());
1070  }
1071
1072  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1073  static bool classof(const ObjCImplDecl *D) { return true; }
1074  static bool classofKind(Kind K) {
1075    return K >= firstObjCImpl && K <= lastObjCImpl;
1076  }
1077};
1078
1079/// ObjCCategoryImplDecl - An object of this class encapsulates a category
1080/// @implementation declaration. If a category class has declaration of a
1081/// property, its implementation must be specified in the category's
1082/// @implementation declaration. Example:
1083/// @interface I @end
1084/// @interface I(CATEGORY)
1085///    @property int p1, d1;
1086/// @end
1087/// @implementation I(CATEGORY)
1088///  @dynamic p1,d1;
1089/// @end
1090///
1091/// ObjCCategoryImplDecl
1092class ObjCCategoryImplDecl : public ObjCImplDecl {
1093  // Category name
1094  IdentifierInfo *Id;
1095
1096  ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1097                       ObjCInterfaceDecl *classInterface)
1098    : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {}
1099public:
1100  static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
1101                                      SourceLocation L, IdentifierInfo *Id,
1102                                      ObjCInterfaceDecl *classInterface);
1103
1104  /// getIdentifier - Get the identifier that names the category
1105  /// interface associated with this implementation.
1106  /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
1107  /// to mean something different. For example:
1108  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
1109  /// returns the class interface name, whereas
1110  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
1111  /// returns the category name.
1112  IdentifierInfo *getIdentifier() const {
1113    return Id;
1114  }
1115  void setIdentifier(IdentifierInfo *II) { Id = II; }
1116
1117  ObjCCategoryDecl *getCategoryDecl() const;
1118
1119  /// getName - Get the name of identifier for the class interface associated
1120  /// with this implementation as a StringRef.
1121  //
1122  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1123  // something different.
1124  llvm::StringRef getName() const {
1125    return Id ? Id->getNameStart() : "";
1126  }
1127
1128  /// getNameAsCString - Get the name of identifier for the class
1129  /// interface associated with this implementation as a C string
1130  /// (const char*).
1131  //
1132  // FIXME: Deprecated, move clients to getName().
1133  const char *getNameAsCString() const {
1134    return Id ? Id->getNameStart() : "";
1135  }
1136
1137  /// @brief Get the name of the class associated with this interface.
1138  //
1139  // FIXME: Deprecated, move clients to getName().
1140  std::string getNameAsString() const {
1141    return getName();
1142  }
1143
1144  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1145  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
1146  static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
1147};
1148
1149llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
1150                              const ObjCCategoryImplDecl *CID);
1151
1152/// ObjCImplementationDecl - Represents a class definition - this is where
1153/// method definitions are specified. For example:
1154///
1155/// @code
1156/// @implementation MyClass
1157/// - (void)myMethod { /* do something */ }
1158/// @end
1159/// @endcode
1160///
1161/// Typically, instance variables are specified in the class interface,
1162/// *not* in the implementation. Nevertheless (for legacy reasons), we
1163/// allow instance variables to be specified in the implementation.  When
1164/// specified, they need to be *identical* to the interface.
1165///
1166class ObjCImplementationDecl : public ObjCImplDecl {
1167  /// Implementation Class's super class.
1168  ObjCInterfaceDecl *SuperClass;
1169  /// Support for ivar initialization.
1170  /// IvarInitializers - The arguments used to initialize the ivars
1171  CXXBaseOrMemberInitializer **IvarInitializers;
1172  unsigned NumIvarInitializers;
1173
1174  /// true of class extension has at least one bitfield ivar.
1175  bool HasSynthBitfield : 1;
1176
1177  ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
1178                         ObjCInterfaceDecl *classInterface,
1179                         ObjCInterfaceDecl *superDecl)
1180    : ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
1181       SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0),
1182       HasSynthBitfield(false) {}
1183public:
1184  static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
1185                                        SourceLocation L,
1186                                        ObjCInterfaceDecl *classInterface,
1187                                        ObjCInterfaceDecl *superDecl);
1188
1189  /// init_iterator - Iterates through the ivar initializer list.
1190  typedef CXXBaseOrMemberInitializer **init_iterator;
1191
1192  /// init_const_iterator - Iterates through the ivar initializer list.
1193  typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
1194
1195  /// init_begin() - Retrieve an iterator to the first initializer.
1196  init_iterator       init_begin()       { return IvarInitializers; }
1197  /// begin() - Retrieve an iterator to the first initializer.
1198  init_const_iterator init_begin() const { return IvarInitializers; }
1199
1200  /// init_end() - Retrieve an iterator past the last initializer.
1201  init_iterator       init_end()       {
1202    return IvarInitializers + NumIvarInitializers;
1203  }
1204  /// end() - Retrieve an iterator past the last initializer.
1205  init_const_iterator init_end() const {
1206    return IvarInitializers + NumIvarInitializers;
1207  }
1208  /// getNumArgs - Number of ivars which must be initialized.
1209  unsigned getNumIvarInitializers() const {
1210    return NumIvarInitializers;
1211  }
1212
1213  void setNumIvarInitializers(unsigned numNumIvarInitializers) {
1214    NumIvarInitializers = numNumIvarInitializers;
1215  }
1216
1217  void setIvarInitializers(ASTContext &C,
1218                           CXXBaseOrMemberInitializer ** initializers,
1219                           unsigned numInitializers);
1220
1221  bool hasSynthBitfield() const { return HasSynthBitfield; }
1222  void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
1223
1224  /// getIdentifier - Get the identifier that names the class
1225  /// interface associated with this implementation.
1226  IdentifierInfo *getIdentifier() const {
1227    return getClassInterface()->getIdentifier();
1228  }
1229
1230  /// getName - Get the name of identifier for the class interface associated
1231  /// with this implementation as a StringRef.
1232  //
1233  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1234  // something different.
1235  llvm::StringRef getName() const {
1236    assert(getIdentifier() && "Name is not a simple identifier");
1237    return getIdentifier()->getName();
1238  }
1239
1240  /// getNameAsCString - Get the name of identifier for the class
1241  /// interface associated with this implementation as a C string
1242  /// (const char*).
1243  //
1244  // FIXME: Move to StringRef API.
1245  const char *getNameAsCString() const {
1246    return getName().data();
1247  }
1248
1249  /// @brief Get the name of the class associated with this interface.
1250  //
1251  // FIXME: Move to StringRef API.
1252  std::string getNameAsString() const {
1253    return getName();
1254  }
1255
1256  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1257  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
1258
1259  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
1260
1261  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1262  ivar_iterator ivar_begin() const {
1263    return ivar_iterator(decls_begin());
1264  }
1265  ivar_iterator ivar_end() const {
1266    return ivar_iterator(decls_end());
1267  }
1268  unsigned ivar_size() const {
1269    return std::distance(ivar_begin(), ivar_end());
1270  }
1271  bool ivar_empty() const {
1272    return ivar_begin() == ivar_end();
1273  }
1274
1275  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1276  static bool classof(const ObjCImplementationDecl *D) { return true; }
1277  static bool classofKind(Kind K) { return K == ObjCImplementation; }
1278
1279  friend class ASTDeclReader;
1280  friend class ASTDeclWriter;
1281};
1282
1283llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
1284                              const ObjCImplementationDecl *ID);
1285
1286/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1287/// declared as @compatibility_alias alias class.
1288class ObjCCompatibleAliasDecl : public NamedDecl {
1289  /// Class that this is an alias of.
1290  ObjCInterfaceDecl *AliasedClass;
1291
1292  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1293                          ObjCInterfaceDecl* aliasedClass)
1294    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
1295public:
1296  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
1297                                         SourceLocation L, IdentifierInfo *Id,
1298                                         ObjCInterfaceDecl* aliasedClass);
1299
1300  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1301  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
1302  void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
1303
1304  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1305  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
1306  static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
1307
1308};
1309
1310/// ObjCPropertyDecl - Represents one property declaration in an interface.
1311/// For example:
1312/// @property (assign, readwrite) int MyProperty;
1313///
1314class ObjCPropertyDecl : public NamedDecl {
1315public:
1316  enum PropertyAttributeKind {
1317    OBJC_PR_noattr    = 0x00,
1318    OBJC_PR_readonly  = 0x01,
1319    OBJC_PR_getter    = 0x02,
1320    OBJC_PR_assign    = 0x04,
1321    OBJC_PR_readwrite = 0x08,
1322    OBJC_PR_retain    = 0x10,
1323    OBJC_PR_copy      = 0x20,
1324    OBJC_PR_nonatomic = 0x40,
1325    OBJC_PR_setter    = 0x80
1326  };
1327
1328  enum SetterKind { Assign, Retain, Copy };
1329  enum PropertyControl { None, Required, Optional };
1330private:
1331  SourceLocation AtLoc;   // location of @property
1332  TypeSourceInfo *DeclType;
1333  unsigned PropertyAttributes : 8;
1334  unsigned PropertyAttributesAsWritten : 8;
1335  // @required/@optional
1336  unsigned PropertyImplementation : 2;
1337
1338  Selector GetterName;    // getter name of NULL if no getter
1339  Selector SetterName;    // setter name of NULL if no setter
1340
1341  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
1342  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1343  ObjCIvarDecl *PropertyIvarDecl;   // Synthesize ivar for this property
1344
1345  ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1346                   SourceLocation AtLocation, TypeSourceInfo *T)
1347    : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), DeclType(T),
1348      PropertyAttributes(OBJC_PR_noattr),
1349      PropertyAttributesAsWritten(OBJC_PR_noattr),
1350      PropertyImplementation(None),
1351      GetterName(Selector()),
1352      SetterName(Selector()),
1353      GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
1354public:
1355  static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
1356                                  SourceLocation L,
1357                                  IdentifierInfo *Id, SourceLocation AtLocation,
1358                                  TypeSourceInfo *T,
1359                                  PropertyControl propControl = None);
1360  SourceLocation getAtLoc() const { return AtLoc; }
1361  void setAtLoc(SourceLocation L) { AtLoc = L; }
1362
1363  TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
1364  QualType getType() const { return DeclType->getType(); }
1365  void setType(TypeSourceInfo *T) { DeclType = T; }
1366
1367  PropertyAttributeKind getPropertyAttributes() const {
1368    return PropertyAttributeKind(PropertyAttributes);
1369  }
1370  void setPropertyAttributes(PropertyAttributeKind PRVal) {
1371    PropertyAttributes |= PRVal;
1372  }
1373
1374  PropertyAttributeKind getPropertyAttributesAsWritten() const {
1375    return PropertyAttributeKind(PropertyAttributesAsWritten);
1376  }
1377
1378  void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
1379    PropertyAttributesAsWritten = PRVal;
1380  }
1381
1382 void makeitReadWriteAttribute(void) {
1383    PropertyAttributes &= ~OBJC_PR_readonly;
1384    PropertyAttributes |= OBJC_PR_readwrite;
1385 }
1386
1387  // Helper methods for accessing attributes.
1388
1389  /// isReadOnly - Return true iff the property has a setter.
1390  bool isReadOnly() const {
1391    return (PropertyAttributes & OBJC_PR_readonly);
1392  }
1393
1394  /// getSetterKind - Return the method used for doing assignment in
1395  /// the property setter. This is only valid if the property has been
1396  /// defined to have a setter.
1397  SetterKind getSetterKind() const {
1398    if (PropertyAttributes & OBJC_PR_retain)
1399      return Retain;
1400    if (PropertyAttributes & OBJC_PR_copy)
1401      return Copy;
1402    return Assign;
1403  }
1404
1405  Selector getGetterName() const { return GetterName; }
1406  void setGetterName(Selector Sel) { GetterName = Sel; }
1407
1408  Selector getSetterName() const { return SetterName; }
1409  void setSetterName(Selector Sel) { SetterName = Sel; }
1410
1411  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1412  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1413
1414  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1415  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1416
1417  // Related to @optional/@required declared in @protocol
1418  void setPropertyImplementation(PropertyControl pc) {
1419    PropertyImplementation = pc;
1420  }
1421  PropertyControl getPropertyImplementation() const {
1422    return PropertyControl(PropertyImplementation);
1423  }
1424
1425  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
1426    PropertyIvarDecl = Ivar;
1427  }
1428  ObjCIvarDecl *getPropertyIvarDecl() const {
1429    return PropertyIvarDecl;
1430  }
1431
1432  /// Lookup a property by name in the specified DeclContext.
1433  static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
1434                                            IdentifierInfo *propertyID);
1435
1436  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1437  static bool classof(const ObjCPropertyDecl *D) { return true; }
1438  static bool classofKind(Kind K) { return K == ObjCProperty; }
1439};
1440
1441/// ObjCPropertyImplDecl - Represents implementation declaration of a property
1442/// in a class or category implementation block. For example:
1443/// @synthesize prop1 = ivar1;
1444///
1445class ObjCPropertyImplDecl : public Decl {
1446public:
1447  enum Kind {
1448    Synthesize,
1449    Dynamic
1450  };
1451private:
1452  SourceLocation AtLoc;   // location of @synthesize or @dynamic
1453  /// Property declaration being implemented
1454  ObjCPropertyDecl *PropertyDecl;
1455
1456  /// Null for @dynamic. Required for @synthesize.
1457  ObjCIvarDecl *PropertyIvarDecl;
1458
1459  /// Null for @dynamic. Non-null if property must be copy-constructed in getter
1460  Expr *GetterCXXConstructor;
1461
1462  /// Null for @dynamic. Non-null if property has assignment operator to call
1463  /// in Setter synthesis.
1464  Expr *SetterCXXAssignment;
1465
1466  ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
1467                       ObjCPropertyDecl *property,
1468                       Kind PK,
1469                       ObjCIvarDecl *ivarDecl)
1470    : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
1471      PropertyDecl(property), PropertyIvarDecl(ivarDecl),
1472      GetterCXXConstructor(0), SetterCXXAssignment(0) {
1473    assert (PK == Dynamic || PropertyIvarDecl);
1474  }
1475
1476public:
1477  static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
1478                                      SourceLocation atLoc, SourceLocation L,
1479                                      ObjCPropertyDecl *property,
1480                                      Kind PK,
1481                                      ObjCIvarDecl *ivarDecl);
1482
1483  virtual SourceRange getSourceRange() const {
1484    return SourceRange(AtLoc, getLocation());
1485  }
1486  SourceLocation getLocStart() const { return AtLoc; }
1487  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
1488
1489  ObjCPropertyDecl *getPropertyDecl() const {
1490    return PropertyDecl;
1491  }
1492  void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
1493
1494  Kind getPropertyImplementation() const {
1495    return PropertyIvarDecl ? Synthesize : Dynamic;
1496  }
1497
1498  ObjCIvarDecl *getPropertyIvarDecl() const {
1499    return PropertyIvarDecl;
1500  }
1501  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
1502
1503  Expr *getGetterCXXConstructor() const {
1504    return GetterCXXConstructor;
1505  }
1506  void setGetterCXXConstructor(Expr *getterCXXConstructor) {
1507    GetterCXXConstructor = getterCXXConstructor;
1508  }
1509
1510  Expr *getSetterCXXAssignment() const {
1511    return SetterCXXAssignment;
1512  }
1513  void setSetterCXXAssignment(Expr *setterCXXAssignment) {
1514    SetterCXXAssignment = setterCXXAssignment;
1515  }
1516
1517  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1518  static bool classof(const ObjCPropertyImplDecl *D) { return true; }
1519  static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
1520};
1521
1522}  // end namespace clang
1523#endif
1524