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