• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- GlobalDecl.h - Global declaration holder ---------------*- 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 // A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
11 // together with its type.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_AST_GLOBALDECL_H
16 #define LLVM_CLANG_AST_GLOBALDECL_H
17 
18 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/DeclObjC.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/Basic/ABI.h"
22 
23 namespace clang {
24 
25 /// GlobalDecl - represents a global declaration. This can either be a
26 /// CXXConstructorDecl and the constructor type (Base, Complete).
27 /// a CXXDestructorDecl and the destructor type (Base, Complete) or
28 /// a VarDecl, a FunctionDecl or a BlockDecl.
29 class GlobalDecl {
30   llvm::PointerIntPair<const Decl*, 2> Value;
31 
Init(const Decl * D)32   void Init(const Decl *D) {
33     assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
34     assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
35 
36     Value.setPointer(D);
37   }
38 
39 public:
GlobalDecl()40   GlobalDecl() {}
41 
GlobalDecl(const VarDecl * D)42   GlobalDecl(const VarDecl *D) { Init(D);}
GlobalDecl(const FunctionDecl * D)43   GlobalDecl(const FunctionDecl *D) { Init(D); }
GlobalDecl(const BlockDecl * D)44   GlobalDecl(const BlockDecl *D) { Init(D); }
GlobalDecl(const CapturedDecl * D)45   GlobalDecl(const CapturedDecl *D) { Init(D); }
GlobalDecl(const ObjCMethodDecl * D)46   GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
GlobalDecl(const OMPDeclareReductionDecl * D)47   GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
48 
GlobalDecl(const CXXConstructorDecl * D,CXXCtorType Type)49   GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
50   : Value(D, Type) {}
GlobalDecl(const CXXDestructorDecl * D,CXXDtorType Type)51   GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
52   : Value(D, Type) {}
53 
getCanonicalDecl()54   GlobalDecl getCanonicalDecl() const {
55     GlobalDecl CanonGD;
56     CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
57     CanonGD.Value.setInt(Value.getInt());
58 
59     return CanonGD;
60   }
61 
getDecl()62   const Decl *getDecl() const { return Value.getPointer(); }
63 
getCtorType()64   CXXCtorType getCtorType() const {
65     assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
66     return static_cast<CXXCtorType>(Value.getInt());
67   }
68 
getDtorType()69   CXXDtorType getDtorType() const {
70     assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
71     return static_cast<CXXDtorType>(Value.getInt());
72   }
73 
74   friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
75     return LHS.Value == RHS.Value;
76   }
77 
getAsOpaquePtr()78   void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
79 
getFromOpaquePtr(void * P)80   static GlobalDecl getFromOpaquePtr(void *P) {
81     GlobalDecl GD;
82     GD.Value.setFromOpaqueValue(P);
83     return GD;
84   }
85 
getWithDecl(const Decl * D)86   GlobalDecl getWithDecl(const Decl *D) {
87     GlobalDecl Result(*this);
88     Result.Value.setPointer(D);
89     return Result;
90   }
91 };
92 
93 } // end namespace clang
94 
95 namespace llvm {
96   template<class> struct DenseMapInfo;
97 
98   template<> struct DenseMapInfo<clang::GlobalDecl> {
99     static inline clang::GlobalDecl getEmptyKey() {
100       return clang::GlobalDecl();
101     }
102 
103     static inline clang::GlobalDecl getTombstoneKey() {
104       return clang::GlobalDecl::
105         getFromOpaquePtr(reinterpret_cast<void*>(-1));
106     }
107 
108     static unsigned getHashValue(clang::GlobalDecl GD) {
109       return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
110     }
111 
112     static bool isEqual(clang::GlobalDecl LHS,
113                         clang::GlobalDecl RHS) {
114       return LHS == RHS;
115     }
116 
117   };
118 
119   // GlobalDecl isn't *technically* a POD type. However, its copy constructor,
120   // copy assignment operator, and destructor are all trivial.
121   template <>
122   struct isPodLike<clang::GlobalDecl> {
123     static const bool value = true;
124   };
125 } // end namespace llvm
126 
127 #endif
128