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