@@ -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 ());
@@ -2756,6 +2802,8 @@ bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
2756
2802
return this ->emitNullPtr (nullptr , E);
2757
2803
case PT_FnPtr:
2758
2804
return this ->emitNullFnPtr (nullptr , E);
2805
+ case PT_MemberPtr:
2806
+ return this ->emitNullMemberPtr (nullptr , E);
2759
2807
case PT_Float: {
2760
2808
return this ->emitConstFloat (APFloat::getZero (Ctx.getFloatSemantics (QT)), E);
2761
2809
}
@@ -2858,6 +2906,7 @@ bool ByteCodeExprGen<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
2858
2906
return this ->emitConstBool (Value, E);
2859
2907
case PT_Ptr:
2860
2908
case PT_FnPtr:
2909
+ case PT_MemberPtr:
2861
2910
case PT_Float:
2862
2911
case PT_IntAP:
2863
2912
case PT_IntAPS:
@@ -3281,10 +3330,28 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
3281
3330
}
3282
3331
}
3283
3332
3333
+ std::optional<unsigned > CalleeOffset;
3284
3334
// Add the (optional, implicit) This pointer.
3285
3335
if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
3286
- if (!this ->visit (MC->getImplicitObjectArgument ()))
3287
- return false ;
3336
+ if (!FuncDecl && classifyPrim (E->getCallee ()) == PT_MemberPtr) {
3337
+ // If we end up creating a CallPtr op for this, we need the base of the
3338
+ // member pointer as the instance pointer, and later extract the function
3339
+ // decl as the function pointer.
3340
+ const Expr *Callee = E->getCallee ();
3341
+ CalleeOffset =
3342
+ this ->allocateLocalPrimitive (Callee, PT_MemberPtr, true , false );
3343
+ if (!this ->visit (Callee))
3344
+ return false ;
3345
+ if (!this ->emitSetLocal (PT_MemberPtr, *CalleeOffset, E))
3346
+ return false ;
3347
+ if (!this ->emitGetLocal (PT_MemberPtr, *CalleeOffset, E))
3348
+ return false ;
3349
+ if (!this ->emitGetMemberPtrBase (E))
3350
+ return false ;
3351
+ } else {
3352
+ if (!this ->visit (MC->getImplicitObjectArgument ()))
3353
+ return false ;
3354
+ }
3288
3355
}
3289
3356
3290
3357
llvm::BitVector NonNullArgs = collectNonNullArgs (FuncDecl, Args);
@@ -3352,11 +3419,22 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
3352
3419
for (unsigned I = 0 , N = E->getNumArgs (); I != N; ++I)
3353
3420
ArgSize += align (primSize (classify (E->getArg (I)).value_or (PT_Ptr)));
3354
3421
3355
- if (!this ->visit (E->getCallee ()))
3356
- return false ;
3422
+ // Get the callee, either from a member pointer saved in CalleeOffset,
3423
+ // or by just visiting the Callee expr.
3424
+ if (CalleeOffset) {
3425
+ if (!this ->emitGetLocal (PT_MemberPtr, *CalleeOffset, E))
3426
+ return false ;
3427
+ if (!this ->emitGetMemberPtrDecl (E))
3428
+ return false ;
3429
+ if (!this ->emitCallPtr (ArgSize, E, E))
3430
+ return false ;
3431
+ } else {
3432
+ if (!this ->visit (E->getCallee ()))
3433
+ return false ;
3357
3434
3358
- if (!this ->emitCallPtr (ArgSize, E, E))
3359
- return false ;
3435
+ if (!this ->emitCallPtr (ArgSize, E, E))
3436
+ return false ;
3437
+ }
3360
3438
}
3361
3439
3362
3440
// Cleanup for discarded return values.
@@ -3595,6 +3673,11 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
3595
3673
return false ;
3596
3674
return DiscardResult ? this ->emitPop (*T, E) : true ;
3597
3675
case UO_AddrOf: // &x
3676
+ if (E->getType ()->isMemberPointerType ()) {
3677
+ // C++11 [expr.unary.op]p3 has very strict rules on how the address of a
3678
+ // member can be formed.
3679
+ return this ->emitGetMemberPtr (cast<DeclRefExpr>(SubExpr)->getDecl (), E);
3680
+ }
3598
3681
// We should already have a pointer when we get here.
3599
3682
return this ->delegate (SubExpr);
3600
3683
case UO_Deref: // *x
0 commit comments