Fix type width for pointer types
Этот коммит содержится в:
родитель
e436ca7c8d
коммит
01d2cc566e
1 изменённых файлов: 31 добавлений и 5 удалений
36
tgo.go
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:
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче