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/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 753af76..55abaa3 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -67,10 +67,8 @@
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
QualType BoolTy = getContext().BoolTy;
if (E->getType()->isMemberFunctionPointerType()) {
- LValue LV = EmitAggExprToLValue(E);
-
- return CGM.getCXXABI().EmitMemberFunctionPointerIsNotNull(CGF,
- LV.getAddress(),
+ llvm::Value *MemPtr = EmitScalarExpr(E);
+ return CGM.getCXXABI().EmitMemberFunctionPointerIsNotNull(CGF, MemPtr,
E->getType()->getAs<MemberPointerType>());
}
if (!E->getType()->isAnyComplexType())
@@ -614,18 +612,15 @@
if (LV.isSimple()) {
llvm::Value *Ptr = LV.getAddress();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- // Simple scalar l-value.
- //
- // FIXME: We shouldn't have to use isSingleValueType here.
- if (EltTy->isSingleValueType())
- return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
- LV.getAlignment(), ExprType));
+ // Functions are l-values that don't require loading.
+ if (ExprType->isFunctionType())
+ return RValue::get(Ptr);
- assert(ExprType->isFunctionType() && "Unknown scalar value");
- return RValue::get(Ptr);
+ // Everything needs a load.
+ return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
+ LV.getAlignment(), ExprType));
+
}
if (LV.isVectorElt()) {
@@ -1177,12 +1172,19 @@
return LV;
}
+ // If we're emitting an instance method as an independent lvalue,
+ // we're actually emitting a member pointer.
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
+ if (MD->isInstance()) {
+ llvm::Value *V = CGM.getCXXABI().EmitMemberFunctionPointer(MD);
+ return MakeAddrLValue(V, MD->getType(), Alignment);
+ }
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
return EmitFunctionDeclLValue(*this, E, FD);
- // FIXME: the qualifier check does not seem sufficient here
- if (E->getQualifier()) {
- const FieldDecl *FD = cast<FieldDecl>(ND);
+ // If we're emitting a field as an independent lvalue, we're
+ // actually emitting a member pointer.
+ if (const FieldDecl *FD = dyn_cast<FieldDecl>(ND)) {
llvm::Value *V = CGM.EmitPointerToDataMember(FD);
return MakeAddrLValue(V, FD->getType(), Alignment);
}