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