14
14
#define LLVM_CLANG_AST_INTERP_POINTER_H
15
15
16
16
#include " Descriptor.h"
17
+ #include " FunctionPointer.h"
17
18
#include " InterpBlock.h"
18
19
#include " clang/AST/ComparisonCategories.h"
19
20
#include " clang/AST/Decl.h"
@@ -45,7 +46,7 @@ struct IntPointer {
45
46
uint64_t Value;
46
47
};
47
48
48
- enum class Storage { Block, Int };
49
+ enum class Storage { Block, Int, Fn };
49
50
50
51
// / A pointer to a memory block, live or dead.
51
52
// /
@@ -96,6 +97,10 @@ class Pointer {
96
97
PointeeStorage.Int .Value = Address;
97
98
PointeeStorage.Int .Desc = Desc;
98
99
}
100
+ Pointer (const Function *F, uint64_t Offset = 0 )
101
+ : Offset(Offset), StorageKind(Storage::Fn) {
102
+ PointeeStorage.Fn = FunctionPointer (F);
103
+ }
99
104
~Pointer ();
100
105
101
106
void operator =(const Pointer &P);
@@ -126,6 +131,8 @@ class Pointer {
126
131
uint64_t getIntegerRepresentation () const {
127
132
if (isIntegralPointer ())
128
133
return asIntPointer ().Value + (Offset * elemSize ());
134
+ if (isFunctionPointer ())
135
+ return asFunctionPointer ().getIntegerRepresentation ();
129
136
return reinterpret_cast <uint64_t >(asBlockPointer ().Pointee ) + Offset;
130
137
}
131
138
@@ -137,6 +144,8 @@ class Pointer {
137
144
[[nodiscard]] Pointer atIndex (uint64_t Idx) const {
138
145
if (isIntegralPointer ())
139
146
return Pointer (asIntPointer ().Value , asIntPointer ().Desc , Idx);
147
+ if (isFunctionPointer ())
148
+ return Pointer (asFunctionPointer ().getFunction (), Idx);
140
149
141
150
if (asBlockPointer ().Base == RootPtrMark)
142
151
return Pointer (asBlockPointer ().Pointee , RootPtrMark,
@@ -247,18 +256,20 @@ class Pointer {
247
256
bool isZero () const {
248
257
if (isBlockPointer ())
249
258
return asBlockPointer ().Pointee == nullptr ;
259
+ if (isFunctionPointer ())
260
+ return asFunctionPointer ().isZero ();
250
261
assert (isIntegralPointer ());
251
262
return asIntPointer ().Value == 0 && Offset == 0 ;
252
263
}
253
264
// / Checks if the pointer is live.
254
265
bool isLive () const {
255
- if (isIntegralPointer ())
266
+ if (! isBlockPointer ())
256
267
return true ;
257
268
return asBlockPointer ().Pointee && !asBlockPointer ().Pointee ->IsDead ;
258
269
}
259
270
// / Checks if the item is a field in an object.
260
271
bool isField () const {
261
- if (isIntegralPointer ())
272
+ if (! isBlockPointer ())
262
273
return false ;
263
274
264
275
return !isRoot () && getFieldDesc ()->asDecl ();
@@ -268,6 +279,8 @@ class Pointer {
268
279
const Descriptor *getDeclDesc () const {
269
280
if (isIntegralPointer ())
270
281
return asIntPointer ().Desc ;
282
+ if (isFunctionPointer ())
283
+ return nullptr ;
271
284
272
285
assert (isBlockPointer ());
273
286
assert (asBlockPointer ().Pointee );
@@ -279,7 +292,10 @@ class Pointer {
279
292
DeclTy getSource () const {
280
293
if (isBlockPointer ())
281
294
return getDeclDesc ()->getSource ();
282
-
295
+ if (isFunctionPointer ()) {
296
+ const Function *F = asFunctionPointer ().getFunction ();
297
+ return F ? F->getDecl () : DeclTy ();
298
+ }
283
299
assert (isIntegralPointer ());
284
300
return asIntPointer ().Desc ? asIntPointer ().Desc ->getSource () : DeclTy ();
285
301
}
@@ -354,6 +370,7 @@ class Pointer {
354
370
// / Returns the offset into an array.
355
371
unsigned getOffset () const {
356
372
assert (Offset != PastEndMark && " invalid offset" );
373
+ assert (isBlockPointer ());
357
374
if (asBlockPointer ().Base == RootPtrMark)
358
375
return Offset;
359
376
@@ -421,8 +438,14 @@ class Pointer {
421
438
assert (isIntegralPointer ());
422
439
return PointeeStorage.Int ;
423
440
}
441
+ [[nodiscard]] const FunctionPointer &asFunctionPointer () const {
442
+ assert (isFunctionPointer ());
443
+ return PointeeStorage.Fn ;
444
+ }
445
+
424
446
bool isBlockPointer () const { return StorageKind == Storage::Block; }
425
447
bool isIntegralPointer () const { return StorageKind == Storage::Int; }
448
+ bool isFunctionPointer () const { return StorageKind == Storage::Fn; }
426
449
427
450
// / Returns the record descriptor of a class.
428
451
const Record *getRecord () const { return getFieldDesc ()->ElemRecord ; }
@@ -445,7 +468,7 @@ class Pointer {
445
468
}
446
469
// / Checks if the storage is static.
447
470
bool isStatic () const {
448
- if (isIntegralPointer ())
471
+ if (! isBlockPointer ())
449
472
return true ;
450
473
assert (asBlockPointer ().Pointee );
451
474
return asBlockPointer ().Pointee ->isStatic ();
@@ -469,7 +492,7 @@ class Pointer {
469
492
}
470
493
471
494
bool isWeak () const {
472
- if (isIntegralPointer ())
495
+ if (! isBlockPointer ())
473
496
return false ;
474
497
475
498
assert (isBlockPointer ());
@@ -528,8 +551,8 @@ class Pointer {
528
551
529
552
// / Returns the number of elements.
530
553
unsigned getNumElems () const {
531
- if (isIntegralPointer ())
532
- return ~unsigned ( 0 ) ;
554
+ if (! isBlockPointer ())
555
+ return ~0u ;
533
556
return getSize () / elemSize ();
534
557
}
535
558
@@ -555,7 +578,7 @@ class Pointer {
555
578
556
579
// / Checks if the index is one past end.
557
580
bool isOnePastEnd () const {
558
- if (isIntegralPointer ())
581
+ if (isIntegralPointer () || isFunctionPointer () )
559
582
return false ;
560
583
561
584
if (!asBlockPointer ().Pointee )
@@ -692,6 +715,7 @@ class Pointer {
692
715
union {
693
716
BlockPointer BS;
694
717
IntPointer Int;
718
+ FunctionPointer Fn;
695
719
} PointeeStorage;
696
720
Storage StorageKind = Storage::Int;
697
721
};
0 commit comments