]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h
MFV r318929: 7786 zfs`vdev_online() needs better notification about state changes
[FreeBSD/FreeBSD.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/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
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:
40   GlobalDecl() {}
41
42   GlobalDecl(const VarDecl *D) { Init(D);}
43   GlobalDecl(const FunctionDecl *D) { Init(D); }
44   GlobalDecl(const BlockDecl *D) { Init(D); }
45   GlobalDecl(const CapturedDecl *D) { Init(D); }
46   GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
47   GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
48
49   GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type)
50   : Value(D, Type) {}
51   GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type)
52   : Value(D, Type) {}
53
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
62   const Decl *getDecl() const { return Value.getPointer(); }
63
64   CXXCtorType getCtorType() const {
65     assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
66     return static_cast<CXXCtorType>(Value.getInt());
67   }
68
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   
78   void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
79
80   static GlobalDecl getFromOpaquePtr(void *P) {
81     GlobalDecl GD;
82     GD.Value.setFromOpaqueValue(P);
83     return GD;
84   }
85   
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