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