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