@@ -100,6 +100,35 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
100
100
return this ->emitMemcpy (CE);
101
101
}
102
102
103
+ case CK_DerivedToBaseMemberPointer: {
104
+ assert (classifyPrim (CE->getType ()) == PT_MemberPtr);
105
+ assert (classifyPrim (SubExpr->getType ()) == PT_MemberPtr);
106
+ const auto *FromMP = SubExpr->getType ()->getAs <MemberPointerType>();
107
+ const auto *ToMP = CE->getType ()->getAs <MemberPointerType>();
108
+
109
+ unsigned DerivedOffset = collectBaseOffset (QualType (ToMP->getClass (), 0 ),
110
+ QualType (FromMP->getClass (), 0 ));
111
+
112
+ if (!this ->visit (SubExpr))
113
+ return false ;
114
+
115
+ return this ->emitGetMemberPtrBasePop (DerivedOffset, CE);
116
+ }
117
+
118
+ case CK_BaseToDerivedMemberPointer: {
119
+ assert (classifyPrim (CE) == PT_MemberPtr);
120
+ assert (classifyPrim (SubExpr) == PT_MemberPtr);
121
+ const auto *FromMP = SubExpr->getType ()->getAs <MemberPointerType>();
122
+ const auto *ToMP = CE->getType ()->getAs <MemberPointerType>();
123
+
124
+ unsigned DerivedOffset = collectBaseOffset (QualType (FromMP->getClass (), 0 ),
125
+ QualType (ToMP->getClass (), 0 ));
126
+
127
+ if (!this ->visit (SubExpr))
128
+ return false ;
129
+ return this ->emitGetMemberPtrBasePop (-DerivedOffset, CE);
130
+ }
131
+
103
132
case CK_UncheckedDerivedToBase:
104
133
case CK_DerivedToBase: {
105
134
if (!this ->visit (SubExpr))
@@ -187,7 +216,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
187
216
return this ->emitCastFloatingIntegral (*ToT, CE);
188
217
}
189
218
190
- case CK_NullToPointer: {
219
+ case CK_NullToPointer:
220
+ case CK_NullToMemberPointer: {
191
221
if (DiscardResult)
192
222
return true ;
193
223
@@ -326,7 +356,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
326
356
return this ->emitCast (*FromT, *ToT, CE);
327
357
}
328
358
329
- case CK_PointerToBoolean: {
359
+ case CK_PointerToBoolean:
360
+ case CK_MemberPointerToBoolean: {
330
361
PrimType PtrT = classifyPrim (SubExpr->getType ());
331
362
332
363
// Just emit p != nullptr for this.
@@ -534,8 +565,23 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
534
565
BO->isComparisonOp ())
535
566
return this ->emitComplexComparison (LHS, RHS, BO);
536
567
537
- if (BO->isPtrMemOp ())
538
- return this ->visit (RHS);
568
+ if (BO->isPtrMemOp ()) {
569
+ if (!this ->visit (LHS))
570
+ return false ;
571
+
572
+ if (!this ->visit (RHS))
573
+ return false ;
574
+
575
+ if (!this ->emitToMemberPtr (BO))
576
+ return false ;
577
+
578
+ if (classifyPrim (BO) == PT_MemberPtr)
579
+ return true ;
580
+
581
+ if (!this ->emitCastMemberPtrPtr (BO))
582
+ return false ;
583
+ return DiscardResult ? this ->emitPopPtr (BO) : true ;
584
+ }
539
585
540
586
// Typecheck the args.
541
587
std::optional<PrimType> LT = classify (LHS->getType ());
@@ -2773,6 +2819,8 @@ bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
2773
2819
return this ->emitNullPtr (nullptr , E);
2774
2820
case PT_FnPtr:
2775
2821
return this ->emitNullFnPtr (nullptr , E);
2822
+ case PT_MemberPtr:
2823
+ return this ->emitNullMemberPtr (nullptr , E);
2776
2824
case PT_Float: {
2777
2825
return this ->emitConstFloat (APFloat::getZero (Ctx.getFloatSemantics (QT)), E);
2778
2826
}
@@ -2875,6 +2923,7 @@ bool ByteCodeExprGen<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
2875
2923
return this ->emitConstBool (Value, E);
2876
2924
case PT_Ptr:
2877
2925
case PT_FnPtr:
2926
+ case PT_MemberPtr:
2878
2927
case PT_Float:
2879
2928
case PT_IntAP:
2880
2929
case PT_IntAPS:
@@ -3308,10 +3357,27 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
3308
3357
}
3309
3358
}
3310
3359
3360
+ std::optional<unsigned > CalleeOffset;
3311
3361
// Add the (optional, implicit) This pointer.
3312
3362
if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
3313
- if (!this ->visit (MC->getImplicitObjectArgument ()))
3363
+ if (!FuncDecl && classifyPrim (E->getCallee ()) == PT_MemberPtr) {
3364
+ // If we end up creating a CallPtr op for this, we need the base of the
3365
+ // member pointer as the instance pointer, and later extract the function
3366
+ // decl as the function pointer.
3367
+ const Expr *Callee = E->getCallee ();
3368
+ CalleeOffset =
3369
+ this ->allocateLocalPrimitive (Callee, PT_MemberPtr, true , false );
3370
+ if (!this ->visit (Callee))
3371
+ return false ;
3372
+ if (!this ->emitSetLocal (PT_MemberPtr, *CalleeOffset, E))
3373
+ return false ;
3374
+ if (!this ->emitGetLocal (PT_MemberPtr, *CalleeOffset, E))
3375
+ return false ;
3376
+ if (!this ->emitGetMemberPtrBase (E))
3377
+ return false ;
3378
+ } else if (!this ->visit (MC->getImplicitObjectArgument ())) {
3314
3379
return false ;
3380
+ }
3315
3381
}
3316
3382
3317
3383
llvm::BitVector NonNullArgs = collectNonNullArgs (FuncDecl, Args);
@@ -3380,11 +3446,22 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
3380
3446
for (unsigned I = 0 , N = E->getNumArgs (); I != N; ++I)
3381
3447
ArgSize += align (primSize (classify (E->getArg (I)).value_or (PT_Ptr)));
3382
3448
3383
- if (!this ->visit (E->getCallee ()))
3384
- return false ;
3449
+ // Get the callee, either from a member pointer saved in CalleeOffset,
3450
+ // or by just visiting the Callee expr.
3451
+ if (CalleeOffset) {
3452
+ if (!this ->emitGetLocal (PT_MemberPtr, *CalleeOffset, E))
3453
+ return false ;
3454
+ if (!this ->emitGetMemberPtrDecl (E))
3455
+ return false ;
3456
+ if (!this ->emitCallPtr (ArgSize, E, E))
3457
+ return false ;
3458
+ } else {
3459
+ if (!this ->visit (E->getCallee ()))
3460
+ return false ;
3385
3461
3386
- if (!this ->emitCallPtr (ArgSize, E, E))
3387
- return false ;
3462
+ if (!this ->emitCallPtr (ArgSize, E, E))
3463
+ return false ;
3464
+ }
3388
3465
}
3389
3466
3390
3467
// Cleanup for discarded return values.
@@ -3623,6 +3700,11 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
3623
3700
return false ;
3624
3701
return DiscardResult ? this ->emitPop (*T, E) : true ;
3625
3702
case UO_AddrOf: // &x
3703
+ if (E->getType ()->isMemberPointerType ()) {
3704
+ // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
3705
+ // member can be formed.
3706
+ return this ->emitGetMemberPtr (cast<DeclRefExpr>(SubExpr)->getDecl (), E);
3707
+ }
3626
3708
// We should already have a pointer when we get here.
3627
3709
return this ->delegate (SubExpr);
3628
3710
case UO_Deref: // *x
0 commit comments