Move ABI specific code for functions / calls to CGCall.cpp:
 - Factor out EmitFunction{Pro,Epi}log


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56031 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index a3a330e..8900432 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -114,3 +114,105 @@
   // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
   constructParamAttrListInternal(0, ArgTypes, PAL);
 }
+
+/***/
+
+void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn,
+                                         QualType RetTy, 
+                                         const FunctionArgList &Args) {
+  // Emit allocs for param decls.  Give the LLVM Argument nodes names.
+  llvm::Function::arg_iterator AI = Fn->arg_begin();
+  
+  // Name the struct return argument.
+  if (hasAggregateLLVMType(RetTy)) {
+    AI->setName("agg.result");
+    ++AI;
+  }
+     
+  for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
+       i != e; ++i, ++AI) {
+    const VarDecl *Arg = i->first;
+    QualType T = i->second;
+    assert(AI != Fn->arg_end() && "Argument mismatch!");
+    llvm::Value* V = AI;
+    if (!getContext().typesAreCompatible(T, Arg->getType())) {
+      // This must be a promotion, for something like
+      // "void a(x) short x; {..."
+      V = EmitScalarConversion(V, T, Arg->getType());
+      }
+    EmitParmDecl(*Arg, V);
+  }
+  assert(AI == Fn->arg_end() && "Argument mismatch!");
+}
+
+void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, 
+                                         llvm::Value *ReturnValue) {
+  if (!ReturnValue) {
+    Builder.CreateRetVoid();
+  } else { 
+    if (!hasAggregateLLVMType(RetTy)) {
+      Builder.CreateRet(Builder.CreateLoad(ReturnValue));
+    } else if (RetTy->isAnyComplexType()) {
+      EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
+      Builder.CreateRetVoid();
+    } else {
+      EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
+      Builder.CreateRetVoid();
+    }
+  }
+}
+
+RValue CodeGenFunction::EmitCall(llvm::Value *Callee, 
+                                 QualType ResultType, 
+                                 const CallArgList &CallArgs) {
+  // FIXME: Factor out code to load from args into locals into target.
+  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. :(
+    TempArg0 = CreateTempAlloca(ConvertType(ResultType));
+    Args.push_back(TempArg0);
+  }
+  
+  for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); 
+       I != E; ++I) {
+    RValue RV = I->first;
+    if (RV.isScalar()) {
+      Args.push_back(RV.getScalarVal());
+    } else if (RV.isComplex()) {
+      // Make a temporary alloca to pass the argument.
+      Args.push_back(CreateTempAlloca(ConvertType(I->second)));
+      StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); 
+    } else {
+      Args.push_back(RV.getAggregateAddr());
+    }
+  }
+  
+  llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
+  CGCallInfo CallInfo(ResultType, CallArgs);
+
+  CodeGen::ParamAttrListType ParamAttrList;
+  CallInfo.constructParamAttrList(ParamAttrList);
+  CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), 
+                                         ParamAttrList.size()));  
+
+  if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee))
+    CI->setCallingConv(F->getCallingConv());
+  if (CI->getType() != llvm::Type::VoidTy)
+    CI->setName("call");
+  else if (ResultType->isAnyComplexType())
+    return RValue::getComplex(LoadComplexFromAddr(TempArg0, false));
+  else if (hasAggregateLLVMType(ResultType))
+    // Struct return.
+    return RValue::getAggregate(TempArg0);
+  else {
+    // void return.
+    assert(ResultType->isVoidType() && "Should only have a void expr here");
+    CI = 0;
+  }
+      
+  return RValue::get(CI);  
+}