Merge pull request #22 from xushiwei/q

TestPrintf
This commit is contained in:
xushiwei
2024-04-20 13:54:29 +08:00
committed by GitHub
3 changed files with 66 additions and 17 deletions

View File

@@ -105,19 +105,24 @@ type aFunction struct {
Expr
prog Program
params []Type
params []Type
hasVArg bool
}
type Function = *aFunction
func newFunction(fn llvm.Value, t Type, prog Program) Function {
return &aFunction{Expr{fn, t}, prog, newParams(t, prog)}
params, hasVArg := newParams(t, prog)
return &aFunction{Expr{fn, t}, prog, params, hasVArg}
}
func newParams(fn Type, prog Program) (params []Type) {
func newParams(fn Type, prog Program) (params []Type, hasVArg bool) {
sig := fn.t.(*types.Signature)
in := sig.Params()
if n := in.Len(); n > 0 {
if hasVArg = HasVArg(in, n); hasVArg {
n--
}
params = make([]Type, n)
for i := 0; i < n; i++ {
params[i] = prog.llvmType(in.At(i).Type())

View File

@@ -192,6 +192,21 @@ define { i64, double } @fn(double %0) {
`)
}
func TestPrintf(t *testing.T) {
prog := NewProgram(nil)
pkg := prog.NewPackage("bar", "foo/bar")
pchar := types.NewPointer(types.Typ[types.Int8])
params := types.NewTuple(types.NewVar(0, nil, "format", pchar), VArg())
rets := types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int32]))
sig := types.NewSignatureType(nil, nil, nil, params, rets, false)
pkg.NewFunc("printf", sig)
assertPkg(t, pkg, `; ModuleID = 'foo/bar'
source_filename = "foo/bar"
declare i32 @printf(ptr, ...)
`)
}
func TestBinOp(t *testing.T) {
prog := NewProgram(nil)
pkg := prog.NewPackage("bar", "foo/bar")

View File

@@ -18,6 +18,7 @@ package ssa
import (
"go/types"
"log"
"github.com/goplus/llvm"
)
@@ -40,6 +41,24 @@ const (
// -----------------------------------------------------------------------------
const (
nameValist = "__llgo_va_list"
)
func VArg() *types.Var {
return types.NewParam(0, nil, nameValist, types.Typ[types.Invalid])
}
func IsVArg(arg *types.Var) bool {
return arg.Name() == nameValist
}
func HasVArg(t *types.Tuple, n int) bool {
return n > 0 && IsVArg(t.At(n-1))
}
// -----------------------------------------------------------------------------
type aType struct {
ll llvm.Type
t types.Type
@@ -181,6 +200,7 @@ func (p Program) toLLVMType(typ types.Type) Type {
return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkInvalid}
case *types.Chan:
}
log.Println("toLLVMType: todo -", typ)
panic("todo")
}
@@ -196,30 +216,39 @@ func (p Program) toLLVMStruct(typ *types.Struct) Type {
return &aType{p.ctx.StructType(fields, false), typ, vkInvalid}
}
func (p Program) toLLVMFields(typ *types.Struct) []llvm.Type {
func (p Program) toLLVMFields(typ *types.Struct) (fields []llvm.Type) {
n := typ.NumFields()
fields := make([]llvm.Type, n)
for i := 0; i < n; i++ {
fields[i] = p.llvmType(typ.Field(i).Type()).ll
if n > 0 {
fields = make([]llvm.Type, n)
for i := 0; i < n; i++ {
fields[i] = p.llvmType(typ.Field(i).Type()).ll
}
}
return fields
return
}
func (p Program) toLLVMTuple(t *types.Tuple) llvm.Type {
return p.ctx.StructType(p.toLLVMTypes(t), false)
return p.ctx.StructType(p.toLLVMTypes(t, t.Len()), false)
}
func (p Program) toLLVMTypes(t *types.Tuple) []llvm.Type {
n := t.Len()
ret := make([]llvm.Type, n)
for i := 0; i < n; i++ {
ret[i] = p.llvmType(t.At(i).Type()).ll
func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.Type) {
if n > 0 {
ret = make([]llvm.Type, n)
for i := 0; i < n; i++ {
ret[i] = p.llvmType(t.At(i).Type()).ll
}
}
return ret
return
}
func (p Program) toLLVMFunc(sig *types.Signature) Type {
params := p.toLLVMTypes(sig.Params())
tParams := sig.Params()
n := tParams.Len()
hasVArg := HasVArg(tParams, n)
if hasVArg {
n--
}
params := p.toLLVMTypes(tParams, n)
out := sig.Results()
var ret llvm.Type
switch nret := out.Len(); nret {
@@ -230,7 +259,7 @@ func (p Program) toLLVMFunc(sig *types.Signature) Type {
default:
ret = p.toLLVMTuple(out)
}
ft := llvm.FunctionType(ret, params, sig.Variadic())
ft := llvm.FunctionType(ret, params, hasVArg)
return &aType{ft, sig, vkFunc}
}