/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/IR/ValueHandle.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- ValueHandle.h - Value Smart Pointer classes --------------*- 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 | | // This file declares the ValueHandle class and its sub-classes. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_IR_VALUEHANDLE_H |
15 | | #define LLVM_IR_VALUEHANDLE_H |
16 | | |
17 | | #include "llvm/ADT/DenseMapInfo.h" |
18 | | #include "llvm/ADT/PointerIntPair.h" |
19 | | #include "llvm/IR/Value.h" |
20 | | #include "llvm/Support/Casting.h" |
21 | | #include <cassert> |
22 | | |
23 | | namespace llvm { |
24 | | |
25 | | /// \brief This is the common base class of value handles. |
26 | | /// |
27 | | /// ValueHandle's are smart pointers to Value's that have special behavior when |
28 | | /// the value is deleted or ReplaceAllUsesWith'd. See the specific handles |
29 | | /// below for details. |
30 | | class ValueHandleBase { |
31 | | friend class Value; |
32 | | |
33 | | protected: |
34 | | /// \brief This indicates what sub class the handle actually is. |
35 | | /// |
36 | | /// This is to avoid having a vtable for the light-weight handle pointers. The |
37 | | /// fully general Callback version does have a vtable. |
38 | | enum HandleBaseKind { Assert, Callback, Weak, WeakTracking }; |
39 | | |
40 | | ValueHandleBase(const ValueHandleBase &RHS) |
41 | 486M | : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {} |
42 | | |
43 | | ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) |
44 | 566M | : PrevPair(nullptr, Kind), Val(RHS.getValPtr()) { |
45 | 566M | if (isValid(getValPtr())) |
46 | 92.0M | AddToExistingUseList(RHS.getPrevPtr()); |
47 | 566M | } |
48 | | |
49 | | private: |
50 | | PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; |
51 | | ValueHandleBase *Next = nullptr; |
52 | | Value *Val = nullptr; |
53 | | |
54 | 113M | void setValPtr(Value *V) { Val = V; } |
55 | | |
56 | | public: |
57 | | explicit ValueHandleBase(HandleBaseKind Kind) |
58 | 23.4M | : PrevPair(nullptr, Kind) {} |
59 | | ValueHandleBase(HandleBaseKind Kind, Value *V) |
60 | 702M | : PrevPair(nullptr, Kind), Val(V) { |
61 | 702M | if (isValid(getValPtr())) |
62 | 128M | AddToUseList(); |
63 | 702M | } |
64 | | |
65 | 1.29G | ~ValueHandleBase() { |
66 | 1.29G | if (isValid(getValPtr())) |
67 | 282M | RemoveFromUseList(); |
68 | 1.29G | } |
69 | | |
70 | 25.0M | Value *operator=(Value *RHS) { |
71 | 25.0M | if (getValPtr() == RHS) |
72 | 266 | return RHS; |
73 | 25.0M | if (25.0M isValid(getValPtr())25.0M ) |
74 | 2.62M | RemoveFromUseList(); |
75 | 25.0M | setValPtr(RHS); |
76 | 25.0M | if (isValid(getValPtr())) |
77 | 24.2M | AddToUseList(); |
78 | 25.0M | return RHS; |
79 | 25.0M | } |
80 | | |
81 | 88.0M | Value *operator=(const ValueHandleBase &RHS) { |
82 | 88.0M | if (getValPtr() == RHS.getValPtr()) |
83 | 71.9k | return RHS.getValPtr(); |
84 | 87.9M | if (87.9M isValid(getValPtr())87.9M ) |
85 | 24.7M | RemoveFromUseList(); |
86 | 87.9M | setValPtr(RHS.getValPtr()); |
87 | 87.9M | if (isValid(getValPtr())) |
88 | 65.0M | AddToExistingUseList(RHS.getPrevPtr()); |
89 | 87.9M | return getValPtr(); |
90 | 88.0M | } |
91 | | |
92 | 502k | Value *operator->() const { return getValPtr(); } |
93 | 1.01M | Value &operator*() const { return *getValPtr(); } |
94 | | |
95 | | protected: |
96 | 8.07G | Value *getValPtr() const { return Val; } |
97 | | |
98 | 2.78G | static bool isValid(Value *V) { |
99 | 2.78G | return V && |
100 | 2.74G | V != DenseMapInfo<Value *>::getEmptyKey() && |
101 | 1.16G | V != DenseMapInfo<Value *>::getTombstoneKey(); |
102 | 2.78G | } |
103 | | |
104 | | /// \brief Remove this ValueHandle from its current use list. |
105 | | void RemoveFromUseList(); |
106 | | |
107 | | /// \brief Clear the underlying pointer without clearing the use list. |
108 | | /// |
109 | | /// This should only be used if a derived class has manually removed the |
110 | | /// handle from the use list. |
111 | 0 | void clearValPtr() { setValPtr(nullptr); } |
112 | | |
113 | | public: |
114 | | // Callbacks made from Value. |
115 | | static void ValueIsDeleted(Value *V); |
116 | | static void ValueIsRAUWd(Value *Old, Value *New); |
117 | | |
118 | | private: |
119 | | // Internal implementation details. |
120 | 470M | ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); } |
121 | 3.89M | HandleBaseKind getKind() const { return PrevPair.getInt(); } |
122 | 690M | void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); } |
123 | | |
124 | | /// \brief Add this ValueHandle to the use list for V. |
125 | | /// |
126 | | /// List is the address of either the head of the list or a Next node within |
127 | | /// the existing use list. |
128 | | void AddToExistingUseList(ValueHandleBase **List); |
129 | | |
130 | | /// \brief Add this ValueHandle to the use list after Node. |
131 | | void AddToExistingUseListAfter(ValueHandleBase *Node); |
132 | | |
133 | | /// \brief Add this ValueHandle to the use list for V. |
134 | | void AddToUseList(); |
135 | | }; |
136 | | |
137 | | /// \brief A nullable Value handle that is nullable. |
138 | | /// |
139 | | /// This is a value handle that points to a value, and nulls itself |
140 | | /// out if that value is deleted. |
141 | | class WeakVH : public ValueHandleBase { |
142 | | public: |
143 | 0 | WeakVH() : ValueHandleBase(Weak) {} |
144 | 4.51M | WeakVH(Value *P) : ValueHandleBase(Weak, P) {} |
145 | | WeakVH(const WeakVH &RHS) |
146 | 4.92M | : ValueHandleBase(Weak, RHS) {} |
147 | | |
148 | 0 | WeakVH &operator=(const WeakVH &RHS) = default; |
149 | | |
150 | 0 | Value *operator=(Value *RHS) { |
151 | 0 | return ValueHandleBase::operator=(RHS); |
152 | 0 | } |
153 | 0 | Value *operator=(const ValueHandleBase &RHS) { |
154 | 0 | return ValueHandleBase::operator=(RHS); |
155 | 0 | } |
156 | | |
157 | 12.4M | operator Value*() const { |
158 | 12.4M | return getValPtr(); |
159 | 12.4M | } |
160 | | }; |
161 | | |
162 | | // Specialize simplify_type to allow WeakVH to participate in |
163 | | // dyn_cast, isa, etc. |
164 | | template <> struct simplify_type<WeakVH> { |
165 | | using SimpleType = Value *; |
166 | | |
167 | 1.87M | static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; } |
168 | | }; |
169 | | template <> struct simplify_type<const WeakVH> { |
170 | | using SimpleType = Value *; |
171 | | |
172 | 5.30M | static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } |
173 | | }; |
174 | | |
175 | | /// \brief Value handle that is nullable, but tries to track the Value. |
176 | | /// |
177 | | /// This is a value handle that tries hard to point to a Value, even across |
178 | | /// RAUW operations, but will null itself out if the value is destroyed. this |
179 | | /// is useful for advisory sorts of information, but should not be used as the |
180 | | /// key of a map (since the map would have to rearrange itself when the pointer |
181 | | /// changes). |
182 | | class WeakTrackingVH : public ValueHandleBase { |
183 | | public: |
184 | 23.4M | WeakTrackingVH() : ValueHandleBase(WeakTracking) {} |
185 | 47.9M | WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {} |
186 | | WeakTrackingVH(const WeakTrackingVH &RHS) |
187 | 72.5M | : ValueHandleBase(WeakTracking, RHS) {} |
188 | | |
189 | 3.69M | WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default; |
190 | | |
191 | 23.2M | Value *operator=(Value *RHS) { |
192 | 23.2M | return ValueHandleBase::operator=(RHS); |
193 | 23.2M | } |
194 | 0 | Value *operator=(const ValueHandleBase &RHS) { |
195 | 0 | return ValueHandleBase::operator=(RHS); |
196 | 0 | } |
197 | | |
198 | 157M | operator Value*() const { |
199 | 157M | return getValPtr(); |
200 | 157M | } |
201 | | |
202 | 0 | bool pointsToAliveValue() const { |
203 | 0 | return ValueHandleBase::isValid(getValPtr()); |
204 | 0 | } |
205 | | }; |
206 | | |
207 | | // Specialize simplify_type to allow WeakTrackingVH to participate in |
208 | | // dyn_cast, isa, etc. |
209 | | template <> struct simplify_type<WeakTrackingVH> { |
210 | | using SimpleType = Value *; |
211 | | |
212 | 1.70M | static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; } |
213 | | }; |
214 | | template <> struct simplify_type<const WeakTrackingVH> { |
215 | | using SimpleType = Value *; |
216 | | |
217 | 7.40M | static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) { |
218 | 7.40M | return WVH; |
219 | 7.40M | } |
220 | | }; |
221 | | |
222 | | /// \brief Value handle that asserts if the Value is deleted. |
223 | | /// |
224 | | /// This is a Value Handle that points to a value and asserts out if the value |
225 | | /// is destroyed while the handle is still live. This is very useful for |
226 | | /// catching dangling pointer bugs and other things which can be non-obvious. |
227 | | /// One particularly useful place to use this is as the Key of a map. Dangling |
228 | | /// pointer bugs often lead to really subtle bugs that only occur if another |
229 | | /// object happens to get allocated to the same address as the old one. Using |
230 | | /// an AssertingVH ensures that an assert is triggered as soon as the bad |
231 | | /// delete occurs. |
232 | | /// |
233 | | /// Note that an AssertingVH handle does *not* follow values across RAUW |
234 | | /// operations. This means that RAUW's need to explicitly update the |
235 | | /// AssertingVH's as it moves. This is required because in non-assert mode this |
236 | | /// class turns into a trivial wrapper around a pointer. |
237 | | template <typename ValueTy> |
238 | | class AssertingVH |
239 | | #ifndef NDEBUG |
240 | | : public ValueHandleBase |
241 | | #endif |
242 | | { |
243 | | friend struct DenseMapInfo<AssertingVH<ValueTy>>; |
244 | | |
245 | | #ifndef NDEBUG |
246 | | Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); } |
247 | | void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); } |
248 | | #else |
249 | | Value *ThePtr; |
250 | 1.01G | Value *getRawValPtr() const { return ThePtr; } llvm::AssertingVH<llvm::BasicBlock>::getRawValPtr() const Line | Count | Source | 250 | 4.94M | Value *getRawValPtr() const { return ThePtr; } |
llvm::AssertingVH<llvm::Value>::getRawValPtr() const Line | Count | Source | 250 | 539M | Value *getRawValPtr() const { return ThePtr; } |
llvm::AssertingVH<llvm::PHINode>::getRawValPtr() const Line | Count | Source | 250 | 262k | Value *getRawValPtr() const { return ThePtr; } |
llvm::AssertingVH<llvm::Function>::getRawValPtr() const Line | Count | Source | 250 | 454 | Value *getRawValPtr() const { return ThePtr; } |
llvm::AssertingVH<llvm::Instruction>::getRawValPtr() const Line | Count | Source | 250 | 468M | Value *getRawValPtr() const { return ThePtr; } |
|
251 | 150M | void setRawValPtr(Value *P) { ThePtr = P; } llvm::AssertingVH<llvm::Value>::setRawValPtr(llvm::Value*) Line | Count | Source | 251 | 140M | void setRawValPtr(Value *P) { ThePtr = P; } |
llvm::AssertingVH<llvm::Function>::setRawValPtr(llvm::Value*) Line | Count | Source | 251 | 8 | void setRawValPtr(Value *P) { ThePtr = P; } |
llvm::AssertingVH<llvm::PHINode>::setRawValPtr(llvm::Value*) Line | Count | Source | 251 | 72.5k | void setRawValPtr(Value *P) { ThePtr = P; } |
llvm::AssertingVH<llvm::Instruction>::setRawValPtr(llvm::Value*) Line | Count | Source | 251 | 9.50M | void setRawValPtr(Value *P) { ThePtr = P; } |
llvm::AssertingVH<llvm::BasicBlock>::setRawValPtr(llvm::Value*) Line | Count | Source | 251 | 3.24k | void setRawValPtr(Value *P) { ThePtr = P; } |
|
252 | | #endif |
253 | | // Convert a ValueTy*, which may be const, to the raw Value*. |
254 | 97.0M | static Value *GetAsValue(Value *V) { return V; } llvm::AssertingVH<llvm::Function>::GetAsValue(llvm::Value*) Line | Count | Source | 254 | 224 | static Value *GetAsValue(Value *V) { return V; } |
llvm::AssertingVH<llvm::Instruction>::GetAsValue(llvm::Value*) Line | Count | Source | 254 | 1.77M | static Value *GetAsValue(Value *V) { return V; } |
llvm::AssertingVH<llvm::PHINode>::GetAsValue(llvm::Value*) Line | Count | Source | 254 | 72.4k | static Value *GetAsValue(Value *V) { return V; } |
llvm::AssertingVH<llvm::Value>::GetAsValue(llvm::Value*) Line | Count | Source | 254 | 90.3M | static Value *GetAsValue(Value *V) { return V; } |
llvm::AssertingVH<llvm::BasicBlock>::GetAsValue(llvm::Value*) Line | Count | Source | 254 | 4.92M | static Value *GetAsValue(Value *V) { return V; } |
|
255 | | static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } |
256 | | |
257 | 143M | ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); } llvm::AssertingVH<llvm::BasicBlock>::getValPtr() const Line | Count | Source | 257 | 4.92M | ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); } |
llvm::AssertingVH<llvm::Value>::getValPtr() const Line | Count | Source | 257 | 134M | ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); } |
llvm::AssertingVH<llvm::PHINode>::getValPtr() const Line | Count | Source | 257 | 128k | ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); } |
llvm::AssertingVH<llvm::Function>::getValPtr() const Line | Count | Source | 257 | 454 | ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); } |
llvm::AssertingVH<llvm::Instruction>::getValPtr() const Line | Count | Source | 257 | 4.01M | ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); } |
|
258 | 68.3M | void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } llvm::AssertingVH<llvm::Value>::setValPtr(llvm::Value*) Line | Count | Source | 258 | 67.1M | void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } |
llvm::AssertingVH<llvm::BasicBlock>::setValPtr(llvm::BasicBlock*) Line | Count | Source | 258 | 379 | void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } |
llvm::AssertingVH<llvm::Function>::setValPtr(llvm::Function*) Line | Count | Source | 258 | 8 | void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } |
llvm::AssertingVH<llvm::PHINode>::setValPtr(llvm::PHINode*) Line | Count | Source | 258 | 64.1k | void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } |
llvm::AssertingVH<llvm::Instruction>::setValPtr(llvm::Instruction*) Line | Count | Source | 258 | 1.19M | void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } |
|
259 | | |
260 | | public: |
261 | | #ifndef NDEBUG |
262 | | AssertingVH() : ValueHandleBase(Assert) {} |
263 | | AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {} |
264 | | AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {} |
265 | | #else |
266 | 81.8M | AssertingVH() : ThePtr(nullptr) {} llvm::AssertingVH<llvm::Instruction>::AssertingVH() Line | Count | Source | 266 | 8.49M | AssertingVH() : ThePtr(nullptr) {} |
llvm::AssertingVH<llvm::BasicBlock>::AssertingVH() Line | Count | Source | 266 | 2.86k | AssertingVH() : ThePtr(nullptr) {} |
llvm::AssertingVH<llvm::PHINode>::AssertingVH() Line | Count | Source | 266 | 8.33k | AssertingVH() : ThePtr(nullptr) {} |
llvm::AssertingVH<llvm::Value>::AssertingVH() Line | Count | Source | 266 | 73.3M | AssertingVH() : ThePtr(nullptr) {} |
Unexecuted instantiation: llvm::AssertingVH<llvm::Function>::AssertingVH() |
267 | 28.7M | AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} llvm::AssertingVH<llvm::PHINode>::AssertingVH(llvm::PHINode*) Line | Count | Source | 267 | 8.26k | AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} |
llvm::AssertingVH<llvm::BasicBlock>::AssertingVH(llvm::BasicBlock*) Line | Count | Source | 267 | 4.92M | AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} |
llvm::AssertingVH<llvm::Value>::AssertingVH(llvm::Value*) Line | Count | Source | 267 | 23.2M | AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} |
llvm::AssertingVH<llvm::Function>::AssertingVH(llvm::Function*) Line | Count | Source | 267 | 216 | AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} |
llvm::AssertingVH<llvm::Instruction>::AssertingVH(llvm::Instruction*) Line | Count | Source | 267 | 574k | AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} |
|
268 | | #endif |
269 | | |
270 | 6.94M | operator ValueTy*() const { |
271 | 6.94M | return getValPtr(); |
272 | 6.94M | } llvm::AssertingVH<llvm::Instruction>::operator llvm::Instruction*() const Line | Count | Source | 270 | 1.99M | operator ValueTy*() const { | 271 | 1.99M | return getValPtr(); | 272 | 1.99M | } |
llvm::AssertingVH<llvm::Function>::operator llvm::Function*() const Line | Count | Source | 270 | 446 | operator ValueTy*() const { | 271 | 446 | return getValPtr(); | 272 | 446 | } |
llvm::AssertingVH<llvm::Value>::operator llvm::Value*() const Line | Count | Source | 270 | 33.6k | operator ValueTy*() const { | 271 | 33.6k | return getValPtr(); | 272 | 33.6k | } |
llvm::AssertingVH<llvm::BasicBlock>::operator llvm::BasicBlock*() const Line | Count | Source | 270 | 4.92M | operator ValueTy*() const { | 271 | 4.92M | return getValPtr(); | 272 | 4.92M | } |
|
273 | | |
274 | 375k | ValueTy *operator=(ValueTy *RHS) { |
275 | 375k | setValPtr(RHS); |
276 | 375k | return getValPtr(); |
277 | 375k | } llvm::AssertingVH<llvm::Function>::operator=(llvm::Function*) Line | Count | Source | 274 | 8 | ValueTy *operator=(ValueTy *RHS) { | 275 | 8 | setValPtr(RHS); | 276 | 8 | return getValPtr(); | 277 | 8 | } |
llvm::AssertingVH<llvm::Instruction>::operator=(llvm::Instruction*) Line | Count | Source | 274 | 371k | ValueTy *operator=(ValueTy *RHS) { | 275 | 371k | setValPtr(RHS); | 276 | 371k | return getValPtr(); | 277 | 371k | } |
llvm::AssertingVH<llvm::Value>::operator=(llvm::Value*) Line | Count | Source | 274 | 3.17k | ValueTy *operator=(ValueTy *RHS) { | 275 | 3.17k | setValPtr(RHS); | 276 | 3.17k | return getValPtr(); | 277 | 3.17k | } |
|
278 | 67.9M | ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { |
279 | 67.9M | setValPtr(RHS.getValPtr()); |
280 | 67.9M | return getValPtr(); |
281 | 67.9M | } Unexecuted instantiation: llvm::AssertingVH<llvm::Function>::operator=(llvm::AssertingVH<llvm::Function> const&) llvm::AssertingVH<llvm::Value>::operator=(llvm::AssertingVH<llvm::Value> const&) Line | Count | Source | 278 | 67.1M | ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { | 279 | 67.1M | setValPtr(RHS.getValPtr()); | 280 | 67.1M | return getValPtr(); | 281 | 67.1M | } |
llvm::AssertingVH<llvm::BasicBlock>::operator=(llvm::AssertingVH<llvm::BasicBlock> const&) Line | Count | Source | 278 | 379 | ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { | 279 | 379 | setValPtr(RHS.getValPtr()); | 280 | 379 | return getValPtr(); | 281 | 379 | } |
llvm::AssertingVH<llvm::PHINode>::operator=(llvm::AssertingVH<llvm::PHINode> const&) Line | Count | Source | 278 | 64.1k | ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { | 279 | 64.1k | setValPtr(RHS.getValPtr()); | 280 | 64.1k | return getValPtr(); | 281 | 64.1k | } |
llvm::AssertingVH<llvm::Instruction>::operator=(llvm::AssertingVH<llvm::Instruction> const&) Line | Count | Source | 278 | 825k | ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { | 279 | 825k | setValPtr(RHS.getValPtr()); | 280 | 825k | return getValPtr(); | 281 | 825k | } |
|
282 | | |
283 | | ValueTy *operator->() const { return getValPtr(); } |
284 | | ValueTy &operator*() const { return *getValPtr(); } |
285 | | }; |
286 | | |
287 | | // Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. |
288 | | template<typename T> |
289 | | struct DenseMapInfo<AssertingVH<T>> { |
290 | 48.5M | static inline AssertingVH<T> getEmptyKey() { |
291 | 48.5M | AssertingVH<T> Res; |
292 | 48.5M | Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); |
293 | 48.5M | return Res; |
294 | 48.5M | } llvm::DenseMapInfo<llvm::AssertingVH<llvm::Instruction> >::getEmptyKey() Line | Count | Source | 290 | 4.16M | static inline AssertingVH<T> getEmptyKey() { | 291 | 4.16M | AssertingVH<T> Res; | 292 | 4.16M | Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); | 293 | 4.16M | return Res; | 294 | 4.16M | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::BasicBlock> >::getEmptyKey() Line | Count | Source | 290 | 1.70k | static inline AssertingVH<T> getEmptyKey() { | 291 | 1.70k | AssertingVH<T> Res; | 292 | 1.70k | Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); | 293 | 1.70k | return Res; | 294 | 1.70k | } |
Unexecuted instantiation: llvm::DenseMapInfo<llvm::AssertingVH<llvm::Function> >::getEmptyKey() llvm::DenseMapInfo<llvm::AssertingVH<llvm::PHINode> >::getEmptyKey() Line | Count | Source | 290 | 5.23k | static inline AssertingVH<T> getEmptyKey() { | 291 | 5.23k | AssertingVH<T> Res; | 292 | 5.23k | Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); | 293 | 5.23k | return Res; | 294 | 5.23k | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::Value> >::getEmptyKey() Line | Count | Source | 290 | 44.4M | static inline AssertingVH<T> getEmptyKey() { | 291 | 44.4M | AssertingVH<T> Res; | 292 | 44.4M | Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); | 293 | 44.4M | return Res; | 294 | 44.4M | } |
|
295 | | |
296 | 33.1M | static inline AssertingVH<T> getTombstoneKey() { |
297 | 33.1M | AssertingVH<T> Res; |
298 | 33.1M | Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); |
299 | 33.1M | return Res; |
300 | 33.1M | } llvm::DenseMapInfo<llvm::AssertingVH<llvm::Value> >::getTombstoneKey() Line | Count | Source | 296 | 28.9M | static inline AssertingVH<T> getTombstoneKey() { | 297 | 28.9M | AssertingVH<T> Res; | 298 | 28.9M | Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); | 299 | 28.9M | return Res; | 300 | 28.9M | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::BasicBlock> >::getTombstoneKey() Line | Count | Source | 296 | 1.16k | static inline AssertingVH<T> getTombstoneKey() { | 297 | 1.16k | AssertingVH<T> Res; | 298 | 1.16k | Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); | 299 | 1.16k | return Res; | 300 | 1.16k | } |
Unexecuted instantiation: llvm::DenseMapInfo<llvm::AssertingVH<llvm::Function> >::getTombstoneKey() llvm::DenseMapInfo<llvm::AssertingVH<llvm::Instruction> >::getTombstoneKey() Line | Count | Source | 296 | 4.14M | static inline AssertingVH<T> getTombstoneKey() { | 297 | 4.14M | AssertingVH<T> Res; | 298 | 4.14M | Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); | 299 | 4.14M | return Res; | 300 | 4.14M | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::PHINode> >::getTombstoneKey() Line | Count | Source | 296 | 3.10k | static inline AssertingVH<T> getTombstoneKey() { | 297 | 3.10k | AssertingVH<T> Res; | 298 | 3.10k | Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); | 299 | 3.10k | return Res; | 300 | 3.10k | } |
|
301 | | |
302 | 28.5M | static unsigned getHashValue(const AssertingVH<T> &Val) { |
303 | 28.5M | return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); |
304 | 28.5M | } llvm::DenseMapInfo<llvm::AssertingVH<llvm::BasicBlock> >::getHashValue(llvm::AssertingVH<llvm::BasicBlock> const&) Line | Count | Source | 302 | 1.01k | static unsigned getHashValue(const AssertingVH<T> &Val) { | 303 | 1.01k | return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); | 304 | 1.01k | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::Value> >::getHashValue(llvm::AssertingVH<llvm::Value> const&) Line | Count | Source | 302 | 27.6M | static unsigned getHashValue(const AssertingVH<T> &Val) { | 303 | 27.6M | return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); | 304 | 27.6M | } |
Unexecuted instantiation: llvm::DenseMapInfo<llvm::AssertingVH<llvm::Function> >::getHashValue(llvm::AssertingVH<llvm::Function> const&) llvm::DenseMapInfo<llvm::AssertingVH<llvm::Instruction> >::getHashValue(llvm::AssertingVH<llvm::Instruction> const&) Line | Count | Source | 302 | 831k | static unsigned getHashValue(const AssertingVH<T> &Val) { | 303 | 831k | return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); | 304 | 831k | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::PHINode> >::getHashValue(llvm::AssertingVH<llvm::PHINode> const&) Line | Count | Source | 302 | 1.13k | static unsigned getHashValue(const AssertingVH<T> &Val) { | 303 | 1.13k | return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); | 304 | 1.13k | } |
|
305 | | |
306 | 420M | static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { |
307 | 420M | return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), |
308 | 420M | RHS.getRawValPtr()); |
309 | 420M | } llvm::DenseMapInfo<llvm::AssertingVH<llvm::Instruction> >::isEqual(llvm::AssertingVH<llvm::Instruction> const&, llvm::AssertingVH<llvm::Instruction> const&) Line | Count | Source | 306 | 231M | static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { | 307 | 231M | return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), | 308 | 231M | RHS.getRawValPtr()); | 309 | 231M | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::Value> >::isEqual(llvm::AssertingVH<llvm::Value> const&, llvm::AssertingVH<llvm::Value> const&) Line | Count | Source | 306 | 188M | static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { | 307 | 188M | return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), | 308 | 188M | RHS.getRawValPtr()); | 309 | 188M | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::BasicBlock> >::isEqual(llvm::AssertingVH<llvm::BasicBlock> const&, llvm::AssertingVH<llvm::BasicBlock> const&) Line | Count | Source | 306 | 12.2k | static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { | 307 | 12.2k | return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), | 308 | 12.2k | RHS.getRawValPtr()); | 309 | 12.2k | } |
llvm::DenseMapInfo<llvm::AssertingVH<llvm::PHINode> >::isEqual(llvm::AssertingVH<llvm::PHINode> const&, llvm::AssertingVH<llvm::PHINode> const&) Line | Count | Source | 306 | 66.4k | static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { | 307 | 66.4k | return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), | 308 | 66.4k | RHS.getRawValPtr()); | 309 | 66.4k | } |
Unexecuted instantiation: llvm::DenseMapInfo<llvm::AssertingVH<llvm::Function> >::isEqual(llvm::AssertingVH<llvm::Function> const&, llvm::AssertingVH<llvm::Function> const&) |
310 | | }; |
311 | | |
312 | | template <typename T> |
313 | | struct isPodLike<AssertingVH<T>> { |
314 | | #ifdef NDEBUG |
315 | | static const bool value = true; |
316 | | #else |
317 | | static const bool value = false; |
318 | | #endif |
319 | | }; |
320 | | |
321 | | /// \brief Value handle that tracks a Value across RAUW. |
322 | | /// |
323 | | /// TrackingVH is designed for situations where a client needs to hold a handle |
324 | | /// to a Value (or subclass) across some operations which may move that value, |
325 | | /// but should never destroy it or replace it with some unacceptable type. |
326 | | /// |
327 | | /// It is an error to attempt to replace a value with one of a type which is |
328 | | /// incompatible with any of its outstanding TrackingVHs. |
329 | | /// |
330 | | /// It is an error to read from a TrackingVH that does not point to a valid |
331 | | /// value. A TrackingVH is said to not point to a valid value if either it |
332 | | /// hasn't yet been assigned a value yet or because the value it was tracking |
333 | | /// has since been deleted. |
334 | | /// |
335 | | /// Assigning a value to a TrackingVH is always allowed, even if said TrackingVH |
336 | | /// no longer points to a valid value. |
337 | | template <typename ValueTy> class TrackingVH { |
338 | | WeakTrackingVH InnerHandle; |
339 | | |
340 | | public: |
341 | 6.17M | ValueTy *getValPtr() const { |
342 | 6.17M | assert(InnerHandle.pointsToAliveValue() && |
343 | 6.17M | "TrackingVH must be non-null and valid on dereference!"); |
344 | 6.17M | |
345 | 6.17M | // Check that the value is a member of the correct subclass. We would like |
346 | 6.17M | // to check this property on assignment for better debugging, but we don't |
347 | 6.17M | // want to require a virtual interface on this VH. Instead we allow RAUW to |
348 | 6.17M | // replace this value with a value of an invalid type, and check it here. |
349 | 6.17M | assert(isa<ValueTy>(InnerHandle) && |
350 | 6.17M | "Tracked Value was replaced by one with an invalid type!"); |
351 | 6.17M | return cast<ValueTy>(InnerHandle); |
352 | 6.17M | } llvm::TrackingVH<llvm::MemoryAccess>::getValPtr() const Line | Count | Source | 341 | 3 | ValueTy *getValPtr() const { | 342 | 3 | assert(InnerHandle.pointsToAliveValue() && | 343 | 3 | "TrackingVH must be non-null and valid on dereference!"); | 344 | 3 | | 345 | 3 | // Check that the value is a member of the correct subclass. We would like | 346 | 3 | // to check this property on assignment for better debugging, but we don't | 347 | 3 | // want to require a virtual interface on this VH. Instead we allow RAUW to | 348 | 3 | // replace this value with a value of an invalid type, and check it here. | 349 | 3 | assert(isa<ValueTy>(InnerHandle) && | 350 | 3 | "Tracked Value was replaced by one with an invalid type!"); | 351 | 3 | return cast<ValueTy>(InnerHandle); | 352 | 3 | } |
llvm::TrackingVH<llvm::Value>::getValPtr() const Line | Count | Source | 341 | 6.17M | ValueTy *getValPtr() const { | 342 | 6.17M | assert(InnerHandle.pointsToAliveValue() && | 343 | 6.17M | "TrackingVH must be non-null and valid on dereference!"); | 344 | 6.17M | | 345 | 6.17M | // Check that the value is a member of the correct subclass. We would like | 346 | 6.17M | // to check this property on assignment for better debugging, but we don't | 347 | 6.17M | // want to require a virtual interface on this VH. Instead we allow RAUW to | 348 | 6.17M | // replace this value with a value of an invalid type, and check it here. | 349 | 6.17M | assert(isa<ValueTy>(InnerHandle) && | 350 | 6.17M | "Tracked Value was replaced by one with an invalid type!"); | 351 | 6.17M | return cast<ValueTy>(InnerHandle); | 352 | 6.17M | } |
|
353 | | |
354 | 4.15M | void setValPtr(ValueTy *P) { |
355 | 4.15M | // Assigning to non-valid TrackingVH's are fine so we just unconditionally |
356 | 4.15M | // assign here. |
357 | 4.15M | InnerHandle = GetAsValue(P); |
358 | 4.15M | } llvm::TrackingVH<llvm::MemoryAccess>::setValPtr(llvm::MemoryAccess*) Line | Count | Source | 354 | 3 | void setValPtr(ValueTy *P) { | 355 | 3 | // Assigning to non-valid TrackingVH's are fine so we just unconditionally | 356 | 3 | // assign here. | 357 | 3 | InnerHandle = GetAsValue(P); | 358 | 3 | } |
llvm::TrackingVH<llvm::Value>::setValPtr(llvm::Value*) Line | Count | Source | 354 | 4.15M | void setValPtr(ValueTy *P) { | 355 | 4.15M | // Assigning to non-valid TrackingVH's are fine so we just unconditionally | 356 | 4.15M | // assign here. | 357 | 4.15M | InnerHandle = GetAsValue(P); | 358 | 4.15M | } |
|
359 | | |
360 | | // Convert a ValueTy*, which may be const, to the type the base |
361 | | // class expects. |
362 | 4.15M | static Value *GetAsValue(Value *V) { return V; } llvm::TrackingVH<llvm::MemoryAccess>::GetAsValue(llvm::Value*) Line | Count | Source | 362 | 3 | static Value *GetAsValue(Value *V) { return V; } |
llvm::TrackingVH<llvm::Value>::GetAsValue(llvm::Value*) Line | Count | Source | 362 | 4.15M | static Value *GetAsValue(Value *V) { return V; } |
|
363 | | static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } |
364 | | |
365 | | public: |
366 | 4.33M | TrackingVH() = default; |
367 | 296k | TrackingVH(ValueTy *P) { setValPtr(P); } llvm::TrackingVH<llvm::Value>::TrackingVH(llvm::Value*) Line | Count | Source | 367 | 296k | TrackingVH(ValueTy *P) { setValPtr(P); } |
llvm::TrackingVH<llvm::MemoryAccess>::TrackingVH(llvm::MemoryAccess*) Line | Count | Source | 367 | 3 | TrackingVH(ValueTy *P) { setValPtr(P); } |
|
368 | | |
369 | 2.30M | operator ValueTy*() const { |
370 | 2.30M | return getValPtr(); |
371 | 2.30M | } llvm::TrackingVH<llvm::Value>::operator llvm::Value*() const Line | Count | Source | 369 | 2.30M | operator ValueTy*() const { | 370 | 2.30M | return getValPtr(); | 371 | 2.30M | } |
llvm::TrackingVH<llvm::MemoryAccess>::operator llvm::MemoryAccess*() const Line | Count | Source | 369 | 3 | operator ValueTy*() const { | 370 | 3 | return getValPtr(); | 371 | 3 | } |
|
372 | | |
373 | 3.85M | ValueTy *operator=(ValueTy *RHS) { |
374 | 3.85M | setValPtr(RHS); |
375 | 3.85M | return getValPtr(); |
376 | 3.85M | } |
377 | | |
378 | 11.8k | ValueTy *operator->() const { return getValPtr(); } |
379 | 204 | ValueTy &operator*() const { return *getValPtr(); } |
380 | | }; |
381 | | |
382 | | /// \brief Value handle with callbacks on RAUW and destruction. |
383 | | /// |
384 | | /// This is a value handle that allows subclasses to define callbacks that run |
385 | | /// when the underlying Value has RAUW called on it or is destroyed. This |
386 | | /// class can be used as the key of a map, as long as the user takes it out of |
387 | | /// the map before calling setValPtr() (since the map has to rearrange itself |
388 | | /// when the pointer changes). Unlike ValueHandleBase, this class has a vtable. |
389 | | class CallbackVH : public ValueHandleBase { |
390 | | virtual void anchor(); |
391 | | protected: |
392 | 1.13G | ~CallbackVH() = default; |
393 | 486M | CallbackVH(const CallbackVH &) = default; |
394 | 84.3M | CallbackVH &operator=(const CallbackVH &) = default; |
395 | | |
396 | 141k | void setValPtr(Value *P) { |
397 | 141k | ValueHandleBase::operator=(P); |
398 | 141k | } |
399 | | |
400 | | public: |
401 | 0 | CallbackVH() : ValueHandleBase(Callback) {} |
402 | 650M | CallbackVH(Value *P) : ValueHandleBase(Callback, P) {} |
403 | | |
404 | 3.05G | operator Value*() const { |
405 | 3.05G | return getValPtr(); |
406 | 3.05G | } |
407 | | |
408 | | /// \brief Callback for Value destruction. |
409 | | /// |
410 | | /// Called when this->getValPtr() is destroyed, inside ~Value(), so you |
411 | | /// may call any non-virtual Value method on getValPtr(), but no subclass |
412 | | /// methods. If WeakTrackingVH were implemented as a CallbackVH, it would use |
413 | | /// this |
414 | | /// method to call setValPtr(NULL). AssertingVH would use this method to |
415 | | /// cause an assertion failure. |
416 | | /// |
417 | | /// All implementations must remove the reference from this object to the |
418 | | /// Value that's being destroyed. |
419 | 3 | virtual void deleted() { setValPtr(nullptr); } |
420 | | |
421 | | /// \brief Callback for Value RAUW. |
422 | | /// |
423 | | /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called, |
424 | | /// _before_ any of the uses have actually been replaced. If WeakTrackingVH |
425 | | /// were |
426 | | /// implemented as a CallbackVH, it would use this method to call |
427 | | /// setValPtr(new_value). AssertingVH would do nothing in this method. |
428 | 73.1k | virtual void allUsesReplacedWith(Value *) {} |
429 | | }; |
430 | | |
431 | | /// Value handle that poisons itself if the Value is deleted. |
432 | | /// |
433 | | /// This is a Value Handle that points to a value and poisons itself if the |
434 | | /// value is destroyed while the handle is still live. This is very useful for |
435 | | /// catching dangling pointer bugs where an \c AssertingVH cannot be used |
436 | | /// because the dangling handle needs to outlive the value without ever being |
437 | | /// used. |
438 | | /// |
439 | | /// One particularly useful place to use this is as the Key of a map. Dangling |
440 | | /// pointer bugs often lead to really subtle bugs that only occur if another |
441 | | /// object happens to get allocated to the same address as the old one. Using |
442 | | /// a PoisoningVH ensures that an assert is triggered if looking up a new value |
443 | | /// in the map finds a handle from the old value. |
444 | | /// |
445 | | /// Note that a PoisoningVH handle does *not* follow values across RAUW |
446 | | /// operations. This means that RAUW's need to explicitly update the |
447 | | /// PoisoningVH's as it moves. This is required because in non-assert mode this |
448 | | /// class turns into a trivial wrapper around a pointer. |
449 | | template <typename ValueTy> |
450 | | class PoisoningVH |
451 | | #ifndef NDEBUG |
452 | | final : public CallbackVH |
453 | | #endif |
454 | | { |
455 | | friend struct DenseMapInfo<PoisoningVH<ValueTy>>; |
456 | | |
457 | | // Convert a ValueTy*, which may be const, to the raw Value*. |
458 | 221M | static Value *GetAsValue(Value *V) { return V; } |
459 | | static Value *GetAsValue(const Value *V) { return const_cast<Value *>(V); } |
460 | | |
461 | | #ifndef NDEBUG |
462 | | /// A flag tracking whether this value has been poisoned. |
463 | | /// |
464 | | /// On delete and RAUW, we leave the value pointer alone so that as a raw |
465 | | /// pointer it produces the same value (and we fit into the same key of |
466 | | /// a hash table, etc), but we poison the handle so that any top-level usage |
467 | | /// will fail. |
468 | | bool Poisoned = false; |
469 | | |
470 | | Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); } |
471 | | void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); } |
472 | | |
473 | | /// Handle deletion by poisoning the handle. |
474 | | void deleted() override { |
475 | | assert(!Poisoned && "Tried to delete an already poisoned handle!"); |
476 | | Poisoned = true; |
477 | | RemoveFromUseList(); |
478 | | } |
479 | | |
480 | | /// Handle RAUW by poisoning the handle. |
481 | | void allUsesReplacedWith(Value *) override { |
482 | | assert(!Poisoned && "Tried to RAUW an already poisoned handle!"); |
483 | | Poisoned = true; |
484 | | RemoveFromUseList(); |
485 | | } |
486 | | #else // NDEBUG |
487 | | Value *ThePtr = nullptr; |
488 | | |
489 | 1.70G | Value *getRawValPtr() const { return ThePtr; } |
490 | 494M | void setRawValPtr(Value *P) { ThePtr = P; } |
491 | | #endif |
492 | | |
493 | 1.46M | ValueTy *getValPtr() const { |
494 | 1.46M | assert(!Poisoned && "Accessed a poisoned value handle!"); |
495 | 1.46M | return static_cast<ValueTy *>(getRawValPtr()); |
496 | 1.46M | } |
497 | | void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } |
498 | | |
499 | | public: |
500 | 494M | PoisoningVH() = default; |
501 | | #ifndef NDEBUG |
502 | | PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {} |
503 | | PoisoningVH(const PoisoningVH &RHS) |
504 | | : CallbackVH(RHS), Poisoned(RHS.Poisoned) {} |
505 | | |
506 | | ~PoisoningVH() { |
507 | | if (Poisoned) |
508 | | clearValPtr(); |
509 | | } |
510 | | |
511 | | PoisoningVH &operator=(const PoisoningVH &RHS) { |
512 | | if (Poisoned) |
513 | | clearValPtr(); |
514 | | CallbackVH::operator=(RHS); |
515 | | Poisoned = RHS.Poisoned; |
516 | | return *this; |
517 | | } |
518 | | #else |
519 | 221M | PoisoningVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} |
520 | | #endif |
521 | | |
522 | 1.46M | operator ValueTy *() const { return getValPtr(); } |
523 | | |
524 | | ValueTy *operator->() const { return getValPtr(); } |
525 | | ValueTy &operator*() const { return *getValPtr(); } |
526 | | }; |
527 | | |
528 | | // Specialize DenseMapInfo to allow PoisoningVH to participate in DenseMap. |
529 | | template <typename T> struct DenseMapInfo<PoisoningVH<T>> { |
530 | 261M | static inline PoisoningVH<T> getEmptyKey() { |
531 | 261M | PoisoningVH<T> Res; |
532 | 261M | Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey()); |
533 | 261M | return Res; |
534 | 261M | } |
535 | | |
536 | 232M | static inline PoisoningVH<T> getTombstoneKey() { |
537 | 232M | PoisoningVH<T> Res; |
538 | 232M | Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey()); |
539 | 232M | return Res; |
540 | 232M | } |
541 | | |
542 | 224M | static unsigned getHashValue(const PoisoningVH<T> &Val) { |
543 | 224M | return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr()); |
544 | 224M | } |
545 | | |
546 | 740M | static bool isEqual(const PoisoningVH<T> &LHS, const PoisoningVH<T> &RHS) { |
547 | 740M | return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(), |
548 | 740M | RHS.getRawValPtr()); |
549 | 740M | } |
550 | | }; |
551 | | |
552 | | template <typename T> struct isPodLike<PoisoningVH<T>> { |
553 | | #ifdef NDEBUG |
554 | | static const bool value = true; |
555 | | #else |
556 | | static const bool value = false; |
557 | | #endif |
558 | | }; |
559 | | |
560 | | } // end namespace llvm |
561 | | |
562 | | #endif // LLVM_IR_VALUEHANDLE_H |