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