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