]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/GlobalDecl.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / GlobalDecl.h
1 //===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A GlobalDecl can hold either a regular variable/function or a C++ ctor/dtor
10 // together with its type.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_AST_GLOBALDECL_H
15 #define LLVM_CLANG_AST_GLOBALDECL_H
16
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/DeclOpenMP.h"
20 #include "clang/Basic/ABI.h"
21 #include "clang/Basic/LLVM.h"
22 #include "llvm/ADT/DenseMapInfo.h"
23 #include "llvm/ADT/PointerIntPair.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/type_traits.h"
26 #include <cassert>
27
28 namespace clang {
29
30 enum class DynamicInitKind : unsigned {
31   NoStub = 0,
32   Initializer,
33   AtExit,
34 };
35
36 /// GlobalDecl - represents a global declaration. This can either be a
37 /// CXXConstructorDecl and the constructor type (Base, Complete).
38 /// a CXXDestructorDecl and the destructor type (Base, Complete) or
39 /// a VarDecl, a FunctionDecl or a BlockDecl.
40 class GlobalDecl {
41   llvm::PointerIntPair<const Decl *, 2> Value;
42   unsigned MultiVersionIndex = 0;
43
44   void Init(const Decl *D) {
45     assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!");
46     assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!");
47
48     Value.setPointer(D);
49   }
50
51 public:
52   GlobalDecl() = default;
53   GlobalDecl(const VarDecl *D) { Init(D);}
54   GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0)
55       : MultiVersionIndex(MVIndex) {
56     Init(D);
57   }
58   GlobalDecl(const BlockDecl *D) { Init(D); }
59   GlobalDecl(const CapturedDecl *D) { Init(D); }
60   GlobalDecl(const ObjCMethodDecl *D) { Init(D); }
61   GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); }
62   GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {}
63   GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {}
64   GlobalDecl(const VarDecl *D, DynamicInitKind StubKind)
65       : Value(D, unsigned(StubKind)) {}
66
67   GlobalDecl getCanonicalDecl() const {
68     GlobalDecl CanonGD;
69     CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl());
70     CanonGD.Value.setInt(Value.getInt());
71     CanonGD.MultiVersionIndex = MultiVersionIndex;
72
73     return CanonGD;
74   }
75
76   const Decl *getDecl() const { return Value.getPointer(); }
77
78   CXXCtorType getCtorType() const {
79     assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!");
80     return static_cast<CXXCtorType>(Value.getInt());
81   }
82
83   CXXDtorType getDtorType() const {
84     assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!");
85     return static_cast<CXXDtorType>(Value.getInt());
86   }
87
88   DynamicInitKind getDynamicInitKind() const {
89     assert(isa<VarDecl>(getDecl()) &&
90            cast<VarDecl>(getDecl())->hasGlobalStorage() &&
91            "Decl is not a global variable!");
92     return static_cast<DynamicInitKind>(Value.getInt());
93   }
94
95   unsigned getMultiVersionIndex() const {
96     assert(isa<FunctionDecl>(getDecl()) &&
97            !isa<CXXConstructorDecl>(getDecl()) &&
98            !isa<CXXDestructorDecl>(getDecl()) &&
99            "Decl is not a plain FunctionDecl!");
100     return MultiVersionIndex;
101   }
102
103   friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) {
104     return LHS.Value == RHS.Value &&
105            LHS.MultiVersionIndex == RHS.MultiVersionIndex;
106   }
107
108   void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
109
110   static GlobalDecl getFromOpaquePtr(void *P) {
111     GlobalDecl GD;
112     GD.Value.setFromOpaqueValue(P);
113     return GD;
114   }
115
116   GlobalDecl getWithDecl(const Decl *D) {
117     GlobalDecl Result(*this);
118     Result.Value.setPointer(D);
119     return Result;
120   }
121
122   GlobalDecl getWithCtorType(CXXCtorType Type) {
123     assert(isa<CXXConstructorDecl>(getDecl()));
124     GlobalDecl Result(*this);
125     Result.Value.setInt(Type);
126     return Result;
127   }
128
129   GlobalDecl getWithDtorType(CXXDtorType Type) {
130     assert(isa<CXXDestructorDecl>(getDecl()));
131     GlobalDecl Result(*this);
132     Result.Value.setInt(Type);
133     return Result;
134   }
135
136   GlobalDecl getWithMultiVersionIndex(unsigned Index) {
137     assert(isa<FunctionDecl>(getDecl()) &&
138            !isa<CXXConstructorDecl>(getDecl()) &&
139            !isa<CXXDestructorDecl>(getDecl()) &&
140            "Decl is not a plain FunctionDecl!");
141     GlobalDecl Result(*this);
142     Result.MultiVersionIndex = Index;
143     return Result;
144   }
145 };
146
147 } // namespace clang
148
149 namespace llvm {
150
151   template<> struct DenseMapInfo<clang::GlobalDecl> {
152     static inline clang::GlobalDecl getEmptyKey() {
153       return clang::GlobalDecl();
154     }
155
156     static inline clang::GlobalDecl getTombstoneKey() {
157       return clang::GlobalDecl::
158         getFromOpaquePtr(reinterpret_cast<void*>(-1));
159     }
160
161     static unsigned getHashValue(clang::GlobalDecl GD) {
162       return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr());
163     }
164
165     static bool isEqual(clang::GlobalDecl LHS,
166                         clang::GlobalDecl RHS) {
167       return LHS == RHS;
168     }
169   };
170
171 } // namespace llvm
172
173 #endif // LLVM_CLANG_AST_GLOBALDECL_H