ir-gen related patch for type conversion
with class type conversion methods. WIP.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80365 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 3c7115d..04dbe97 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -262,19 +262,20 @@
          "EmitCXXFunctionalCastExpr - called with wrong cast");
   
   CXXMethodDecl *MD = E->getTypeConversionMethod();
+  assert(MD && "EmitCXXFunctionalCastExpr - null conversion method");
+  assert(isa<CXXConversionDecl>(MD) && "EmitCXXFunctionalCastExpr - not"
+         " method decl");
   const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType();
-  llvm::Constant *Callee;
-  if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(MD))
-    Callee = CGM.GetAddrOfCXXConstructor(CD, Ctor_Complete); 
-  else {
-    const llvm::Type *Ty = 
-      CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 
-                                     FPT->isVariadic());
-    Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
-  }
-  llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress();
   
-  return EmitCXXMemberCall(MD, Callee, This, 0, 0);
+  const llvm::Type *Ty = 
+    CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), 
+                                   FPT->isVariadic());
+  llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty);
+  llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress();
+  RValue RV = EmitCXXMemberCall(MD, Callee, This, 0, 0);
+  if (RV.isAggregate())
+    RV = RValue::get(RV.getAggregateAddr()); 
+  return RV;
 }
 
 llvm::Value *CodeGenFunction::LoadCXXThis() {
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 0d45ce9..24442c3 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1172,6 +1172,11 @@
 /// all the reasons that casts are permitted with aggregate result, including
 /// noop aggregate casts, and cast from scalar to union.
 LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
+  if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) {
+    const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E);
+    return  LValue::MakeAddr(EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0);
+  }
+  
   // If this is an aggregate-to-aggregate cast, just use the input's address as
   // the lvalue.
   if (E->getCastKind() == CastExpr::CK_NoOp)