Decl.h revision 4473921b663539cc489435d6eae5c14df1bc4a96
1//===--- Decl.h - Classes for representing declarations ---------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the Decl interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_DECL_H
15#define LLVM_CLANG_AST_DECL_H
16
17#include "clang/Basic/SourceLocation.h"
18#include "clang/AST/Type.h"
19#include "llvm/ADT/APSInt.h"
20
21namespace clang {
22class IdentifierInfo;
23class Expr;
24class Stmt;
25class FunctionDecl;
26class ObjcMethodDecl;
27class AttributeList;
28
29
30/// Decl - This represents one declaration (or definition), e.g. a variable,
31/// typedef, function, struct, etc.
32///
33class Decl {
34public:
35  enum Kind {
36    // Concrete sub-classes of ValueDecl
37    Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
38    // Concrete sub-classes of TypeDecl
39    Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass, ObjcMethod,
40    // Concrete sub-class of Decl
41    Field, ObjcIvar
42  };
43
44  /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
45  /// labels, tags, members and ordinary identifiers.
46  enum IdentifierNamespace {
47    IDNS_Label,
48    IDNS_Tag,
49    IDNS_Member,
50    IDNS_Ordinary
51  };
52private:
53  /// DeclKind - This indicates which class this is.
54  Kind DeclKind   :  8;
55
56  /// InvalidDecl - This indicates a semantic error occurred.
57  int InvalidDecl :  1;
58
59  /// Loc - The location that this decl.
60  SourceLocation Loc;
61
62  /// Identifier - The identifier for this declaration (e.g. the name for the
63  /// variable, the tag for a struct).
64  IdentifierInfo *Identifier;
65
66  /// When this decl is in scope while parsing, the Next field contains a
67  /// pointer to the shadowed decl of the same name.  When the scope is popped,
68  /// Decls are relinked onto a containing decl object.
69  ///
70  Decl *Next;
71
72  /// NextDeclarator - If this decl was part of a multi-declarator declaration,
73  /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
74  Decl *NextDeclarator;
75
76protected:
77  Decl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *NextDecl)
78    : DeclKind(DK), InvalidDecl(0), Loc(L), Identifier(Id), Next(0),
79      NextDeclarator(NextDecl) {
80    if (Decl::CollectingStats()) addDeclKind(DK);
81  }
82  virtual ~Decl();
83
84public:
85  IdentifierInfo *getIdentifier() const { return Identifier; }
86  SourceLocation getLocation() const { return Loc; }
87  void setLocation(SourceLocation L) { Loc = L; }
88  const char *getName() const;
89
90  Kind getKind() const { return DeclKind; }
91  Decl *getNext() const { return Next; }
92  void setNext(Decl *N) { Next = N; }
93
94  /// setInvalidDecl - Indicates the Decl had a semantic error. This
95  /// allows for graceful error recovery.
96  void setInvalidDecl() { InvalidDecl = 1; }
97  int isInvalidDecl() const { return InvalidDecl; }
98
99  /// getNextDeclarator - If this decl was part of a multi-declarator
100  /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
101  /// declarator.  Otherwise it returns null.
102  Decl *getNextDeclarator() { return NextDeclarator; }
103  const Decl *getNextDeclarator() const { return NextDeclarator; }
104  void setNextDeclarator(Decl *N) { NextDeclarator = N; }
105
106  IdentifierNamespace getIdentifierNamespace() const {
107    switch (DeclKind) {
108    default: assert(0 && "Unknown decl kind!");
109    case Typedef:
110    case Function:
111    case BlockVariable:
112    case FileVariable:
113    case ParmVariable:
114    case EnumConstant:
115      return IDNS_Ordinary;
116    case Struct:
117    case Union:
118    case Class:
119    case Enum:
120      return IDNS_Tag;
121    }
122  }
123  // global temp stats (until we have a per-module visitor)
124  static void addDeclKind(const Kind k);
125  static bool CollectingStats(bool enable=false);
126  static void PrintStats();
127
128  // Implement isa/cast/dyncast/etc.
129  static bool classof(const Decl *) { return true; }
130};
131
132/// ValueDecl - Represent the declaration of a variable (in which case it is
133/// an lvalue) a function (in which case it is a function designator) or
134/// an enum constant.
135class ValueDecl : public Decl {
136  QualType DeclType;
137protected:
138  ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
139            Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), DeclType(T) {}
140public:
141  QualType getType() const { return DeclType; }
142  void setType(QualType newType) { DeclType = newType; }
143  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
144
145  // Implement isa/cast/dyncast/etc.
146  static bool classof(const Decl *D) {
147    return D->getKind() >= Function && D->getKind() <= EnumConstant;
148  }
149  static bool classof(const ValueDecl *D) { return true; }
150};
151
152/// VarDecl - An instance of this class is created to represent a variable
153/// declaration or definition.
154class VarDecl : public ValueDecl {
155public:
156  enum StorageClass {
157    None, Extern, Static, Auto, Register
158  };
159  StorageClass getStorageClass() const { return SClass; }
160
161  const Expr *getInit() const { return Init; }
162  Expr *getInit() { return Init; }
163  void setInit(Expr *I) { Init = I; }
164
165  // hasAutoStorage - Returns true if either the implicit or explicit
166  //  storage class of a variable is "auto."  In particular, variables
167  //  declared within a function that lack a storage keyword are
168  //  implicitly "auto", but are represented internally with a storage
169  //  class of None.
170  bool hasAutoStorage() {
171    return (SClass == Auto || (SClass == None && getKind() != FileVariable));
172  }
173
174  // hasStaticStorage - Returns true if either the implicit or
175  //  explicit storage class of a variable is "static."  In
176  //  particular, variables declared within a file (outside of a
177  //  function) that lack a storage keyword are implicitly "static,"
178  //  but are represented internally with a storage class of "None".
179  bool hasStaticStorage() {
180    return (SClass == Static || (SClass == None && getKind() == FileVariable));
181  }
182
183  // hasLocalStorage - Returns true if a variable with function scope
184  //  is a non-static local variable.
185  bool hasLocalStorage() { return (hasAutoStorage() || SClass == Register); }
186
187  // hasGlobalStorage - Returns true for all variables that do not
188  //  have local storage.  This includs all global variables as well
189  //  as static variables declared within a function.
190  bool hasGlobalStorage() { return !hasAutoStorage(); }
191
192  // Implement isa/cast/dyncast/etc.
193  static bool classof(const Decl *D) {
194    return D->getKind() >= BlockVariable && D->getKind() <= ParmVariable;
195  }
196  static bool classof(const VarDecl *D) { return true; }
197protected:
198  VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
199          StorageClass SC, Decl *PrevDecl)
200    : ValueDecl(DK, L, Id, T, PrevDecl), Init(0) { SClass = SC; }
201private:
202  StorageClass SClass;
203  Expr *Init;
204};
205
206/// BlockVarDecl - Represent a local variable declaration.
207class BlockVarDecl : public VarDecl {
208public:
209  BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
210               Decl *PrevDecl)
211    : VarDecl(BlockVariable, L, Id, T, S, PrevDecl) {}
212
213  // Implement isa/cast/dyncast/etc.
214  static bool classof(const Decl *D) { return D->getKind() == BlockVariable; }
215  static bool classof(const BlockVarDecl *D) { return true; }
216};
217
218/// FileVarDecl - Represent a file scoped variable declaration. This
219/// will allow us to reason about external variable declarations and tentative
220/// definitions (C99 6.9.2p2) using our type system (without storing a
221/// pointer to the decl's scope, which is transient).
222class FileVarDecl : public VarDecl {
223public:
224  FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
225              Decl *PrevDecl)
226    : VarDecl(FileVariable, L, Id, T, S, PrevDecl) {}
227
228  // Implement isa/cast/dyncast/etc.
229  static bool classof(const Decl *D) { return D->getKind() == FileVariable; }
230  static bool classof(const FileVarDecl *D) { return true; }
231};
232
233/// ParmVarDecl - Represent a parameter to a function.
234class ParmVarDecl : public VarDecl {
235public:
236  ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
237              Decl *PrevDecl)
238    : VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
239
240  // Implement isa/cast/dyncast/etc.
241  static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
242  static bool classof(const ParmVarDecl *D) { return true; }
243};
244
245/// FunctionDecl - An instance of this class is created to represent a function
246/// declaration or definition.
247class FunctionDecl : public ValueDecl {
248public:
249  enum StorageClass {
250    None, Extern, Static
251  };
252  FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
253               StorageClass S = None, bool isInline = false, Decl *PrevDecl = 0)
254    : ValueDecl(Function, L, Id, T, PrevDecl),
255      ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {}
256  virtual ~FunctionDecl();
257
258  Stmt *getBody() const { return Body; }
259  void setBody(Stmt *B) { Body = B; }
260
261  Decl *getDeclChain() const { return DeclChain; }
262  void setDeclChain(Decl *D) { DeclChain = D; }
263
264  unsigned getNumParams() const;
265  const ParmVarDecl *getParamDecl(unsigned i) const {
266    assert(i < getNumParams() && "Illegal param #");
267    return ParamInfo[i];
268  }
269  ParmVarDecl *getParamDecl(unsigned i) {
270    assert(i < getNumParams() && "Illegal param #");
271    return ParamInfo[i];
272  }
273  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
274
275  QualType getResultType() const {
276    return cast<FunctionType>(getType())->getResultType();
277  }
278  StorageClass getStorageClass() const { return SClass; }
279  bool isInline() const { return IsInline; }
280
281  // Implement isa/cast/dyncast/etc.
282  static bool classof(const Decl *D) { return D->getKind() == Function; }
283  static bool classof(const FunctionDecl *D) { return true; }
284private:
285  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
286  /// parameters of this function.  This is null if a prototype or if there are
287  /// no formals.  TODO: we could allocate this space immediately after the
288  /// FunctionDecl object to save an allocation like FunctionType does.
289  ParmVarDecl **ParamInfo;
290
291  Stmt *Body;  // Null if a prototype.
292
293  /// DeclChain - Linked list of declarations that are defined inside this
294  /// function.
295  Decl *DeclChain;
296
297  StorageClass SClass : 2;
298  bool IsInline : 1;
299};
300
301
302/// FieldDecl - An instance of this class is created by Sema::ParseField to
303/// represent a member of a struct/union/class.
304class FieldDecl : public Decl {
305  QualType DeclType;
306public:
307  FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
308    : Decl(Field, L, Id, PrevDecl), DeclType(T) {}
309  FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
310            Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), DeclType(T) {}
311
312  QualType getType() const { return DeclType; }
313  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
314
315  // Implement isa/cast/dyncast/etc.
316  static bool classof(const Decl *D) {
317    return D->getKind() == Field;
318  }
319  static bool classof(const FieldDecl *D) { return true; }
320};
321
322/// EnumConstantDecl - An instance of this object exists for each enum constant
323/// that is defined.  For example, in "enum X {a,b}", each of a/b are
324/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
325/// TagType for the X EnumDecl.
326class EnumConstantDecl : public ValueDecl {
327  Expr *Init; // an integer constant expression
328  llvm::APSInt Val; // The value.
329public:
330  EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
331                   const llvm::APSInt &V, Decl *PrevDecl)
332    : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {}
333
334  const Expr *getInitExpr() const { return Init; }
335  Expr *getInitExpr() { return Init; }
336  const llvm::APSInt &getInitVal() const { return Val; }
337
338  void setInitExpr(Expr *E) { Init = E; }
339  void setInitVal(llvm::APSInt &V) { Val = V; }
340
341  // Implement isa/cast/dyncast/etc.
342  static bool classof(const Decl *D) {
343    return D->getKind() == EnumConstant;
344  }
345  static bool classof(const EnumConstantDecl *D) { return true; }
346};
347
348
349/// TypeDecl - Represents a declaration of a type.
350///
351class TypeDecl : public Decl {
352  /// TypeForDecl - This indicates the Type object that represents this
353  /// TypeDecl.  It is a cache maintained by ASTContext::getTypedefType and
354  /// ASTContext::getTagDeclType.
355  Type *TypeForDecl;
356  friend class ASTContext;
357protected:
358  TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
359    : Decl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
360public:
361  // Implement isa/cast/dyncast/etc.
362  static bool classof(const Decl *D) {
363    return D->getKind() >= Typedef && D->getKind() <= Enum;
364  }
365  static bool classof(const TypeDecl *D) { return true; }
366};
367
368
369class TypedefDecl : public TypeDecl {
370  /// UnderlyingType - This is the type the typedef is set to.
371  QualType UnderlyingType;
372public:
373  TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
374    : TypeDecl(Typedef, L, Id, PrevDecl), UnderlyingType(T) {}
375
376  QualType getUnderlyingType() const { return UnderlyingType; }
377  void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
378
379  // Implement isa/cast/dyncast/etc.
380  static bool classof(const Decl *D) { return D->getKind() == Typedef; }
381  static bool classof(const TypedefDecl *D) { return true; }
382};
383
384
385/// TagDecl - Represents the declaration of a struct/union/class/enum.
386class TagDecl : public TypeDecl {
387  /// IsDefinition - True if this is a definition ("struct foo {};"), false if
388  /// it is a declaration ("struct foo;").
389  bool IsDefinition : 1;
390protected:
391  TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
392    : TypeDecl(DK, L, Id, PrevDecl) {
393    IsDefinition = false;
394  }
395public:
396
397  /// isDefinition - Return true if this decl has its body specified.
398  bool isDefinition() const {
399    return IsDefinition;
400  }
401
402  const char *getKindName() const {
403    switch (getKind()) {
404    default: assert(0 && "Unknown TagDecl!");
405    case Struct: return "struct";
406    case Union:  return "union";
407    case Class:  return "class";
408    case Enum:   return "enum";
409    }
410  }
411
412  // Implement isa/cast/dyncast/etc.
413  static bool classof(const Decl *D) {
414    return D->getKind() == Struct || D->getKind() == Union ||
415           D->getKind() == Class || D->getKind() == Enum;
416  }
417  static bool classof(const TagDecl *D) { return true; }
418protected:
419  void setDefinition(bool V) { IsDefinition = V; }
420};
421
422/// EnumDecl - Represents an enum.  As an extension, we allow forward-declared
423/// enums.
424class EnumDecl : public TagDecl {
425  /// ElementList - this is a linked list of EnumConstantDecl's which are linked
426  /// together through their getNextDeclarator pointers.
427  EnumConstantDecl *ElementList;
428
429  /// IntegerType - This represent the integer type that the enum corresponds
430  /// to for code generation purposes.  Note that the enumerator constants may
431  /// have a different type than this does.
432  QualType IntegerType;
433public:
434  EnumDecl(SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
435    : TagDecl(Enum, L, Id, PrevDecl) {
436    ElementList = 0;
437  }
438
439  /// defineElements - When created, EnumDecl correspond to a forward declared
440  /// enum.  This method is used to mark the decl as being defined, with the
441  /// specified list of enums.
442  void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
443    assert(!isDefinition() && "Cannot redefine enums!");
444    ElementList = ListHead;
445    setDefinition(true);
446
447    IntegerType = NewType;
448  }
449
450  /// getIntegerType - Return the integer type this enum decl corresponds to.
451  /// This returns a null qualtype for an enum forward definition.
452  QualType getIntegerType() const { return IntegerType; }
453
454  /// getEnumConstantList - Return the first EnumConstantDecl in the enum.
455  ///
456  EnumConstantDecl *getEnumConstantList() { return ElementList; }
457  const EnumConstantDecl *getEnumConstantList() const { return ElementList; }
458
459  static bool classof(const Decl *D) {
460    return D->getKind() == Enum;
461  }
462  static bool classof(const EnumDecl *D) { return true; }
463};
464
465
466/// RecordDecl - Represents a struct/union/class.
467class RecordDecl : public TagDecl {
468  /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
469  /// array member (e.g. int X[]) or if this union contains a struct that does.
470  /// If so, this cannot be contained in arrays or other structs as a member.
471  bool HasFlexibleArrayMember : 1;
472
473  /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
474  FieldDecl **Members;   // Null if not defined.
475  int NumMembers;   // -1 if not defined.
476public:
477  RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
478    : TagDecl(DK, L, Id, PrevDecl) {
479    HasFlexibleArrayMember = false;
480    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
481    Members = 0;
482    NumMembers = -1;
483  }
484
485  bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
486  void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
487
488  /// getNumMembers - Return the number of members, or -1 if this is a forward
489  /// definition.
490  int getNumMembers() const { return NumMembers; }
491  const FieldDecl *getMember(unsigned i) const { return Members[i]; }
492  FieldDecl *getMember(unsigned i) { return Members[i]; }
493
494  /// defineBody - When created, RecordDecl's correspond to a forward declared
495  /// record.  This method is used to mark the decl as being defined, with the
496  /// specified contents.
497  void defineBody(FieldDecl **Members, unsigned numMembers);
498
499  /// getMember - If the member doesn't exist, or there are no members, this
500  /// function will return 0;
501  FieldDecl *getMember(IdentifierInfo *name);
502
503  static bool classof(const Decl *D) {
504    return D->getKind() == Struct || D->getKind() == Union ||
505           D->getKind() == Class;
506  }
507  static bool classof(const RecordDecl *D) { return true; }
508};
509
510class ObjcInterfaceDecl : public TypeDecl {
511  /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
512  FieldDecl **Ivars;   // Null if not defined.
513  int NumIvars;   // -1 if not defined.
514
515  /// instance methods
516  ObjcMethodDecl **InsMethods;  // Null if not defined
517  int NumInsMethods;  // -1 if not defined
518
519  /// class methods
520  ObjcMethodDecl **ClsMethods;  // Null if not defined
521  int NumClsMethods;  // -1 if not defined
522
523  bool isForwardDecl; // declared with @class.
524public:
525  ObjcInterfaceDecl(SourceLocation L, IdentifierInfo *Id, bool FD = false)
526    : TypeDecl(ObjcInterface, L, Id, 0), Ivars(0), NumIvars(-1),
527      InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1),
528      isForwardDecl(FD) { }
529
530  void addInstanceVariable(FieldDecl ivar);
531
532  void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
533                      ObjcMethodDecl **clsMethods, unsigned numClsMembers);
534
535  static bool classof(const Decl *D) {
536    return D->getKind() == ObjcInterface;
537  }
538  static bool classof(const ObjcInterfaceDecl *D) { return true; }
539};
540
541class ObjcIvarDecl : public FieldDecl {
542public:
543  ObjcIvarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
544    : FieldDecl(ObjcIvar, L, Id, T, PrevDecl) {}
545
546  enum AccessControl {
547    None, Private, Protected, Public, Package
548  };
549  void setAccessControl(AccessControl ac) { DeclAccess = ac; }
550  AccessControl getAccessControl() const { return DeclAccess; }
551
552  // Implement isa/cast/dyncast/etc.
553  static bool classof(const Decl *D) { return D->getKind() == ObjcIvar; }
554  static bool classof(const ObjcIvarDecl *D) { return true; }
555private:
556  AccessControl DeclAccess : 3;
557};
558
559class ObjcClassDecl : public TypeDecl {
560  ObjcInterfaceDecl **ForwardDecls;   // Null if not defined.
561  int NumForwardDecls;               // -1 if not defined.
562public:
563  ObjcClassDecl(SourceLocation L, unsigned nElts)
564    : TypeDecl(ObjcClass, L, 0, 0) {
565    if (nElts) {
566      ForwardDecls = new ObjcInterfaceDecl*[nElts];
567      memset(ForwardDecls, '\0', nElts*sizeof(ObjcInterfaceDecl*));
568    }
569    NumForwardDecls = nElts;
570  }
571  void setInterfaceDecl(int idx, ObjcInterfaceDecl *OID) {
572    assert((idx < NumForwardDecls) && "index out of range");
573    ForwardDecls[idx] = OID;
574  }
575  static bool classof(const Decl *D) {
576    return D->getKind() == ObjcClass;
577  }
578  static bool classof(const ObjcClassDecl *D) { return true; }
579};
580
581/// ObjcMethodDecl - An instance of this class is created to represent an instance
582/// or class method declaration.
583class ObjcMethodDecl : public Decl {
584public:
585  ObjcMethodDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
586		 AttributeList *M = 0, bool isInstance = true,
587		 Decl *PrevDecl = 0)
588    : Decl(ObjcMethod, L, Id, PrevDecl), MethodDeclType(T), ParamInfo(0),
589      MethodAttrs(M), IsInstance(isInstance) {}
590
591  virtual ~ObjcMethodDecl();
592  QualType getMethodType() const { return MethodDeclType; }
593  unsigned getNumMethodParams() const;
594  ParmVarDecl *getMethodParamDecl(unsigned i) {
595    assert(i < getNumMethodParams() && "Illegal param #");
596    return ParamInfo[i];
597  }
598  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
599
600  AttributeList *getMethodAttrs() const {return MethodAttrs;}
601  bool isInstance() const { return IsInstance; }
602
603  // Implement isa/cast/dyncast/etc.
604  static bool classof(const Decl *D) { return D->getKind() == ObjcMethod; }
605  static bool classof(const ObjcMethodDecl *D) { return true; }
606
607private:
608  // Type of this method.
609  QualType MethodDeclType;
610  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
611  /// parameters of this Method.  This is null if there are no formals.
612  ParmVarDecl **ParamInfo;
613
614  /// List of attributes for this method declaration.
615  AttributeList *MethodAttrs;
616
617  /// instance (true) or class (false) method.
618  bool IsInstance : 1;
619};
620
621}  // end namespace clang
622#endif
623