diff --git a/compiler/calls.go b/compiler/calls.go index 08952c4db..fb8238062 100644 --- a/compiler/calls.go +++ b/compiler/calls.go @@ -102,6 +102,10 @@ func (b *builder) createInvoke(fnType llvm.Type, fn llvm.Value, args []llvm.Valu // Expand an argument type to a list that can be used in a function call // parameter list. func (c *compilerContext) expandFormalParamType(t llvm.Type, name string, goType types.Type) []paramInfo { + return c.expandDirectFormalParamType(t, name, goType) +} + +func (c *compilerContext) expandDirectFormalParamType(t llvm.Type, name string, goType types.Type) []paramInfo { switch t.TypeKind() { case llvm.StructTypeKind: fieldInfos := c.flattenAggregateType(t, name, goType) diff --git a/compiler/func.go b/compiler/func.go index ed5808c72..c5a48a7fe 100644 --- a/compiler/func.go +++ b/compiler/func.go @@ -10,6 +10,21 @@ import ( "tinygo.org/x/go-llvm" ) +func (c *compilerContext) getLLVMResultType(sig *types.Signature) llvm.Type { + switch sig.Results().Len() { + case 0: + return c.ctx.VoidType() + case 1: + return c.getLLVMType(sig.Results().At(0).Type()) + default: + results := make([]llvm.Type, sig.Results().Len()) + for i := range results { + results[i] = c.getLLVMType(sig.Results().At(i).Type()) + } + return c.ctx.StructType(results, false) + } +} + // createFuncValue creates a function value from a raw function pointer with no // context. func (b *builder) createFuncValue(funcPtr, context llvm.Value, sig *types.Signature) llvm.Value { @@ -48,25 +63,7 @@ func (c *compilerContext) getFuncType(typ *types.Signature) llvm.Type { // getLLVMFunctionType returns a LLVM function type for a given signature. func (c *compilerContext) getLLVMFunctionType(typ *types.Signature) llvm.Type { - // Get the return type. - var returnType llvm.Type - switch typ.Results().Len() { - case 0: - // No return values. - returnType = c.ctx.VoidType() - case 1: - // Just one return value. - returnType = c.getLLVMType(typ.Results().At(0).Type()) - default: - // Multiple return values. Put them together in a struct. - // This appears to be the common way to handle multiple return values in - // LLVM. - members := make([]llvm.Type, typ.Results().Len()) - for i := 0; i < typ.Results().Len(); i++ { - members[i] = c.getLLVMType(typ.Results().At(i).Type()) - } - returnType = c.ctx.StructType(members, false) - } + returnType := c.getLLVMResultType(typ) // Get the parameter types. var paramTypes []llvm.Type diff --git a/compiler/symbol.go b/compiler/symbol.go index 90dfc0d08..891981fb5 100644 --- a/compiler/symbol.go +++ b/compiler/symbol.go @@ -79,18 +79,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value) return llvmFn.GlobalValueType(), llvmFn } - var retType llvm.Type - if fn.Signature.Results() == nil { - retType = c.ctx.VoidType() - } else if fn.Signature.Results().Len() == 1 { - retType = c.getLLVMType(fn.Signature.Results().At(0).Type()) - } else { - results := make([]llvm.Type, 0, fn.Signature.Results().Len()) - for v := range fn.Signature.Results().Variables() { - results = append(results, c.getLLVMType(v.Type())) - } - retType = c.ctx.StructType(results, false) - } + retType := c.getLLVMResultType(fn.Signature) var paramInfos []paramInfo for _, param := range getParams(fn.Signature) {