DeclObjC.h revision bf967be66ea8c51b66c61659c23240f762a56dbe
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 "clang/AST/SelectorLocationsKind.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/Support/Compiler.h"
21
22namespace clang {
23class Expr;
24class Stmt;
25class FunctionDecl;
26class RecordDecl;
27class ObjCIvarDecl;
28class ObjCMethodDecl;
29class ObjCProtocolDecl;
30class ObjCCategoryDecl;
31class ObjCPropertyDecl;
32class ObjCPropertyImplDecl;
33class CXXCtorInitializer;
34
35class ObjCListBase {
36  ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION;
37  void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION;
38protected:
39  /// List is an array of pointers to objects that are not owned by this object.
40  void **List;
41  unsigned NumElts;
42
43public:
44  ObjCListBase() : List(0), NumElts(0) {}
45  unsigned size() const { return NumElts; }
46  bool empty() const { return NumElts == 0; }
47
48protected:
49  void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
50};
51
52
53/// ObjCList - This is a simple template class used to hold various lists of
54/// decls etc, which is heavily used by the ObjC front-end.  This only use case
55/// this supports is setting the list all at once and then reading elements out
56/// of it.
57template <typename T>
58class ObjCList : public ObjCListBase {
59public:
60  void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
61    ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
62  }
63
64  typedef T* const * iterator;
65  iterator begin() const { return (iterator)List; }
66  iterator end() const { return (iterator)List+NumElts; }
67
68  T* operator[](unsigned Idx) const {
69    assert(Idx < NumElts && "Invalid access");
70    return (T*)List[Idx];
71  }
72};
73
74/// \brief A list of Objective-C protocols, along with the source
75/// locations at which they were referenced.
76class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
77  SourceLocation *Locations;
78
79  using ObjCList<ObjCProtocolDecl>::set;
80
81public:
82  ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { }
83
84  typedef const SourceLocation *loc_iterator;
85  loc_iterator loc_begin() const { return Locations; }
86  loc_iterator loc_end() const { return Locations + size(); }
87
88  void set(ObjCProtocolDecl* const* InList, unsigned Elts,
89           const SourceLocation *Locs, ASTContext &Ctx);
90};
91
92
93/// ObjCMethodDecl - Represents an instance or class method declaration.
94/// ObjC methods can be declared within 4 contexts: class interfaces,
95/// categories, protocols, and class implementations. While C++ member
96/// functions leverage C syntax, Objective-C method syntax is modeled after
97/// Smalltalk (using colons to specify argument types/expressions).
98/// Here are some brief examples:
99///
100/// Setter/getter instance methods:
101/// - (void)setMenu:(NSMenu *)menu;
102/// - (NSMenu *)menu;
103///
104/// Instance method that takes 2 NSView arguments:
105/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
106///
107/// Getter class method:
108/// + (NSMenu *)defaultMenu;
109///
110/// A selector represents a unique name for a method. The selector names for
111/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
112///
113class ObjCMethodDecl : public NamedDecl, public DeclContext {
114public:
115  enum ImplementationControl { None, Required, Optional };
116private:
117  // The conventional meaning of this method; an ObjCMethodFamily.
118  // This is not serialized; instead, it is computed on demand and
119  // cached.
120  mutable unsigned Family : ObjCMethodFamilyBitWidth;
121
122  /// instance (true) or class (false) method.
123  unsigned IsInstance : 1;
124  unsigned IsVariadic : 1;
125
126  /// True if this method is the getter or setter for an explicit property.
127  unsigned IsPropertyAccessor : 1;
128
129  // Method has a definition.
130  unsigned IsDefined : 1;
131
132  /// \brief Method redeclaration in the same interface.
133  unsigned IsRedeclaration : 1;
134
135  /// \brief Is redeclared in the same interface.
136  mutable unsigned HasRedeclaration : 1;
137
138  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
139  /// \@required/\@optional
140  unsigned DeclImplementation : 2;
141
142  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
143  /// in, inout, etc.
144  unsigned objcDeclQualifier : 6;
145
146  /// \brief Indicates whether this method has a related result type.
147  unsigned RelatedResultType : 1;
148
149  /// \brief Whether the locations of the selector identifiers are in a
150  /// "standard" position, a enum SelectorLocationsKind.
151  unsigned SelLocsKind : 2;
152
153  /// \brief Whether this method overrides any other in the class hierarchy.
154  ///
155  /// A method is said to override any method in the class's
156  /// base classes, its protocols, or its categories' protocols, that has
157  /// the same selector and is of the same kind (class or instance).
158  /// A method in an implementation is not considered as overriding the same
159  /// method in the interface or its categories.
160  unsigned IsOverriding : 1;
161
162  // Result type of this method.
163  QualType MethodDeclType;
164
165  // Type source information for the result type.
166  TypeSourceInfo *ResultTInfo;
167
168  /// \brief Array of ParmVarDecls for the formal parameters of this method
169  /// and optionally followed by selector locations.
170  void *ParamsAndSelLocs;
171  unsigned NumParams;
172
173  /// List of attributes for this method declaration.
174  SourceLocation DeclEndLoc; // the location of the ';' or '{'.
175
176  // The following are only used for method definitions, null otherwise.
177  LazyDeclStmtPtr Body;
178
179  /// SelfDecl - Decl for the implicit self parameter. This is lazily
180  /// constructed by createImplicitParams.
181  ImplicitParamDecl *SelfDecl;
182  /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
183  /// constructed by createImplicitParams.
184  ImplicitParamDecl *CmdDecl;
185
186  SelectorLocationsKind getSelLocsKind() const {
187    return (SelectorLocationsKind)SelLocsKind;
188  }
189  bool hasStandardSelLocs() const {
190    return getSelLocsKind() != SelLoc_NonStandard;
191  }
192
193  /// \brief Get a pointer to the stored selector identifiers locations array.
194  /// No locations will be stored if HasStandardSelLocs is true.
195  SourceLocation *getStoredSelLocs() {
196    return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
197  }
198  const SourceLocation *getStoredSelLocs() const {
199    return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
200  }
201
202  /// \brief Get a pointer to the stored selector identifiers locations array.
203  /// No locations will be stored if HasStandardSelLocs is true.
204  ParmVarDecl **getParams() {
205    return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
206  }
207  const ParmVarDecl *const *getParams() const {
208    return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
209  }
210
211  /// \brief Get the number of stored selector identifiers locations.
212  /// No locations will be stored if HasStandardSelLocs is true.
213  unsigned getNumStoredSelLocs() const {
214    if (hasStandardSelLocs())
215      return 0;
216    return getNumSelectorLocs();
217  }
218
219  void setParamsAndSelLocs(ASTContext &C,
220                           ArrayRef<ParmVarDecl*> Params,
221                           ArrayRef<SourceLocation> SelLocs);
222
223  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
224                 Selector SelInfo, QualType T,
225                 TypeSourceInfo *ResultTInfo,
226                 DeclContext *contextDecl,
227                 bool isInstance = true,
228                 bool isVariadic = false,
229                 bool isPropertyAccessor = false,
230                 bool isImplicitlyDeclared = false,
231                 bool isDefined = false,
232                 ImplementationControl impControl = None,
233                 bool HasRelatedResultType = false)
234  : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
235    DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
236    IsInstance(isInstance), IsVariadic(isVariadic),
237    IsPropertyAccessor(isPropertyAccessor),
238    IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
239    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
240    RelatedResultType(HasRelatedResultType),
241    SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0),
242    MethodDeclType(T), ResultTInfo(ResultTInfo),
243    ParamsAndSelLocs(0), NumParams(0),
244    DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
245    setImplicit(isImplicitlyDeclared);
246  }
247
248  /// \brief A definition will return its interface declaration.
249  /// An interface declaration will return its definition.
250  /// Otherwise it will return itself.
251  virtual ObjCMethodDecl *getNextRedeclaration();
252
253public:
254  static ObjCMethodDecl *Create(ASTContext &C,
255                                SourceLocation beginLoc,
256                                SourceLocation endLoc,
257                                Selector SelInfo,
258                                QualType T,
259                                TypeSourceInfo *ResultTInfo,
260                                DeclContext *contextDecl,
261                                bool isInstance = true,
262                                bool isVariadic = false,
263                                bool isPropertyAccessor = false,
264                                bool isImplicitlyDeclared = false,
265                                bool isDefined = false,
266                                ImplementationControl impControl = None,
267                                bool HasRelatedResultType = false);
268
269  static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
270
271  virtual ObjCMethodDecl *getCanonicalDecl();
272  const ObjCMethodDecl *getCanonicalDecl() const {
273    return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
274  }
275
276  ObjCDeclQualifier getObjCDeclQualifier() const {
277    return ObjCDeclQualifier(objcDeclQualifier);
278  }
279  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
280
281  /// \brief Determine whether this method has a result type that is related
282  /// to the message receiver's type.
283  bool hasRelatedResultType() const { return RelatedResultType; }
284
285  /// \brief Note whether this method has a related result type.
286  void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
287
288  /// \brief True if this is a method redeclaration in the same interface.
289  bool isRedeclaration() const { return IsRedeclaration; }
290  void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
291
292  /// \brief Returns the location where the declarator ends. It will be
293  /// the location of ';' for a method declaration and the location of '{'
294  /// for a method definition.
295  SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; }
296
297  // Location information, modeled after the Stmt API.
298  SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
299  SourceLocation getLocEnd() const LLVM_READONLY;
300  virtual SourceRange getSourceRange() const LLVM_READONLY {
301    return SourceRange(getLocation(), getLocEnd());
302  }
303
304  SourceLocation getSelectorStartLoc() const {
305    if (isImplicit())
306      return getLocStart();
307    return getSelectorLoc(0);
308  }
309  SourceLocation getSelectorLoc(unsigned Index) const {
310    assert(Index < getNumSelectorLocs() && "Index out of range!");
311    if (hasStandardSelLocs())
312      return getStandardSelectorLoc(Index, getSelector(),
313                                   getSelLocsKind() == SelLoc_StandardWithSpace,
314                      llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
315                                         NumParams),
316                                   DeclEndLoc);
317    return getStoredSelLocs()[Index];
318  }
319
320  void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const;
321
322  unsigned getNumSelectorLocs() const {
323    if (isImplicit())
324      return 0;
325    Selector Sel = getSelector();
326    if (Sel.isUnarySelector())
327      return 1;
328    return Sel.getNumArgs();
329  }
330
331  ObjCInterfaceDecl *getClassInterface();
332  const ObjCInterfaceDecl *getClassInterface() const {
333    return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
334  }
335
336  Selector getSelector() const { return getDeclName().getObjCSelector(); }
337
338  QualType getResultType() const { return MethodDeclType; }
339  void setResultType(QualType T) { MethodDeclType = T; }
340
341  /// \brief Determine the type of an expression that sends a message to this
342  /// function.
343  QualType getSendResultType() const {
344    return getResultType().getNonLValueExprType(getASTContext());
345  }
346
347  TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
348  void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
349
350  // Iterator access to formal parameters.
351  unsigned param_size() const { return NumParams; }
352  typedef const ParmVarDecl *const *param_const_iterator;
353  typedef ParmVarDecl *const *param_iterator;
354  param_const_iterator param_begin() const { return getParams(); }
355  param_const_iterator param_end() const { return getParams() + NumParams; }
356  param_iterator param_begin() { return getParams(); }
357  param_iterator param_end() { return getParams() + NumParams; }
358  // This method returns and of the parameters which are part of the selector
359  // name mangling requirements.
360  param_const_iterator sel_param_end() const {
361    return param_begin() + getSelector().getNumArgs();
362  }
363
364  /// \brief Sets the method's parameters and selector source locations.
365  /// If the method is implicit (not coming from source) \p SelLocs is
366  /// ignored.
367  void setMethodParams(ASTContext &C,
368                       ArrayRef<ParmVarDecl*> Params,
369                       ArrayRef<SourceLocation> SelLocs =
370                           ArrayRef<SourceLocation>());
371
372  // Iterator access to parameter types.
373  typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
374  typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
375      arg_type_iterator;
376
377  arg_type_iterator arg_type_begin() const {
378    return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
379  }
380  arg_type_iterator arg_type_end() const {
381    return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
382  }
383
384  /// createImplicitParams - Used to lazily create the self and cmd
385  /// implict parameters. This must be called prior to using getSelfDecl()
386  /// or getCmdDecl(). The call is ignored if the implicit paramters
387  /// have already been created.
388  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
389
390  ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
391  void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
392  ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
393  void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
394
395  /// Determines the family of this method.
396  ObjCMethodFamily getMethodFamily() const;
397
398  bool isInstanceMethod() const { return IsInstance; }
399  void setInstanceMethod(bool isInst) { IsInstance = isInst; }
400  bool isVariadic() const { return IsVariadic; }
401  void setVariadic(bool isVar) { IsVariadic = isVar; }
402
403  bool isClassMethod() const { return !IsInstance; }
404
405  bool isPropertyAccessor() const { return IsPropertyAccessor; }
406  void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; }
407
408  bool isDefined() const { return IsDefined; }
409  void setDefined(bool isDefined) { IsDefined = isDefined; }
410
411  /// \brief Whether this method overrides any other in the class hierarchy.
412  ///
413  /// A method is said to override any method in the class's
414  /// base classes, its protocols, or its categories' protocols, that has
415  /// the same selector and is of the same kind (class or instance).
416  /// A method in an implementation is not considered as overriding the same
417  /// method in the interface or its categories.
418  bool isOverriding() const { return IsOverriding; }
419  void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
420
421  /// \brief Return overridden methods for the given \p Method.
422  ///
423  /// An ObjC method is considered to override any method in the class's
424  /// base classes (and base's categories), its protocols, or its categories'
425  /// protocols, that has
426  /// the same selector and is of the same kind (class or instance).
427  /// A method in an implementation is not considered as overriding the same
428  /// method in the interface or its categories.
429  void getOverriddenMethods(
430                     SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
431
432  /// \brief Returns the property associated with this method's selector.
433  ///
434  /// Note that even if this particular method is not marked as a property
435  /// accessor, it is still possible for it to match a property declared in a
436  /// superclass. Pass \c false if you only want to check the current class.
437  const ObjCPropertyDecl *findPropertyDecl(bool CheckOverrides = true) const;
438
439  // Related to protocols declared in  \@protocol
440  void setDeclImplementation(ImplementationControl ic) {
441    DeclImplementation = ic;
442  }
443  ImplementationControl getImplementationControl() const {
444    return ImplementationControl(DeclImplementation);
445  }
446
447  /// \brief Determine whether this method has a body.
448  virtual bool hasBody() const { return Body; }
449
450  /// \brief Retrieve the body of this method, if it has one.
451  virtual Stmt *getBody() const;
452
453  void setLazyBody(uint64_t Offset) { Body = Offset; }
454
455  CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
456  void setBody(Stmt *B) { Body = B; }
457
458  /// \brief Returns whether this specific method is a definition.
459  bool isThisDeclarationADefinition() const { return Body; }
460
461  // Implement isa/cast/dyncast/etc.
462  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
463  static bool classof(const ObjCMethodDecl *D) { return true; }
464  static bool classofKind(Kind K) { return K == ObjCMethod; }
465  static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
466    return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
467  }
468  static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
469    return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
470  }
471
472  friend class ASTDeclReader;
473  friend class ASTDeclWriter;
474};
475
476/// ObjCContainerDecl - Represents a container for method declarations.
477/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl,
478/// ObjCProtocolDecl, and ObjCImplDecl.
479///
480class ObjCContainerDecl : public NamedDecl, public DeclContext {
481  virtual void anchor();
482
483  SourceLocation AtStart;
484
485  // These two locations in the range mark the end of the method container.
486  // The first points to the '@' token, and the second to the 'end' token.
487  SourceRange AtEnd;
488public:
489
490  ObjCContainerDecl(Kind DK, DeclContext *DC,
491                    IdentifierInfo *Id, SourceLocation nameLoc,
492                    SourceLocation atStartLoc)
493    : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {}
494
495  // Iterator access to properties.
496  typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
497  prop_iterator prop_begin() const {
498    return prop_iterator(decls_begin());
499  }
500  prop_iterator prop_end() const {
501    return prop_iterator(decls_end());
502  }
503
504  // Iterator access to instance/class methods.
505  typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
506  method_iterator meth_begin() const {
507    return method_iterator(decls_begin());
508  }
509  method_iterator meth_end() const {
510    return method_iterator(decls_end());
511  }
512
513  typedef filtered_decl_iterator<ObjCMethodDecl,
514                                 &ObjCMethodDecl::isInstanceMethod>
515    instmeth_iterator;
516  instmeth_iterator instmeth_begin() const {
517    return instmeth_iterator(decls_begin());
518  }
519  instmeth_iterator instmeth_end() const {
520    return instmeth_iterator(decls_end());
521  }
522
523  typedef filtered_decl_iterator<ObjCMethodDecl,
524                                 &ObjCMethodDecl::isClassMethod>
525    classmeth_iterator;
526  classmeth_iterator classmeth_begin() const {
527    return classmeth_iterator(decls_begin());
528  }
529  classmeth_iterator classmeth_end() const {
530    return classmeth_iterator(decls_end());
531  }
532
533  // Get the local instance/class method declared in this interface.
534  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const;
535  ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
536    return getMethod(Sel, true/*isInstance*/);
537  }
538  ObjCMethodDecl *getClassMethod(Selector Sel) const {
539    return getMethod(Sel, false/*isInstance*/);
540  }
541  ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const;
542
543  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
544
545  SourceLocation getAtStartLoc() const { return AtStart; }
546  void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; }
547
548  // Marks the end of the container.
549  SourceRange getAtEndRange() const {
550    return AtEnd;
551  }
552  void setAtEndRange(SourceRange atEnd) {
553    AtEnd = atEnd;
554  }
555
556  virtual SourceRange getSourceRange() const LLVM_READONLY {
557    return SourceRange(AtStart, getAtEndRange().getEnd());
558  }
559
560  // Implement isa/cast/dyncast/etc.
561  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
562  static bool classof(const ObjCContainerDecl *D) { return true; }
563  static bool classofKind(Kind K) {
564    return K >= firstObjCContainer &&
565           K <= lastObjCContainer;
566  }
567
568  static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
569    return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
570  }
571  static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
572    return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
573  }
574};
575
576/// \brief Represents an ObjC class declaration.
577///
578/// For example:
579///
580/// \code
581///   // MostPrimitive declares no super class (not particularly useful).
582///   \@interface MostPrimitive
583///     // no instance variables or methods.
584///   \@end
585///
586///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
587///   \@interface NSResponder : NSObject \<NSCoding>
588///   { // instance variables are represented by ObjCIvarDecl.
589///     id nextResponder; // nextResponder instance variable.
590///   }
591///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
592///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
593///   \@end                                    // to an NSEvent.
594/// \endcode
595///
596///   Unlike C/C++, forward class declarations are accomplished with \@class.
597///   Unlike C/C++, \@class allows for a list of classes to be forward declared.
598///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
599///   typically inherit from NSObject (an exception is NSProxy).
600///
601class ObjCInterfaceDecl : public ObjCContainerDecl
602                        , public Redeclarable<ObjCInterfaceDecl> {
603  virtual void anchor();
604
605  /// TypeForDecl - This indicates the Type object that represents this
606  /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
607  mutable const Type *TypeForDecl;
608  friend class ASTContext;
609
610  struct DefinitionData {
611    /// \brief The definition of this class, for quick access from any
612    /// declaration.
613    ObjCInterfaceDecl *Definition;
614
615    /// Class's super class.
616    ObjCInterfaceDecl *SuperClass;
617
618    /// Protocols referenced in the \@interface  declaration
619    ObjCProtocolList ReferencedProtocols;
620
621    /// Protocols reference in both the \@interface and class extensions.
622    ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
623
624    /// \brief List of categories and class extensions defined for this class.
625    ///
626    /// Categories are stored as a linked list in the AST, since the categories
627    /// and class extensions come long after the initial interface declaration,
628    /// and we avoid dynamically-resized arrays in the AST wherever possible.
629    ObjCCategoryDecl *CategoryList;
630
631    /// IvarList - List of all ivars defined by this class; including class
632    /// extensions and implementation. This list is built lazily.
633    ObjCIvarDecl *IvarList;
634
635    /// \brief Indicates that the contents of this Objective-C class will be
636    /// completed by the external AST source when required.
637    mutable bool ExternallyCompleted : 1;
638
639    /// \brief The location of the superclass, if any.
640    SourceLocation SuperClassLoc;
641
642    /// \brief The location of the last location in this declaration, before
643    /// the properties/methods. For example, this will be the '>', '}', or
644    /// identifier,
645    SourceLocation EndLoc;
646
647    DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
648                       ExternallyCompleted() { }
649  };
650
651  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
652                    SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
653                    bool isInternal);
654
655  void LoadExternalDefinition() const;
656
657  /// \brief Contains a pointer to the data associated with this class,
658  /// which will be NULL if this class has not yet been defined.
659  DefinitionData *Data;
660
661  DefinitionData &data() const {
662    assert(Data != 0 && "Declaration has no definition!");
663    return *Data;
664  }
665
666  /// \brief Allocate the definition data for this class.
667  void allocateDefinitionData();
668
669  typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
670  virtual ObjCInterfaceDecl *getNextRedeclaration() {
671    return RedeclLink.getNext();
672  }
673  virtual ObjCInterfaceDecl *getPreviousDeclImpl() {
674    return getPreviousDecl();
675  }
676  virtual ObjCInterfaceDecl *getMostRecentDeclImpl() {
677    return getMostRecentDecl();
678  }
679
680public:
681  static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC,
682                                   SourceLocation atLoc,
683                                   IdentifierInfo *Id,
684                                   ObjCInterfaceDecl *PrevDecl,
685                                   SourceLocation ClassLoc = SourceLocation(),
686                                   bool isInternal = false);
687
688  static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
689
690  virtual SourceRange getSourceRange() const LLVM_READONLY {
691    if (isThisDeclarationADefinition())
692      return ObjCContainerDecl::getSourceRange();
693
694    return SourceRange(getAtStartLoc(), getLocation());
695  }
696
697  /// \brief Indicate that this Objective-C class is complete, but that
698  /// the external AST source will be responsible for filling in its contents
699  /// when a complete class is required.
700  void setExternallyCompleted();
701
702  const ObjCProtocolList &getReferencedProtocols() const {
703    assert(hasDefinition() && "Caller did not check for forward reference!");
704    if (data().ExternallyCompleted)
705      LoadExternalDefinition();
706
707    return data().ReferencedProtocols;
708  }
709
710  ObjCImplementationDecl *getImplementation() const;
711  void setImplementation(ObjCImplementationDecl *ImplD);
712
713  ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
714
715  // Get the local instance/class method declared in a category.
716  ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const;
717  ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const;
718  ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const {
719    return isInstance ? getInstanceMethod(Sel)
720                      : getClassMethod(Sel);
721  }
722
723  typedef ObjCProtocolList::iterator protocol_iterator;
724
725  protocol_iterator protocol_begin() const {
726    // FIXME: Should make sure no callers ever do this.
727    if (!hasDefinition())
728      return protocol_iterator();
729
730    if (data().ExternallyCompleted)
731      LoadExternalDefinition();
732
733    return data().ReferencedProtocols.begin();
734  }
735  protocol_iterator protocol_end() const {
736    // FIXME: Should make sure no callers ever do this.
737    if (!hasDefinition())
738      return protocol_iterator();
739
740    if (data().ExternallyCompleted)
741      LoadExternalDefinition();
742
743    return data().ReferencedProtocols.end();
744  }
745
746  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
747
748  protocol_loc_iterator protocol_loc_begin() const {
749    // FIXME: Should make sure no callers ever do this.
750    if (!hasDefinition())
751      return protocol_loc_iterator();
752
753    if (data().ExternallyCompleted)
754      LoadExternalDefinition();
755
756    return data().ReferencedProtocols.loc_begin();
757  }
758
759  protocol_loc_iterator protocol_loc_end() const {
760    // FIXME: Should make sure no callers ever do this.
761    if (!hasDefinition())
762      return protocol_loc_iterator();
763
764    if (data().ExternallyCompleted)
765      LoadExternalDefinition();
766
767    return data().ReferencedProtocols.loc_end();
768  }
769
770  typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
771
772  all_protocol_iterator all_referenced_protocol_begin() const {
773    // FIXME: Should make sure no callers ever do this.
774    if (!hasDefinition())
775      return all_protocol_iterator();
776
777    if (data().ExternallyCompleted)
778      LoadExternalDefinition();
779
780    return data().AllReferencedProtocols.empty()
781             ? protocol_begin()
782             : data().AllReferencedProtocols.begin();
783  }
784  all_protocol_iterator all_referenced_protocol_end() const {
785    // FIXME: Should make sure no callers ever do this.
786    if (!hasDefinition())
787      return all_protocol_iterator();
788
789    if (data().ExternallyCompleted)
790      LoadExternalDefinition();
791
792    return data().AllReferencedProtocols.empty()
793             ? protocol_end()
794             : data().AllReferencedProtocols.end();
795  }
796
797  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
798
799  ivar_iterator ivar_begin() const {
800    if (const ObjCInterfaceDecl *Def = getDefinition())
801      return ivar_iterator(Def->decls_begin());
802
803    // FIXME: Should make sure no callers ever do this.
804    return ivar_iterator();
805  }
806  ivar_iterator ivar_end() const {
807    if (const ObjCInterfaceDecl *Def = getDefinition())
808      return ivar_iterator(Def->decls_end());
809
810    // FIXME: Should make sure no callers ever do this.
811    return ivar_iterator();
812  }
813
814  unsigned ivar_size() const {
815    return std::distance(ivar_begin(), ivar_end());
816  }
817
818  bool ivar_empty() const { return ivar_begin() == ivar_end(); }
819
820  ObjCIvarDecl *all_declared_ivar_begin();
821  const ObjCIvarDecl *all_declared_ivar_begin() const {
822    // Even though this modifies IvarList, it's conceptually const:
823    // the ivar chain is essentially a cached property of ObjCInterfaceDecl.
824    return const_cast<ObjCInterfaceDecl *>(this)->all_declared_ivar_begin();
825  }
826  void setIvarList(ObjCIvarDecl *ivar) { data().IvarList = ivar; }
827
828  /// setProtocolList - Set the list of protocols that this interface
829  /// implements.
830  void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
831                       const SourceLocation *Locs, ASTContext &C) {
832    data().ReferencedProtocols.set(List, Num, Locs, C);
833  }
834
835  /// mergeClassExtensionProtocolList - Merge class extension's protocol list
836  /// into the protocol list for this class.
837  void mergeClassExtensionProtocolList(ObjCProtocolDecl *const* List,
838                                       unsigned Num,
839                                       ASTContext &C);
840
841  /// \brief Determine whether this particular declaration of this class is
842  /// actually also a definition.
843  bool isThisDeclarationADefinition() const {
844    return Data && Data->Definition == this;
845  }
846
847  /// \brief Determine whether this class has been defined.
848  bool hasDefinition() const { return Data; }
849
850  /// \brief Retrieve the definition of this class, or NULL if this class
851  /// has been forward-declared (with \@class) but not yet defined (with
852  /// \@interface).
853  ObjCInterfaceDecl *getDefinition() {
854    return hasDefinition()? Data->Definition : 0;
855  }
856
857  /// \brief Retrieve the definition of this class, or NULL if this class
858  /// has been forward-declared (with \@class) but not yet defined (with
859  /// \@interface).
860  const ObjCInterfaceDecl *getDefinition() const {
861    return hasDefinition()? Data->Definition : 0;
862  }
863
864  /// \brief Starts the definition of this Objective-C class, taking it from
865  /// a forward declaration (\@class) to a definition (\@interface).
866  void startDefinition();
867
868  ObjCInterfaceDecl *getSuperClass() const {
869    // FIXME: Should make sure no callers ever do this.
870    if (!hasDefinition())
871      return 0;
872
873    if (data().ExternallyCompleted)
874      LoadExternalDefinition();
875
876    return data().SuperClass;
877  }
878
879  void setSuperClass(ObjCInterfaceDecl * superCls) {
880    data().SuperClass =
881      (superCls && superCls->hasDefinition()) ? superCls->getDefinition()
882                                              : superCls;
883  }
884
885  ObjCCategoryDecl* getCategoryList() const {
886    // FIXME: Should make sure no callers ever do this.
887    if (!hasDefinition())
888      return 0;
889
890    if (data().ExternallyCompleted)
891      LoadExternalDefinition();
892
893    return data().CategoryList;
894  }
895
896  void setCategoryList(ObjCCategoryDecl *category) {
897    data().CategoryList = category;
898  }
899
900  ObjCCategoryDecl* getFirstClassExtension() const;
901
902  ObjCPropertyDecl
903    *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
904
905  /// isSuperClassOf - Return true if this class is the specified class or is a
906  /// super class of the specified interface class.
907  bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
908    // If RHS is derived from LHS it is OK; else it is not OK.
909    while (I != NULL) {
910      if (declaresSameEntity(this, I))
911        return true;
912
913      I = I->getSuperClass();
914    }
915    return false;
916  }
917
918  /// isArcWeakrefUnavailable - Checks for a class or one of its super classes
919  /// to be incompatible with __weak references. Returns true if it is.
920  bool isArcWeakrefUnavailable() const {
921    const ObjCInterfaceDecl *Class = this;
922    while (Class) {
923      if (Class->hasAttr<ArcWeakrefUnavailableAttr>())
924        return true;
925      Class = Class->getSuperClass();
926   }
927   return false;
928  }
929
930  /// isObjCRequiresPropertyDefs - Checks that a class or one of its super
931  /// classes must not be auto-synthesized. Returns class decl. if it must not
932  /// be; 0, otherwise.
933  const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const {
934    const ObjCInterfaceDecl *Class = this;
935    while (Class) {
936      if (Class->hasAttr<ObjCRequiresPropertyDefsAttr>())
937        return Class;
938      Class = Class->getSuperClass();
939   }
940   return 0;
941  }
942
943  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
944                                       ObjCInterfaceDecl *&ClassDeclared);
945  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
946    ObjCInterfaceDecl *ClassDeclared;
947    return lookupInstanceVariable(IVarName, ClassDeclared);
948  }
949
950  // Lookup a method. First, we search locally. If a method isn't
951  // found, we search referenced protocols and class categories.
952  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
953                               bool shallowCategoryLookup= false) const;
954  ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
955                            bool shallowCategoryLookup = false) const {
956    return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
957  }
958  ObjCMethodDecl *lookupClassMethod(Selector Sel,
959                     bool shallowCategoryLookup = false) const {
960    return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
961  }
962  ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
963
964  /// \brief Lookup a method in the classes implementation hierarchy.
965  ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
966                                      bool Instance=true) const;
967
968  ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
969    return lookupPrivateMethod(Sel, false);
970  }
971
972  SourceLocation getEndOfDefinitionLoc() const {
973    if (!hasDefinition())
974      return getLocation();
975
976    return data().EndLoc;
977  }
978
979  void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; }
980
981  void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; }
982  SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; }
983
984  /// isImplicitInterfaceDecl - check that this is an implicitly declared
985  /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation
986  /// declaration without an \@interface declaration.
987  bool isImplicitInterfaceDecl() const {
988    return hasDefinition() ? Data->Definition->isImplicit() : isImplicit();
989  }
990
991  /// ClassImplementsProtocol - Checks that 'lProto' protocol
992  /// has been implemented in IDecl class, its super class or categories (if
993  /// lookupCategory is true).
994  bool ClassImplementsProtocol(ObjCProtocolDecl *lProto,
995                               bool lookupCategory,
996                               bool RHSIsQualifiedID = false);
997
998  typedef redeclarable_base::redecl_iterator redecl_iterator;
999  using redeclarable_base::redecls_begin;
1000  using redeclarable_base::redecls_end;
1001  using redeclarable_base::getPreviousDecl;
1002  using redeclarable_base::getMostRecentDecl;
1003
1004  /// Retrieves the canonical declaration of this Objective-C class.
1005  ObjCInterfaceDecl *getCanonicalDecl() {
1006    return getFirstDeclaration();
1007  }
1008  const ObjCInterfaceDecl *getCanonicalDecl() const {
1009    return getFirstDeclaration();
1010  }
1011
1012  // Low-level accessor
1013  const Type *getTypeForDecl() const { return TypeForDecl; }
1014  void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
1015
1016  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1017  static bool classof(const ObjCInterfaceDecl *D) { return true; }
1018  static bool classofKind(Kind K) { return K == ObjCInterface; }
1019
1020  friend class ASTReader;
1021  friend class ASTDeclReader;
1022  friend class ASTDeclWriter;
1023};
1024
1025/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
1026/// instance variables are identical to C. The only exception is Objective-C
1027/// supports C++ style access control. For example:
1028///
1029///   \@interface IvarExample : NSObject
1030///   {
1031///     id defaultToProtected;
1032///   \@public:
1033///     id canBePublic; // same as C++.
1034///   \@protected:
1035///     id canBeProtected; // same as C++.
1036///   \@package:
1037///     id canBePackage; // framework visibility (not available in C++).
1038///   }
1039///
1040class ObjCIvarDecl : public FieldDecl {
1041  virtual void anchor();
1042
1043public:
1044  enum AccessControl {
1045    None, Private, Protected, Public, Package
1046  };
1047
1048private:
1049  ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
1050               SourceLocation IdLoc, IdentifierInfo *Id,
1051               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
1052               bool synthesized)
1053    : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
1054                /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
1055      NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {}
1056
1057public:
1058  static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
1059                              SourceLocation StartLoc, SourceLocation IdLoc,
1060                              IdentifierInfo *Id, QualType T,
1061                              TypeSourceInfo *TInfo,
1062                              AccessControl ac, Expr *BW = NULL,
1063                              bool synthesized=false);
1064
1065  static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1066
1067  /// \brief Return the class interface that this ivar is logically contained
1068  /// in; this is either the interface where the ivar was declared, or the
1069  /// interface the ivar is conceptually a part of in the case of synthesized
1070  /// ivars.
1071  const ObjCInterfaceDecl *getContainingInterface() const;
1072
1073  ObjCIvarDecl *getNextIvar() { return NextIvar; }
1074  const ObjCIvarDecl *getNextIvar() const { return NextIvar; }
1075  void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
1076
1077  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
1078
1079  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
1080
1081  AccessControl getCanonicalAccessControl() const {
1082    return DeclAccess == None ? Protected : AccessControl(DeclAccess);
1083  }
1084
1085  void setSynthesize(bool synth) { Synthesized = synth; }
1086  bool getSynthesize() const { return Synthesized; }
1087
1088  // Implement isa/cast/dyncast/etc.
1089  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1090  static bool classof(const ObjCIvarDecl *D) { return true; }
1091  static bool classofKind(Kind K) { return K == ObjCIvar; }
1092private:
1093  /// NextIvar - Next Ivar in the list of ivars declared in class; class's
1094  /// extensions and class's implementation
1095  ObjCIvarDecl *NextIvar;
1096
1097  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
1098  unsigned DeclAccess : 3;
1099  unsigned Synthesized : 1;
1100};
1101
1102
1103/// \brief Represents a field declaration created by an \@defs(...).
1104class ObjCAtDefsFieldDecl : public FieldDecl {
1105  virtual void anchor();
1106  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
1107                      SourceLocation IdLoc, IdentifierInfo *Id,
1108                      QualType T, Expr *BW)
1109    : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
1110                /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
1111                BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
1112
1113public:
1114  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
1115                                     SourceLocation StartLoc,
1116                                     SourceLocation IdLoc, IdentifierInfo *Id,
1117                                     QualType T, Expr *BW);
1118
1119  static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1120
1121  // Implement isa/cast/dyncast/etc.
1122  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1123  static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
1124  static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
1125};
1126
1127/// \brief Represents an Objective-C protocol declaration.
1128///
1129/// Objective-C protocols declare a pure abstract type (i.e., no instance
1130/// variables are permitted).  Protocols originally drew inspiration from
1131/// C++ pure virtual functions (a C++ feature with nice semantics and lousy
1132/// syntax:-). Here is an example:
1133///
1134/// \code
1135/// \@protocol NSDraggingInfo <refproto1, refproto2>
1136/// - (NSWindow *)draggingDestinationWindow;
1137/// - (NSImage *)draggedImage;
1138/// \@end
1139/// \endcode
1140///
1141/// This says that NSDraggingInfo requires two methods and requires everything
1142/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
1143/// well.
1144///
1145/// \code
1146/// \@interface ImplementsNSDraggingInfo : NSObject \<NSDraggingInfo>
1147/// \@end
1148/// \endcode
1149///
1150/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
1151/// protocols are in distinct namespaces. For example, Cocoa defines both
1152/// an NSObject protocol and class (which isn't allowed in Java). As a result,
1153/// protocols are referenced using angle brackets as follows:
1154///
1155/// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
1156///
1157class ObjCProtocolDecl : public ObjCContainerDecl,
1158                         public Redeclarable<ObjCProtocolDecl> {
1159  virtual void anchor();
1160
1161  struct DefinitionData {
1162    // \brief The declaration that defines this protocol.
1163    ObjCProtocolDecl *Definition;
1164
1165    /// \brief Referenced protocols
1166    ObjCProtocolList ReferencedProtocols;
1167  };
1168
1169  DefinitionData *Data;
1170
1171  DefinitionData &data() const {
1172    assert(Data && "Objective-C protocol has no definition!");
1173    return *Data;
1174  }
1175
1176  ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
1177                   SourceLocation nameLoc, SourceLocation atStartLoc,
1178                   ObjCProtocolDecl *PrevDecl);
1179
1180  void allocateDefinitionData();
1181
1182  typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
1183  virtual ObjCProtocolDecl *getNextRedeclaration() {
1184    return RedeclLink.getNext();
1185  }
1186  virtual ObjCProtocolDecl *getPreviousDeclImpl() {
1187    return getPreviousDecl();
1188  }
1189  virtual ObjCProtocolDecl *getMostRecentDeclImpl() {
1190    return getMostRecentDecl();
1191  }
1192
1193public:
1194  static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
1195                                  IdentifierInfo *Id,
1196                                  SourceLocation nameLoc,
1197                                  SourceLocation atStartLoc,
1198                                  ObjCProtocolDecl *PrevDecl);
1199
1200  static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1201
1202  const ObjCProtocolList &getReferencedProtocols() const {
1203    assert(hasDefinition() && "No definition available!");
1204    return data().ReferencedProtocols;
1205  }
1206  typedef ObjCProtocolList::iterator protocol_iterator;
1207  protocol_iterator protocol_begin() const {
1208    if (!hasDefinition())
1209      return protocol_iterator();
1210
1211    return data().ReferencedProtocols.begin();
1212  }
1213  protocol_iterator protocol_end() const {
1214    if (!hasDefinition())
1215      return protocol_iterator();
1216
1217    return data().ReferencedProtocols.end();
1218  }
1219  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1220  protocol_loc_iterator protocol_loc_begin() const {
1221    if (!hasDefinition())
1222      return protocol_loc_iterator();
1223
1224    return data().ReferencedProtocols.loc_begin();
1225  }
1226  protocol_loc_iterator protocol_loc_end() const {
1227    if (!hasDefinition())
1228      return protocol_loc_iterator();
1229
1230    return data().ReferencedProtocols.loc_end();
1231  }
1232  unsigned protocol_size() const {
1233    if (!hasDefinition())
1234      return 0;
1235
1236    return data().ReferencedProtocols.size();
1237  }
1238
1239  /// setProtocolList - Set the list of protocols that this interface
1240  /// implements.
1241  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
1242                       const SourceLocation *Locs, ASTContext &C) {
1243    assert(Data && "Protocol is not defined");
1244    data().ReferencedProtocols.set(List, Num, Locs, C);
1245  }
1246
1247  ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
1248
1249  // Lookup a method. First, we search locally. If a method isn't
1250  // found, we search referenced protocols and class categories.
1251  ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const;
1252  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
1253    return lookupMethod(Sel, true/*isInstance*/);
1254  }
1255  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
1256    return lookupMethod(Sel, false/*isInstance*/);
1257  }
1258
1259  /// \brief Determine whether this protocol has a definition.
1260  bool hasDefinition() const { return Data != 0; }
1261
1262  /// \brief Retrieve the definition of this protocol, if any.
1263  ObjCProtocolDecl *getDefinition() {
1264    return Data? Data->Definition : 0;
1265  }
1266
1267  /// \brief Retrieve the definition of this protocol, if any.
1268  const ObjCProtocolDecl *getDefinition() const {
1269    return Data? Data->Definition : 0;
1270  }
1271
1272  /// \brief Determine whether this particular declaration is also the
1273  /// definition.
1274  bool isThisDeclarationADefinition() const {
1275    return getDefinition() == this;
1276  }
1277
1278  /// \brief Starts the definition of this Objective-C protocol.
1279  void startDefinition();
1280
1281  virtual SourceRange getSourceRange() const LLVM_READONLY {
1282    if (isThisDeclarationADefinition())
1283      return ObjCContainerDecl::getSourceRange();
1284
1285    return SourceRange(getAtStartLoc(), getLocation());
1286  }
1287
1288  typedef redeclarable_base::redecl_iterator redecl_iterator;
1289  using redeclarable_base::redecls_begin;
1290  using redeclarable_base::redecls_end;
1291  using redeclarable_base::getPreviousDecl;
1292  using redeclarable_base::getMostRecentDecl;
1293
1294  /// Retrieves the canonical declaration of this Objective-C protocol.
1295  ObjCProtocolDecl *getCanonicalDecl() {
1296    return getFirstDeclaration();
1297  }
1298  const ObjCProtocolDecl *getCanonicalDecl() const {
1299    return getFirstDeclaration();
1300  }
1301
1302  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1303  static bool classof(const ObjCProtocolDecl *D) { return true; }
1304  static bool classofKind(Kind K) { return K == ObjCProtocol; }
1305
1306  friend class ASTReader;
1307  friend class ASTDeclReader;
1308  friend class ASTDeclWriter;
1309};
1310
1311/// ObjCCategoryDecl - Represents a category declaration. A category allows
1312/// you to add methods to an existing class (without subclassing or modifying
1313/// the original class interface or implementation:-). Categories don't allow
1314/// you to add instance data. The following example adds "myMethod" to all
1315/// NSView's within a process:
1316///
1317/// \@interface NSView (MyViewMethods)
1318/// - myMethod;
1319/// \@end
1320///
1321/// Categories also allow you to split the implementation of a class across
1322/// several files (a feature more naturally supported in C++).
1323///
1324/// Categories were originally inspired by dynamic languages such as Common
1325/// Lisp and Smalltalk.  More traditional class-based languages (C++, Java)
1326/// don't support this level of dynamism, which is both powerful and dangerous.
1327///
1328class ObjCCategoryDecl : public ObjCContainerDecl {
1329  virtual void anchor();
1330
1331  /// Interface belonging to this category
1332  ObjCInterfaceDecl *ClassInterface;
1333
1334  /// referenced protocols in this category.
1335  ObjCProtocolList ReferencedProtocols;
1336
1337  /// Next category belonging to this class.
1338  /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
1339  ObjCCategoryDecl *NextClassCategory;
1340
1341  /// \brief The location of the category name in this declaration.
1342  SourceLocation CategoryNameLoc;
1343
1344  /// class extension may have private ivars.
1345  SourceLocation IvarLBraceLoc;
1346  SourceLocation IvarRBraceLoc;
1347
1348  ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
1349                   SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc,
1350                   IdentifierInfo *Id, ObjCInterfaceDecl *IDecl,
1351                   SourceLocation IvarLBraceLoc=SourceLocation(),
1352                   SourceLocation IvarRBraceLoc=SourceLocation())
1353    : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
1354      ClassInterface(IDecl), NextClassCategory(0),
1355      CategoryNameLoc(CategoryNameLoc),
1356      IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
1357  }
1358public:
1359
1360  static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
1361                                  SourceLocation AtLoc,
1362                                  SourceLocation ClassNameLoc,
1363                                  SourceLocation CategoryNameLoc,
1364                                  IdentifierInfo *Id,
1365                                  ObjCInterfaceDecl *IDecl,
1366                                  SourceLocation IvarLBraceLoc=SourceLocation(),
1367                                  SourceLocation IvarRBraceLoc=SourceLocation());
1368  static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1369
1370  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1371  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1372
1373  ObjCCategoryImplDecl *getImplementation() const;
1374  void setImplementation(ObjCCategoryImplDecl *ImplD);
1375
1376  /// setProtocolList - Set the list of protocols that this interface
1377  /// implements.
1378  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
1379                       const SourceLocation *Locs, ASTContext &C) {
1380    ReferencedProtocols.set(List, Num, Locs, C);
1381  }
1382
1383  const ObjCProtocolList &getReferencedProtocols() const {
1384    return ReferencedProtocols;
1385  }
1386
1387  typedef ObjCProtocolList::iterator protocol_iterator;
1388  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
1389  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
1390  unsigned protocol_size() const { return ReferencedProtocols.size(); }
1391  typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1392  protocol_loc_iterator protocol_loc_begin() const {
1393    return ReferencedProtocols.loc_begin();
1394  }
1395  protocol_loc_iterator protocol_loc_end() const {
1396    return ReferencedProtocols.loc_end();
1397  }
1398
1399  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
1400
1401  bool IsClassExtension() const { return getIdentifier() == 0; }
1402  const ObjCCategoryDecl *getNextClassExtension() const;
1403
1404  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1405  ivar_iterator ivar_begin() const {
1406    return ivar_iterator(decls_begin());
1407  }
1408  ivar_iterator ivar_end() const {
1409    return ivar_iterator(decls_end());
1410  }
1411  unsigned ivar_size() const {
1412    return std::distance(ivar_begin(), ivar_end());
1413  }
1414  bool ivar_empty() const {
1415    return ivar_begin() == ivar_end();
1416  }
1417
1418  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1419  void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
1420
1421  void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
1422  SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
1423  void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
1424  SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
1425
1426  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1427  static bool classof(const ObjCCategoryDecl *D) { return true; }
1428  static bool classofKind(Kind K) { return K == ObjCCategory; }
1429
1430  friend class ASTDeclReader;
1431  friend class ASTDeclWriter;
1432};
1433
1434class ObjCImplDecl : public ObjCContainerDecl {
1435  virtual void anchor();
1436
1437  /// Class interface for this class/category implementation
1438  ObjCInterfaceDecl *ClassInterface;
1439
1440protected:
1441  ObjCImplDecl(Kind DK, DeclContext *DC,
1442               ObjCInterfaceDecl *classInterface,
1443               SourceLocation nameLoc, SourceLocation atStartLoc)
1444    : ObjCContainerDecl(DK, DC,
1445                        classInterface? classInterface->getIdentifier() : 0,
1446                        nameLoc, atStartLoc),
1447      ClassInterface(classInterface) {}
1448
1449public:
1450  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1451  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1452  void setClassInterface(ObjCInterfaceDecl *IFace);
1453
1454  void addInstanceMethod(ObjCMethodDecl *method) {
1455    // FIXME: Context should be set correctly before we get here.
1456    method->setLexicalDeclContext(this);
1457    addDecl(method);
1458  }
1459  void addClassMethod(ObjCMethodDecl *method) {
1460    // FIXME: Context should be set correctly before we get here.
1461    method->setLexicalDeclContext(this);
1462    addDecl(method);
1463  }
1464
1465  void addPropertyImplementation(ObjCPropertyImplDecl *property);
1466
1467  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
1468  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
1469
1470  // Iterator access to properties.
1471  typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
1472  propimpl_iterator propimpl_begin() const {
1473    return propimpl_iterator(decls_begin());
1474  }
1475  propimpl_iterator propimpl_end() const {
1476    return propimpl_iterator(decls_end());
1477  }
1478
1479  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1480  static bool classof(const ObjCImplDecl *D) { return true; }
1481  static bool classofKind(Kind K) {
1482    return K >= firstObjCImpl && K <= lastObjCImpl;
1483  }
1484};
1485
1486/// ObjCCategoryImplDecl - An object of this class encapsulates a category
1487/// \@implementation declaration. If a category class has declaration of a
1488/// property, its implementation must be specified in the category's
1489/// \@implementation declaration. Example:
1490/// \@interface I \@end
1491/// \@interface I(CATEGORY)
1492///    \@property int p1, d1;
1493/// \@end
1494/// \@implementation I(CATEGORY)
1495///  \@dynamic p1,d1;
1496/// \@end
1497///
1498/// ObjCCategoryImplDecl
1499class ObjCCategoryImplDecl : public ObjCImplDecl {
1500  virtual void anchor();
1501
1502  // Category name
1503  IdentifierInfo *Id;
1504
1505  // Category name location
1506  SourceLocation CategoryNameLoc;
1507
1508  ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id,
1509                       ObjCInterfaceDecl *classInterface,
1510                       SourceLocation nameLoc, SourceLocation atStartLoc,
1511                       SourceLocation CategoryNameLoc)
1512    : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
1513      Id(Id), CategoryNameLoc(CategoryNameLoc) {}
1514public:
1515  static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
1516                                      IdentifierInfo *Id,
1517                                      ObjCInterfaceDecl *classInterface,
1518                                      SourceLocation nameLoc,
1519                                      SourceLocation atStartLoc,
1520                                      SourceLocation CategoryNameLoc);
1521  static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1522
1523  /// getIdentifier - Get the identifier that names the category
1524  /// interface associated with this implementation.
1525  /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
1526  /// to mean something different. For example:
1527  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
1528  /// returns the class interface name, whereas
1529  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
1530  /// returns the category name.
1531  IdentifierInfo *getIdentifier() const {
1532    return Id;
1533  }
1534  void setIdentifier(IdentifierInfo *II) { Id = II; }
1535
1536  ObjCCategoryDecl *getCategoryDecl() const;
1537
1538  SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1539
1540  /// getName - Get the name of identifier for the class interface associated
1541  /// with this implementation as a StringRef.
1542  //
1543  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1544  // something different.
1545  StringRef getName() const {
1546    return Id ? Id->getNameStart() : "";
1547  }
1548
1549  /// @brief Get the name of the class associated with this interface.
1550  //
1551  // FIXME: Deprecated, move clients to getName().
1552  std::string getNameAsString() const {
1553    return getName();
1554  }
1555
1556  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1557  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
1558  static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
1559
1560  friend class ASTDeclReader;
1561  friend class ASTDeclWriter;
1562};
1563
1564raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
1565
1566/// ObjCImplementationDecl - Represents a class definition - this is where
1567/// method definitions are specified. For example:
1568///
1569/// @code
1570/// \@implementation MyClass
1571/// - (void)myMethod { /* do something */ }
1572/// \@end
1573/// @endcode
1574///
1575/// Typically, instance variables are specified in the class interface,
1576/// *not* in the implementation. Nevertheless (for legacy reasons), we
1577/// allow instance variables to be specified in the implementation.  When
1578/// specified, they need to be *identical* to the interface.
1579///
1580class ObjCImplementationDecl : public ObjCImplDecl {
1581  virtual void anchor();
1582  /// Implementation Class's super class.
1583  ObjCInterfaceDecl *SuperClass;
1584  /// \@implementation may have private ivars.
1585  SourceLocation IvarLBraceLoc;
1586  SourceLocation IvarRBraceLoc;
1587
1588  /// Support for ivar initialization.
1589  /// IvarInitializers - The arguments used to initialize the ivars
1590  CXXCtorInitializer **IvarInitializers;
1591  unsigned NumIvarInitializers;
1592
1593  /// true if class has a .cxx_[construct,destruct] method.
1594  bool HasCXXStructors : 1;
1595
1596  ObjCImplementationDecl(DeclContext *DC,
1597                         ObjCInterfaceDecl *classInterface,
1598                         ObjCInterfaceDecl *superDecl,
1599                         SourceLocation nameLoc, SourceLocation atStartLoc,
1600                         SourceLocation IvarLBraceLoc=SourceLocation(),
1601                         SourceLocation IvarRBraceLoc=SourceLocation())
1602    : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
1603       SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc),
1604       IvarRBraceLoc(IvarRBraceLoc),
1605       IvarInitializers(0), NumIvarInitializers(0),
1606       HasCXXStructors(false) {}
1607public:
1608  static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
1609                                        ObjCInterfaceDecl *classInterface,
1610                                        ObjCInterfaceDecl *superDecl,
1611                                        SourceLocation nameLoc,
1612                                        SourceLocation atStartLoc,
1613                                        SourceLocation IvarLBraceLoc=SourceLocation(),
1614                                        SourceLocation IvarRBraceLoc=SourceLocation());
1615
1616  static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1617
1618  /// init_iterator - Iterates through the ivar initializer list.
1619  typedef CXXCtorInitializer **init_iterator;
1620
1621  /// init_const_iterator - Iterates through the ivar initializer list.
1622  typedef CXXCtorInitializer * const * init_const_iterator;
1623
1624  /// init_begin() - Retrieve an iterator to the first initializer.
1625  init_iterator       init_begin()       { return IvarInitializers; }
1626  /// begin() - Retrieve an iterator to the first initializer.
1627  init_const_iterator init_begin() const { return IvarInitializers; }
1628
1629  /// init_end() - Retrieve an iterator past the last initializer.
1630  init_iterator       init_end()       {
1631    return IvarInitializers + NumIvarInitializers;
1632  }
1633  /// end() - Retrieve an iterator past the last initializer.
1634  init_const_iterator init_end() const {
1635    return IvarInitializers + NumIvarInitializers;
1636  }
1637  /// getNumArgs - Number of ivars which must be initialized.
1638  unsigned getNumIvarInitializers() const {
1639    return NumIvarInitializers;
1640  }
1641
1642  void setNumIvarInitializers(unsigned numNumIvarInitializers) {
1643    NumIvarInitializers = numNumIvarInitializers;
1644  }
1645
1646  void setIvarInitializers(ASTContext &C,
1647                           CXXCtorInitializer ** initializers,
1648                           unsigned numInitializers);
1649
1650  bool hasCXXStructors() const { return HasCXXStructors; }
1651  void setHasCXXStructors(bool val) { HasCXXStructors = val; }
1652
1653  /// getIdentifier - Get the identifier that names the class
1654  /// interface associated with this implementation.
1655  IdentifierInfo *getIdentifier() const {
1656    return getClassInterface()->getIdentifier();
1657  }
1658
1659  /// getName - Get the name of identifier for the class interface associated
1660  /// with this implementation as a StringRef.
1661  //
1662  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
1663  // something different.
1664  StringRef getName() const {
1665    assert(getIdentifier() && "Name is not a simple identifier");
1666    return getIdentifier()->getName();
1667  }
1668
1669  /// @brief Get the name of the class associated with this interface.
1670  //
1671  // FIXME: Move to StringRef API.
1672  std::string getNameAsString() const {
1673    return getName();
1674  }
1675
1676  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1677  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
1678
1679  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
1680
1681  void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; }
1682  SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; }
1683  void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; }
1684  SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
1685
1686  typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1687  ivar_iterator ivar_begin() const {
1688    return ivar_iterator(decls_begin());
1689  }
1690  ivar_iterator ivar_end() const {
1691    return ivar_iterator(decls_end());
1692  }
1693  unsigned ivar_size() const {
1694    return std::distance(ivar_begin(), ivar_end());
1695  }
1696  bool ivar_empty() const {
1697    return ivar_begin() == ivar_end();
1698  }
1699
1700  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1701  static bool classof(const ObjCImplementationDecl *D) { return true; }
1702  static bool classofKind(Kind K) { return K == ObjCImplementation; }
1703
1704  friend class ASTDeclReader;
1705  friend class ASTDeclWriter;
1706};
1707
1708raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
1709
1710/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
1711/// declared as \@compatibility_alias alias class.
1712class ObjCCompatibleAliasDecl : public NamedDecl {
1713  virtual void anchor();
1714  /// Class that this is an alias of.
1715  ObjCInterfaceDecl *AliasedClass;
1716
1717  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1718                          ObjCInterfaceDecl* aliasedClass)
1719    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
1720public:
1721  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
1722                                         SourceLocation L, IdentifierInfo *Id,
1723                                         ObjCInterfaceDecl* aliasedClass);
1724
1725  static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C,
1726                                                     unsigned ID);
1727
1728  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1729  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
1730  void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
1731
1732  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1733  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
1734  static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
1735
1736};
1737
1738/// \brief Represents one property declaration in an Objective-C interface.
1739///
1740/// For example:
1741/// \code{.mm}
1742/// \@property (assign, readwrite) int MyProperty;
1743/// \endcode
1744class ObjCPropertyDecl : public NamedDecl {
1745  virtual void anchor();
1746public:
1747  enum PropertyAttributeKind {
1748    OBJC_PR_noattr    = 0x00,
1749    OBJC_PR_readonly  = 0x01,
1750    OBJC_PR_getter    = 0x02,
1751    OBJC_PR_assign    = 0x04,
1752    OBJC_PR_readwrite = 0x08,
1753    OBJC_PR_retain    = 0x10,
1754    OBJC_PR_copy      = 0x20,
1755    OBJC_PR_nonatomic = 0x40,
1756    OBJC_PR_setter    = 0x80,
1757    OBJC_PR_atomic    = 0x100,
1758    OBJC_PR_weak      = 0x200,
1759    OBJC_PR_strong    = 0x400,
1760    OBJC_PR_unsafe_unretained = 0x800
1761    // Adding a property should change NumPropertyAttrsBits
1762  };
1763
1764  enum {
1765    /// \brief Number of bits fitting all the property attributes.
1766    NumPropertyAttrsBits = 12
1767  };
1768
1769  enum SetterKind { Assign, Retain, Copy, Weak };
1770  enum PropertyControl { None, Required, Optional };
1771private:
1772  SourceLocation AtLoc;   // location of \@property
1773  SourceLocation LParenLoc; // location of '(' starting attribute list or null.
1774  TypeSourceInfo *DeclType;
1775  unsigned PropertyAttributes : NumPropertyAttrsBits;
1776  unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits;
1777  // \@required/\@optional
1778  unsigned PropertyImplementation : 2;
1779
1780  Selector GetterName;    // getter name of NULL if no getter
1781  Selector SetterName;    // setter name of NULL if no setter
1782
1783  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
1784  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1785  ObjCIvarDecl *PropertyIvarDecl;   // Synthesize ivar for this property
1786
1787  ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1788                   SourceLocation AtLocation,  SourceLocation LParenLocation,
1789                   TypeSourceInfo *T)
1790    : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation),
1791      LParenLoc(LParenLocation), DeclType(T),
1792      PropertyAttributes(OBJC_PR_noattr),
1793      PropertyAttributesAsWritten(OBJC_PR_noattr),
1794      PropertyImplementation(None),
1795      GetterName(Selector()),
1796      SetterName(Selector()),
1797      GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
1798public:
1799  static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
1800                                  SourceLocation L,
1801                                  IdentifierInfo *Id, SourceLocation AtLocation,
1802                                  SourceLocation LParenLocation,
1803                                  TypeSourceInfo *T,
1804                                  PropertyControl propControl = None);
1805
1806  static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1807
1808  SourceLocation getAtLoc() const { return AtLoc; }
1809  void setAtLoc(SourceLocation L) { AtLoc = L; }
1810
1811  SourceLocation getLParenLoc() const { return LParenLoc; }
1812  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
1813
1814  TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
1815  QualType getType() const { return DeclType->getType(); }
1816  void setType(TypeSourceInfo *T) { DeclType = T; }
1817
1818  PropertyAttributeKind getPropertyAttributes() const {
1819    return PropertyAttributeKind(PropertyAttributes);
1820  }
1821  void setPropertyAttributes(PropertyAttributeKind PRVal) {
1822    PropertyAttributes |= PRVal;
1823  }
1824
1825  PropertyAttributeKind getPropertyAttributesAsWritten() const {
1826    return PropertyAttributeKind(PropertyAttributesAsWritten);
1827  }
1828
1829  bool hasWrittenStorageAttribute() const {
1830    return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy |
1831        OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong |
1832        OBJC_PR_weak);
1833  }
1834
1835  void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
1836    PropertyAttributesAsWritten = PRVal;
1837  }
1838
1839 void makeitReadWriteAttribute(void) {
1840    PropertyAttributes &= ~OBJC_PR_readonly;
1841    PropertyAttributes |= OBJC_PR_readwrite;
1842 }
1843
1844  // Helper methods for accessing attributes.
1845
1846  /// isReadOnly - Return true iff the property has a setter.
1847  bool isReadOnly() const {
1848    return (PropertyAttributes & OBJC_PR_readonly);
1849  }
1850
1851  /// isAtomic - Return true if the property is atomic.
1852  bool isAtomic() const {
1853    return (PropertyAttributes & OBJC_PR_atomic);
1854  }
1855
1856  /// isRetaining - Return true if the property retains its value.
1857  bool isRetaining() const {
1858    return (PropertyAttributes &
1859            (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy));
1860  }
1861
1862  /// getSetterKind - Return the method used for doing assignment in
1863  /// the property setter. This is only valid if the property has been
1864  /// defined to have a setter.
1865  SetterKind getSetterKind() const {
1866    if (PropertyAttributes & OBJC_PR_strong)
1867      return getType()->isBlockPointerType() ? Copy : Retain;
1868    if (PropertyAttributes & OBJC_PR_retain)
1869      return Retain;
1870    if (PropertyAttributes & OBJC_PR_copy)
1871      return Copy;
1872    if (PropertyAttributes & OBJC_PR_weak)
1873      return Weak;
1874    return Assign;
1875  }
1876
1877  Selector getGetterName() const { return GetterName; }
1878  void setGetterName(Selector Sel) { GetterName = Sel; }
1879
1880  Selector getSetterName() const { return SetterName; }
1881  void setSetterName(Selector Sel) { SetterName = Sel; }
1882
1883  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1884  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1885
1886  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1887  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1888
1889  // Related to \@optional/\@required declared in \@protocol
1890  void setPropertyImplementation(PropertyControl pc) {
1891    PropertyImplementation = pc;
1892  }
1893  PropertyControl getPropertyImplementation() const {
1894    return PropertyControl(PropertyImplementation);
1895  }
1896
1897  void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
1898    PropertyIvarDecl = Ivar;
1899  }
1900  ObjCIvarDecl *getPropertyIvarDecl() const {
1901    return PropertyIvarDecl;
1902  }
1903
1904  virtual SourceRange getSourceRange() const LLVM_READONLY {
1905    return SourceRange(AtLoc, getLocation());
1906  }
1907
1908  /// Get the default name of the synthesized ivar.
1909  IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const;
1910
1911  /// Lookup a property by name in the specified DeclContext.
1912  static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC,
1913                                            IdentifierInfo *propertyID);
1914
1915  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1916  static bool classof(const ObjCPropertyDecl *D) { return true; }
1917  static bool classofKind(Kind K) { return K == ObjCProperty; }
1918};
1919
1920/// ObjCPropertyImplDecl - Represents implementation declaration of a property
1921/// in a class or category implementation block. For example:
1922/// \@synthesize prop1 = ivar1;
1923///
1924class ObjCPropertyImplDecl : public Decl {
1925public:
1926  enum Kind {
1927    Synthesize,
1928    Dynamic
1929  };
1930private:
1931  SourceLocation AtLoc;   // location of \@synthesize or \@dynamic
1932
1933  /// \brief For \@synthesize, the location of the ivar, if it was written in
1934  /// the source code.
1935  ///
1936  /// \code
1937  /// \@synthesize int a = b
1938  /// \endcode
1939  SourceLocation IvarLoc;
1940
1941  /// Property declaration being implemented
1942  ObjCPropertyDecl *PropertyDecl;
1943
1944  /// Null for \@dynamic. Required for \@synthesize.
1945  ObjCIvarDecl *PropertyIvarDecl;
1946
1947  /// Null for \@dynamic. Non-null if property must be copy-constructed in
1948  /// getter.
1949  Expr *GetterCXXConstructor;
1950
1951  /// Null for \@dynamic. Non-null if property has assignment operator to call
1952  /// in Setter synthesis.
1953  Expr *SetterCXXAssignment;
1954
1955  ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
1956                       ObjCPropertyDecl *property,
1957                       Kind PK,
1958                       ObjCIvarDecl *ivarDecl,
1959                       SourceLocation ivarLoc)
1960    : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
1961      IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
1962      GetterCXXConstructor(0), SetterCXXAssignment(0) {
1963    assert (PK == Dynamic || PropertyIvarDecl);
1964  }
1965
1966public:
1967  static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
1968                                      SourceLocation atLoc, SourceLocation L,
1969                                      ObjCPropertyDecl *property,
1970                                      Kind PK,
1971                                      ObjCIvarDecl *ivarDecl,
1972                                      SourceLocation ivarLoc);
1973
1974  static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1975
1976  virtual SourceRange getSourceRange() const LLVM_READONLY;
1977
1978  SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
1979  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
1980
1981  ObjCPropertyDecl *getPropertyDecl() const {
1982    return PropertyDecl;
1983  }
1984  void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
1985
1986  Kind getPropertyImplementation() const {
1987    return PropertyIvarDecl ? Synthesize : Dynamic;
1988  }
1989
1990  ObjCIvarDecl *getPropertyIvarDecl() const {
1991    return PropertyIvarDecl;
1992  }
1993  SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
1994
1995  void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
1996                           SourceLocation IvarLoc) {
1997    PropertyIvarDecl = Ivar;
1998    this->IvarLoc = IvarLoc;
1999  }
2000
2001  /// \brief For \@synthesize, returns true if an ivar name was explicitly
2002  /// specified.
2003  ///
2004  /// \code
2005  /// \@synthesize int a = b; // true
2006  /// \@synthesize int a; // false
2007  /// \endcode
2008  bool isIvarNameSpecified() const {
2009    return IvarLoc.isValid() && IvarLoc != getLocation();
2010  }
2011
2012  Expr *getGetterCXXConstructor() const {
2013    return GetterCXXConstructor;
2014  }
2015  void setGetterCXXConstructor(Expr *getterCXXConstructor) {
2016    GetterCXXConstructor = getterCXXConstructor;
2017  }
2018
2019  Expr *getSetterCXXAssignment() const {
2020    return SetterCXXAssignment;
2021  }
2022  void setSetterCXXAssignment(Expr *setterCXXAssignment) {
2023    SetterCXXAssignment = setterCXXAssignment;
2024  }
2025
2026  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
2027  static bool classof(const ObjCPropertyImplDecl *D) { return true; }
2028  static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
2029
2030  friend class ASTDeclReader;
2031};
2032
2033}  // end namespace clang
2034#endif
2035