Clean up ssa.Convert and ssa.ChangeType
Этот коммит содержится в:
родитель
8b95b869ab
коммит
eed25c78df
1 изменённых файлов: 42 добавлений и 24 удалений
44
compiler.go
44
compiler.go
|
@ -1472,7 +1472,17 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return llvm.Value{}, err
|
return llvm.Value{}, err
|
||||||
}
|
}
|
||||||
return c.parseConvert(expr.X.Type(), expr.Type(), x)
|
// The only case when we need to bitcast is when casting between named
|
||||||
|
// struct types, as those are actually different in LLVM. Let's just
|
||||||
|
// bitcast all struct types for ease of use.
|
||||||
|
if _, ok := expr.Type().Underlying().(*types.Struct); ok {
|
||||||
|
llvmType, err := c.getLLVMType(expr.X.Type())
|
||||||
|
if err != nil {
|
||||||
|
return llvm.Value{}, err
|
||||||
|
}
|
||||||
|
return c.builder.CreateBitCast(x, llvmType, "changetype"), nil
|
||||||
|
}
|
||||||
|
return x, nil
|
||||||
case *ssa.Const:
|
case *ssa.Const:
|
||||||
return c.parseConst(expr)
|
return c.parseConst(expr)
|
||||||
case *ssa.Convert:
|
case *ssa.Convert:
|
||||||
|
@ -2037,26 +2047,32 @@ func (c *Compiler) parseConvert(typeFrom, typeTo types.Type, value llvm.Value) (
|
||||||
return llvm.Value{}, err
|
return llvm.Value{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch typeTo := typeTo.Underlying().(type) {
|
// Conversion between unsafe.Pointer and uintptr.
|
||||||
case *types.Basic:
|
isPtrFrom := isPointer(typeFrom.Underlying())
|
||||||
isPtrFrom := isPointer(typeFrom)
|
isPtrTo := isPointer(typeTo.Underlying())
|
||||||
isPtrTo := isPointer(typeTo)
|
|
||||||
if isPtrFrom && !isPtrTo {
|
if isPtrFrom && !isPtrTo {
|
||||||
return c.builder.CreatePtrToInt(value, llvmTypeTo, ""), nil
|
return c.builder.CreatePtrToInt(value, llvmTypeTo, ""), nil
|
||||||
} else if !isPtrFrom && isPtrTo {
|
} else if !isPtrFrom && isPtrTo {
|
||||||
return c.builder.CreateIntToPtr(value, llvmTypeTo, ""), nil
|
return c.builder.CreateIntToPtr(value, llvmTypeTo, ""), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeFrom := c.targetData.TypeAllocSize(llvmTypeFrom)
|
// Conversion between pointers and unsafe.Pointer.
|
||||||
sizeTo := c.targetData.TypeAllocSize(llvmTypeTo)
|
if isPtrFrom && isPtrTo {
|
||||||
if sizeFrom == sizeTo {
|
|
||||||
return c.builder.CreateBitCast(value, llvmTypeTo, ""), nil
|
return c.builder.CreateBitCast(value, llvmTypeTo, ""), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if typeTo.Info()&types.IsInteger == 0 { // if not integer
|
switch typeTo := typeTo.Underlying().(type) {
|
||||||
return llvm.Value{}, errors.New("todo: convert: extend non-integer type")
|
case *types.Basic:
|
||||||
|
sizeFrom := c.targetData.TypeAllocSize(llvmTypeFrom)
|
||||||
|
|
||||||
|
if typeTo.Kind() == types.String {
|
||||||
|
return llvm.Value{}, errors.New("todo: convert to string: " + typeFrom.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typeFrom := typeFrom.Underlying().(*types.Basic)
|
||||||
|
sizeTo := c.targetData.TypeAllocSize(llvmTypeTo)
|
||||||
|
if typeFrom.Info() & types.IsInteger != 0 && typeTo.Info() & types.IsInteger != 0 {
|
||||||
|
// Conversion between two integers.
|
||||||
if sizeFrom > sizeTo {
|
if sizeFrom > sizeTo {
|
||||||
return c.builder.CreateTrunc(value, llvmTypeTo, ""), nil
|
return c.builder.CreateTrunc(value, llvmTypeTo, ""), nil
|
||||||
} else if typeTo.Info()&types.IsUnsigned != 0 { // if unsigned
|
} else if typeTo.Info()&types.IsUnsigned != 0 { // if unsigned
|
||||||
|
@ -2064,10 +2080,12 @@ func (c *Compiler) parseConvert(typeFrom, typeTo types.Type, value llvm.Value) (
|
||||||
} else { // if signed
|
} else { // if signed
|
||||||
return c.builder.CreateSExt(value, llvmTypeTo, ""), nil
|
return c.builder.CreateSExt(value, llvmTypeTo, ""), nil
|
||||||
}
|
}
|
||||||
case *types.Pointer:
|
}
|
||||||
return c.builder.CreateBitCast(value, llvmTypeTo, ""), nil
|
|
||||||
|
return llvm.Value{}, errors.New("todo: convert: basic non-integer type: " + typeTo.String())
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return llvm.Value{}, errors.New("todo: convert: extend non-basic type: " + typeTo.String())
|
return llvm.Value{}, errors.New("todo: convert " + typeTo.String() + " <- " + typeFrom.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче