]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / include / clang / AST / DeclObjC.h
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:
42   ObjCListBase() : List(0), NumElts(0) {}
43   unsigned size() const { return NumElts; }
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:
58   void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
59     ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
60   }
61
62   typedef T* const * iterator;
63   iterator begin() const { return (iterator)List; }
64   iterator end() const { return (iterator)List+NumElts; }
65
66   T* operator[](unsigned Idx) const {
67     assert(Idx < NumElts && "Invalid access");
68     return (T*)List[Idx];
69   }
70 };
71
72 /// \brief A list of Objective-C protocols, along with the source
73 /// locations at which they were referenced.
74 class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
75   SourceLocation *Locations;
76
77   using ObjCList<ObjCProtocolDecl>::set;
78
79 public:
80   ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { }
81
82   typedef const SourceLocation *loc_iterator;
83   loc_iterator loc_begin() const { return Locations; }
84   loc_iterator loc_end() const { return Locations + size(); }
85
86   void set(ObjCProtocolDecl* const* InList, unsigned Elts, 
87            const SourceLocation *Locs, ASTContext &Ctx);
88 };
89
90
91 /// ObjCMethodDecl - Represents an instance or class method declaration.
92 /// ObjC methods can be declared within 4 contexts: class interfaces,
93 /// categories, protocols, and class implementations. While C++ member
94 /// functions leverage C syntax, Objective-C method syntax is modeled after
95 /// Smalltalk (using colons to specify argument types/expressions).
96 /// Here are some brief examples:
97 ///
98 /// Setter/getter instance methods:
99 /// - (void)setMenu:(NSMenu *)menu;
100 /// - (NSMenu *)menu;
101 ///
102 /// Instance method that takes 2 NSView arguments:
103 /// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
104 ///
105 /// Getter class method:
106 /// + (NSMenu *)defaultMenu;
107 ///
108 /// A selector represents a unique name for a method. The selector names for
109 /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
110 ///
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)
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();
210   const ObjCMethodDecl *getCanonicalDecl() const {
211     return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
212   }
213
214   ObjCDeclQualifier getObjCDeclQualifier() const {
215     return ObjCDeclQualifier(objcDeclQualifier);
216   }
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.
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   
226   unsigned getNumSelectorArgs() const { return NumSelectorArgs; }
227   void setNumSelectorArgs(unsigned numSelectorArgs) { 
228     NumSelectorArgs = numSelectorArgs; 
229   }
230   
231   // Location information, modeled after the Stmt API.
232   SourceLocation getLocStart() const { return getLocation(); }
233   SourceLocation getLocEnd() const { return EndLoc; }
234   void setEndLoc(SourceLocation Loc) { EndLoc = Loc; }
235   virtual SourceRange getSourceRange() const {
236     return SourceRange(getLocation(), EndLoc);
237   }
238
239   ObjCInterfaceDecl *getClassInterface();
240   const ObjCInterfaceDecl *getClassInterface() const {
241     return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
242   }
243
244   Selector getSelector() const { return getDeclName().getObjCSelector(); }
245
246   QualType getResultType() const { return MethodDeclType; }
247   void setResultType(QualType T) { MethodDeclType = T; }
248
249   /// \brief Determine the type of an expression that sends a message to this 
250   /// function.
251   QualType getSendResultType() const {
252     return getResultType().getNonLValueExprType(getASTContext());
253   }
254   
255   TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
256   void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
257
258   // Iterator access to formal parameters.
259   unsigned param_size() const { return ParamInfo.size(); }
260   typedef ObjCList<ParmVarDecl>::iterator param_iterator;
261   param_iterator param_begin() const { return ParamInfo.begin(); }
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.
265   param_iterator sel_param_end() const { 
266     return ParamInfo.begin() + NumSelectorArgs; 
267   }
268
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
279   arg_type_iterator arg_type_begin() const {
280     return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
281   }
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
292   ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
293   void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; }
294   ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
295   void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; }
296
297   /// Determines the family of this method.
298   ObjCMethodFamily getMethodFamily() const;
299
300   bool isInstanceMethod() const { return IsInstance; }
301   void setInstanceMethod(bool isInst) { IsInstance = isInst; }
302   bool isVariadic() const { return IsVariadic; }
303   void setVariadic(bool isVar) { IsVariadic = isVar; }
304
305   bool isClassMethod() const { return !IsInstance; }
306
307   bool isSynthesized() const { return IsSynthesized; }
308   void setSynthesized(bool isSynth) { IsSynthesized = isSynth; }
309   
310   bool isDefined() const { return IsDefined; }
311   void setDefined(bool isDefined) { IsDefined = isDefined; }
312
313   // Related to protocols declared in  @protocol
314   void setDeclImplementation(ImplementationControl ic) {
315     DeclImplementation = ic;
316   }
317   ImplementationControl getImplementationControl() const {
318     return ImplementationControl(DeclImplementation);
319   }
320
321   virtual Stmt *getBody() const {
322     return (Stmt*) Body;
323   }
324   CompoundStmt *getCompoundBody() { return (CompoundStmt*)Body; }
325   void setBody(Stmt *B) { Body = B; }
326
327   /// \brief Returns whether this specific method is a definition.
328   bool isThisDeclarationADefinition() const { return Body; }
329
330   // Implement isa/cast/dyncast/etc.
331   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
332   static bool classof(const ObjCMethodDecl *D) { return true; }
333   static bool classofKind(Kind K) { return K == ObjCMethod; }
334   static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
335     return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
336   }
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
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;
358   prop_iterator prop_begin() const {
359     return prop_iterator(decls_begin());
360   }
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;
367   method_iterator meth_begin() const {
368     return method_iterator(decls_begin());
369   }
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;
377   instmeth_iterator instmeth_begin() const {
378     return instmeth_iterator(decls_begin());
379   }
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;
387   classmeth_iterator classmeth_begin() const {
388     return classmeth_iterator(decls_begin());
389   }
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;
396   ObjCMethodDecl *getInstanceMethod(Selector Sel) const {
397     return getMethod(Sel, true/*isInstance*/);
398   }
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.
407   SourceRange getAtEndRange() const {
408     return AtEnd;
409   }
410   void setAtEndRange(SourceRange atEnd) {
411     AtEnd = atEnd;
412   }
413
414   virtual SourceRange getSourceRange() const {
415     return SourceRange(getLocation(), getAtEndRange().getEnd());
416   }
417
418   // Implement isa/cast/dyncast/etc.
419   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
420   static bool classof(const ObjCContainerDecl *D) { return true; }
421   static bool classofKind(Kind K) {
422     return K >= firstObjCContainer &&
423            K <= lastObjCContainer;
424   }
425
426   static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
427     return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
428   }
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   
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;
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   
531   protocol_iterator protocol_begin() const {
532     if (ExternallyCompleted)
533       LoadExternalDefinition();
534
535     return ReferencedProtocols.begin();
536   }
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
546   protocol_loc_iterator protocol_loc_begin() const { 
547     if (ExternallyCompleted)
548       LoadExternalDefinition();
549
550     return ReferencedProtocols.loc_begin(); 
551   }
552
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   
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   }
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
579   ivar_iterator ivar_begin() const { return  ivar_iterator(decls_begin()); }
580   ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); }
581
582   unsigned ivar_size() const {
583     return std::distance(ivar_begin(), ivar_end());
584   }
585   
586   bool ivar_empty() const { return ivar_begin() == ivar_end(); }
587   
588   ObjCIvarDecl  *all_declared_ivar_begin();
589   void setIvarList(ObjCIvarDecl *ivar) { IvarList = ivar; }
590   
591   /// setProtocolList - Set the list of protocols that this interface
592   /// implements.
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
604   bool isForwardDecl() const { return ForwardDecl; }
605   void setForwardDecl(bool val) { ForwardDecl = val; }
606
607   ObjCInterfaceDecl *getSuperClass() const { 
608     if (ExternallyCompleted)
609       LoadExternalDefinition();
610
611     return SuperClass; 
612   }
613   
614   void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
615
616   ObjCCategoryDecl* getCategoryList() const { 
617     if (ExternallyCompleted)
618       LoadExternalDefinition();
619
620     return CategoryList; 
621   }
622   
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.
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.
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);
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;
666   ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
667     return lookupMethod(Sel, true/*isInstance*/);
668   }
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.
678   SourceLocation getLocStart() const { return getLocation(); } // '@'interface
679   SourceLocation getLocEnd() const { return EndLoc; }
680   void setLocEnd(SourceLocation LE) { EndLoc = LE; }
681
682   void setClassLoc(SourceLocation Loc) { ClassLoc = Loc; }
683   SourceLocation getClassLoc() const { return ClassLoc; }
684   void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
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.
690   bool isImplicitInterfaceDecl() const { return InternalInterface; }
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
701   const Type *getTypeForDecl() const { return TypeForDecl; }
702   void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }
703
704   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
705   static bool classof(const ObjCInterfaceDecl *D) { return true; }
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:
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   
756   ObjCIvarDecl *getNextIvar() { return NextIvar; }
757   void setNextIvar(ObjCIvarDecl *ivar) { NextIvar = ivar; }
758
759   void setAccessControl(AccessControl ac) { DeclAccess = ac; }
760
761   AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
762
763   AccessControl getCanonicalAccessControl() const {
764     return DeclAccess == None ? Protected : AccessControl(DeclAccess);
765   }
766
767   void setSynthesize(bool synth) { Synthesized = synth; }
768   bool getSynthesize() const { return Synthesized; }
769   
770   // Implement isa/cast/dyncast/etc.
771   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
772   static bool classof(const ObjCIvarDecl *D) { return true; }
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:
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.
803   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
804   static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
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
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
849   const ObjCProtocolList &getReferencedProtocols() const {
850     return ReferencedProtocols;
851   }
852   typedef ObjCProtocolList::iterator protocol_iterator;
853   protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
854   protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
855   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
856   protocol_loc_iterator protocol_loc_begin() const { 
857     return ReferencedProtocols.loc_begin(); 
858   }
859   protocol_loc_iterator protocol_loc_end() const { 
860     return ReferencedProtocols.loc_end(); 
861   }
862   unsigned protocol_size() const { return ReferencedProtocols.size(); }
863
864   /// setProtocolList - Set the list of protocols that this interface
865   /// implements.
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;
876   ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
877     return lookupMethod(Sel, true/*isInstance*/);
878   }
879   ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
880     return lookupMethod(Sel, false/*isInstance*/);
881   }
882   
883   bool isForwardDecl() const { return isForwardProtoDecl; }
884   void setForwardDecl(bool val) { isForwardProtoDecl = val; }
885
886   // Location information, modeled after the Stmt API.
887   SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
888   SourceLocation getLocEnd() const { return EndLoc; }
889   void setLocEnd(SourceLocation LE) { EndLoc = LE; }
890
891   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
892   static bool classof(const ObjCProtocolDecl *D) { return true; }
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:
906     ObjCClassRef(ObjCInterfaceDecl *d, SourceLocation l) : ID(d), L(l) {}
907     SourceLocation getLocation() const { return L; }
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;
926   iterator begin() const { return ForwardDecls; }
927   iterator end() const { return ForwardDecls + NumDecls; }
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
934   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
935   static bool classof(const ObjCClassDecl *D) { return true; }
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
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;
964   protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
965   protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
966   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
967   protocol_loc_iterator protocol_loc_begin() const { 
968     return ReferencedProtocols.loc_begin(); 
969   }
970   protocol_loc_iterator protocol_loc_end() const { 
971     return ReferencedProtocols.loc_end(); 
972   }
973
974   unsigned protocol_size() const { return ReferencedProtocols.size(); }
975
976   /// setProtocolList - Set the list of forward protocols.
977   void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
978                        const SourceLocation *Locs, ASTContext &C) {
979     ReferencedProtocols.set(List, Num, Locs, C);
980   }
981   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
982   static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
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
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
1038   ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1039   const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
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.
1047   void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
1048                        const SourceLocation *Locs, ASTContext &C) {
1049     ReferencedProtocols.set(List, Num, Locs, C);
1050   }
1051
1052   const ObjCProtocolList &getReferencedProtocols() const {
1053     return ReferencedProtocols;
1054   }
1055
1056   typedef ObjCProtocolList::iterator protocol_iterator;
1057   protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
1058   protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
1059   unsigned protocol_size() const { return ReferencedProtocols.size(); }
1060   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
1061   protocol_loc_iterator protocol_loc_begin() const { 
1062     return ReferencedProtocols.loc_begin(); 
1063   }
1064   protocol_loc_iterator protocol_loc_end() const { 
1065     return ReferencedProtocols.loc_end(); 
1066   }
1067
1068   ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
1069   void setNextClassCategory(ObjCCategoryDecl *Cat) {
1070     NextClassCategory = Cat;
1071   }
1072   void insertNextClassCategory() {
1073     NextClassCategory = ClassInterface->getCategoryList();
1074     ClassInterface->setCategoryList(this);
1075     ClassInterface->setChangedSinceDeserialization(true);
1076   }
1077
1078   bool IsClassExtension() const { return getIdentifier() == 0; }
1079   const ObjCCategoryDecl *getNextClassExtension() const;
1080   
1081   bool hasSynthBitfield() const { return HasSynthBitfield; }
1082   void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
1083   
1084   typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1085   ivar_iterator ivar_begin() const {
1086     return ivar_iterator(decls_begin());
1087   }
1088   ivar_iterator ivar_end() const {
1089     return ivar_iterator(decls_end());
1090   }
1091   unsigned ivar_size() const {
1092     return std::distance(ivar_begin(), ivar_end());
1093   }
1094   bool ivar_empty() const {
1095     return ivar_begin() == ivar_end();
1096   }
1097   
1098   SourceLocation getAtLoc() const { return AtLoc; }
1099   void setAtLoc(SourceLocation At) { AtLoc = At; }
1100
1101   SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
1102   void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; }
1103
1104   virtual SourceRange getSourceRange() const {
1105     return SourceRange(AtLoc, getAtEndRange().getEnd());
1106   }
1107
1108   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1109   static bool classof(const ObjCCategoryDecl *D) { return true; }
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:
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:
1125   const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
1126   ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
1127   void setClassInterface(ObjCInterfaceDecl *IFace);
1128
1129   void addInstanceMethod(ObjCMethodDecl *method) {
1130     // FIXME: Context should be set correctly before we get here.
1131     method->setLexicalDeclContext(this);
1132     addDecl(method);
1133   }
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;
1147   propimpl_iterator propimpl_begin() const {
1148     return propimpl_iterator(decls_begin());
1149   }
1150   propimpl_iterator propimpl_end() const {
1151     return propimpl_iterator(decls_end());
1152   }
1153
1154   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1155   static bool classof(const ObjCImplDecl *D) { return true; }
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
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.
1194   IdentifierInfo *getIdentifier() const {
1195     return Id;
1196   }
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.
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().
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().
1222   std::string getNameAsString() const {
1223     return getName();
1224   }
1225
1226   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1227   static bool classof(const ObjCCategoryImplDecl *D) { return true; }
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   
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.
1281   init_iterator       init_begin()       { return IvarInitializers; }
1282   /// begin() - Retrieve an iterator to the first initializer.
1283   init_const_iterator init_begin() const { return IvarInitializers; }
1284   
1285   /// init_end() - Retrieve an iterator past the last initializer.
1286   init_iterator       init_end()       {
1287     return IvarInitializers + NumIvarInitializers;
1288   }
1289   /// end() - Retrieve an iterator past the last initializer.
1290   init_const_iterator init_end() const {
1291     return IvarInitializers + NumIvarInitializers;
1292   }
1293   /// getNumArgs - Number of ivars which must be initialized.
1294   unsigned getNumIvarInitializers() const {
1295     return NumIvarInitializers;
1296   }
1297   
1298   void setNumIvarInitializers(unsigned numNumIvarInitializers) {
1299     NumIvarInitializers = numNumIvarInitializers;
1300   }
1301   
1302   void setIvarInitializers(ASTContext &C,
1303                            CXXCtorInitializer ** initializers,
1304                            unsigned numInitializers);
1305
1306   bool hasCXXStructors() const { return HasCXXStructors; }
1307   void setHasCXXStructors(bool val) { HasCXXStructors = val; }
1308   
1309   bool hasSynthBitfield() const { return HasSynthBitfield; }
1310   void setHasSynthBitfield (bool val) { HasSynthBitfield = val; }
1311     
1312   /// getIdentifier - Get the identifier that names the class
1313   /// interface associated with this implementation.
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.
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.
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.
1340   std::string getNameAsString() const {
1341     return getName();
1342   }
1343
1344   const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
1345   ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
1346
1347   void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
1348
1349   typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
1350   ivar_iterator ivar_begin() const {
1351     return ivar_iterator(decls_begin());
1352   }
1353   ivar_iterator ivar_end() const {
1354     return ivar_iterator(decls_end());
1355   }
1356   unsigned ivar_size() const {
1357     return std::distance(ivar_begin(), ivar_end());
1358   }
1359   bool ivar_empty() const {
1360     return ivar_begin() == ivar_end();
1361   }
1362
1363   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1364   static bool classof(const ObjCImplementationDecl *D) { return true; }
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
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
1388   const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
1389   ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
1390   void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
1391
1392   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1393   static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
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
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);
1458   SourceLocation getAtLoc() const { return AtLoc; }
1459   void setAtLoc(SourceLocation L) { AtLoc = L; }
1460   
1461   TypeSourceInfo *getTypeSourceInfo() const { return DeclType; }
1462   QualType getType() const { return DeclType->getType(); }
1463   void setType(TypeSourceInfo *T) { DeclType = T; }
1464
1465   PropertyAttributeKind getPropertyAttributes() const {
1466     return PropertyAttributeKind(PropertyAttributes);
1467   }
1468   void setPropertyAttributes(PropertyAttributeKind PRVal) {
1469     PropertyAttributes |= PRVal;
1470   }
1471
1472   PropertyAttributeKind getPropertyAttributesAsWritten() const {
1473     return PropertyAttributeKind(PropertyAttributesAsWritten);
1474   }
1475
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   
1482   void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) {
1483     PropertyAttributesAsWritten = PRVal;
1484   }
1485   
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.
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.
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
1509   Selector getGetterName() const { return GetterName; }
1510   void setGetterName(Selector Sel) { GetterName = Sel; }
1511
1512   Selector getSetterName() const { return SetterName; }
1513   void setSetterName(Selector Sel) { SetterName = Sel; }
1514
1515   ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1516   void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1517
1518   ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1519   void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1520
1521   // Related to @optional/@required declared in @protocol
1522   void setPropertyImplementation(PropertyControl pc) {
1523     PropertyImplementation = pc;
1524   }
1525   PropertyControl getPropertyImplementation() const {
1526     return PropertyControl(PropertyImplementation);
1527   }
1528
1529   void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
1530     PropertyIvarDecl = Ivar;
1531   }
1532   ObjCIvarDecl *getPropertyIvarDecl() const {
1533     return PropertyIvarDecl;
1534   }
1535
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
1544   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1545   static bool classof(const ObjCPropertyDecl *D) { return true; }
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
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   
1604   SourceLocation getLocStart() const { return AtLoc; }
1605   void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
1606
1607   ObjCPropertyDecl *getPropertyDecl() const {
1608     return PropertyDecl;
1609   }
1610   void setPropertyDecl(ObjCPropertyDecl *Prop) { PropertyDecl = Prop; }
1611
1612   Kind getPropertyImplementation() const {
1613     return PropertyIvarDecl ? Synthesize : Dynamic;
1614   }
1615
1616   ObjCIvarDecl *getPropertyIvarDecl() const {
1617     return PropertyIvarDecl;
1618   }
1619   SourceLocation getPropertyIvarDeclLoc() const { return IvarLoc; }
1620   
1621   void setPropertyIvarDecl(ObjCIvarDecl *Ivar,
1622                            SourceLocation IvarLoc) { 
1623     PropertyIvarDecl = Ivar; 
1624     this->IvarLoc = IvarLoc;
1625   }
1626   
1627   Expr *getGetterCXXConstructor() const {
1628     return GetterCXXConstructor;
1629   }
1630   void setGetterCXXConstructor(Expr *getterCXXConstructor) {
1631     GetterCXXConstructor = getterCXXConstructor;
1632   }
1633
1634   Expr *getSetterCXXAssignment() const {
1635     return SetterCXXAssignment;
1636   }
1637   void setSetterCXXAssignment(Expr *setterCXXAssignment) {
1638     SetterCXXAssignment = setterCXXAssignment;
1639   }
1640   
1641   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1642   static bool classof(const ObjCPropertyImplDecl *D) { return true; }
1643   static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }
1644   
1645   friend class ASTDeclReader;
1646 };
1647
1648 }  // end namespace clang
1649 #endif