DeclObjC.h revision d497bae0ed149584636f07b638ba8db6e3f0fcb3
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
19namespace clang {
20class Expr;
21class Stmt;
22class FunctionDecl;
23class AttributeList;
24class RecordDecl;
25class ObjCIvarDecl;
26class ObjCMethodDecl;
27class ObjCProtocolDecl;
28class ObjCCategoryDecl;
29class ObjCPropertyDecl;
30class ObjCPropertyImplDecl;
31
32class ObjCListBase {
33  void operator=(const ObjCListBase &);     // DO NOT IMPLEMENT
34  ObjCListBase(const ObjCListBase&);        // DO NOT IMPLEMENT
35protected:
36  /// List is an array of pointers to objects that are not owned by this object.
37  void **List;
38  unsigned NumElts;
39
40public:
41  ObjCListBase() : List(0), NumElts(0) {}
42  ~ObjCListBase() {
43    assert(List == 0 && "Destroy should have been called before dtor");
44  }
45
46  void Destroy(ASTContext &Ctx);
47
48  unsigned size() const { return NumElts; }
49  bool empty() const { return NumElts == 0; }
50
51protected:
52  void set(void *const* InList, unsigned Elts, ASTContext &Ctx);
53};
54
55
56/// ObjCList - This is a simple template class used to hold various lists of
57/// decls etc, which is heavily used by the ObjC front-end.  This only use case
58/// this supports is setting the list all at once and then reading elements out
59/// of it.
60template <typename T>
61class ObjCList : public ObjCListBase {
62public:
63  void set(T* const* InList, unsigned Elts, ASTContext &Ctx) {
64    ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx);
65  }
66
67  typedef T* const * iterator;
68  iterator begin() const { return (iterator)List; }
69  iterator end() const { return (iterator)List+NumElts; }
70
71  T* operator[](unsigned Idx) const {
72    assert(Idx < NumElts && "Invalid access");
73    return (T*)List[Idx];
74  }
75};
76
77
78
79/// ObjCMethodDecl - Represents an instance or class method declaration.
80/// ObjC methods can be declared within 4 contexts: class interfaces,
81/// categories, protocols, and class implementations. While C++ member
82/// functions leverage C syntax, Objective-C method syntax is modeled after
83/// Smalltalk (using colons to specify argument types/expressions).
84/// Here are some brief examples:
85///
86/// Setter/getter instance methods:
87/// - (void)setMenu:(NSMenu *)menu;
88/// - (NSMenu *)menu;
89///
90/// Instance method that takes 2 NSView arguments:
91/// - (void)replaceSubview:(NSView *)oldView with:(NSView *)newView;
92///
93/// Getter class method:
94/// + (NSMenu *)defaultMenu;
95///
96/// A selector represents a unique name for a method. The selector names for
97/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
98///
99class ObjCMethodDecl : public NamedDecl, public DeclContext {
100public:
101  enum ImplementationControl { None, Required, Optional };
102private:
103  /// Bitfields must be first fields in this class so they pack with those
104  /// declared in class Decl.
105  /// instance (true) or class (false) method.
106  bool IsInstance : 1;
107  bool IsVariadic : 1;
108
109  // Synthesized declaration method for a property setter/getter
110  bool IsSynthesized : 1;
111
112  // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
113  /// @required/@optional
114  unsigned DeclImplementation : 2;
115
116  // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum
117  /// in, inout, etc.
118  unsigned objcDeclQualifier : 6;
119
120  // Type of this method.
121  QualType MethodDeclType;
122  /// ParamInfo - List of pointers to VarDecls for the formal parameters of this
123  /// Method.
124  ObjCList<ParmVarDecl> ParamInfo;
125
126  /// List of attributes for this method declaration.
127  SourceLocation EndLoc; // the location of the ';' or '{'.
128
129  // The following are only used for method definitions, null otherwise.
130  // FIXME: space savings opportunity, consider a sub-class.
131  Stmt *Body;
132
133  /// SelfDecl - Decl for the implicit self parameter. This is lazily
134  /// constructed by createImplicitParams.
135  ImplicitParamDecl *SelfDecl;
136  /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily
137  /// constructed by createImplicitParams.
138  ImplicitParamDecl *CmdDecl;
139
140  ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
141                 Selector SelInfo, QualType T,
142                 DeclContext *contextDecl,
143                 bool isInstance = true,
144                 bool isVariadic = false,
145                 bool isSynthesized = false,
146                 ImplementationControl impControl = None)
147  : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
148    DeclContext(ObjCMethod),
149    IsInstance(isInstance), IsVariadic(isVariadic),
150    IsSynthesized(isSynthesized),
151    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
152    MethodDeclType(T),
153    EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
154
155  virtual ~ObjCMethodDecl() {}
156
157public:
158
159  /// Destroy - Call destructors and release memory.
160  virtual void Destroy(ASTContext& C);
161
162  static ObjCMethodDecl *Create(ASTContext &C,
163                                SourceLocation beginLoc,
164                                SourceLocation endLoc, Selector SelInfo,
165                                QualType T, DeclContext *contextDecl,
166                                bool isInstance = true,
167                                bool isVariadic = false,
168                                bool isSynthesized = false,
169                                ImplementationControl impControl = None);
170
171  ObjCDeclQualifier getObjCDeclQualifier() const {
172    return ObjCDeclQualifier(objcDeclQualifier);
173  }
174  void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
175
176  // Location information, modeled after the Stmt API.
177  SourceLocation getLocStart() const { return getLocation(); }
178  SourceLocation getLocEnd() const { return EndLoc; }
179  SourceRange getSourceRange() const {
180    return SourceRange(getLocation(), EndLoc);
181  }
182
183  ObjCInterfaceDecl *getClassInterface();
184  const ObjCInterfaceDecl *getClassInterface() const {
185    return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
186  }
187
188  Selector getSelector() const { return getDeclName().getObjCSelector(); }
189  unsigned getSynthesizedMethodSize() const;
190  QualType getResultType() const { return MethodDeclType; }
191
192  // Iterator access to formal parameters.
193  unsigned param_size() const { return ParamInfo.size(); }
194  typedef ObjCList<ParmVarDecl>::iterator param_iterator;
195  param_iterator param_begin() const { return ParamInfo.begin(); }
196  param_iterator param_end() const { return ParamInfo.end(); }
197
198  void setMethodParams(ParmVarDecl *const *List, unsigned Num,
199                       ASTContext &C) {
200    ParamInfo.set(List, Num, C);
201  }
202
203  /// createImplicitParams - Used to lazily create the self and cmd
204  /// implict parameters. This must be called prior to using getSelfDecl()
205  /// or getCmdDecl(). The call is ignored if the implicit paramters
206  /// have already been created.
207  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
208
209  ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
210  ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
211
212  bool isInstanceMethod() const { return IsInstance; }
213  bool isVariadic() const { return IsVariadic; }
214
215  bool isClassMethod() const { return !IsInstance; }
216
217  bool isSynthesized() const { return IsSynthesized; }
218  void setIsSynthesized() { IsSynthesized = true; }
219
220  // Related to protocols declared in  @protocol
221  void setDeclImplementation(ImplementationControl ic) {
222    DeclImplementation = ic;
223  }
224  ImplementationControl getImplementationControl() const {
225    return ImplementationControl(DeclImplementation);
226  }
227
228  virtual CompoundStmt *getBody() const { return (CompoundStmt*) Body; }
229  void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
230
231  // Implement isa/cast/dyncast/etc.
232  static bool classof(const Decl *D) { return D->getKind() == ObjCMethod; }
233  static bool classof(const ObjCMethodDecl *D) { return true; }
234  static DeclContext *castToDeclContext(const ObjCMethodDecl *D) {
235    return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D));
236  }
237  static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) {
238    return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC));
239  }
240};
241
242/// ObjCContainerDecl - Represents a container for method declarations.
243/// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, and
244/// ObjCProtocolDecl.
245/// FIXME: Use for ObjC implementation decls.
246///
247class ObjCContainerDecl : public NamedDecl, public DeclContext {
248  SourceLocation AtEndLoc; // marks the end of the method container.
249public:
250
251  ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L,
252                    IdentifierInfo *Id)
253    : NamedDecl(DK, DC, L, Id), DeclContext(DK) {}
254
255  virtual ~ObjCContainerDecl() {}
256
257  // Iterator access to properties.
258  typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
259  prop_iterator prop_begin() const {
260    return prop_iterator(decls_begin());
261  }
262  prop_iterator prop_end() const {
263    return prop_iterator(decls_end());
264  }
265
266  // Iterator access to instance/class methods.
267  typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
268  method_iterator meth_begin() const {
269    return method_iterator(decls_begin());
270  }
271  method_iterator meth_end() const {
272    return method_iterator(decls_end());
273  }
274
275  typedef filtered_decl_iterator<ObjCMethodDecl,
276                                 &ObjCMethodDecl::isInstanceMethod>
277    instmeth_iterator;
278  instmeth_iterator instmeth_begin() const {
279    return instmeth_iterator(decls_begin());
280  }
281  instmeth_iterator instmeth_end() const {
282    return instmeth_iterator(decls_end());
283  }
284
285  typedef filtered_decl_iterator<ObjCMethodDecl,
286                                 &ObjCMethodDecl::isClassMethod>
287    classmeth_iterator;
288  classmeth_iterator classmeth_begin() const {
289    return classmeth_iterator(decls_begin());
290  }
291  classmeth_iterator classmeth_end() const {
292    return classmeth_iterator(decls_end());
293  }
294
295  // Get the local instance/class method declared in this interface.
296  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
297  ObjCMethodDecl *getClassMethod(Selector Sel) const;
298  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
299    return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
300  }
301
302  ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
303
304  // Marks the end of the container.
305  SourceLocation getAtEndLoc() const { return AtEndLoc; }
306  void setAtEndLoc(SourceLocation L) { AtEndLoc = L; }
307
308  // Implement isa/cast/dyncast/etc.
309  static bool classof(const Decl *D) {
310    return D->getKind() >= ObjCContainerFirst &&
311           D->getKind() <= ObjCContainerLast;
312  }
313  static bool classof(const ObjCContainerDecl *D) { return true; }
314
315  static DeclContext *castToDeclContext(const ObjCContainerDecl *D) {
316    return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D));
317  }
318  static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) {
319    return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC));
320  }
321};
322
323/// ObjCInterfaceDecl - Represents an ObjC class declaration. For example:
324///
325///   // MostPrimitive declares no super class (not particularly useful).
326///   @interface MostPrimitive
327///     // no instance variables or methods.
328///   @end
329///
330///   // NSResponder inherits from NSObject & implements NSCoding (a protocol).
331///   @interface NSResponder : NSObject <NSCoding>
332///   { // instance variables are represented by ObjCIvarDecl.
333///     id nextResponder; // nextResponder instance variable.
334///   }
335///   - (NSResponder *)nextResponder; // return a pointer to NSResponder.
336///   - (void)mouseMoved:(NSEvent *)theEvent; // return void, takes a pointer
337///   @end                                    // to an NSEvent.
338///
339///   Unlike C/C++, forward class declarations are accomplished with @class.
340///   Unlike C/C++, @class allows for a list of classes to be forward declared.
341///   Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
342///   typically inherit from NSObject (an exception is NSProxy).
343///
344class ObjCInterfaceDecl : public ObjCContainerDecl {
345  /// TypeForDecl - This indicates the Type object that represents this
346  /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
347  Type *TypeForDecl;
348  friend class ASTContext;
349
350  /// Class's super class.
351  ObjCInterfaceDecl *SuperClass;
352
353  /// Protocols referenced in interface header declaration
354  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
355
356  /// Instance variables in the interface.
357  ObjCList<ObjCIvarDecl> IVars;
358
359  /// List of categories defined for this class.
360  /// FIXME: Why is this a linked list??
361  ObjCCategoryDecl *CategoryList;
362
363  bool ForwardDecl:1; // declared with @class.
364  bool InternalInterface:1; // true - no @interface for @implementation
365
366  SourceLocation ClassLoc; // location of the class identifier.
367  SourceLocation SuperClassLoc; // location of the super class identifier.
368  SourceLocation EndLoc; // marks the '>', '}', or identifier.
369
370  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
371                    SourceLocation CLoc, bool FD, bool isInternal);
372
373  virtual ~ObjCInterfaceDecl() {}
374
375public:
376
377  /// Destroy - Call destructors and release memory.
378  virtual void Destroy(ASTContext& C);
379
380  static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
381                                   SourceLocation atLoc,
382                                   IdentifierInfo *Id,
383                                   SourceLocation ClassLoc = SourceLocation(),
384                                   bool ForwardDecl = false,
385                                   bool isInternal = false);
386  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
387    return ReferencedProtocols;
388  }
389
390  ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const;
391
392  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
393  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
394  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
395
396  typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator;
397  ivar_iterator ivar_begin() const { return IVars.begin(); }
398  ivar_iterator ivar_end() const { return IVars.end(); }
399  unsigned ivar_size() const { return IVars.size(); }
400  bool ivar_empty() const { return IVars.empty(); }
401
402  /// setProtocolList - Set the list of protocols that this interface
403  /// implements.
404  void setProtocolList(ObjCProtocolDecl *const* List, unsigned Num,
405                       ASTContext &C) {
406    ReferencedProtocols.set(List, Num, C);
407  }
408
409  void setIVarList(ObjCIvarDecl * const *List, unsigned Num, ASTContext &C) {
410    IVars.set(List, Num, C);
411  }
412  FieldDecl *lookupFieldDeclForIvar(ASTContext &Context,
413                                    const ObjCIvarDecl *ivar);
414
415  bool isForwardDecl() const { return ForwardDecl; }
416  void setForwardDecl(bool val) { ForwardDecl = val; }
417
418  ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
419  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
420
421  ObjCCategoryDecl* getCategoryList() const { return CategoryList; }
422  void setCategoryList(ObjCCategoryDecl *category) {
423    CategoryList = category;
424  }
425
426  /// isSuperClassOf - Return true if this class is the specified class or is a
427  /// super class of the specified interface class.
428  bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
429    // If RHS is derived from LHS it is OK; else it is not OK.
430    while (I != NULL) {
431      if (this == I)
432        return true;
433      I = I->getSuperClass();
434    }
435    return false;
436  }
437
438  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName,
439                                       ObjCInterfaceDecl *&ClassDeclared);
440  ObjCIvarDecl *lookupInstanceVariable(IdentifierInfo *IVarName) {
441    ObjCInterfaceDecl *ClassDeclared;
442    return lookupInstanceVariable(IVarName, ClassDeclared);
443  }
444
445  // Lookup a method. First, we search locally. If a method isn't
446  // found, we search referenced protocols and class categories.
447  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
448  ObjCMethodDecl *lookupClassMethod(Selector Sel);
449
450  // Location information, modeled after the Stmt API.
451  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
452  SourceLocation getLocEnd() const { return EndLoc; }
453  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
454
455  SourceLocation getClassLoc() const { return ClassLoc; }
456  void setSuperClassLoc(SourceLocation Loc) { SuperClassLoc = Loc; }
457  SourceLocation getSuperClassLoc() const { return SuperClassLoc; }
458
459  /// ImplicitInterfaceDecl - check that this is an implicitely declared
460  /// ObjCInterfaceDecl node. This is for legacy objective-c @implementation
461  /// declaration without an @interface declaration.
462  bool ImplicitInterfaceDecl() const { return InternalInterface; }
463
464  static bool classof(const Decl *D) { return D->getKind() == ObjCInterface; }
465  static bool classof(const ObjCInterfaceDecl *D) { return true; }
466};
467
468/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
469/// instance variables are identical to C. The only exception is Objective-C
470/// supports C++ style access control. For example:
471///
472///   @interface IvarExample : NSObject
473///   {
474///     id defaultToProtected;
475///   @public:
476///     id canBePublic; // same as C++.
477///   @protected:
478///     id canBeProtected; // same as C++.
479///   @package:
480///     id canBePackage; // framework visibility (not available in C++).
481///   }
482///
483class ObjCIvarDecl : public FieldDecl {
484public:
485  enum AccessControl {
486    None, Private, Protected, Public, Package
487  };
488
489private:
490  ObjCIvarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
491               QualType T, AccessControl ac, Expr *BW)
492    : FieldDecl(ObjCIvar, DC, L, Id, T, BW, /*Mutable=*/false),
493      DeclAccess(ac) {}
494
495public:
496  static ObjCIvarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
497                              IdentifierInfo *Id, QualType T,
498                              AccessControl ac, Expr *BW = NULL);
499
500  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
501
502  AccessControl getAccessControl() const { return AccessControl(DeclAccess); }
503
504  AccessControl getCanonicalAccessControl() const {
505    return DeclAccess == None ? Protected : AccessControl(DeclAccess);
506  }
507
508  // Implement isa/cast/dyncast/etc.
509  static bool classof(const Decl *D) { return D->getKind() == ObjCIvar; }
510  static bool classof(const ObjCIvarDecl *D) { return true; }
511private:
512  // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
513  unsigned DeclAccess : 3;
514};
515
516
517/// ObjCAtDefsFieldDecl - Represents a field declaration created by an
518///  @defs(...).
519class ObjCAtDefsFieldDecl : public FieldDecl {
520private:
521  ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
522                      QualType T, Expr *BW)
523    : FieldDecl(ObjCAtDefsField, DC, L, Id, T, BW, /*Mutable=*/false) {}
524
525public:
526  static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC,
527                                     SourceLocation L,
528                                     IdentifierInfo *Id, QualType T,
529                                     Expr *BW);
530
531  virtual void Destroy(ASTContext& C);
532
533  // Implement isa/cast/dyncast/etc.
534  static bool classof(const Decl *D) { return D->getKind() == ObjCAtDefsField; }
535  static bool classof(const ObjCAtDefsFieldDecl *D) { return true; }
536};
537
538/// ObjCProtocolDecl - Represents a protocol declaration. ObjC protocols
539/// declare a pure abstract type (i.e no instance variables are permitted).
540/// Protocols orginally drew inspiration from C++ pure virtual functions (a C++
541/// feature with nice semantics and lousy syntax:-). Here is an example:
542///
543/// @protocol NSDraggingInfo <refproto1, refproto2>
544/// - (NSWindow *)draggingDestinationWindow;
545/// - (NSImage *)draggedImage;
546/// @end
547///
548/// This says that NSDraggingInfo requires two methods and requires everything
549/// that the two "referenced protocols" 'refproto1' and 'refproto2' require as
550/// well.
551///
552/// @interface ImplementsNSDraggingInfo : NSObject <NSDraggingInfo>
553/// @end
554///
555/// ObjC protocols inspired Java interfaces. Unlike Java, ObjC classes and
556/// protocols are in distinct namespaces. For example, Cocoa defines both
557/// an NSObject protocol and class (which isn't allowed in Java). As a result,
558/// protocols are referenced using angle brackets as follows:
559///
560/// id <NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo;
561///
562class ObjCProtocolDecl : public ObjCContainerDecl {
563  /// Referenced protocols
564  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
565
566  bool isForwardProtoDecl; // declared with @protocol.
567
568  SourceLocation EndLoc; // marks the '>' or identifier.
569  SourceLocation AtEndLoc; // marks the end of the entire interface.
570
571  ObjCProtocolDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
572    : ObjCContainerDecl(ObjCProtocol, DC, L, Id),
573      isForwardProtoDecl(true) {
574  }
575
576  virtual ~ObjCProtocolDecl() {}
577
578public:
579  static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC,
580                                  SourceLocation L, IdentifierInfo *Id);
581
582  /// Destroy - Call destructors and release memory.
583  virtual void Destroy(ASTContext& C);
584
585  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
586    return ReferencedProtocols;
587  }
588  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
589  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
590  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
591
592  /// setProtocolList - Set the list of protocols that this interface
593  /// implements.
594  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
595                       ASTContext &C) {
596    ReferencedProtocols.set(List, Num, C);
597  }
598
599  ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
600
601  // Lookup a method. First, we search locally. If a method isn't
602  // found, we search referenced protocols and class categories.
603  ObjCMethodDecl *lookupInstanceMethod(Selector Sel);
604  ObjCMethodDecl *lookupClassMethod(Selector Sel);
605
606  bool isForwardDecl() const { return isForwardProtoDecl; }
607  void setForwardDecl(bool val) { isForwardProtoDecl = val; }
608
609  // Location information, modeled after the Stmt API.
610  SourceLocation getLocStart() const { return getLocation(); } // '@'protocol
611  SourceLocation getLocEnd() const { return EndLoc; }
612  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
613
614  static bool classof(const Decl *D) { return D->getKind() == ObjCProtocol; }
615  static bool classof(const ObjCProtocolDecl *D) { return true; }
616};
617
618/// ObjCClassDecl - Specifies a list of forward class declarations. For example:
619///
620/// @class NSCursor, NSImage, NSPasteboard, NSWindow;
621///
622class ObjCClassDecl : public Decl {
623  ObjCList<ObjCInterfaceDecl> ForwardDecls;
624
625  ObjCClassDecl(DeclContext *DC, SourceLocation L,
626                ObjCInterfaceDecl *const *Elts, unsigned nElts, ASTContext &C);
627  virtual ~ObjCClassDecl() {}
628public:
629
630  /// Destroy - Call destructors and release memory.
631  virtual void Destroy(ASTContext& C);
632
633  static ObjCClassDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
634                               ObjCInterfaceDecl *const *Elts, unsigned nElts);
635
636  typedef ObjCList<ObjCInterfaceDecl>::iterator iterator;
637  iterator begin() const { return ForwardDecls.begin(); }
638  iterator end() const { return ForwardDecls.end(); }
639
640  static bool classof(const Decl *D) { return D->getKind() == ObjCClass; }
641  static bool classof(const ObjCClassDecl *D) { return true; }
642};
643
644/// ObjCForwardProtocolDecl - Specifies a list of forward protocol declarations.
645/// For example:
646///
647/// @protocol NSTextInput, NSChangeSpelling, NSDraggingInfo;
648///
649class ObjCForwardProtocolDecl : public Decl {
650  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
651
652  ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
653                          ObjCProtocolDecl *const *Elts, unsigned nElts,
654                          ASTContext &C);
655  virtual ~ObjCForwardProtocolDecl() {}
656
657public:
658  static ObjCForwardProtocolDecl *Create(ASTContext &C, DeclContext *DC,
659                                         SourceLocation L,
660                                         ObjCProtocolDecl *const *Elts,
661                                         unsigned Num);
662
663  /// Destroy - Call destructors and release memory.
664  virtual void Destroy(ASTContext& C);
665
666  typedef ObjCList<ObjCProtocolDecl>::iterator iterator;
667  iterator begin() const { return ReferencedProtocols.begin(); }
668  iterator end() const { return ReferencedProtocols.end(); }
669
670  static bool classof(const Decl *D) {
671    return D->getKind() == ObjCForwardProtocol;
672  }
673  static bool classof(const ObjCForwardProtocolDecl *D) { return true; }
674};
675
676/// ObjCCategoryDecl - Represents a category declaration. A category allows
677/// you to add methods to an existing class (without subclassing or modifying
678/// the original class interface or implementation:-). Categories don't allow
679/// you to add instance data. The following example adds "myMethod" to all
680/// NSView's within a process:
681///
682/// @interface NSView (MyViewMethods)
683/// - myMethod;
684/// @end
685///
686/// Cateogries also allow you to split the implementation of a class across
687/// several files (a feature more naturally supported in C++).
688///
689/// Categories were originally inspired by dynamic languages such as Common
690/// Lisp and Smalltalk.  More traditional class-based languages (C++, Java)
691/// don't support this level of dynamism, which is both powerful and dangerous.
692///
693class ObjCCategoryDecl : public ObjCContainerDecl {
694  /// Interface belonging to this category
695  ObjCInterfaceDecl *ClassInterface;
696
697  /// referenced protocols in this category.
698  ObjCList<ObjCProtocolDecl> ReferencedProtocols;
699
700  /// Next category belonging to this class.
701  /// FIXME: this should not be a singly-linked list.  Move storage elsewhere.
702  ObjCCategoryDecl *NextClassCategory;
703
704  SourceLocation EndLoc; // marks the '>' or identifier.
705
706  ObjCCategoryDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
707    : ObjCContainerDecl(ObjCCategory, DC, L, Id),
708      ClassInterface(0), NextClassCategory(0){
709  }
710public:
711
712  static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC,
713                                  SourceLocation L, IdentifierInfo *Id);
714
715  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
716  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
717  void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
718
719  /// setProtocolList - Set the list of protocols that this interface
720  /// implements.
721  void setProtocolList(ObjCProtocolDecl *const*List, unsigned Num,
722                              ASTContext &C) {
723    ReferencedProtocols.set(List, Num, C);
724  }
725
726  const ObjCList<ObjCProtocolDecl> &getReferencedProtocols() const {
727    return ReferencedProtocols;
728  }
729
730  typedef ObjCList<ObjCProtocolDecl>::iterator protocol_iterator;
731  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
732  protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
733
734  ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
735  void insertNextClassCategory() {
736    NextClassCategory = ClassInterface->getCategoryList();
737    ClassInterface->setCategoryList(this);
738  }
739  // Location information, modeled after the Stmt API.
740  SourceLocation getLocStart() const { return getLocation(); } // '@'interface
741  SourceLocation getLocEnd() const { return EndLoc; }
742  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
743
744  static bool classof(const Decl *D) { return D->getKind() == ObjCCategory; }
745  static bool classof(const ObjCCategoryDecl *D) { return true; }
746};
747
748class ObjCImplDecl : public Decl, public DeclContext {
749  /// Class interface for this category implementation
750  ObjCInterfaceDecl *ClassInterface;
751
752  /// implemented instance methods
753  llvm::SmallVector<ObjCMethodDecl*, 16> InstanceMethods;
754
755  /// implemented class methods
756  llvm::SmallVector<ObjCMethodDecl*, 16> ClassMethods;
757
758  /// Property Implementations in this category
759  llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
760
761  SourceLocation EndLoc;
762
763protected:
764  ObjCImplDecl(Kind DK, DeclContext *DC, SourceLocation L,
765               ObjCInterfaceDecl *classInterface)
766      : Decl(DK, DC, L), DeclContext(DK),
767        ClassInterface(classInterface) {}
768
769public:
770  virtual ~ObjCImplDecl() {}
771
772  const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
773  ObjCInterfaceDecl *getClassInterface() { return ClassInterface; }
774
775  void addInstanceMethod(ObjCMethodDecl *method) {
776    InstanceMethods.push_back(method);
777  }
778  void addClassMethod(ObjCMethodDecl *method) {
779    ClassMethods.push_back(method);
780  }
781
782  // Get the local instance/class method declared in this interface.
783  ObjCMethodDecl *getInstanceMethod(Selector Sel) const;
784  ObjCMethodDecl *getClassMethod(Selector Sel) const;
785  ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
786    return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
787  }
788
789  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
790    PropertyImplementations.push_back(property);
791  }
792
793  ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const;
794  ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const;
795
796  typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
797    propimpl_iterator;
798  propimpl_iterator propimpl_begin() const {
799    return PropertyImplementations.begin();
800  }
801  propimpl_iterator propimpl_end() const {
802    return PropertyImplementations.end();
803  }
804
805  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
806    instmeth_iterator;
807  instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
808  instmeth_iterator instmeth_end() const { return InstanceMethods.end(); }
809
810  typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
811    classmeth_iterator;
812  classmeth_iterator classmeth_begin() const { return ClassMethods.begin(); }
813  classmeth_iterator classmeth_end() const { return ClassMethods.end(); }
814
815
816  // Location information, modeled after the Stmt API.
817  SourceLocation getLocStart() const { return getLocation(); }
818  SourceLocation getLocEnd() const { return EndLoc; }
819  void setLocEnd(SourceLocation LE) { EndLoc = LE; };
820};
821
822/// ObjCCategoryImplDecl - An object of this class encapsulates a category
823/// @implementation declaration. If a category class has declaration of a
824/// property, its implementation must be specified in the category's
825/// @implementation declaration. Example:
826/// @interface I @end
827/// @interface I(CATEGORY)
828///    @property int p1, d1;
829/// @end
830/// @implementation I(CATEGORY)
831///  @dynamic p1,d1;
832/// @end
833///
834/// ObjCCategoryImplDecl
835class ObjCCategoryImplDecl : public ObjCImplDecl {
836  // Category name
837  IdentifierInfo *Id;
838
839  ObjCCategoryImplDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
840                       ObjCInterfaceDecl *classInterface)
841    : ObjCImplDecl(ObjCCategoryImpl, DC, L, classInterface), Id(Id) {}
842public:
843  static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
844                                      SourceLocation L, IdentifierInfo *Id,
845                                      ObjCInterfaceDecl *classInterface);
846
847  /// getIdentifier - Get the identifier that names the class
848  /// interface associated with this implementation.
849  IdentifierInfo *getIdentifier() const {
850    return Id;
851  }
852
853  /// getNameAsCString - Get the name of identifier for the class
854  /// interface associated with this implementation as a C string
855  /// (const char*).
856  const char *getNameAsCString() const {
857    return Id ? Id->getName() : "";
858  }
859
860  /// @brief Get the name of the class associated with this interface.
861  std::string getNameAsString() const {
862    return Id ? Id->getName() : "";
863  }
864
865  static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
866  static bool classof(const ObjCCategoryImplDecl *D) { return true; }
867  static DeclContext *castToDeclContext(const ObjCCategoryImplDecl *D) {
868    return static_cast<DeclContext *>(const_cast<ObjCCategoryImplDecl*>(D));
869  }
870  static ObjCCategoryImplDecl *castFromDeclContext(const DeclContext *DC) {
871    return static_cast<ObjCCategoryImplDecl *>(const_cast<DeclContext*>(DC));
872  }
873};
874
875/// ObjCImplementationDecl - Represents a class definition - this is where
876/// method definitions are specified. For example:
877///
878/// @code
879/// @implementation MyClass
880/// - (void)myMethod { /* do something */ }
881/// @end
882/// @endcode
883///
884/// Typically, instance variables are specified in the class interface,
885/// *not* in the implementation. Nevertheless (for legacy reasons), we
886/// allow instance variables to be specified in the implementation.  When
887/// specified, they need to be *identical* to the interface.
888///
889class ObjCImplementationDecl : public ObjCImplDecl {
890  /// Implementation Class's super class.
891  ObjCInterfaceDecl *SuperClass;
892
893  /// Instance variables declared in the @implementation.
894  ObjCList<ObjCIvarDecl> IVars;
895
896  ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
897                         ObjCInterfaceDecl *classInterface,
898                         ObjCInterfaceDecl *superDecl)
899    : ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
900       SuperClass(superDecl){}
901public:
902  static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
903                                        SourceLocation L,
904                                        ObjCInterfaceDecl *classInterface,
905                                        ObjCInterfaceDecl *superDecl);
906
907  /// Destroy - Call destructors and release memory.
908  virtual void Destroy(ASTContext& C);
909
910  void setIVarList(ObjCIvarDecl *const *InArray, unsigned Num, ASTContext &C) {
911    IVars.set(InArray, Num, C);
912  }
913
914  /// getIdentifier - Get the identifier that names the class
915  /// interface associated with this implementation.
916  IdentifierInfo *getIdentifier() const {
917    return getClassInterface()->getIdentifier();
918  }
919
920  /// getNameAsCString - Get the name of identifier for the class
921  /// interface associated with this implementation as a C string
922  /// (const char*).
923  const char *getNameAsCString() const {
924    assert(getIdentifier() && "Name is not a simple identifier");
925    return getIdentifier()->getName();
926  }
927
928  /// @brief Get the name of the class associated with this interface.
929  std::string getNameAsString() const {
930    return getClassInterface()->getNameAsString();
931  }
932
933  const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
934  ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
935
936  void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; }
937
938  typedef ObjCList<ObjCIvarDecl>::iterator ivar_iterator;
939  ivar_iterator ivar_begin() const { return IVars.begin(); }
940  ivar_iterator ivar_end() const { return IVars.end(); }
941  unsigned ivar_size() const { return IVars.size(); }
942  bool ivar_empty() const { return IVars.empty(); }
943
944  static bool classof(const Decl *D) {
945    return D->getKind() == ObjCImplementation;
946  }
947  static bool classof(const ObjCImplementationDecl *D) { return true; }
948  static DeclContext *castToDeclContext(const ObjCImplementationDecl *D) {
949    return static_cast<DeclContext *>(const_cast<ObjCImplementationDecl*>(D));
950  }
951  static ObjCImplementationDecl *castFromDeclContext(const DeclContext *DC) {
952    return static_cast<ObjCImplementationDecl *>(const_cast<DeclContext*>(DC));
953  }
954};
955
956/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
957/// declared as @compatibility_alias alias class.
958class ObjCCompatibleAliasDecl : public NamedDecl {
959  /// Class that this is an alias of.
960  ObjCInterfaceDecl *AliasedClass;
961
962  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
963                          ObjCInterfaceDecl* aliasedClass)
964    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
965public:
966  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
967                                         SourceLocation L, IdentifierInfo *Id,
968                                         ObjCInterfaceDecl* aliasedClass);
969
970  const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; }
971  ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
972
973  static bool classof(const Decl *D) {
974    return D->getKind() == ObjCCompatibleAlias;
975  }
976  static bool classof(const ObjCCompatibleAliasDecl *D) { return true; }
977
978};
979
980/// ObjCPropertyDecl - Represents one property declaration in an interface.
981/// For example:
982/// @property (assign, readwrite) int MyProperty;
983///
984class ObjCPropertyDecl : public NamedDecl {
985public:
986  enum PropertyAttributeKind {
987    OBJC_PR_noattr    = 0x00,
988    OBJC_PR_readonly  = 0x01,
989    OBJC_PR_getter    = 0x02,
990    OBJC_PR_assign    = 0x04,
991    OBJC_PR_readwrite = 0x08,
992    OBJC_PR_retain    = 0x10,
993    OBJC_PR_copy      = 0x20,
994    OBJC_PR_nonatomic = 0x40,
995    OBJC_PR_setter    = 0x80
996  };
997
998  enum SetterKind { Assign, Retain, Copy };
999  enum PropertyControl { None, Required, Optional };
1000private:
1001  QualType DeclType;
1002  unsigned PropertyAttributes : 8;
1003
1004  // @required/@optional
1005  unsigned PropertyImplementation : 2;
1006
1007  Selector GetterName;    // getter name of NULL if no getter
1008  Selector SetterName;    // setter name of NULL if no setter
1009
1010  ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
1011  ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
1012
1013  ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
1014                   QualType T)
1015    : NamedDecl(ObjCProperty, DC, L, Id), DeclType(T),
1016      PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
1017      GetterName(Selector()),
1018      SetterName(Selector()),
1019      GetterMethodDecl(0), SetterMethodDecl(0) {}
1020public:
1021  static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
1022                                  SourceLocation L,
1023                                  IdentifierInfo *Id, QualType T,
1024                                  PropertyControl propControl = None);
1025  QualType getType() const { return DeclType; }
1026
1027  PropertyAttributeKind getPropertyAttributes() const {
1028    return PropertyAttributeKind(PropertyAttributes);
1029  }
1030  void setPropertyAttributes(PropertyAttributeKind PRVal) {
1031    PropertyAttributes |= PRVal;
1032  }
1033
1034 void makeitReadWriteAttribute(void) {
1035    PropertyAttributes &= ~OBJC_PR_readonly;
1036    PropertyAttributes |= OBJC_PR_readwrite;
1037 }
1038
1039  // Helper methods for accessing attributes.
1040
1041  /// isReadOnly - Return true iff the property has a setter.
1042  bool isReadOnly() const {
1043    return (PropertyAttributes & OBJC_PR_readonly);
1044  }
1045
1046  /// getSetterKind - Return the method used for doing assignment in
1047  /// the property setter. This is only valid if the property has been
1048  /// defined to have a setter.
1049  SetterKind getSetterKind() const {
1050    if (PropertyAttributes & OBJC_PR_retain)
1051      return Retain;
1052    if (PropertyAttributes & OBJC_PR_copy)
1053      return Copy;
1054    return Assign;
1055  }
1056
1057  Selector getGetterName() const { return GetterName; }
1058  void setGetterName(Selector Sel) { GetterName = Sel; }
1059
1060  Selector getSetterName() const { return SetterName; }
1061  void setSetterName(Selector Sel) { SetterName = Sel; }
1062
1063  ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
1064  void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
1065
1066  ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; }
1067  void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; }
1068
1069  // Related to @optional/@required declared in @protocol
1070  void setPropertyImplementation(PropertyControl pc) {
1071    PropertyImplementation = pc;
1072  }
1073  PropertyControl getPropertyImplementation() const {
1074    return PropertyControl(PropertyImplementation);
1075  }
1076
1077  static bool classof(const Decl *D) {
1078    return D->getKind() == ObjCProperty;
1079  }
1080  static bool classof(const ObjCPropertyDecl *D) { return true; }
1081};
1082
1083/// ObjCPropertyImplDecl - Represents implementation declaration of a property
1084/// in a class or category implementation block. For example:
1085/// @synthesize prop1 = ivar1;
1086///
1087class ObjCPropertyImplDecl : public Decl {
1088public:
1089  enum Kind {
1090    Synthesize,
1091    Dynamic
1092  };
1093private:
1094  unsigned IvarKind : 1;
1095  SourceLocation AtLoc;   // location of @synthesize or @dynamic
1096  /// Property declaration being implemented
1097  ObjCPropertyDecl *PropertyDecl;
1098
1099  /// Null for @dynamic. Required for @synthesize.
1100  ObjCIvarDecl *PropertyIvarDecl;
1101
1102  ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
1103                       ObjCPropertyDecl *property,
1104                       Kind PK,
1105                       ObjCIvarDecl *ivarDecl)
1106    : Decl(ObjCPropertyImpl, DC, L), IvarKind(false), AtLoc(atLoc),
1107      PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
1108    assert (PK == Dynamic || PropertyIvarDecl);
1109  }
1110
1111public:
1112  static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC,
1113                                      SourceLocation atLoc, SourceLocation L,
1114                                      ObjCPropertyDecl *property,
1115                                      Kind PK,
1116                                      ObjCIvarDecl *ivarDecl);
1117
1118  SourceLocation getLocStart() const { return AtLoc; }
1119
1120  ObjCPropertyDecl *getPropertyDecl() const {
1121    return PropertyDecl;
1122  }
1123
1124  Kind getPropertyImplementation() const {
1125    return PropertyIvarDecl ? Synthesize : Dynamic;
1126  }
1127
1128  ObjCIvarDecl *getPropertyIvarDecl() const {
1129    return PropertyIvarDecl;
1130  }
1131  void SetPropertyIvarDecl(ObjCIvarDecl *Ivar) {
1132    assert(PropertyIvarDecl && "PropertyIvarDecl is already defined");
1133    PropertyIvarDecl = Ivar;
1134  }
1135  void SetIvarSynthesized() {
1136    IvarKind = true;
1137  }
1138  bool IsIvarSynthesized() const {
1139    return IvarKind;
1140  }
1141
1142  static bool classof(const Decl *D) {
1143    return D->getKind() == ObjCPropertyImpl;
1144  }
1145  static bool classof(const ObjCPropertyImplDecl *D) { return true; }
1146};
1147
1148}  // end namespace clang
1149#endif
1150