Implement support for formal arguments.  We can now compile this:

int test(int X, short Y, float Z) {
  return (int)(X*Y+Z);
}

to:

define i32 @test(i32 %X, i16 %Y, float %Z) {
entry:
        %promote = sext i16 %Y to i32           ; <i32> [#uses=1]
        %mul = mul i32 %promote, %X             ; <i32> [#uses=1]
        %promote3 = sitofp i32 %mul to float            ; <float> [#uses=1]
        %add = add float %promote3, %Z          ; <float> [#uses=1]
        %conv = fptosi float %add to i32                ; <i32> [#uses=1]
        ret i32 %conv
}

with:

$ clang -emit-llvm t.c | llvm-as | opt -std-compile-opts | llvm-dis

llvm-svn: 39652
diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp
index bb7a057..6b6f3cb 100644
--- a/clang/CodeGen/CodeGenFunction.cpp
+++ b/clang/CodeGen/CodeGenFunction.cpp
@@ -141,11 +141,16 @@
   return OpaqueType::get();
 }
 
-void  CodeGenFunction::DecodeArgumentTypes(const FunctionTypeProto &FTP, 
-                                           std::vector<const llvm::Type*> &
-                                           ArgTys, SourceLocation Loc) {
-  for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i)
-    ArgTys.push_back(ConvertType(FTP.getArgType(i), Loc));
+void CodeGenFunction::DecodeArgumentTypes(const FunctionTypeProto &FTP, 
+                                          std::vector<const llvm::Type*> &
+                                          ArgTys, SourceLocation Loc) {
+  for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
+    const llvm::Type *Ty = ConvertType(FTP.getArgType(i), Loc);
+    if (Ty->isFirstClassType())
+      ArgTys.push_back(Ty);
+    else
+      ArgTys.push_back(llvm::PointerType::get(Ty));
+  }
 }
 
 void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
@@ -155,14 +160,14 @@
   const llvm::FunctionType *Ty = 
     cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation()));
   
+  // FIXME: param attributes for sext/zext etc.
+  
   CurFuncDecl = FD;
   CurFn = new Function(Ty, Function::ExternalLinkage,
                        FD->getName(), &CGM.getModule());
   
   BasicBlock *EntryBB = new BasicBlock("entry", CurFn);
   
-  // TODO: Walk the decls, creating allocas etc.
-  
   Builder.SetInsertPoint(EntryBB);
 
   // Create a marker to make it easy to insert allocas into the entryblock
@@ -170,7 +175,12 @@
   AllocaInsertPt = Builder.CreateBitCast(UndefValue::get(llvm::Type::Int32Ty),
                                          llvm::Type::Int32Ty, "allocapt");
   
-  // TODO: handle params. 
+  // Emit allocs for param decls. 
+  llvm::Function::arg_iterator AI = CurFn->arg_begin();
+  for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
+    assert(AI != CurFn->arg_end() && "Argument mismatch!");
+    EmitParmDecl(*FD->getParamDecl(i), AI);
+  }
   
   // Emit the function body.
   EmitStmt(FD->getBody());