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