Experiment with using first-class aggregates to represent member function
pointers. I find the resulting code to be substantially cleaner, and it
makes it very easy to use the same APIs for data member pointers (which I have
conscientiously avoided here), and it avoids a plethora of potential
inefficiencies due to excessive memory copying, but we'll have to see if it
actually works.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111776 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index e0335b6..b97e725 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -460,7 +460,7 @@
llvm::Constant *VisitUnaryAddrOf(UnaryOperator *E) {
if (const MemberPointerType *MPT =
- E->getType()->getAs<MemberPointerType>()) {
+ E->getType()->getAs<MemberPointerType>()) {
QualType T = MPT->getPointeeType();
DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
@@ -533,13 +533,21 @@
llvm::StructType::get(C->getType()->getContext(), Types, false);
return llvm::ConstantStruct::get(STy, Elts);
}
- case CastExpr::CK_NullToMemberPointer:
- return CGM.getCXXABI().EmitNullMemberFunctionPointer(
- E->getType()->getAs<MemberPointerType>());
+ case CastExpr::CK_NullToMemberPointer: {
+ const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
+ if (MPT->getPointeeType()->isFunctionType())
+ return CGM.getCXXABI().EmitNullMemberFunctionPointer(MPT);
+ return CGM.EmitNullConstant(E->getType());
+ }
case CastExpr::CK_BaseToDerivedMemberPointer: {
- Expr *SubExpr = E->getSubExpr();
+ const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
+ // TODO: support data-member conversions here!
+ if (!MPT->getPointeeType()->isFunctionType())
+ return 0;
+
+ Expr *SubExpr = E->getSubExpr();
llvm::Constant *C =
CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
if (!C) return 0;