Correct function name for calls to other packages

Этот коммит содержится в:
Ayke van Laethem 2018-04-22 19:22:12 +02:00
родитель 9d3dfd8868
коммит cefce41df0

64
tgo.go
Просмотреть файл

@ -57,12 +57,18 @@ type Compiler struct {
} }
type Frame struct { type Frame struct {
pkgPrefix string llvmFn llvm.Value
llvmFn llvm.Value params map[*ssa.Parameter]int // arguments to the function
params map[*ssa.Parameter]int // arguments to the function locals map[ssa.Value]llvm.Value // local variables
locals map[ssa.Value]llvm.Value // local variables blocks map[*ssa.BasicBlock]llvm.BasicBlock
blocks map[*ssa.BasicBlock]llvm.BasicBlock phis []Phi
phis []Phi }
func pkgPrefix(pkg *ssa.Package) string {
if pkg.Pkg.Name() == "main" {
return "main"
}
return pkg.Pkg.Path()
} }
type Phi struct { type Phi struct {
@ -224,14 +230,9 @@ func (c *Compiler) Parse(mainPath string) error {
for _, name := range memberNames { for _, name := range memberNames {
member := pkg.Members[name] member := pkg.Members[name]
pkgPrefix := pkg.Pkg.Path()
if pkg.Pkg.Name() == "main" {
pkgPrefix = "main"
}
switch member := member.(type) { switch member := member.(type) {
case *ssa.Function: case *ssa.Function:
frame, err := c.parseFuncDecl(pkgPrefix, member) frame, err := c.parseFuncDecl(member)
if err != nil { if err != nil {
return err return err
} }
@ -244,7 +245,7 @@ func (c *Compiler) Parse(mainPath string) error {
if err != nil { if err != nil {
return err return err
} }
global := llvm.AddGlobal(c.mod, typ, pkgPrefix + "." + member.Name()) global := llvm.AddGlobal(c.mod, typ, pkgPrefix(member.Pkg) + "." + member.Name())
if ast.IsExported(member.Name()) { if ast.IsExported(member.Name()) {
global.SetLinkage(llvm.PrivateLinkage) global.SetLinkage(llvm.PrivateLinkage)
} }
@ -252,7 +253,7 @@ func (c *Compiler) Parse(mainPath string) error {
ms := program.MethodSets.MethodSet(member.Type()) ms := program.MethodSets.MethodSet(member.Type())
for i := 0; i < ms.Len(); i++ { for i := 0; i < ms.Len(); i++ {
fn := program.MethodValue(ms.At(i)) fn := program.MethodValue(ms.At(i))
frame, err := c.parseFuncDecl(pkgPrefix, fn) frame, err := c.parseFuncDecl(fn)
if err != nil { if err != nil {
return err return err
} }
@ -361,30 +362,30 @@ func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value {
return llvm.ConstInt(llvm.Int32Type(), c.itfTypeNumbers[typ], false) return llvm.ConstInt(llvm.Int32Type(), c.itfTypeNumbers[typ], false)
} }
func (c *Compiler) getFunctionName(pkgPrefix string, fn *ssa.Function) string { func (c *Compiler) getFunctionName(fn *ssa.Function) string {
if fn.Signature.Recv() != nil { if fn.Signature.Recv() != nil {
// Method on a defined type. // Method on a defined type.
typeName := fn.Params[0].Type().(*types.Named).Obj().Name() typeName := fn.Params[0].Type().(*types.Named).Obj().Name()
return pkgPrefix + "." + typeName + "." + fn.Name() return pkgPrefix(fn.Pkg) + "." + typeName + "." + fn.Name()
} else { } else {
// Bare function. // Bare function.
return pkgPrefix + "." + fn.Name() if strings.HasPrefix(fn.Name(), "_Cfunc_") {
// Name CGo functions directly.
return fn.Name()[len("_Cfunc_"):]
} else {
return pkgPrefix(fn.Pkg) + "." + fn.Name()
}
} }
} }
func (c *Compiler) parseFuncDecl(pkgPrefix string, f *ssa.Function) (*Frame, error) { func (c *Compiler) parseFuncDecl(f *ssa.Function) (*Frame, error) {
name := c.getFunctionName(pkgPrefix, f) f.WriteTo(os.Stdout)
if strings.HasPrefix(name, pkgPrefix + "._Cfunc_") { name := c.getFunctionName(f)
// CGo wrapper declaration.
// Don't wrap the function, instead declare it.
name = name[len(pkgPrefix + "._Cfunc_"):]
}
frame := &Frame{ frame := &Frame{
pkgPrefix: pkgPrefix, params: make(map[*ssa.Parameter]int),
params: make(map[*ssa.Parameter]int), locals: make(map[ssa.Value]llvm.Value),
locals: make(map[ssa.Value]llvm.Value), blocks: make(map[*ssa.BasicBlock]llvm.BasicBlock),
blocks: make(map[*ssa.BasicBlock]llvm.BasicBlock),
} }
var retType llvm.Type var retType llvm.Type
@ -581,12 +582,7 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
func (c *Compiler) parseFunctionCall(frame *Frame, call *ssa.CallCommon, fn *ssa.Function) (llvm.Value, error) { func (c *Compiler) parseFunctionCall(frame *Frame, call *ssa.CallCommon, fn *ssa.Function) (llvm.Value, error) {
fmt.Printf(" function: %s\n", fn) fmt.Printf(" function: %s\n", fn)
name := c.getFunctionName(frame.pkgPrefix, fn) name := c.getFunctionName(fn)
if strings.HasPrefix(name, frame.pkgPrefix + "._Cfunc_") {
// Call C function directly.
name = name[len(frame.pkgPrefix + "._Cfunc_"):]
}
target := c.mod.NamedFunction(name) target := c.mod.NamedFunction(name)
if target.IsNil() { if target.IsNil() {
return llvm.Value{}, errors.New("undefined function: " + name) return llvm.Value{}, errors.New("undefined function: " + name)