Fix type width for pointer types

Этот коммит содержится в:
Ayke van Laethem 2018-04-20 16:18:09 +02:00
родитель e436ca7c8d
коммит 01d2cc566e

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

@ -34,6 +34,7 @@ type Compiler struct {
ctx llvm.Context ctx llvm.Context
builder llvm.Builder builder llvm.Builder
machine llvm.TargetMachine machine llvm.TargetMachine
targetData llvm.TargetData
intType llvm.Type intType llvm.Type
stringLenType llvm.Type stringLenType llvm.Type
stringType llvm.Type stringType llvm.Type
@ -73,6 +74,7 @@ func NewCompiler(pkgName, triple string) (*Compiler, error) {
return nil, err return nil, err
} }
c.machine = target.CreateTargetMachine(triple, "", "", llvm.CodeGenLevelDefault, llvm.RelocDefault, llvm.CodeModelDefault) c.machine = target.CreateTargetMachine(triple, "", "", llvm.CodeGenLevelDefault, llvm.RelocDefault, llvm.CodeModelDefault)
c.targetData = c.machine.CreateTargetData()
c.mod = llvm.NewModule(pkgName) c.mod = llvm.NewModule(pkgName)
c.ctx = c.mod.Context() c.ctx = c.mod.Context()
@ -269,6 +271,26 @@ func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) {
} }
} }
func (c *Compiler) getTypeWidth(typ types.Type) (int, error) {
switch typ := typ.(type) {
case *types.Basic:
if typ.Kind() == types.UnsafePointer {
return c.targetData.PointerSize(), nil
}
llvmType, err := c.getLLVMType(typ)
if err != nil {
return 0, err
}
return llvmType.IntTypeWidth(), nil
case *types.Named:
return c.getTypeWidth(typ.Underlying())
case *types.Pointer:
return c.targetData.PointerSize(), nil
default:
return 0, errors.New("todo: type width")
}
}
func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value { func (c *Compiler) getInterfaceType(typ types.Type) llvm.Value {
if _, ok := c.itfTypeNumbers[typ]; !ok { if _, ok := c.itfTypeNumbers[typ]; !ok {
num := uint64(len(c.itfTypes)) num := uint64(len(c.itfTypes))
@ -716,7 +738,7 @@ func (c *Compiler) parseConvert(frame *Frame, expr *ssa.Convert) (llvm.Value, er
return value, nil return value, nil
} }
typeFrom, err := c.getLLVMType(expr.X.Type()) sizeFrom, err := c.getTypeWidth(expr.X.Type())
if err != nil { if err != nil {
return llvm.Value{}, err return llvm.Value{}, err
} }
@ -724,11 +746,15 @@ func (c *Compiler) parseConvert(frame *Frame, expr *ssa.Convert) (llvm.Value, er
if err != nil { if err != nil {
return llvm.Value{}, err return llvm.Value{}, err
} }
sizeFrom := typeFrom.IntTypeWidth() sizeTo, err := c.getTypeWidth(expr.Type())
sizeTo := typeTo.IntTypeWidth() if err != nil {
return llvm.Value{}, err
}
if sizeFrom >= sizeTo { if sizeFrom > sizeTo {
return c.builder.CreateTruncOrBitCast(value, typeTo, ""), nil return c.builder.CreateTrunc(value, typeTo, ""), nil
} else if sizeFrom == sizeTo {
return c.builder.CreateBitCast(value, typeTo, ""), nil
} else { // sizeFrom < sizeTo: extend } else { // sizeFrom < sizeTo: extend
switch typ := expr.X.Type().(type) { // typeFrom switch typ := expr.X.Type().(type) { // typeFrom
case *types.Basic: case *types.Basic: