Decl.h revision 8f3fde00ad4d4f943321e338b914ae4740711c84
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  /// DeclKind - This indicates which class this is.
58  Kind DeclKind   :  8;
59
60  /// InvalidDecl - This indicates a semantic error occurred.
61  unsigned int InvalidDecl :  1;
62
63protected:
64  Decl(Kind DK) : DeclKind(DK), InvalidDecl(0) {
65    if (Decl::CollectingStats()) addDeclKind(DK);
66  }
67
68  virtual ~Decl();
69
70public:
71
72  Kind getKind() const { return DeclKind; }
73  const char *getDeclKindName() const;
74
75  /// setInvalidDecl - Indicates the Decl had a semantic error. This
76  /// allows for graceful error recovery.
77  void setInvalidDecl() { InvalidDecl = 1; }
78  int isInvalidDecl() const { return InvalidDecl; }
79
80  IdentifierNamespace getIdentifierNamespace() const {
81    switch (DeclKind) {
82    default: assert(0 && "Unknown decl kind!");
83    case Typedef:
84    case Function:
85    case BlockVariable:
86    case FileVariable:
87    case ParmVariable:
88    case EnumConstant:
89    case ObjcInterface:
90      return IDNS_Ordinary;
91    case Struct:
92    case Union:
93    case Class:
94    case Enum:
95      return IDNS_Tag;
96    case ObjcProtocol:
97      return IDNS_Protocol;
98    }
99  }
100  // global temp stats (until we have a per-module visitor)
101  static void addDeclKind(const Kind k);
102  static bool CollectingStats(bool enable=false);
103  static void PrintStats();
104
105  // Implement isa/cast/dyncast/etc.
106  static bool classof(const Decl *) { return true; }
107};
108
109/// ScopedDecl - Represent lexically scoped names, used for all ValueDecl's
110/// and TypeDecl's.
111class ScopedDecl : public Decl {
112  /// Identifier - The identifier for this declaration (e.g. the name for the
113  /// variable, the tag for a struct).
114  IdentifierInfo *Identifier;
115
116  /// Loc - The location that this decl.
117  SourceLocation Loc;
118
119  /// NextDeclarator - If this decl was part of a multi-declarator declaration,
120  /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
121  ScopedDecl *NextDeclarator;
122
123  /// When this decl is in scope while parsing, the Next field contains a
124  /// pointer to the shadowed decl of the same name.  When the scope is popped,
125  /// Decls are relinked onto a containing decl object.
126  ///
127  ScopedDecl *Next;
128protected:
129  ScopedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
130    : Decl(DK), Identifier(Id), Loc(L), NextDeclarator(PrevDecl), Next(0) {}
131public:
132  IdentifierInfo *getIdentifier() const { return Identifier; }
133  SourceLocation getLocation() const { return Loc; }
134  void setLocation(SourceLocation L) { Loc = L; }
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  /// Loc - The location that this decl.
334  SourceLocation Loc;
335
336  QualType DeclType;
337public:
338  FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T)
339    : Decl(Field), Identifier(Id), Loc(L), DeclType(T) {}
340  FieldDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T)
341    : Decl(DK), Identifier(Id), Loc(L), DeclType(T) {}
342
343  IdentifierInfo *getIdentifier() const { return Identifier; }
344  SourceLocation getLocation() const { return Loc; }
345  void setLocation(SourceLocation L) { Loc = L; }
346  const char *getName() const;
347
348  QualType getType() const { return DeclType; }
349  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
350
351  // Implement isa/cast/dyncast/etc.
352  static bool classof(const Decl *D) {
353    return D->getKind() == Field || D->getKind() == ObjcIvar;
354  }
355  static bool classof(const FieldDecl *D) { return true; }
356};
357
358/// EnumConstantDecl - An instance of this object exists for each enum constant
359/// that is defined.  For example, in "enum X {a,b}", each of a/b are
360/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
361/// TagType for the X EnumDecl.
362class EnumConstantDecl : public ValueDecl {
363  Expr *Init; // an integer constant expression
364  llvm::APSInt Val; // The value.
365public:
366  EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
367                   const llvm::APSInt &V, ScopedDecl *PrevDecl)
368    : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {}
369
370  const Expr *getInitExpr() const { return Init; }
371  Expr *getInitExpr() { return Init; }
372  const llvm::APSInt &getInitVal() const { return Val; }
373
374  void setInitExpr(Expr *E) { Init = E; }
375  void setInitVal(llvm::APSInt &V) { Val = V; }
376
377  // Implement isa/cast/dyncast/etc.
378  static bool classof(const Decl *D) {
379    return D->getKind() == EnumConstant;
380  }
381  static bool classof(const EnumConstantDecl *D) { return true; }
382};
383
384
385/// TypeDecl - Represents a declaration of a type.
386///
387class TypeDecl : public ScopedDecl {
388  /// TypeForDecl - This indicates the Type object that represents this
389  /// TypeDecl.  It is a cache maintained by ASTContext::getTypedefType and
390  /// ASTContext::getTagDeclType.
391  Type *TypeForDecl;
392  friend class ASTContext;
393protected:
394  TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
395    : ScopedDecl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
396public:
397  // Implement isa/cast/dyncast/etc.
398  static bool classof(const Decl *D) {
399    return D->getKind() >= Typedef && D->getKind() <= Enum;
400  }
401  static bool classof(const TypeDecl *D) { return true; }
402};
403
404
405class TypedefDecl : public TypeDecl {
406  /// UnderlyingType - This is the type the typedef is set to.
407  QualType UnderlyingType;
408public:
409  TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, ScopedDecl *PD)
410    : TypeDecl(Typedef, L, Id, PD), UnderlyingType(T) {}
411
412  QualType getUnderlyingType() const { return UnderlyingType; }
413  void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
414
415  // Implement isa/cast/dyncast/etc.
416  static bool classof(const Decl *D) { return D->getKind() == Typedef; }
417  static bool classof(const TypedefDecl *D) { return true; }
418};
419
420
421/// TagDecl - Represents the declaration of a struct/union/class/enum.
422class TagDecl : public TypeDecl {
423  /// IsDefinition - True if this is a definition ("struct foo {};"), false if
424  /// it is a declaration ("struct foo;").
425  bool IsDefinition : 1;
426protected:
427  TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
428    : TypeDecl(DK, L, Id, PrevDecl) {
429    IsDefinition = false;
430  }
431public:
432
433  /// isDefinition - Return true if this decl has its body specified.
434  bool isDefinition() const {
435    return IsDefinition;
436  }
437
438  const char *getKindName() const {
439    switch (getKind()) {
440    default: assert(0 && "Unknown TagDecl!");
441    case Struct: return "struct";
442    case Union:  return "union";
443    case Class:  return "class";
444    case Enum:   return "enum";
445    }
446  }
447
448  // Implement isa/cast/dyncast/etc.
449  static bool classof(const Decl *D) {
450    return D->getKind() == Struct || D->getKind() == Union ||
451           D->getKind() == Class || D->getKind() == Enum;
452  }
453  static bool classof(const TagDecl *D) { return true; }
454protected:
455  void setDefinition(bool V) { IsDefinition = V; }
456};
457
458/// EnumDecl - Represents an enum.  As an extension, we allow forward-declared
459/// enums.
460class EnumDecl : public TagDecl {
461  /// ElementList - this is a linked list of EnumConstantDecl's which are linked
462  /// together through their getNextDeclarator pointers.
463  EnumConstantDecl *ElementList;
464
465  /// IntegerType - This represent the integer type that the enum corresponds
466  /// to for code generation purposes.  Note that the enumerator constants may
467  /// have a different type than this does.
468  QualType IntegerType;
469public:
470  EnumDecl(SourceLocation L, IdentifierInfo *Id, ScopedDecl *PrevDecl)
471    : TagDecl(Enum, L, Id, PrevDecl) {
472    ElementList = 0;
473  }
474
475  /// defineElements - When created, EnumDecl correspond to a forward declared
476  /// enum.  This method is used to mark the decl as being defined, with the
477  /// specified list of enums.
478  void defineElements(EnumConstantDecl *ListHead, QualType NewType) {
479    assert(!isDefinition() && "Cannot redefine enums!");
480    ElementList = ListHead;
481    setDefinition(true);
482
483    IntegerType = NewType;
484  }
485
486  /// getIntegerType - Return the integer type this enum decl corresponds to.
487  /// This returns a null qualtype for an enum forward definition.
488  QualType getIntegerType() const { return IntegerType; }
489
490  /// getEnumConstantList - Return the first EnumConstantDecl in the enum.
491  ///
492  EnumConstantDecl *getEnumConstantList() { return ElementList; }
493  const EnumConstantDecl *getEnumConstantList() const { return ElementList; }
494
495  static bool classof(const Decl *D) {
496    return D->getKind() == Enum;
497  }
498  static bool classof(const EnumDecl *D) { return true; }
499};
500
501
502/// RecordDecl - Represents a struct/union/class.  For example:
503///   struct X;                  // Forward declaration, no "body".
504///   union Y { int A, B; };     // Has body with members A and B (FieldDecls).
505///
506class RecordDecl : public TagDecl {
507  /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
508  /// array member (e.g. int X[]) or if this union contains a struct that does.
509  /// If so, this cannot be contained in arrays or other structs as a member.
510  bool HasFlexibleArrayMember : 1;
511
512  /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
513  FieldDecl **Members;   // Null if not defined.
514  int NumMembers;   // -1 if not defined.
515public:
516  RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, ScopedDecl*PrevDecl)
517    : TagDecl(DK, L, Id, PrevDecl) {
518    HasFlexibleArrayMember = false;
519    assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
520    Members = 0;
521    NumMembers = -1;
522  }
523
524  bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
525  void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
526
527  /// getNumMembers - Return the number of members, or -1 if this is a forward
528  /// definition.
529  int getNumMembers() const { return NumMembers; }
530  const FieldDecl *getMember(unsigned i) const { return Members[i]; }
531  FieldDecl *getMember(unsigned i) { return Members[i]; }
532
533  /// defineBody - When created, RecordDecl's correspond to a forward declared
534  /// record.  This method is used to mark the decl as being defined, with the
535  /// specified contents.
536  void defineBody(FieldDecl **Members, unsigned numMembers);
537
538  /// getMember - If the member doesn't exist, or there are no members, this
539  /// function will return 0;
540  FieldDecl *getMember(IdentifierInfo *name);
541
542  static bool classof(const Decl *D) {
543    return D->getKind() == Struct || D->getKind() == Union ||
544           D->getKind() == Class;
545  }
546  static bool classof(const RecordDecl *D) { return true; }
547};
548
549}  // end namespace clang
550#endif
551