Decl.h revision 583e008bbfbb937524d567ad6450b8f0e8485bca
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/AST/Type.h"
18#include "clang/Basic/SourceLocation.h"
19#include "clang/Parse/AttributeList.h"
20#include "llvm/ADT/APSInt.h"
21#include "llvm/Bitcode/SerializationFwd.h"
22
23namespace clang {
24class Decl;
25}
26
27namespace clang {
28class Expr;
29class Stmt;
30class FunctionDecl;
31class IdentifierInfo;
32
33/// Decl - This represents one declaration (or definition), e.g. a variable,
34/// typedef, function, struct, etc.
35///
36class Decl {
37public:
38  enum Kind {
39    // This lists the concrete classes of Decl in order of the inheritance
40    // hierarchy.  This allows us to do efficient classof tests based on the
41    // enums below.   The commented out names are abstract class names.
42
43    // Decl
44    //   NamedDecl
45           Field,
46             ObjcIvar,
47           ObjcCategory,
48           ObjcCategoryImpl,
49           ObjcImplementation,
50           ObjcProtocol,
51           PropertyDecl,
52    //     ScopedDecl
53             CompatibleAlias,
54    //       TypeDecl
55               ObjcInterface,
56               Typedef,
57    //         TagDecl
58                 Enum,
59    //           RecordDecl,
60                   Struct,
61                   Union,
62                   Class,
63    //       ValueDecl
64               EnumConstant,
65               Function,
66    //         VarDecl
67                 BlockVar,
68                 FileVar,
69                 ParmVar,
70         ObjcMethod,
71         ObjcClass,
72         ObjcForwardProtocol,
73
74    // For each non-leaf class, we now define a mapping to the first/last member
75    // of the class, to allow efficient classof.
76    NamedFirst  = Field,         NamedLast  = ParmVar,
77    FieldFirst  = Field,         FieldLast  = ObjcIvar,
78    ScopedFirst = CompatibleAlias, ScopedLast = ParmVar,
79    TypeFirst   = ObjcInterface, TypeLast   = Class,
80    TagFirst    = Enum         , TagLast    = Class,
81    RecordFirst = Struct       , RecordLast = Class,
82    ValueFirst  = EnumConstant , ValueLast  = ParmVar,
83    VarFirst    = BlockVar     , VarLast    = ParmVar
84  };
85
86  /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
87  /// labels, tags, members and ordinary identifiers.
88  enum IdentifierNamespace {
89    IDNS_Label,
90    IDNS_Tag,
91    IDNS_Member,
92    IDNS_Ordinary
93  };
94
95  /// ObjcDeclQualifier - Qualifier used on types in method declarations
96  /// for remote messaging. They are meant for the arguments though and
97  /// applied to the Decls (ObjcMethodDecl and ParmVarDecl).
98  enum ObjcDeclQualifier {
99    OBJC_TQ_None = 0x0,
100    OBJC_TQ_In = 0x1,
101    OBJC_TQ_Inout = 0x2,
102    OBJC_TQ_Out = 0x4,
103    OBJC_TQ_Bycopy = 0x8,
104    OBJC_TQ_Byref = 0x10,
105    OBJC_TQ_Oneway = 0x20
106  };
107
108private:
109  /// Loc - The location that this decl.
110  SourceLocation Loc;
111
112  /// DeclKind - This indicates which class this is.
113  Kind DeclKind   :  8;
114
115  /// InvalidDecl - This indicates a semantic error occurred.
116  unsigned int InvalidDecl :  1;
117
118protected:
119  Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0) {
120    if (Decl::CollectingStats()) addDeclKind(DK);
121  }
122
123  virtual ~Decl();
124
125public:
126  SourceLocation getLocation() const { return Loc; }
127  void setLocation(SourceLocation L) { Loc = L; }
128
129  Kind getKind() const { return DeclKind; }
130  const char *getDeclKindName() const;
131
132  /// setInvalidDecl - Indicates the Decl had a semantic error. This
133  /// allows for graceful error recovery.
134  void setInvalidDecl() { InvalidDecl = 1; }
135  bool isInvalidDecl() const { return (bool) InvalidDecl; }
136
137  IdentifierNamespace getIdentifierNamespace() const {
138    switch (DeclKind) {
139    default: assert(0 && "Unknown decl kind!");
140    case Typedef:
141    case Function:
142    case BlockVar:
143    case FileVar:
144    case ParmVar:
145    case EnumConstant:
146    case ObjcInterface:
147    case CompatibleAlias:
148      return IDNS_Ordinary;
149    case Struct:
150    case Union:
151    case Class:
152    case Enum:
153      return IDNS_Tag;
154    }
155  }
156  // global temp stats (until we have a per-module visitor)
157  static void addDeclKind(const Kind k);
158  static bool CollectingStats(bool enable=false);
159  static void PrintStats();
160
161  // Implement isa/cast/dyncast/etc.
162  static bool classof(const Decl *) { return true; }
163
164  /// Emit - Serialize this Decl to Bitcode.
165  void Emit(llvm::Serializer& S) const;
166
167  /// Create - Deserialize a Decl from Bitcode.
168  static Decl* Create(llvm::Deserializer& D);
169
170protected:
171  /// EmitImpl - Provides the subclass-specific serialization logic for
172  ///   serializing out a decl.
173  virtual void EmitImpl(llvm::Serializer& S) const {
174    // FIXME: This will eventually be a pure virtual function.
175    assert (false && "Not implemented.");
176  }
177
178  void EmitInRec(llvm::Serializer& S) const;
179  void ReadInRec(llvm::Deserializer& D);
180};
181
182/// NamedDecl - This represents a decl with an identifier for a name.  Many
183/// decls have names, but not ObjcMethodDecl, @class, etc.
184class NamedDecl : public Decl {
185  /// Identifier - The identifier for this declaration (e.g. the name for the
186  /// variable, the tag for a struct).
187  IdentifierInfo *Identifier;
188public:
189  NamedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
190   : Decl(DK, L), Identifier(Id) {}
191
192  IdentifierInfo *getIdentifier() const { return Identifier; }
193  const char *getName() const;
194
195  static bool classof(const Decl *D) {
196    return D->getKind() >= NamedFirst && D->getKind() <= NamedLast;
197  }
198  static bool classof(const NamedDecl *D) { return true; }
199
200protected:
201  void EmitInRec(llvm::Serializer& S) const;
202  void ReadInRec(llvm::Deserializer& D);
203};
204
205/// ScopedDecl - Represent lexically scoped names, used for all ValueDecl's
206/// and TypeDecl's.
207class ScopedDecl : public NamedDecl {
208  /// NextDeclarator - If this decl was part of a multi-declarator declaration,
209  /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
210  ScopedDecl *NextDeclarator;
211
212  /// When this decl is in scope while parsing, the Next field contains a
213  /// pointer to the shadowed decl of the same name.  When the scope is popped,
214  /// Decls are relinked onto a containing decl object.
215  ///
216  ScopedDecl *Next;
217
218protected:
219  ScopedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id,ScopedDecl *PrevDecl)
220    : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0) {}
221
222public:
223  ScopedDecl *getNext() const { return Next; }
224  void setNext(ScopedDecl *N) { Next = N; }
225
226  /// getNextDeclarator - If this decl was part of a multi-declarator
227  /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
228  /// declarator.  Otherwise it returns null.
229  ScopedDecl *getNextDeclarator() { return NextDeclarator; }
230  const ScopedDecl *getNextDeclarator() const { return NextDeclarator; }
231  void setNextDeclarator(ScopedDecl *N) { NextDeclarator = N; }
232
233  // Implement isa/cast/dyncast/etc.
234  static bool classof(const Decl *D) {
235    return D->getKind() >= ScopedFirst && D->getKind() <= ScopedLast;
236  }
237  static bool classof(const ScopedDecl *D) { return true; }
238
239protected:
240  void EmitInRec(llvm::Serializer& S) const;
241  void ReadInRec(llvm::Deserializer& D);
242
243  void EmitOutRec(llvm::Serializer& S) const;
244  void ReadOutRec(llvm::Deserializer& D);
245};
246
247/// ValueDecl - Represent the declaration of a variable (in which case it is
248/// an lvalue) a function (in which case it is a function designator) or
249/// an enum constant.
250class ValueDecl : public ScopedDecl {
251  QualType DeclType;
252
253  /// Attributes - Linked list of attributes that are attached to this
254  /// function.
255  AttributeList *Attributes;
256protected:
257  ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
258            ScopedDecl *PrevDecl, AttributeList *A = 0)
259    : ScopedDecl(DK, L, Id, PrevDecl), DeclType(T), Attributes(A) {}
260public:
261  QualType getType() const { return DeclType; }
262  void setType(QualType newType) { DeclType = newType; }
263  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
264
265  AttributeList *getAttributes() const { return Attributes; }
266
267  // Implement isa/cast/dyncast/etc.
268  static bool classof(const Decl *D) {
269    return D->getKind() >= ValueFirst && D->getKind() <= ValueLast;
270  }
271  static bool classof(const ValueDecl *D) { return true; }
272
273protected:
274  void EmitInRec(llvm::Serializer& S) const;
275  void ReadInRec(llvm::Deserializer& D);
276};
277
278/// VarDecl - An instance of this class is created to represent a variable
279/// declaration or definition.
280class VarDecl : public ValueDecl {
281public:
282  enum StorageClass {
283    None, Extern, Static, Auto, Register
284  };
285  StorageClass getStorageClass() const { return (StorageClass)SClass; }
286
287  const Expr *getInit() const { return Init; }
288  Expr *getInit() { return Init; }
289  void setInit(Expr *I) { Init = I; }
290
291  // hasAutoStorage - Returns true if either the implicit or explicit
292  //  storage class of a variable is "auto."  In particular, variables
293  //  declared within a function that lack a storage keyword are
294  //  implicitly "auto", but are represented internally with a storage
295  //  class of None.
296  bool hasAutoStorage() const {
297    return getStorageClass() == Auto ||
298          (getStorageClass() == None && getKind() != FileVar);
299  }
300
301  // hasStaticStorage - Returns true if either the implicit or
302  //  explicit storage class of a variable is "static."  In
303  //  particular, variables declared within a file (outside of a
304  //  function) that lack a storage keyword are implicitly "static,"
305  //  but are represented internally with a storage class of "None".
306  bool hasStaticStorage() const {
307    return getStorageClass() == Static ||
308          (getStorageClass() == None && getKind() == FileVar);
309  }
310
311  // hasLocalStorage - Returns true if a variable with function scope
312  //  is a non-static local variable.
313  bool hasLocalStorage() const {
314    return hasAutoStorage() || getStorageClass() == Register;
315  }
316
317  // hasGlobalStorage - Returns true for all variables that do not
318  //  have local storage.  This includs all global variables as well
319  //  as static variables declared within a function.
320  bool hasGlobalStorage() const { return !hasAutoStorage(); }
321
322  ObjcDeclQualifier getObjcDeclQualifier() const { return objcDeclQualifier; }
323  void setObjcDeclQualifier(ObjcDeclQualifier QTVal)
324    { objcDeclQualifier = QTVal; }
325
326  // Implement isa/cast/dyncast/etc.
327  static bool classof(const Decl *D) {
328    return D->getKind() >= VarFirst && D->getKind() <= VarLast;
329  }
330  static bool classof(const VarDecl *D) { return true; }
331protected:
332  VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
333          StorageClass SC, ScopedDecl *PrevDecl, AttributeList *A = 0)
334    : ValueDecl(DK, L, Id, T, PrevDecl, A), Init(0),
335      objcDeclQualifier(OBJC_TQ_None) { SClass = SC; }
336private:
337  Expr *Init;
338  // FIXME: This can be packed into the bitfields in Decl.
339  unsigned SClass : 3;
340  /// FIXME: Also can be paced into the bitfields in Decl.
341  /// in, inout, etc.
342  ObjcDeclQualifier objcDeclQualifier : 6;
343
344  friend class StmtIteratorBase;
345
346protected:
347  void EmitInRec(llvm::Serializer& S) const;
348  void ReadInRec(llvm::Deserializer& D);
349
350  void EmitOutRec(llvm::Serializer& S) const;
351  void ReadOutRec(llvm::Deserializer& D);
352
353  /// EmitImpl - Serialize this VarDecl. Called by Decl::Emit.
354  virtual void EmitImpl(llvm::Serializer& S) const;
355
356  /// ReadImpl - Deserialize this VarDecl. Called by subclasses.
357  virtual void ReadImpl(llvm::Deserializer& S);
358};
359
360/// BlockVarDecl - Represent a local variable declaration.
361class BlockVarDecl : public VarDecl {
362public:
363  BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
364               ScopedDecl *PrevDecl, AttributeList *A = 0)
365    : VarDecl(BlockVar, L, Id, T, S, PrevDecl, A) {}
366
367  // Implement isa/cast/dyncast/etc.
368  static bool classof(const Decl *D) { return D->getKind() == BlockVar; }
369  static bool classof(const BlockVarDecl *D) { return true; }
370
371protected:
372  /// CreateImpl - Deserialize a BlockVarDecl.  Called by Decl::Create.
373  static BlockVarDecl* CreateImpl(llvm::Deserializer& D);
374
375  friend Decl* Decl::Create(llvm::Deserializer& D);
376};
377
378/// FileVarDecl - Represent a file scoped variable declaration. This
379/// will allow us to reason about external variable declarations and tentative
380/// definitions (C99 6.9.2p2) using our type system (without storing a
381/// pointer to the decl's scope, which is transient).
382class FileVarDecl : public VarDecl {
383public:
384  FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
385              ScopedDecl *PrevDecl, AttributeList *A = 0)
386    : VarDecl(FileVar, L, Id, T, S, PrevDecl, A) {}
387
388  // Implement isa/cast/dyncast/etc.
389  static bool classof(const Decl *D) { return D->getKind() == FileVar; }
390  static bool classof(const FileVarDecl *D) { return true; }
391
392protected:
393  /// CreateImpl - Deserialize a FileVarDecl.  Called by Decl::Create.
394  static FileVarDecl* CreateImpl(llvm::Deserializer& D);
395
396  friend Decl* Decl::Create(llvm::Deserializer& D);
397};
398
399/// ParmVarDecl - Represent a parameter to a function.
400class ParmVarDecl : public VarDecl {
401public:
402  ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
403              ScopedDecl *PrevDecl, AttributeList *A = 0)
404    : VarDecl(ParmVar, L, Id, T, S, PrevDecl, A) {}
405
406  // Implement isa/cast/dyncast/etc.
407  static bool classof(const Decl *D) { return D->getKind() == ParmVar; }
408  static bool classof(const ParmVarDecl *D) { return true; }
409
410protected:
411  /// CreateImpl - Deserialize a ParmVarDecl.  Called by Decl::Create.
412  static ParmVarDecl* CreateImpl(llvm::Deserializer& D);
413
414  friend Decl* Decl::Create(llvm::Deserializer& D);
415};
416
417/// FunctionDecl - An instance of this class is created to represent a function
418/// declaration or definition.
419class FunctionDecl : public ValueDecl {
420public:
421  enum StorageClass {
422    None, Extern, Static
423  };
424  FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
425               StorageClass S = None, bool isInline = false,
426               ScopedDecl *PrevDecl = 0, AttributeList *Attrs = 0)
427    : ValueDecl(Function, L, Id, T, PrevDecl, Attrs),
428      ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {}
429  virtual ~FunctionDecl();
430
431  Stmt *getBody() const { return Body; }
432  void setBody(Stmt *B) { Body = B; }
433
434  ScopedDecl *getDeclChain() const { return DeclChain; }
435  void setDeclChain(ScopedDecl *D) { DeclChain = D; }
436
437  unsigned getNumParams() const;
438  const ParmVarDecl *getParamDecl(unsigned i) const {
439    assert(i < getNumParams() && "Illegal param #");
440    return ParamInfo[i];
441  }
442  ParmVarDecl *getParamDecl(unsigned i) {
443    assert(i < getNumParams() && "Illegal param #");
444    return ParamInfo[i];
445  }
446  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
447
448  QualType getResultType() const {
449    return cast<FunctionType>(getType())->getResultType();
450  }
451  StorageClass getStorageClass() const { return SClass; }
452  bool isInline() const { return IsInline; }
453
454  // Implement isa/cast/dyncast/etc.
455  static bool classof(const Decl *D) { return D->getKind() == Function; }
456  static bool classof(const FunctionDecl *D) { return true; }
457
458private:
459  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
460  /// parameters of this function.  This is null if a prototype or if there are
461  /// no formals.  TODO: we could allocate this space immediately after the
462  /// FunctionDecl object to save an allocation like FunctionType does.
463  ParmVarDecl **ParamInfo;
464
465  Stmt *Body;  // Null if a prototype.
466
467  /// DeclChain - Linked list of declarations that are defined inside this
468  /// function.
469  ScopedDecl *DeclChain;
470
471  StorageClass SClass : 2;
472  bool IsInline : 1;
473
474protected:
475  /// EmitImpl - Serialize this FunctionDecl.  Called by Decl::Emit.
476  virtual void EmitImpl(llvm::Serializer& S) const;
477
478  /// CreateImpl - Deserialize a FunctionDecl.  Called by Decl::Create.
479  static FunctionDecl* CreateImpl(llvm::Deserializer& D);
480
481  friend Decl* Decl::Create(llvm::Deserializer& D);
482};
483
484
485/// FieldDecl - An instance of this class is created by Sema::ActOnField to
486/// represent a member of a struct/union/class.
487class FieldDecl : public NamedDecl {
488  QualType DeclType;
489  Expr *BitWidth;
490public:
491  FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
492            Expr *BW = NULL)
493    : NamedDecl(Field, L, Id), DeclType(T), BitWidth(BW) {}
494  FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
495            Expr *BW = NULL)
496    : NamedDecl(DK, L, Id), DeclType(T), BitWidth(BW) {}
497
498  QualType getType() const { return DeclType; }
499  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
500
501  bool isBitField() const { return BitWidth != NULL; }
502  Expr *getBitWidth() const { return BitWidth; }
503  // Implement isa/cast/dyncast/etc.
504  static bool classof(const Decl *D) {
505    return D->getKind() >= FieldFirst && D->getKind() <= FieldLast;
506  }
507  static bool classof(const FieldDecl *D) { return true; }
508
509protected:
510  /// EmitImpl - Serialize this FieldDecl.  Called by Decl::Emit.
511  virtual void EmitImpl(llvm::Serializer& S) const;
512
513  /// CreateImpl - Deserialize a FieldDecl.  Called by Decl::Create.
514  static FieldDecl* CreateImpl(llvm::Deserializer& D);
515
516  friend Decl* Decl::Create(llvm::Deserializer& D);
517};
518
519/// EnumConstantDecl - An instance of this object exists for each enum constant
520/// that is defined.  For example, in "enum X {a,b}", each of a/b are
521/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
522/// TagType for the X EnumDecl.
523class EnumConstantDecl : public ValueDecl {
524  Expr *Init; // an integer constant expression
525  llvm::APSInt Val; // The value.
526public:
527  EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
528                   const llvm::APSInt &V, ScopedDecl *PrevDecl)
529    : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {}
530
531  const Expr *getInitExpr() const { return Init; }
532  Expr *getInitExpr() { return Init; }
533  const llvm::APSInt &getInitVal() const { return Val; }
534
535  void setInitExpr(Expr *E) { Init = E; }
536  void setInitVal(llvm::APSInt &V) { Val = V; }
537
538  // Implement isa/cast/dyncast/etc.
539  static bool classof(const Decl *D) { return D->getKind() == EnumConstant; }
540  static bool classof(const EnumConstantDecl *D) { return true; }
541
542  friend class StmtIteratorBase;
543
544protected:
545  /// EmitImpl - Serialize this EnumConstantDecl.  Called by Decl::Emit.
546  virtual void EmitImpl(llvm::Serializer& S) const;
547
548  /// CreateImpl - Deserialize a EnumConstantDecl.  Called by Decl::Create.
549  static EnumConstantDecl* CreateImpl(llvm::Deserializer& D);
550
551  friend Decl* Decl::Create(llvm::Deserializer& D);
552};
553
554
555/// TypeDecl - Represents a declaration of a type.
556///
557class TypeDecl : public ScopedDecl {
558  /// TypeForDecl - This indicates the Type object that represents this
559  /// TypeDecl.  It is a cache maintained by ASTContext::getTypedefType and
560  /// ASTContext::getTagDeclType.
561  Type *TypeForDecl;
562  friend class ASTContext;
563protected:
564  TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
565    : ScopedDecl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
566public:
567  // Implement isa/cast/dyncast/etc.
568  static bool classof(const Decl *D) {
569    return D->getKind() >= TypeFirst && D->getKind() <= TypeLast;
570  }
571  static bool classof(const TypeDecl *D) { return true; }
572};
573
574
575class TypedefDecl : public TypeDecl {
576  /// UnderlyingType - This is the type the typedef is set to.
577  QualType UnderlyingType;
578public:
579  TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PD)
580    : TypeDecl(Typedef, L, Id, PD), UnderlyingType(T) {}
581
582  QualType getUnderlyingType() const { return UnderlyingType; }
583  void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
584
585  // Implement isa/cast/dyncast/etc.
586  static bool classof(const Decl *D) { return D->getKind() == Typedef; }
587  static bool classof(const TypedefDecl *D) { return true; }
588
589protected:
590  /// EmitImpl - Serialize this TypedefDecl.  Called by Decl::Emit.
591  virtual void EmitImpl(llvm::Serializer& S) const;
592
593  /// CreateImpl - Deserialize a TypedefDecl.  Called by Decl::Create.
594  static TypedefDecl* CreateImpl(llvm::Deserializer& D);
595
596  friend Decl* Decl::Create(llvm::Deserializer& D);
597};
598
599
600/// TagDecl - Represents the declaration of a struct/union/class/enum.
601class TagDecl : public TypeDecl {
602  /// IsDefinition - True if this is a definition ("struct foo {};"), false if
603  /// it is a declaration ("struct foo;").
604  bool IsDefinition : 1;
605protected:
606  TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
607    : TypeDecl(DK, L, Id, PrevDecl) {
608    IsDefinition = false;
609  }
610public:
611
612  /// isDefinition - Return true if this decl has its body specified.
613  bool isDefinition() const {
614    return IsDefinition;
615  }
616
617  const char *getKindName() const {
618    switch (getKind()) {
619    default: assert(0 && "Unknown TagDecl!");
620    case Struct: return "struct";
621    case Union:  return "union";
622    case Class:  return "class";
623    case Enum:   return "enum";
624    }
625  }
626
627  // Implement isa/cast/dyncast/etc.
628  static bool classof(const Decl *D) {
629    return D->getKind() >= TagFirst && D->getKind() <= TagLast;
630  }
631  static bool classof(const TagDecl *D) { return true; }
632protected:
633  void setDefinition(bool V) { IsDefinition = V; }
634};
635
636/// EnumDecl - Represents an enum.  As an extension, we allow forward-declared
637/// enums.
638class EnumDecl : public TagDecl {
639  /// ElementList - this is a linked list of EnumConstantDecl's which are linked
640  /// together through their getNextDeclarator pointers.
641  EnumConstantDecl *ElementList;
642
643  /// IntegerType - This represent the integer type that the enum corresponds
644  /// to for code generation purposes.  Note that the enumerator constants may
645  /// have a different type than this does.
646  QualType IntegerType;
647public:
648  EnumDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
649    : TagDecl(Enum, L, Id, PrevDecl) {
650    ElementList = 0;
651  }
652
653  /// defineElements - When created, EnumDecl correspond to a forward declared
654  /// enum.  This method is used to mark the decl as being defined, with the
655  /// specified list of enums.
656  void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
657    assert(!isDefinition() && "Cannot redefine enums!");
658    ElementList = ListHead;
659    setDefinition(true);
660
661    IntegerType = NewType;
662  }
663
664  /// getIntegerType - Return the integer type this enum decl corresponds to.
665  /// This returns a null qualtype for an enum forward definition.
666  QualType getIntegerType() const { return IntegerType; }
667
668  /// getEnumConstantList - Return the first EnumConstantDecl in the enum.
669  ///
670  EnumConstantDecl *getEnumConstantList() { return ElementList; }
671  const EnumConstantDecl *getEnumConstantList() const { return ElementList; }
672
673  static bool classof(const Decl *D) { return D->getKind() == Enum; }
674  static bool classof(const EnumDecl *D) { return true; }
675
676protected:
677  /// EmitImpl - Serialize this EnumDecl.  Called by Decl::Emit.
678  virtual void EmitImpl(llvm::Serializer& S) const;
679
680  /// CreateImpl - Deserialize a EnumDecl.  Called by Decl::Create.
681  static EnumDecl* CreateImpl(llvm::Deserializer& D);
682
683  friend Decl* Decl::Create(llvm::Deserializer& D);
684};
685
686
687/// RecordDecl - Represents a struct/union/class.  For example:
688///   struct X;                  // Forward declaration, no "body".
689///   union Y { int A, B; };     // Has body with members A and B (FieldDecls).
690///
691class RecordDecl : public TagDecl {
692  /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
693  /// array member (e.g. int X[]) or if this union contains a struct that does.
694  /// If so, this cannot be contained in arrays or other structs as a member.
695  bool HasFlexibleArrayMember : 1;
696
697  /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
698  FieldDecl **Members;   // Null if not defined.
699  int NumMembers;   // -1 if not defined.
700public:
701  RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl*PrevDecl)
702    : TagDecl(DK, L, Id, PrevDecl) {
703    HasFlexibleArrayMember = false;
704    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
705    Members = 0;
706    NumMembers = -1;
707  }
708
709  bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
710  void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
711
712  /// getNumMembers - Return the number of members, or -1 if this is a forward
713  /// definition.
714  int getNumMembers() const { return NumMembers; }
715  const FieldDecl *getMember(unsigned i) const { return Members[i]; }
716  FieldDecl *getMember(unsigned i) { return Members[i]; }
717
718  /// defineBody - When created, RecordDecl's correspond to a forward declared
719  /// record.  This method is used to mark the decl as being defined, with the
720  /// specified contents.
721  void defineBody(FieldDecl **Members, unsigned numMembers);
722
723  /// getMember - If the member doesn't exist, or there are no members, this
724  /// function will return 0;
725  FieldDecl *getMember(IdentifierInfo *name);
726
727  static bool classof(const Decl *D) {
728    return D->getKind() >= RecordFirst && D->getKind() <= RecordLast;
729  }
730  static bool classof(const RecordDecl *D) { return true; }
731
732protected:
733  /// EmitImpl - Serialize this RecordDecl.  Called by Decl::Emit.
734  virtual void EmitImpl(llvm::Serializer& S) const;
735
736  /// CreateImpl - Deserialize a RecordDecl.  Called by Decl::Create.
737  static RecordDecl* CreateImpl(Kind DK, llvm::Deserializer& D);
738
739  friend Decl* Decl::Create(llvm::Deserializer& D);
740};
741
742}  // end namespace clang
743
744#endif
745