Decl.h revision 5912a3544e438a92832b8c52c13f48d4f54795dc
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;
26
27
28/// Decl - This represents one declaration (or definition), e.g. a variable,
29/// typedef, function, struct, etc.
30///
31class Decl {
32public:
33  enum Kind {
34    // Concrete sub-classes of ValueDecl
35    Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
36    // Concrete sub-classes of TypeDecl
37    Typedef, Struct, Union, Class, Enum,
38    // Concrete sub-class of Decl
39    Field
40  };
41
42  /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
43  /// labels, tags, members and ordinary identifiers.
44  enum IdentifierNamespace {
45    IDNS_Label,
46    IDNS_Tag,
47    IDNS_Member,
48    IDNS_Ordinary
49  };
50private:
51  /// DeclKind - This indicates which class this is.
52  Kind DeclKind   :  8;
53
54  /// InvalidDecl - This indicates a semantic error occurred.
55  int InvalidDecl :  1;
56
57  /// Loc - The location that this decl.
58  SourceLocation Loc;
59
60  /// Identifier - The identifier for this declaration (e.g. the name for the
61  /// variable, the tag for a struct).
62  IdentifierInfo *Identifier;
63
64  /// When this decl is in scope while parsing, the Next field contains a
65  /// pointer to the shadowed decl of the same name.  When the scope is popped,
66  /// Decls are relinked onto a containing decl object.
67  ///
68  Decl *Next;
69
70  /// NextDeclarator - If this decl was part of a multi-declarator declaration,
71  /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
72  Decl *NextDeclarator;
73
74protected:
75  Decl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *NextDecl)
76    : DeclKind(DK), InvalidDecl(0), Loc(L), Identifier(Id), Next(0),
77      NextDeclarator(NextDecl) {
78    if (Decl::CollectingStats()) addDeclKind(DK);
79  }
80  virtual ~Decl();
81
82public:
83  IdentifierInfo *getIdentifier() const { return Identifier; }
84  SourceLocation getLocation() const { return Loc; }
85  void setLocation(SourceLocation L) { Loc = L; }
86  const char *getName() const;
87
88  Kind getKind() const { return DeclKind; }
89  Decl *getNext() const { return Next; }
90  void setNext(Decl *N) { Next = N; }
91
92  /// setInvalidDecl - Indicates the Decl had a semantic error. This
93  /// allows for graceful error recovery.
94  void setInvalidDecl() { InvalidDecl = 1; }
95  int isInvalidDecl() const { return InvalidDecl; }
96
97  /// getNextDeclarator - If this decl was part of a multi-declarator
98  /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
99  /// declarator.  Otherwise it returns null.
100  Decl *getNextDeclarator() { return NextDeclarator; }
101  const Decl *getNextDeclarator() const { return NextDeclarator; }
102  void setNextDeclarator(Decl *N) { NextDeclarator = N; }
103
104  IdentifierNamespace getIdentifierNamespace() const {
105    switch (DeclKind) {
106    default: assert(0 && "Unknown decl kind!");
107    case Typedef:
108    case Function:
109    case BlockVariable:
110    case FileVariable:
111    case ParmVariable:
112    case EnumConstant:
113      return IDNS_Ordinary;
114    case Struct:
115    case Union:
116    case Class:
117    case Enum:
118      return IDNS_Tag;
119    }
120  }
121  // global temp stats (until we have a per-module visitor)
122  static void addDeclKind(const Kind k);
123  static bool CollectingStats(bool enable=false);
124  static void PrintStats();
125
126  // Implement isa/cast/dyncast/etc.
127  static bool classof(const Decl *) { return true; }
128};
129
130/// ValueDecl - Represent the declaration of a variable (in which case it is
131/// an lvalue) a function (in which case it is a function designator) or
132/// an enum constant.
133class ValueDecl : public Decl {
134  QualType DeclType;
135protected:
136  ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
137            Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), DeclType(T) {}
138public:
139  QualType getType() const { return DeclType; }
140  void setType(QualType newType) { DeclType = newType; }
141  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
142
143  // Implement isa/cast/dyncast/etc.
144  static bool classof(const Decl *D) {
145    return D->getKind() >= Function && D->getKind() <= EnumConstant;
146  }
147  static bool classof(const ValueDecl *D) { return true; }
148};
149
150/// VarDecl - An instance of this class is created to represent a variable
151/// declaration or definition.
152class VarDecl : public ValueDecl {
153public:
154  enum StorageClass {
155    None, Extern, Static, Auto, Register
156  };
157  StorageClass getStorageClass() const { return SClass; }
158
159  const Expr *getInit() const { return Init; }
160  Expr *getInit() { return Init; }
161  void setInit(Expr *I) { Init = I; }
162
163  // hasAutoStorage - Returns true if either the implicit or explicit
164  //  storage class of a variable is "auto."  In particular, variables
165  //  declared within a function that lack a storage keyword are
166  //  implicitly "auto", but are represented internally with a storage
167  //  class of None.
168  bool hasAutoStorage() {
169    return (SClass == Auto || (SClass == None && getKind() != FileVariable));
170  }
171
172  // hasStaticStorage - Returns true if either the implicit or
173  //  explicit storage class of a variable is "static."  In
174  //  particular, variables declared within a file (outside of a
175  //  function) that lack a storage keyword are implicitly "static,"
176  //  but are represented internally with a storage class of "None".
177  bool hasStaticStorage() {
178    return (SClass == Static || (SClass == None && getKind() == FileVariable));
179  }
180
181  // hasLocalStorage - Returns true if a variable with function scope
182  //  is a non-static local variable.
183  bool hasLocalStorage() { return (hasAutoStorage() || SClass == Register); }
184
185  // hasGlobalStorage - Returns true for all variables that do not
186  //  have local storage.  This includs all global variables as well
187  //  as static variables declared within a function.
188  bool hasGlobalStorage() { return !hasAutoStorage(); }
189
190  // Implement isa/cast/dyncast/etc.
191  static bool classof(const Decl *D) {
192    return D->getKind() >= BlockVariable && D->getKind() <= ParmVariable;
193  }
194  static bool classof(const VarDecl *D) { return true; }
195protected:
196  VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
197          StorageClass SC, Decl *PrevDecl)
198    : ValueDecl(DK, L, Id, T, PrevDecl), Init(0) { SClass = SC; }
199private:
200  StorageClass SClass;
201  Expr *Init;
202};
203
204/// BlockVarDecl - Represent a local variable declaration.
205class BlockVarDecl : public VarDecl {
206public:
207  BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
208               Decl *PrevDecl)
209    : VarDecl(BlockVariable, L, Id, T, S, PrevDecl) {}
210
211  // Implement isa/cast/dyncast/etc.
212  static bool classof(const Decl *D) { return D->getKind() == BlockVariable; }
213  static bool classof(const BlockVarDecl *D) { return true; }
214};
215
216/// FileVarDecl - Represent a file scoped variable declaration. This
217/// will allow us to reason about external variable declarations and tentative
218/// definitions (C99 6.9.2p2) using our type system (without storing a
219/// pointer to the decl's scope, which is transient).
220class FileVarDecl : public VarDecl {
221public:
222  FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
223              Decl *PrevDecl)
224    : VarDecl(FileVariable, L, Id, T, S, PrevDecl) {}
225
226  // Implement isa/cast/dyncast/etc.
227  static bool classof(const Decl *D) { return D->getKind() == FileVariable; }
228  static bool classof(const FileVarDecl *D) { return true; }
229};
230
231/// ParmVarDecl - Represent a parameter to a function.
232class ParmVarDecl : public VarDecl {
233public:
234  ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
235              Decl *PrevDecl)
236    : VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
237
238  // Implement isa/cast/dyncast/etc.
239  static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
240  static bool classof(const ParmVarDecl *D) { return true; }
241};
242
243/// FunctionDecl - An instance of this class is created to represent a function
244/// declaration or definition.
245class FunctionDecl : public ValueDecl {
246public:
247  enum StorageClass {
248    None, Extern, Static
249  };
250  FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
251               StorageClass S = None, bool isInline = false, Decl *PrevDecl = 0)
252    : ValueDecl(Function, L, Id, T, PrevDecl),
253      ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {}
254  virtual ~FunctionDecl();
255
256  Stmt *getBody() const { return Body; }
257  void setBody(Stmt *B) { Body = B; }
258
259  Decl *getDeclChain() const { return DeclChain; }
260  void setDeclChain(Decl *D) { DeclChain = D; }
261
262  unsigned getNumParams() const;
263  const ParmVarDecl *getParamDecl(unsigned i) const {
264    assert(i < getNumParams() && "Illegal param #");
265    return ParamInfo[i];
266  }
267  ParmVarDecl *getParamDecl(unsigned i) {
268    assert(i < getNumParams() && "Illegal param #");
269    return ParamInfo[i];
270  }
271  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
272
273  QualType getResultType() const {
274    return cast<FunctionType>(getType())->getResultType();
275  }
276  StorageClass getStorageClass() const { return SClass; }
277  bool isInline() const { return IsInline; }
278
279  // Implement isa/cast/dyncast/etc.
280  static bool classof(const Decl *D) { return D->getKind() == Function; }
281  static bool classof(const FunctionDecl *D) { return true; }
282private:
283  /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
284  /// parameters of this function.  This is null if a prototype or if there are
285  /// no formals.  TODO: we could allocate this space immediately after the
286  /// FunctionDecl object to save an allocation like FunctionType does.
287  ParmVarDecl **ParamInfo;
288
289  Stmt *Body;  // Null if a prototype.
290
291  /// DeclChain - Linked list of declarations that are defined inside this
292  /// function.
293  Decl *DeclChain;
294
295  StorageClass SClass : 2;
296  bool IsInline : 1;
297};
298
299
300/// FieldDecl - An instance of this class is created by Sema::ParseField to
301/// represent a member of a struct/union/class.
302class FieldDecl : public Decl {
303  QualType DeclType;
304public:
305  FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
306    : Decl(Field, L, Id, PrevDecl), DeclType(T) {}
307
308  QualType getType() const { return DeclType; }
309  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
310
311  // Implement isa/cast/dyncast/etc.
312  static bool classof(const Decl *D) {
313    return D->getKind() == Field;
314  }
315  static bool classof(const FieldDecl *D) { return true; }
316};
317
318/// EnumConstantDecl - An instance of this object exists for each enum constant
319/// that is defined.  For example, in "enum X {a,b}", each of a/b are
320/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
321/// TagType for the X EnumDecl.
322class EnumConstantDecl : public ValueDecl {
323  Expr *Init; // an integer constant expression
324  llvm::APSInt Val; // The value.
325public:
326  EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
327                   const llvm::APSInt &V, Decl *PrevDecl)
328    : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {}
329
330  const Expr *getInitExpr() const { return Init; }
331  Expr *getInitExpr() { return Init; }
332  const llvm::APSInt &getInitVal() const { return Val; }
333
334  // Implement isa/cast/dyncast/etc.
335  static bool classof(const Decl *D) {
336    return D->getKind() == EnumConstant;
337  }
338  static bool classof(const EnumConstantDecl *D) { return true; }
339};
340
341
342/// TypeDecl - Represents a declaration of a type.
343///
344class TypeDecl : public Decl {
345  /// TypeForDecl - This indicates the Type object that represents this
346  /// TypeDecl.  It is a cache maintained by ASTContext::getTypedefType and
347  /// ASTContext::getTagDeclType.
348  Type *TypeForDecl;
349  friend class ASTContext;
350protected:
351  TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
352    : Decl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
353public:
354  // Implement isa/cast/dyncast/etc.
355  static bool classof(const Decl *D) {
356    return D->getKind() >= Typedef && D->getKind() <= Enum;
357  }
358  static bool classof(const TypeDecl *D) { return true; }
359};
360
361
362class TypedefDecl : public TypeDecl {
363  /// UnderlyingType - This is the type the typedef is set to.
364  QualType UnderlyingType;
365public:
366  TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
367    : TypeDecl(Typedef, L, Id, PrevDecl), UnderlyingType(T) {}
368
369  QualType getUnderlyingType() const { return UnderlyingType; }
370  void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
371
372  // Implement isa/cast/dyncast/etc.
373  static bool classof(const Decl *D) { return D->getKind() == Typedef; }
374  static bool classof(const TypedefDecl *D) { return true; }
375};
376
377
378/// TagDecl - Represents the declaration of a struct/union/class/enum.
379class TagDecl : public TypeDecl {
380  /// IsDefinition - True if this is a definition ("struct foo {};"), false if
381  /// it is a declaration ("struct foo;").
382  bool IsDefinition : 1;
383protected:
384  TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
385    : TypeDecl(DK, L, Id, PrevDecl) {
386    IsDefinition = false;
387  }
388public:
389
390  /// isDefinition - Return true if this decl has its body specified.
391  bool isDefinition() const {
392    return IsDefinition;
393  }
394
395  const char *getKindName() const {
396    switch (getKind()) {
397    default: assert(0 && "Unknown TagDecl!");
398    case Struct: return "struct";
399    case Union:  return "union";
400    case Class:  return "class";
401    case Enum:   return "enum";
402    }
403  }
404
405  // Implement isa/cast/dyncast/etc.
406  static bool classof(const Decl *D) {
407    return D->getKind() == Struct || D->getKind() == Union ||
408           D->getKind() == Class || D->getKind() == Enum;
409  }
410  static bool classof(const TagDecl *D) { return true; }
411protected:
412  void setDefinition(bool V) { IsDefinition = V; }
413};
414
415/// EnumDecl - Represents an enum.  As an extension, we allow forward-declared
416/// enums.
417class EnumDecl : public TagDecl {
418  /// ElementList - this is a linked list of EnumConstantDecl's which are linked
419  /// together through their getNextDeclarator pointers.
420  EnumConstantDecl *ElementList;
421
422  /// IntegerType - This represent the integer type that the enum corresponds
423  /// to for code generation purposes.  Note that the enumerator constants may
424  /// have a different type than this does.
425  QualType IntegerType;
426public:
427  EnumDecl(SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
428    : TagDecl(Enum, L, Id, PrevDecl) {
429    ElementList = 0;
430  }
431
432  /// defineElements - When created, EnumDecl correspond to a forward declared
433  /// enum.  This method is used to mark the decl as being defined, with the
434  /// specified list of enums.
435  void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
436    assert(!isDefinition() && "Cannot redefine enums!");
437    ElementList = ListHead;
438    setDefinition(true);
439
440    IntegerType = NewType;
441  }
442
443  /// getIntegerType - Return the integer type this enum decl corresponds to.
444  /// This returns a null qualtype for an enum forward definition.
445  QualType getIntegerType() const { return IntegerType; }
446
447  /// getEnumConstantList - Return the first EnumConstantDecl in the enum.
448  ///
449  EnumConstantDecl *getEnumConstantList() { return ElementList; }
450  const EnumConstantDecl *getEnumConstantList() const { return ElementList; }
451
452  static bool classof(const Decl *D) {
453    return D->getKind() == Enum;
454  }
455  static bool classof(const EnumDecl *D) { return true; }
456};
457
458
459/// RecordDecl - Represents a struct/union/class.
460class RecordDecl : public TagDecl {
461  /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
462  /// array member (e.g. int X[]) or if this union contains a struct that does.
463  /// If so, this cannot be contained in arrays or other structs as a member.
464  bool HasFlexibleArrayMember : 1;
465
466  /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
467  FieldDecl **Members;   // Null if not defined.
468  int NumMembers;   // -1 if not defined.
469public:
470  RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
471    : TagDecl(DK, L, Id, PrevDecl) {
472    HasFlexibleArrayMember = false;
473    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
474    Members = 0;
475    NumMembers = -1;
476  }
477
478  bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
479  void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
480
481  /// getNumMembers - Return the number of members, or -1 if this is a forward
482  /// definition.
483  int getNumMembers() const { return NumMembers; }
484  const FieldDecl *getMember(unsigned i) const { return Members[i]; }
485  FieldDecl *getMember(unsigned i) { return Members[i]; }
486
487  /// defineBody - When created, RecordDecl's correspond to a forward declared
488  /// record.  This method is used to mark the decl as being defined, with the
489  /// specified contents.
490  void defineBody(FieldDecl **Members, unsigned numMembers);
491
492  /// getMember - If the member doesn't exist, or there are no members, this
493  /// function will return 0;
494  FieldDecl *getMember(IdentifierInfo *name);
495
496  static bool classof(const Decl *D) {
497    return D->getKind() == Struct || D->getKind() == Union ||
498           D->getKind() == Class;
499  }
500  static bool classof(const RecordDecl *D) { return true; }
501};
502
503}  // end namespace clang
504
505#endif
506