/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/GlobalDecl.h
Line | Count | Source (jump to first uncovered line) |
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/Attr.h" |
18 | | #include "clang/AST/DeclCXX.h" |
19 | | #include "clang/AST/DeclObjC.h" |
20 | | #include "clang/AST/DeclOpenMP.h" |
21 | | #include "clang/AST/DeclTemplate.h" |
22 | | #include "clang/Basic/ABI.h" |
23 | | #include "clang/Basic/LLVM.h" |
24 | | #include "llvm/ADT/DenseMapInfo.h" |
25 | | #include "llvm/ADT/PointerIntPair.h" |
26 | | #include "llvm/Support/Casting.h" |
27 | | #include "llvm/Support/type_traits.h" |
28 | | #include <cassert> |
29 | | |
30 | | namespace clang { |
31 | | |
32 | | enum class DynamicInitKind : unsigned { |
33 | | NoStub = 0, |
34 | | Initializer, |
35 | | AtExit, |
36 | | GlobalArrayDestructor |
37 | | }; |
38 | | |
39 | | enum class KernelReferenceKind : unsigned { |
40 | | Kernel = 0, |
41 | | Stub = 1, |
42 | | }; |
43 | | |
44 | | /// GlobalDecl - represents a global declaration. This can either be a |
45 | | /// CXXConstructorDecl and the constructor type (Base, Complete). |
46 | | /// a CXXDestructorDecl and the destructor type (Base, Complete), |
47 | | /// a FunctionDecl and the kernel reference type (Kernel, Stub), or |
48 | | /// a VarDecl, a FunctionDecl or a BlockDecl. |
49 | | /// |
50 | | /// When a new type of GlobalDecl is added, the following places should |
51 | | /// be updated to convert a Decl* to a GlobalDecl: |
52 | | /// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp. |
53 | | /// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp |
54 | | /// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp |
55 | | /// |
56 | | class GlobalDecl { |
57 | | llvm::PointerIntPair<const Decl *, 3> Value; |
58 | | unsigned MultiVersionIndex = 0; |
59 | | |
60 | 30.6M | void Init(const Decl *D) { |
61 | 30.6M | assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); |
62 | 0 | assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); |
63 | 0 | assert(!D->hasAttr<CUDAGlobalAttr>() && "Use other ctor with GPU kernels!"); |
64 | | |
65 | 0 | Value.setPointer(D); |
66 | 30.6M | } |
67 | | |
68 | | public: |
69 | 39.4M | GlobalDecl() = default; |
70 | 1.96M | GlobalDecl(const VarDecl *D) { Init(D);} |
71 | | GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0) |
72 | 23.5M | : MultiVersionIndex(MVIndex) { |
73 | 23.5M | if (!D->hasAttr<CUDAGlobalAttr>()) { |
74 | 23.5M | Init(D); |
75 | 23.5M | return; |
76 | 23.5M | } |
77 | 373 | Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D))); |
78 | 373 | } |
79 | | GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind) |
80 | 196 | : Value(D, unsigned(Kind)) { |
81 | 196 | assert(D->hasAttr<CUDAGlobalAttr>() && "Decl is not a GPU kernel!"); |
82 | 196 | } |
83 | 5.06M | GlobalDecl(const NamedDecl *D) { Init(D); } |
84 | 4.74k | GlobalDecl(const BlockDecl *D) { Init(D); } |
85 | 75.0k | GlobalDecl(const CapturedDecl *D) { Init(D); } |
86 | 24.0k | GlobalDecl(const ObjCMethodDecl *D) { Init(D); } |
87 | 10 | GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } |
88 | 0 | GlobalDecl(const OMPDeclareMapperDecl *D) { Init(D); } |
89 | 502k | GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {} |
90 | 125k | GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {} |
91 | | GlobalDecl(const VarDecl *D, DynamicInitKind StubKind) |
92 | 6.42k | : Value(D, unsigned(StubKind)) {} |
93 | | |
94 | 5.40M | GlobalDecl getCanonicalDecl() const { |
95 | 5.40M | GlobalDecl CanonGD; |
96 | 5.40M | CanonGD.Value.setPointer(Value.getPointer()->getCanonicalDecl()); |
97 | 5.40M | CanonGD.Value.setInt(Value.getInt()); |
98 | 5.40M | CanonGD.MultiVersionIndex = MultiVersionIndex; |
99 | | |
100 | 5.40M | return CanonGD; |
101 | 5.40M | } |
102 | | |
103 | 80.6M | const Decl *getDecl() const { return Value.getPointer(); } |
104 | | |
105 | 421k | CXXCtorType getCtorType() const { |
106 | 421k | assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); |
107 | 0 | return static_cast<CXXCtorType>(Value.getInt()); |
108 | 421k | } |
109 | | |
110 | 300k | CXXDtorType getDtorType() const { |
111 | 300k | assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); |
112 | 0 | return static_cast<CXXDtorType>(Value.getInt()); |
113 | 300k | } |
114 | | |
115 | 1.58k | DynamicInitKind getDynamicInitKind() const { |
116 | 1.58k | assert(isa<VarDecl>(getDecl()) && |
117 | 1.58k | cast<VarDecl>(getDecl())->hasGlobalStorage() && |
118 | 1.58k | "Decl is not a global variable!"); |
119 | 0 | return static_cast<DynamicInitKind>(Value.getInt()); |
120 | 1.58k | } |
121 | | |
122 | 508 | unsigned getMultiVersionIndex() const { |
123 | 508 | assert(isa<FunctionDecl>( |
124 | 508 | getDecl()) && |
125 | 508 | !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() && |
126 | 508 | !isa<CXXConstructorDecl>(getDecl()) && |
127 | 508 | !isa<CXXDestructorDecl>(getDecl()) && |
128 | 508 | "Decl is not a plain FunctionDecl!"); |
129 | 0 | return MultiVersionIndex; |
130 | 508 | } |
131 | | |
132 | 610 | KernelReferenceKind getKernelReferenceKind() const { |
133 | 610 | assert(((isa<FunctionDecl>(getDecl()) && |
134 | 610 | cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>()) || |
135 | 610 | (isa<FunctionTemplateDecl>(getDecl()) && |
136 | 610 | cast<FunctionTemplateDecl>(getDecl()) |
137 | 610 | ->getTemplatedDecl() |
138 | 610 | ->hasAttr<CUDAGlobalAttr>())) && |
139 | 610 | "Decl is not a GPU kernel!"); |
140 | 0 | return static_cast<KernelReferenceKind>(Value.getInt()); |
141 | 610 | } |
142 | | |
143 | 103M | friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { |
144 | 103M | return LHS.Value == RHS.Value && |
145 | 103M | LHS.MultiVersionIndex == RHS.MultiVersionIndex21.8M ; |
146 | 103M | } |
147 | | |
148 | 16.8M | void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } |
149 | | |
150 | 4.94M | explicit operator bool() const { return getAsOpaquePtr(); } |
151 | | |
152 | 12.0M | static GlobalDecl getFromOpaquePtr(void *P) { |
153 | 12.0M | GlobalDecl GD; |
154 | 12.0M | GD.Value.setFromOpaqueValue(P); |
155 | 12.0M | return GD; |
156 | 12.0M | } |
157 | | |
158 | 373 | static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) { |
159 | 373 | return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel175 |
160 | 373 | : KernelReferenceKind::Stub198 ; |
161 | 373 | } |
162 | | |
163 | 5.02M | GlobalDecl getWithDecl(const Decl *D) { |
164 | 5.02M | GlobalDecl Result(*this); |
165 | 5.02M | Result.Value.setPointer(D); |
166 | 5.02M | return Result; |
167 | 5.02M | } |
168 | | |
169 | 17.8k | GlobalDecl getWithCtorType(CXXCtorType Type) { |
170 | 17.8k | assert(isa<CXXConstructorDecl>(getDecl())); |
171 | 0 | GlobalDecl Result(*this); |
172 | 17.8k | Result.Value.setInt(Type); |
173 | 17.8k | return Result; |
174 | 17.8k | } |
175 | | |
176 | 7.56k | GlobalDecl getWithDtorType(CXXDtorType Type) { |
177 | 7.56k | assert(isa<CXXDestructorDecl>(getDecl())); |
178 | 0 | GlobalDecl Result(*this); |
179 | 7.56k | Result.Value.setInt(Type); |
180 | 7.56k | return Result; |
181 | 7.56k | } |
182 | | |
183 | 136 | GlobalDecl getWithMultiVersionIndex(unsigned Index) { |
184 | 136 | assert(isa<FunctionDecl>(getDecl()) && |
185 | 136 | !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() && |
186 | 136 | !isa<CXXConstructorDecl>(getDecl()) && |
187 | 136 | !isa<CXXDestructorDecl>(getDecl()) && |
188 | 136 | "Decl is not a plain FunctionDecl!"); |
189 | 0 | GlobalDecl Result(*this); |
190 | 136 | Result.MultiVersionIndex = Index; |
191 | 136 | return Result; |
192 | 136 | } |
193 | | |
194 | 176 | GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) { |
195 | 176 | assert(isa<FunctionDecl>(getDecl()) && |
196 | 176 | cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() && |
197 | 176 | "Decl is not a GPU kernel!"); |
198 | 0 | GlobalDecl Result(*this); |
199 | 176 | Result.Value.setInt(unsigned(Kind)); |
200 | 176 | return Result; |
201 | 176 | } |
202 | | }; |
203 | | |
204 | | } // namespace clang |
205 | | |
206 | | namespace llvm { |
207 | | |
208 | | template<> struct DenseMapInfo<clang::GlobalDecl> { |
209 | 15.2M | static inline clang::GlobalDecl getEmptyKey() { |
210 | 15.2M | return clang::GlobalDecl(); |
211 | 15.2M | } |
212 | | |
213 | 12.0M | static inline clang::GlobalDecl getTombstoneKey() { |
214 | 12.0M | return clang::GlobalDecl:: |
215 | 12.0M | getFromOpaquePtr(reinterpret_cast<void*>(-1)); |
216 | 12.0M | } |
217 | | |
218 | 11.9M | static unsigned getHashValue(clang::GlobalDecl GD) { |
219 | 11.9M | return DenseMapInfo<void*>::getHashValue(GD.getAsOpaquePtr()); |
220 | 11.9M | } |
221 | | |
222 | | static bool isEqual(clang::GlobalDecl LHS, |
223 | 103M | clang::GlobalDecl RHS) { |
224 | 103M | return LHS == RHS; |
225 | 103M | } |
226 | | }; |
227 | | |
228 | | } // namespace llvm |
229 | | |
230 | | #endif // LLVM_CLANG_AST_GLOBALDECL_H |