@@ -100,6 +100,35 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
100100 return this ->emitMemcpy (CE);
101101 }
102102
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+
103132 case CK_UncheckedDerivedToBase:
104133 case CK_DerivedToBase: {
105134 if (!this ->visit (SubExpr))
@@ -187,7 +216,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
187216 return this ->emitCastFloatingIntegral (*ToT, CE);
188217 }
189218
190- case CK_NullToPointer: {
219+ case CK_NullToPointer:
220+ case CK_NullToMemberPointer: {
191221 if (DiscardResult)
192222 return true ;
193223
@@ -326,7 +356,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
326356 return this ->emitCast (*FromT, *ToT, CE);
327357 }
328358
329- case CK_PointerToBoolean: {
359+ case CK_PointerToBoolean:
360+ case CK_MemberPointerToBoolean: {
330361 PrimType PtrT = classifyPrim (SubExpr->getType ());
331362
332363 // Just emit p != nullptr for this.
@@ -534,8 +565,23 @@ bool ByteCodeExprGen<Emitter>::VisitBinaryOperator(const BinaryOperator *BO) {
534565 BO->isComparisonOp ())
535566 return this ->emitComplexComparison (LHS, RHS, BO);
536567
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+ }
539585
540586 // Typecheck the args.
541587 std::optional<PrimType> LT = classify (LHS->getType ());
@@ -2773,6 +2819,8 @@ bool ByteCodeExprGen<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
27732819 return this ->emitNullPtr (nullptr , E);
27742820 case PT_FnPtr:
27752821 return this ->emitNullFnPtr (nullptr , E);
2822+ case PT_MemberPtr:
2823+ return this ->emitNullMemberPtr (nullptr , E);
27762824 case PT_Float: {
27772825 return this ->emitConstFloat (APFloat::getZero (Ctx.getFloatSemantics (QT)), E);
27782826 }
@@ -2875,6 +2923,7 @@ bool ByteCodeExprGen<Emitter>::emitConst(T Value, PrimType Ty, const Expr *E) {
28752923 return this ->emitConstBool (Value, E);
28762924 case PT_Ptr:
28772925 case PT_FnPtr:
2926+ case PT_MemberPtr:
28782927 case PT_Float:
28792928 case PT_IntAP:
28802929 case PT_IntAPS:
@@ -3308,10 +3357,27 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
33083357 }
33093358 }
33103359
3360+ std::optional<unsigned > CalleeOffset;
33113361 // Add the (optional, implicit) This pointer.
33123362 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 ())) {
33143379 return false ;
3380+ }
33153381 }
33163382
33173383 llvm::BitVector NonNullArgs = collectNonNullArgs (FuncDecl, Args);
@@ -3380,11 +3446,22 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
33803446 for (unsigned I = 0 , N = E->getNumArgs (); I != N; ++I)
33813447 ArgSize += align (primSize (classify (E->getArg (I)).value_or (PT_Ptr)));
33823448
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 ;
33853461
3386- if (!this ->emitCallPtr (ArgSize, E, E))
3387- return false ;
3462+ if (!this ->emitCallPtr (ArgSize, E, E))
3463+ return false ;
3464+ }
33883465 }
33893466
33903467 // Cleanup for discarded return values.
@@ -3623,6 +3700,11 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
36233700 return false ;
36243701 return DiscardResult ? this ->emitPop (*T, E) : true ;
36253702 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+ }
36263708 // We should already have a pointer when we get here.
36273709 return this ->delegate (SubExpr);
36283710 case UO_Deref: // *x
0 commit comments