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