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