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