TestPrintf
This commit is contained in:
11
ssa/decl.go
11
ssa/decl.go
@@ -105,19 +105,24 @@ type aFunction struct {
|
|||||||
Expr
|
Expr
|
||||||
prog Program
|
prog Program
|
||||||
|
|
||||||
params []Type
|
params []Type
|
||||||
|
hasVArg bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Function = *aFunction
|
type Function = *aFunction
|
||||||
|
|
||||||
func newFunction(fn llvm.Value, t Type, prog Program) Function {
|
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)
|
sig := fn.t.(*types.Signature)
|
||||||
in := sig.Params()
|
in := sig.Params()
|
||||||
if n := in.Len(); n > 0 {
|
if n := in.Len(); n > 0 {
|
||||||
|
if hasVArg = HasVArg(in, n); hasVArg {
|
||||||
|
n--
|
||||||
|
}
|
||||||
params = make([]Type, n)
|
params = make([]Type, n)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
params[i] = prog.llvmType(in.At(i).Type())
|
params[i] = prog.llvmType(in.At(i).Type())
|
||||||
|
|||||||
@@ -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) {
|
func TestBinOp(t *testing.T) {
|
||||||
prog := NewProgram(nil)
|
prog := NewProgram(nil)
|
||||||
pkg := prog.NewPackage("bar", "foo/bar")
|
pkg := prog.NewPackage("bar", "foo/bar")
|
||||||
|
|||||||
57
ssa/type.go
57
ssa/type.go
@@ -18,6 +18,7 @@ package ssa
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"go/types"
|
"go/types"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/goplus/llvm"
|
"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 {
|
type aType struct {
|
||||||
ll llvm.Type
|
ll llvm.Type
|
||||||
t types.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}
|
return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkInvalid}
|
||||||
case *types.Chan:
|
case *types.Chan:
|
||||||
}
|
}
|
||||||
|
log.Println("toLLVMType: todo -", typ)
|
||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,30 +216,39 @@ func (p Program) toLLVMStruct(typ *types.Struct) Type {
|
|||||||
return &aType{p.ctx.StructType(fields, false), typ, vkInvalid}
|
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()
|
n := typ.NumFields()
|
||||||
fields := make([]llvm.Type, n)
|
if n > 0 {
|
||||||
for i := 0; i < n; i++ {
|
fields = make([]llvm.Type, n)
|
||||||
fields[i] = p.llvmType(typ.Field(i).Type()).ll
|
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 {
|
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 {
|
func (p Program) toLLVMTypes(t *types.Tuple, n int) (ret []llvm.Type) {
|
||||||
n := t.Len()
|
if n > 0 {
|
||||||
ret := make([]llvm.Type, n)
|
ret = make([]llvm.Type, n)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
ret[i] = p.llvmType(t.At(i).Type()).ll
|
ret[i] = p.llvmType(t.At(i).Type()).ll
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Program) toLLVMFunc(sig *types.Signature) Type {
|
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()
|
out := sig.Results()
|
||||||
var ret llvm.Type
|
var ret llvm.Type
|
||||||
switch nret := out.Len(); nret {
|
switch nret := out.Len(); nret {
|
||||||
@@ -230,7 +259,7 @@ func (p Program) toLLVMFunc(sig *types.Signature) Type {
|
|||||||
default:
|
default:
|
||||||
ret = p.toLLVMTuple(out)
|
ret = p.toLLVMTuple(out)
|
||||||
}
|
}
|
||||||
ft := llvm.FunctionType(ret, params, sig.Variadic())
|
ft := llvm.FunctionType(ret, params, hasVArg)
|
||||||
return &aType{ft, sig, vkFunc}
|
return &aType{ft, sig, vkFunc}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user