Refactor handling of calls:
 - Added CodeGenFunction::EmitCall which just takes the callee, return
   type, and a list of (Value*,QualType) pairs.
 - Added CodeGenFunction::EmitCallArg which handles emitting code for
   a call argument and turning it into an appropriate
   (Value*,QualType) pair.
 - Changed Objective-C runtime interface so that the actual emission
   of arguments for message sends is (once again) done in the code to
   emit a message send.

No intended functionality change, this is prep work for better ABI
support and for Objective-C property setter support.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55560 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index d3872c1..c8aa261 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -822,66 +822,77 @@
   // type.
   FnType = FnType->getAsPointerType()->getPointeeType();
   QualType ResultType = FnType->getAsFunctionType()->getResultType();
-  return EmitCallExprExt(Callee, ResultType, ArgBeg, ArgEnd, 0, 0);
+
+  CallArgList Args;
+  for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I)
+    EmitCallArg(*I, Args);
+
+  return EmitCall(Callee, ResultType, Args);
 }
 
-RValue CodeGenFunction::EmitCallExprExt(llvm::Value *Callee, 
-                                        QualType ResultType, 
-                                        CallExpr::const_arg_iterator ArgBeg,
-                                        CallExpr::const_arg_iterator ArgEnd,
-                                        llvm::Value **ExtraArgs,
-                                        unsigned NumExtraArgs) {
-  llvm::SmallVector<llvm::Value*, 16> Args;
+void CodeGenFunction::EmitCallArg(const Expr *E, CallArgList &Args) {
+  QualType ArgTy = E->getType();
+  llvm::Value *ArgValue;
   
+  if (!hasAggregateLLVMType(ArgTy)) {
+    // Scalar argument is passed by-value.
+    ArgValue = EmitScalarExpr(E);
+  } else if (ArgTy->isAnyComplexType()) {
+    // Make a temporary alloca to pass the argument.
+    ArgValue = CreateTempAlloca(ConvertType(ArgTy));
+    EmitComplexExprIntoAddr(E, ArgValue, false);
+  } else {
+    ArgValue = CreateTempAlloca(ConvertType(ArgTy));
+    EmitAggExpr(E, ArgValue, false);
+  }
+  
+  Args.push_back(std::make_pair(ArgValue, E->getType()));
+}
+
+RValue CodeGenFunction::EmitCall(llvm::Value *Callee, 
+                                 QualType ResultType, 
+                                 const CallArgList &CallArgs) {
+  llvm::SmallVector<llvm::Value*, 16> Args;
+  llvm::Value *TempArg0 = 0;
+
   // Handle struct-return functions by passing a pointer to the location that
   // we would like to return into.
   if (hasAggregateLLVMType(ResultType)) {
     // Create a temporary alloca to hold the result of the call. :(
-    Args.push_back(CreateTempAlloca(ConvertType(ResultType)));
-    // FIXME: set the stret attribute on the argument.
+    TempArg0 = CreateTempAlloca(ConvertType(ResultType));
+    Args.push_back(TempArg0);
   }
   
-  Args.insert(Args.end(), ExtraArgs, ExtraArgs + NumExtraArgs);
-
-  for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I) {
-    QualType ArgTy = I->getType();
-
-    if (!hasAggregateLLVMType(ArgTy)) {
-      // Scalar argument is passed by-value.
-      Args.push_back(EmitScalarExpr(*I));
-    } else if (ArgTy->isAnyComplexType()) {
-      // Make a temporary alloca to pass the argument.
-      llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
-      EmitComplexExprIntoAddr(*I, DestMem, false);
-      Args.push_back(DestMem);
-    } else {
-      llvm::Value *DestMem = CreateTempAlloca(ConvertType(ArgTy));
-      EmitAggExpr(*I, DestMem, false);
-      Args.push_back(DestMem);
-    }
-  }
+  for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); 
+       I != E; ++I)
+    Args.push_back(I->first);
   
   llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
 
   // Note that there is parallel code in SetFunctionAttributes in CodeGenModule
   llvm::SmallVector<llvm::ParamAttrsWithIndex, 8> ParamAttrList;
-  if (hasAggregateLLVMType(ResultType))
+  unsigned Index = 1;
+  if (TempArg0) {
     ParamAttrList.push_back(
-        llvm::ParamAttrsWithIndex::get(1, llvm::ParamAttr::StructRet));
-  unsigned increment = NumExtraArgs + (hasAggregateLLVMType(ResultType) ? 2 : 1);
-  
-  unsigned i = 0;
-  for (CallExpr::const_arg_iterator I = ArgBeg; I != ArgEnd; ++I, ++i) {
-    QualType ParamType = I->getType();
+        llvm::ParamAttrsWithIndex::get(Index, llvm::ParamAttr::StructRet));
+    ++Index;
+  }
+
+  for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); 
+       I != E; ++I, ++Index) {
+    QualType ParamType = I->second;
     unsigned ParamAttrs = 0;
     if (ParamType->isRecordType())
       ParamAttrs |= llvm::ParamAttr::ByVal;
-    if (ParamType->isSignedIntegerType() && ParamType->isPromotableIntegerType())
-      ParamAttrs |= llvm::ParamAttr::SExt;
-    if (ParamType->isUnsignedIntegerType() && ParamType->isPromotableIntegerType())
-      ParamAttrs |= llvm::ParamAttr::ZExt;
+    if (ParamType->isPromotableIntegerType()) {
+      if (ParamType->isSignedIntegerType()) {
+        ParamAttrs |= llvm::ParamAttr::SExt;
+      } else if (ParamType->isUnsignedIntegerType()) {
+        ParamAttrs |= llvm::ParamAttr::ZExt;
+      }
+    }
     if (ParamAttrs)
-      ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(i + increment,
+      ParamAttrList.push_back(llvm::ParamAttrsWithIndex::get(Index,
                                                              ParamAttrs));
   }
   CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(),
@@ -892,15 +903,15 @@
   if (CI->getType() != llvm::Type::VoidTy)
     CI->setName("call");
   else if (ResultType->isAnyComplexType())
-    return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
+    return RValue::getComplex(LoadComplexFromAddr(TempArg0, false));
   else if (hasAggregateLLVMType(ResultType))
     // Struct return.
-    return RValue::getAggregate(Args[0]);
+    return RValue::getAggregate(TempArg0);
   else {
     // void return.
     assert(ResultType->isVoidType() && "Should only have a void expr here");
     CI = 0;
   }
       
-  return RValue::get(CI);
+  return RValue::get(CI);  
 }