DeclBase.h revision 0ed844b04ea4387caa4e1cf3dc375d269657536b
1//===-- DeclBase.h - Base 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 and ContextDecl interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_DECLBASE_H
15#define LLVM_CLANG_AST_DECLBASE_H
16
17#include "clang/AST/Attr.h"
18#include "clang/AST/Type.h"
19#include "clang/Basic/SourceLocation.h"
20
21namespace clang {
22class FunctionDecl;
23class ObjCMethodDecl;
24class TagDecl;
25class ObjCInterfaceDecl;
26
27/// Decl - This represents one declaration (or definition), e.g. a variable,
28/// typedef, function, struct, etc.
29///
30class Decl {
31public:
32  enum Kind {
33    // This lists the concrete classes of Decl in order of the inheritance
34    // hierarchy.  This allows us to do efficient classof tests based on the
35    // enums below.   The commented out names are abstract class names.
36
37    // Decl
38    //   NamedDecl
39           Field,
40             ObjCIvar,
41           ObjCCategory,
42           ObjCCategoryImpl,
43           ObjCImplementation,
44           ObjCProtocol,
45           PropertyDecl,
46    //     ScopedDecl
47    //       TypeDecl
48               Typedef,
49    //         TagDecl
50                 Enum,
51    //           RecordDecl
52                   Struct,
53                   Union,
54                   Class,
55    //       ValueDecl
56               EnumConstant,
57               Function,
58    //         VarDecl
59                 BlockVar,
60                 FileVar,
61                 ParmVar,
62         ObjCInterface,
63         ObjCCompatibleAlias,
64         ObjCMethod,
65         ObjCClass,
66         ObjCForwardProtocol,
67         LinkageSpec,
68   FileScopeAsm,
69
70    // For each non-leaf class, we now define a mapping to the first/last member
71    // of the class, to allow efficient classof.
72    NamedFirst  = Field,         NamedLast  = ParmVar,
73    FieldFirst  = Field,         FieldLast  = ObjCIvar,
74    ScopedFirst = Typedef,       ScopedLast = ParmVar,
75    TypeFirst   = Typedef,       TypeLast   = Class,
76    TagFirst    = Enum         , TagLast    = Class,
77    RecordFirst = Struct       , RecordLast = Class,
78    ValueFirst  = EnumConstant , ValueLast  = ParmVar,
79    VarFirst    = BlockVar     , VarLast    = ParmVar
80  };
81
82  /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
83  /// labels, tags, members and ordinary identifiers.
84  enum IdentifierNamespace {
85    IDNS_Label,
86    IDNS_Tag,
87    IDNS_Member,
88    IDNS_Ordinary
89  };
90
91  /// ObjCDeclQualifier - Qualifier used on types in method declarations
92  /// for remote messaging. They are meant for the arguments though and
93  /// applied to the Decls (ObjCMethodDecl and ParmVarDecl).
94  enum ObjCDeclQualifier {
95    OBJC_TQ_None = 0x0,
96    OBJC_TQ_In = 0x1,
97    OBJC_TQ_Inout = 0x2,
98    OBJC_TQ_Out = 0x4,
99    OBJC_TQ_Bycopy = 0x8,
100    OBJC_TQ_Byref = 0x10,
101    OBJC_TQ_Oneway = 0x20
102  };
103
104private:
105  /// Loc - The location that this decl.
106  SourceLocation Loc;
107
108  /// DeclKind - This indicates which class this is.
109  Kind DeclKind   :  8;
110
111  /// InvalidDecl - This indicates a semantic error occurred.
112  unsigned int InvalidDecl :  1;
113
114  /// HasAttrs - This indicates whether the decl has attributes or not.
115  unsigned int HasAttrs : 1;
116protected:
117  Decl(Kind DK, SourceLocation L) : Loc(L), DeclKind(DK), InvalidDecl(0),
118    HasAttrs(false) {
119    if (Decl::CollectingStats()) addDeclKind(DK);
120  }
121
122public:
123  // TODO: This should probably be made protected once derived classes have
124  // destructors.
125  virtual ~Decl();
126
127  SourceLocation getLocation() const { return Loc; }
128  void setLocation(SourceLocation L) { Loc = L; }
129
130  Kind getKind() const { return DeclKind; }
131  const char *getDeclKindName() const;
132
133  void addAttr(Attr *attr);
134  const Attr *getAttrs() const;
135
136  template<typename T> const T *getAttr() const {
137    for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
138      if (const T *V = dyn_cast<T>(attr))
139        return V;
140
141    return 0;
142  }
143
144  /// setInvalidDecl - Indicates the Decl had a semantic error. This
145  /// allows for graceful error recovery.
146  void setInvalidDecl() { InvalidDecl = 1; }
147  bool isInvalidDecl() const { return (bool) InvalidDecl; }
148
149  IdentifierNamespace getIdentifierNamespace() const {
150    switch (DeclKind) {
151    default: assert(0 && "Unknown decl kind!");
152    case Typedef:
153    case Function:
154    case BlockVar:
155    case FileVar:
156    case ParmVar:
157    case EnumConstant:
158    case ObjCInterface:
159    case ObjCCompatibleAlias:
160      return IDNS_Ordinary;
161    case Struct:
162    case Union:
163    case Class:
164    case Enum:
165      return IDNS_Tag;
166    }
167  }
168  // global temp stats (until we have a per-module visitor)
169  static void addDeclKind(Kind k);
170  static bool CollectingStats(bool Enable = false);
171  static void PrintStats();
172
173  // Implement isa/cast/dyncast/etc.
174  static bool classof(const Decl *) { return true; }
175
176  /// Emit - Serialize this Decl to Bitcode.
177  void Emit(llvm::Serializer& S) const;
178
179  /// Create - Deserialize a Decl from Bitcode.
180  static Decl* Create(llvm::Deserializer& D);
181
182protected:
183  /// EmitImpl - Provides the subclass-specific serialization logic for
184  ///   serializing out a decl.
185  virtual void EmitImpl(llvm::Serializer& S) const {
186    // FIXME: This will eventually be a pure virtual function.
187    assert (false && "Not implemented.");
188  }
189
190  void EmitInRec(llvm::Serializer& S) const;
191  void ReadInRec(llvm::Deserializer& D);
192};
193
194/// ContextDecl - This is used only as base class of specific decl types that
195/// can act as declaration contexts. These decls are:
196///
197///   FunctionDecl
198///   ObjCMethodDecl
199///   TagDecl
200///   ObjCInterfaceDecl
201///
202class ContextDecl {
203  /// DeclKind - This indicates which class this is.
204  Decl::Kind DeclKind   :  8;
205
206  // Used in the CastTo template to get the DeclKind
207  // from a Decl or a ContextDecl. ContextDecl doesn't have a getKind() method
208  // to avoid 'ambiguous access' compiler errors.
209  template<typename T> struct KindTrait {
210    static Decl::Kind getKind(const T *D) { return D->getKind(); }
211  };
212
213  // Used only by the ToDecl and FromDecl methods
214  template<typename To, typename From>
215  static To *CastTo(const From *D) {
216    Decl::Kind DK = KindTrait<From>::getKind(D);
217    switch(DK) {
218      case Decl::Function:
219        return static_cast<FunctionDecl*>(const_cast<From*>(D));
220      case Decl::ObjCMethod:
221        return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
222      case Decl::ObjCInterface:
223        return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
224      default:
225        // check for TagDecl
226        if (DK >= Decl::TagFirst && DK <= Decl::TagLast)
227          return static_cast<TagDecl*>(const_cast<From*>(D));
228
229        assert(false && "a decl that inherits ContextDecl isn't handled");
230        return 0;
231    }
232  }
233
234protected:
235  ContextDecl(Decl::Kind K) : DeclKind(K) {}
236
237public:
238  /// getParent - Returns the containing ContextDecl if this is a ScopedDecl,
239  /// else returns NULL.
240  ContextDecl *getParent() const;
241
242  bool isFunctionOrMethod() const {
243    switch (DeclKind) {
244      case Decl::Function:
245      case Decl::ObjCMethod:
246        return true;
247      default:
248        return false;
249    }
250  }
251
252  /// ToDecl and FromDecl make Decl <-> ContextDecl castings.
253  /// They are intended to be used by the simplify_type and cast_convert_val
254  /// templates.
255  static Decl        *ToDecl   (const ContextDecl *D);
256  static ContextDecl *FromDecl (const Decl *D);
257
258  static bool classof(const Decl *D) {
259    switch (D->getKind()) {
260      case Decl::Function:
261      case Decl::ObjCMethod:
262      case Decl::ObjCInterface:
263        return true;
264      default:
265        // check for TagDecl
266        return D->getKind() >= Decl::TagFirst &&
267               D->getKind() <= Decl::TagLast;
268    }
269  }
270  static bool classof(const ContextDecl *D) { return true; }
271  static bool classof(const FunctionDecl *D) { return true; }
272  static bool classof(const ObjCMethodDecl *D) { return true; }
273  static bool classof(const TagDecl *D) { return true; }
274  static bool classof(const ObjCInterfaceDecl *D) { return true; }
275};
276
277template<> struct ContextDecl::KindTrait<ContextDecl> {
278  static Decl::Kind getKind(const ContextDecl *D) { return D->DeclKind; }
279};
280
281} // end clang.
282
283namespace llvm {
284/// Implement simplify_type for ContextDecl, so that we can dyn_cast from
285/// ContextDecl to a specific Decl class.
286  template<> struct simplify_type<const ::clang::ContextDecl*> {
287  typedef ::clang::Decl* SimpleType;
288  static SimpleType getSimplifiedValue(const ::clang::ContextDecl *Val) {
289    return ::clang::ContextDecl::ToDecl(Val);
290  }
291};
292template<> struct simplify_type< ::clang::ContextDecl*>
293  : public simplify_type<const ::clang::ContextDecl*> {};
294
295template<> struct simplify_type<const ::clang::ContextDecl> {
296  typedef ::clang::Decl SimpleType;
297  static SimpleType &getSimplifiedValue(const ::clang::ContextDecl &Val) {
298    return *::clang::ContextDecl::ToDecl(&Val);
299  }
300};
301template<> struct simplify_type< ::clang::ContextDecl>
302  : public simplify_type<const ::clang::ContextDecl> {};
303
304/// Implement cast_convert_val for ContextDecl, so that we can dyn_cast from
305/// a Decl class to ContextDecl.
306template<class FromTy>
307struct cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy> {
308  static ::clang::ContextDecl &doit(const FromTy &Val) {
309    return *::clang::ContextDecl::FromDecl(&Val);
310  }
311};
312template<class FromTy>
313struct cast_convert_val< ::clang::ContextDecl,FromTy,FromTy>
314  : public cast_convert_val< ::clang::ContextDecl,const FromTy,const FromTy>
315    {};
316
317template<class FromTy>
318struct cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*> {
319  static ::clang::ContextDecl *doit(const FromTy *Val) {
320    return ::clang::ContextDecl::FromDecl(Val);
321  }
322};
323template<class FromTy>
324struct cast_convert_val< ::clang::ContextDecl,FromTy*,FromTy*>
325  : public cast_convert_val< ::clang::ContextDecl,const FromTy*,const FromTy*>
326    {};
327
328} // end namespace llvm
329
330#endif
331