@@ -176,57 +176,114 @@ class DbgInfoIntrinsic : public IntrinsicInst {
176
176
// / @}
177
177
};
178
178
179
- // / This is the common base class for debug info intrinsics for variables.
180
- class DbgVariableIntrinsic : public DbgInfoIntrinsic {
179
+ // Iterator for ValueAsMetadata that internally uses direct pointer iteration
180
+ // over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
181
+ // ValueAsMetadata .
182
+ class location_op_iterator
183
+ : public iterator_facade_base<location_op_iterator,
184
+ std::bidirectional_iterator_tag, Value *> {
185
+ PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
186
+
181
187
public:
182
- // Iterator for ValueAsMetadata that internally uses direct pointer iteration
183
- // over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing to the
184
- // ValueAsMetadata .
185
- class location_op_iterator
186
- : public iterator_facade_base<location_op_iterator,
187
- std::bidirectional_iterator_tag, Value *> {
188
- PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
189
-
190
- public:
191
- location_op_iterator (ValueAsMetadata *SingleIter) : I(SingleIter) {}
192
- location_op_iterator (ValueAsMetadata **MultiIter) : I(MultiIter) {}
193
-
194
- location_op_iterator (const location_op_iterator &R) : I(R.I) {}
195
- location_op_iterator &operator =(const location_op_iterator &R) {
196
- I = R.I ;
197
- return *this ;
198
- }
199
- bool operator ==(const location_op_iterator &RHS) const {
200
- return I == RHS.I ;
201
- }
202
- const Value *operator *() const {
203
- ValueAsMetadata *VAM = I.is <ValueAsMetadata *>()
204
- ? I.get <ValueAsMetadata *>()
205
- : *I.get <ValueAsMetadata **>();
206
- return VAM->getValue ();
207
- };
208
- Value *operator *() {
209
- ValueAsMetadata *VAM = I.is <ValueAsMetadata *>()
210
- ? I.get <ValueAsMetadata *>()
211
- : *I.get <ValueAsMetadata **>();
212
- return VAM->getValue ();
213
- }
214
- location_op_iterator &operator ++() {
215
- if (I.is <ValueAsMetadata *>())
216
- I = I.get <ValueAsMetadata *>() + 1 ;
217
- else
218
- I = I.get <ValueAsMetadata **>() + 1 ;
219
- return *this ;
220
- }
221
- location_op_iterator &operator --() {
222
- if (I.is <ValueAsMetadata *>())
223
- I = I.get <ValueAsMetadata *>() - 1 ;
224
- else
225
- I = I.get <ValueAsMetadata **>() - 1 ;
226
- return *this ;
227
- }
188
+ location_op_iterator (ValueAsMetadata *SingleIter) : I(SingleIter) {}
189
+ location_op_iterator (ValueAsMetadata **MultiIter) : I(MultiIter) {}
190
+
191
+ location_op_iterator (const location_op_iterator &R) : I(R.I) {}
192
+ location_op_iterator &operator =(const location_op_iterator &R) {
193
+ I = R.I ;
194
+ return *this ;
195
+ }
196
+ bool operator ==(const location_op_iterator &RHS) const { return I == RHS.I ; }
197
+ const Value *operator *() const {
198
+ ValueAsMetadata *VAM = I.is <ValueAsMetadata *>()
199
+ ? I.get <ValueAsMetadata *>()
200
+ : *I.get <ValueAsMetadata **>();
201
+ return VAM->getValue ();
228
202
};
203
+ Value *operator *() {
204
+ ValueAsMetadata *VAM = I.is <ValueAsMetadata *>()
205
+ ? I.get <ValueAsMetadata *>()
206
+ : *I.get <ValueAsMetadata **>();
207
+ return VAM->getValue ();
208
+ }
209
+ location_op_iterator &operator ++() {
210
+ if (I.is <ValueAsMetadata *>())
211
+ I = I.get <ValueAsMetadata *>() + 1 ;
212
+ else
213
+ I = I.get <ValueAsMetadata **>() + 1 ;
214
+ return *this ;
215
+ }
216
+ location_op_iterator &operator --() {
217
+ if (I.is <ValueAsMetadata *>())
218
+ I = I.get <ValueAsMetadata *>() - 1 ;
219
+ else
220
+ I = I.get <ValueAsMetadata **>() - 1 ;
221
+ return *this ;
222
+ }
223
+ };
224
+
225
+ // / Lightweight class that wraps the location operand metadata of a debug
226
+ // / intrinsic. The raw location may be a ValueAsMetadata, an empty MDTuple,
227
+ // / or a DIArgList.
228
+ class RawLocationWrapper {
229
+ Metadata *RawLocation = nullptr ;
230
+
231
+ public:
232
+ RawLocationWrapper () = default ;
233
+ explicit RawLocationWrapper (Metadata *RawLocation)
234
+ : RawLocation(RawLocation) {
235
+ // Allow ValueAsMetadata, empty MDTuple, DIArgList.
236
+ assert (RawLocation && " unexpected null RawLocation" );
237
+ assert (isa<ValueAsMetadata>(RawLocation) || isa<DIArgList>(RawLocation) ||
238
+ (isa<MDNode>(RawLocation) &&
239
+ !cast<MDNode>(RawLocation)->getNumOperands ()));
240
+ }
241
+ Metadata *getRawLocation () const { return RawLocation; }
242
+ // / Get the locations corresponding to the variable referenced by the debug
243
+ // / info intrinsic. Depending on the intrinsic, this could be the
244
+ // / variable's value or its address.
245
+ iterator_range<location_op_iterator> location_ops () const ;
246
+ Value *getVariableLocationOp (unsigned OpIdx) const ;
247
+ unsigned getNumVariableLocationOps () const {
248
+ if (hasArgList ())
249
+ return cast<DIArgList>(getRawLocation ())->getArgs ().size ();
250
+ return 1 ;
251
+ }
252
+ bool hasArgList () const { return isa<DIArgList>(getRawLocation ()); }
253
+ bool isKillLocation (const DIExpression *Expression) const {
254
+ return (getNumVariableLocationOps () == 0 && !Expression->isComplex ()) ||
255
+ any_of (location_ops (), [](Value *V) { return isa<UndefValue>(V); });
256
+ }
257
+
258
+ friend bool operator ==(const RawLocationWrapper &A,
259
+ const RawLocationWrapper &B) {
260
+ return A.RawLocation == B.RawLocation ;
261
+ }
262
+ friend bool operator !=(const RawLocationWrapper &A,
263
+ const RawLocationWrapper &B) {
264
+ return !(A == B);
265
+ }
266
+ friend bool operator >(const RawLocationWrapper &A,
267
+ const RawLocationWrapper &B) {
268
+ return A.RawLocation > B.RawLocation ;
269
+ }
270
+ friend bool operator >=(const RawLocationWrapper &A,
271
+ const RawLocationWrapper &B) {
272
+ return A.RawLocation >= B.RawLocation ;
273
+ }
274
+ friend bool operator <(const RawLocationWrapper &A,
275
+ const RawLocationWrapper &B) {
276
+ return A.RawLocation < B.RawLocation ;
277
+ }
278
+ friend bool operator <=(const RawLocationWrapper &A,
279
+ const RawLocationWrapper &B) {
280
+ return A.RawLocation <= B.RawLocation ;
281
+ }
282
+ };
229
283
284
+ // / This is the common base class for debug info intrinsics for variables.
285
+ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
286
+ public:
230
287
// / Get the locations corresponding to the variable referenced by the debug
231
288
// / info intrinsic. Depending on the intrinsic, this could be the
232
289
// / variable's value or its address.
@@ -251,12 +308,10 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
251
308
}
252
309
253
310
unsigned getNumVariableLocationOps () const {
254
- if (hasArgList ())
255
- return cast<DIArgList>(getRawLocation ())->getArgs ().size ();
256
- return 1 ;
311
+ return getWrappedLocation ().getNumVariableLocationOps ();
257
312
}
258
313
259
- bool hasArgList () const { return isa<DIArgList>( getRawLocation () ); }
314
+ bool hasArgList () const { return getWrappedLocation (). hasArgList ( ); }
260
315
261
316
// / Does this describe the address of a local variable. True for dbg.declare,
262
317
// / but not dbg.value, which describes its value, or dbg.assign, which
@@ -278,9 +333,7 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
278
333
}
279
334
280
335
bool isKillLocation () const {
281
- return (getNumVariableLocationOps () == 0 &&
282
- !getExpression ()->isComplex ()) ||
283
- any_of (location_ops (), [](Value *V) { return isa<UndefValue>(V); });
336
+ return getWrappedLocation ().isKillLocation (getExpression ());
284
337
}
285
338
286
339
DILocalVariable *getVariable () const {
@@ -295,6 +348,10 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
295
348
return cast<MetadataAsValue>(getArgOperand (0 ))->getMetadata ();
296
349
}
297
350
351
+ RawLocationWrapper getWrappedLocation () const {
352
+ return RawLocationWrapper (getRawLocation ());
353
+ }
354
+
298
355
Metadata *getRawVariable () const {
299
356
return cast<MetadataAsValue>(getArgOperand (1 ))->getMetadata ();
300
357
}
0 commit comments