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