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