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