DeclBase.h revision 1bb19638f2ec0d63ed131b51ca8d9542d1a9afee
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 DeclContext 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 EnumDecl;
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           ObjCProperty,
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
122  virtual ~Decl();
123
124public:
125  SourceLocation getLocation() const { return Loc; }
126  void setLocation(SourceLocation L) { Loc = L; }
127
128  Kind getKind() const { return DeclKind; }
129  const char *getDeclKindName() const;
130
131  void addAttr(Attr *attr);
132  const Attr *getAttrs() const;
133
134  template<typename T> const T *getAttr() const {
135    for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
136      if (const T *V = dyn_cast<T>(attr))
137        return V;
138
139    return 0;
140  }
141
142  /// setInvalidDecl - Indicates the Decl had a semantic error. This
143  /// allows for graceful error recovery.
144  void setInvalidDecl() { InvalidDecl = 1; }
145  bool isInvalidDecl() const { return (bool) InvalidDecl; }
146
147  IdentifierNamespace getIdentifierNamespace() const {
148    switch (DeclKind) {
149    default: assert(0 && "Unknown decl kind!");
150    case Typedef:
151    case Function:
152    case BlockVar:
153    case FileVar:
154    case ParmVar:
155    case EnumConstant:
156    case ObjCInterface:
157    case ObjCCompatibleAlias:
158      return IDNS_Ordinary;
159    case Struct:
160    case Union:
161    case Class:
162    case Enum:
163      return IDNS_Tag;
164    }
165  }
166  // global temp stats (until we have a per-module visitor)
167  static void addDeclKind(Kind k);
168  static bool CollectingStats(bool Enable = false);
169  static void PrintStats();
170
171  // Implement isa/cast/dyncast/etc.
172  static bool classof(const Decl *) { return true; }
173
174  /// Emit - Serialize this Decl to Bitcode.
175  void Emit(llvm::Serializer& S) const;
176
177  /// Create - Deserialize a Decl from Bitcode.
178  static Decl* Create(llvm::Deserializer& D, ASTContext& C);
179
180  /// Destroy - Call destructors and release memory.
181  void Destroy(ASTContext& C) const;
182
183protected:
184  /// EmitImpl - Provides the subclass-specific serialization logic for
185  ///   serializing out a decl.
186  virtual void EmitImpl(llvm::Serializer& S) const {
187    // FIXME: This will eventually be a pure virtual function.
188    assert (false && "Not implemented.");
189  }
190
191  void EmitInRec(llvm::Serializer& S) const;
192  void ReadInRec(llvm::Deserializer& D, ASTContext& C);
193};
194
195/// DeclContext - This is used only as base class of specific decl types that
196/// can act as declaration contexts. These decls are:
197///
198///   FunctionDecl
199///   ObjCMethodDecl
200///   EnumDecl
201///   ObjCInterfaceDecl
202///
203class DeclContext {
204  /// DeclKind - This indicates which class this is.
205  Decl::Kind DeclKind   :  8;
206
207  // Used in the CastTo template to get the DeclKind
208  // from a Decl or a DeclContext. DeclContext doesn't have a getKind() method
209  // to avoid 'ambiguous access' compiler errors.
210  template<typename T> struct KindTrait {
211    static Decl::Kind getKind(const T *D) { return D->getKind(); }
212  };
213
214  // Used only by the ToDecl and FromDecl methods
215  template<typename To, typename From>
216  static To *CastTo(const From *D) {
217    Decl::Kind DK = KindTrait<From>::getKind(D);
218    switch(DK) {
219      case Decl::Function:
220        return static_cast<FunctionDecl*>(const_cast<From*>(D));
221      case Decl::ObjCMethod:
222        return static_cast<ObjCMethodDecl*>(const_cast<From*>(D));
223      case Decl::ObjCInterface:
224        return static_cast<ObjCInterfaceDecl*>(const_cast<From*>(D));
225      case Decl::Enum:
226        return static_cast<EnumDecl*>(const_cast<From*>(D));
227      default:
228        assert(false && "a decl that inherits DeclContext isn't handled");
229        return 0;
230    }
231  }
232
233protected:
234  DeclContext(Decl::Kind K) : DeclKind(K) {}
235
236public:
237  /// getParent - Returns the containing DeclContext if this is a ScopedDecl,
238  /// else returns NULL.
239  DeclContext *getParent() const;
240
241  bool isFunctionOrMethod() const {
242    switch (DeclKind) {
243      case Decl::Function:
244      case Decl::ObjCMethod:
245        return true;
246      default:
247        return false;
248    }
249  }
250
251  /// ToDecl and FromDecl make Decl <-> DeclContext castings.
252  /// They are intended to be used by the simplify_type and cast_convert_val
253  /// templates.
254  static Decl        *ToDecl   (const DeclContext *D);
255  static DeclContext *FromDecl (const Decl *D);
256
257  static bool classof(const Decl *D) {
258    switch (D->getKind()) {
259      case Decl::Function:
260      case Decl::ObjCMethod:
261      case Decl::ObjCInterface:
262      case Decl::Enum:
263        return true;
264      default:
265        return false;
266    }
267  }
268  static bool classof(const DeclContext *D) { return true; }
269  static bool classof(const FunctionDecl *D) { return true; }
270  static bool classof(const ObjCMethodDecl *D) { return true; }
271  static bool classof(const EnumDecl *D) { return true; }
272  static bool classof(const ObjCInterfaceDecl *D) { return true; }
273};
274
275template<> struct DeclContext::KindTrait<DeclContext> {
276  static Decl::Kind getKind(const DeclContext *D) { return D->DeclKind; }
277};
278
279} // end clang.
280
281namespace llvm {
282/// Implement simplify_type for DeclContext, so that we can dyn_cast from
283/// DeclContext to a specific Decl class.
284  template<> struct simplify_type<const ::clang::DeclContext*> {
285  typedef ::clang::Decl* SimpleType;
286  static SimpleType getSimplifiedValue(const ::clang::DeclContext *Val) {
287    return ::clang::DeclContext::ToDecl(Val);
288  }
289};
290template<> struct simplify_type< ::clang::DeclContext*>
291  : public simplify_type<const ::clang::DeclContext*> {};
292
293template<> struct simplify_type<const ::clang::DeclContext> {
294  typedef ::clang::Decl SimpleType;
295  static SimpleType &getSimplifiedValue(const ::clang::DeclContext &Val) {
296    return *::clang::DeclContext::ToDecl(&Val);
297  }
298};
299template<> struct simplify_type< ::clang::DeclContext>
300  : public simplify_type<const ::clang::DeclContext> {};
301
302/// Implement cast_convert_val for DeclContext, so that we can dyn_cast from
303/// a Decl class to DeclContext.
304template<class FromTy>
305struct cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy> {
306  static ::clang::DeclContext &doit(const FromTy &Val) {
307    return *::clang::DeclContext::FromDecl(&Val);
308  }
309};
310template<class FromTy>
311struct cast_convert_val< ::clang::DeclContext,FromTy,FromTy>
312  : public cast_convert_val< ::clang::DeclContext,const FromTy,const FromTy>
313    {};
314
315template<class FromTy>
316struct cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*> {
317  static ::clang::DeclContext *doit(const FromTy *Val) {
318    return ::clang::DeclContext::FromDecl(Val);
319  }
320};
321template<class FromTy>
322struct cast_convert_val< ::clang::DeclContext,FromTy*,FromTy*>
323  : public cast_convert_val< ::clang::DeclContext,const FromTy*,const FromTy*>
324    {};
325
326} // end namespace llvm
327
328#endif
329