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);
   }