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