diff --git a/ssa/func.go b/ssa/func.go index 13ef513a..3890bff7 100644 --- a/ssa/func.go +++ b/ssa/func.go @@ -16,6 +16,10 @@ package ssa +import ( + "github.com/goplus/llvm" +) + // Function represents the parameters, results, and code of a function // or method. // @@ -66,4 +70,5 @@ package ssa // the generic method. TypeArgs() refers to [string,U] or [string,int], // respectively, and is nil in the generic method. type Function struct { + impl llvm.Value } diff --git a/ssa/package.go b/ssa/package.go index cb03fd01..1c897fc7 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -81,7 +81,8 @@ func (p *Package) NewVar(name string, typ types.Type) *Global { } func (p *Package) NewFunc(name string, sig *types.Signature) *Function { - return &Function{} + fn := llvm.AddFunction(p.mod, name, p.prog.llvmSignature(sig)) + return &Function{fn} } func (p *Package) String() string { diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index 743ac761..eed37539 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -78,3 +78,16 @@ source_filename = "foo/bar" @a = external global %Empty `) } + +func TestFunc(t *testing.T) { + prog := NewProgram(nil) + pkg := prog.NewPackage("bar", "foo/bar") + params := types.NewTuple(types.NewVar(0, nil, "a", types.Typ[types.Int])) + sig := types.NewSignatureType(nil, nil, nil, params, nil, false) + pkg.NewFunc("fn", sig) + assertPkg(t, pkg, `; ModuleID = 'foo/bar' +source_filename = "foo/bar" + +declare void @fn(i64) +`) +} diff --git a/ssa/type.go b/ssa/type.go index b752effe..d4a87ea9 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -38,6 +38,15 @@ func (p *Program) llvmType(typ types.Type) llvm.Type { return ret } +func (p *Program) llvmSignature(sig *types.Signature) llvm.Type { + if v := p.typs.At(sig); v != nil { + return v.(llvm.Type) + } + ret := p.toLLVMFunc(sig) + p.typs.Set(sig, ret) + return ret +} + func (p *Program) tyVoidPtr() llvm.Type { if p.voidPtrTy.IsNil() { p.voidPtrTy = llvm.PointerType(p.tyVoid(), 0)