ssa: support string and pointer debug info, fix params debugging
This commit is contained in:
113
ssa/di.go
113
ssa/di.go
@@ -3,7 +3,6 @@ package ssa
|
||||
import (
|
||||
"debug/dwarf"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"path/filepath"
|
||||
@@ -135,12 +134,7 @@ func (b diBuilder) createType(ty Type, pos token.Position) DIType {
|
||||
} else if t.Info()&types.IsComplex != 0 {
|
||||
return b.createComplexType(ty)
|
||||
} else if t.Info()&types.IsString != 0 {
|
||||
typ = b.di.CreateBasicType(llvm.DIBasicType{
|
||||
Name: "string",
|
||||
SizeInBits: b.prog.SizeOf(b.prog.rawType(t)) * 8,
|
||||
Encoding: llvm.DW_ATE_unsigned_char,
|
||||
})
|
||||
return &aDIType{typ}
|
||||
return b.createStringType(pos)
|
||||
} else {
|
||||
panic(fmt.Errorf("can't create debug info of basic type: %v, %T", ty.RawType(), ty.RawType()))
|
||||
}
|
||||
@@ -185,10 +179,6 @@ type aDIFunction struct {
|
||||
|
||||
type DIFunction = *aDIFunction
|
||||
|
||||
func (b diBuilder) createFunction(scope DIScope, pos token.Position, name, linkageName string, ty DIType, isLocalToUnit, isDefinition, isOptimized bool) DIFunction {
|
||||
return &aDIFunction{ll: scope.scopeMeta(b, pos).ll}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
type aDIGlobalVariableExpression struct {
|
||||
@@ -264,6 +254,38 @@ func (b diBuilder) createBasicType(t Type) DIType {
|
||||
})}
|
||||
}
|
||||
|
||||
func (b diBuilder) createStringType(pos token.Position) DIType {
|
||||
ty := b.prog.rtType("String")
|
||||
|
||||
return &aDIType{ll: b.di.CreateStructType(
|
||||
llvm.Metadata{},
|
||||
llvm.DIStructType{
|
||||
Name: "string",
|
||||
SizeInBits: b.prog.SizeOf(ty) * 8,
|
||||
AlignInBits: uint32(b.prog.sizes.Alignof(ty.RawType()) * 8),
|
||||
Elements: []llvm.Metadata{
|
||||
b.di.CreateMemberType(
|
||||
llvm.Metadata{},
|
||||
llvm.DIMemberType{
|
||||
Name: "data",
|
||||
SizeInBits: b.prog.SizeOf(b.prog.CStr()) * 8,
|
||||
AlignInBits: uint32(b.prog.sizes.Alignof(b.prog.CStr().RawType()) * 8),
|
||||
Type: b.diType(b.prog.CStr(), pos).ll,
|
||||
},
|
||||
),
|
||||
b.di.CreateMemberType(
|
||||
llvm.Metadata{},
|
||||
llvm.DIMemberType{
|
||||
Name: "len",
|
||||
SizeInBits: b.prog.SizeOf(b.prog.Int()) * 8,
|
||||
AlignInBits: uint32(b.prog.sizes.Alignof(b.prog.Uint().RawType()) * 8),
|
||||
Type: b.diType(b.prog.Int(), pos).ll,
|
||||
},
|
||||
),
|
||||
},
|
||||
})}
|
||||
}
|
||||
|
||||
func (b diBuilder) createComplexType(t Type) DIType {
|
||||
var tfield Type
|
||||
if t.RawType().(*types.Basic).Kind() == types.Complex128 {
|
||||
@@ -317,18 +339,22 @@ func (b diBuilder) createPointerType(ty Type, pos token.Position) DIType {
|
||||
}
|
||||
|
||||
func (b diBuilder) createStructType(ty Type, pos token.Position) (ret DIType) {
|
||||
structType := ty.RawType().(*types.Struct)
|
||||
|
||||
scope := b.file(pos.Filename)
|
||||
ret = &aDIType{b.di.CreateReplaceableCompositeType(
|
||||
scope.ll,
|
||||
llvm.DIReplaceableCompositeType{
|
||||
Tag: dwarf.TagStructType,
|
||||
Name: ty.RawType().String(),
|
||||
Tag: dwarf.TagStructType,
|
||||
Name: ty.RawType().String(),
|
||||
File: b.file(pos.Filename).ll,
|
||||
Line: pos.Line,
|
||||
SizeInBits: b.prog.SizeOf(ty) * 8,
|
||||
AlignInBits: uint32(b.prog.sizes.Alignof(structType) * 8),
|
||||
},
|
||||
)}
|
||||
b.types[ty] = ret
|
||||
|
||||
// Create struct type
|
||||
structType := ty.RawType().(*types.Struct)
|
||||
fields := make([]llvm.Metadata, structType.NumFields())
|
||||
|
||||
for i := 0; i < structType.NumFields(); i++ {
|
||||
@@ -470,9 +496,9 @@ func (b diBuilder) createExpression(ops []uint64) DIExpression {
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Copy struct parameters to alloca'd memory.
|
||||
func (b Builder) allocatedVar(v Expr) (Expr, bool) {
|
||||
if v, ok := b.allocVars[v]; ok {
|
||||
return v, true
|
||||
func (b Builder) debug(v Expr) (dbgPtr Expr, dbgVal Expr) {
|
||||
if v, ok := b.dbgVars[v]; ok {
|
||||
return v.ptr, v.val
|
||||
}
|
||||
t := v.Type.RawType().Underlying()
|
||||
var ty Type
|
||||
@@ -484,22 +510,30 @@ func (b Builder) allocatedVar(v Expr) (Expr, bool) {
|
||||
} else {
|
||||
ty = b.Prog.Complex64()
|
||||
}
|
||||
} else if t.Info()&types.IsString != 0 {
|
||||
ty = b.Prog.rtType("String")
|
||||
} else {
|
||||
return v, false
|
||||
ty = v.Type
|
||||
}
|
||||
case *types.Struct:
|
||||
ty = v.Type
|
||||
case *types.Slice:
|
||||
ty = b.Prog.Type(b.Prog.rtType("Slice").RawType().Underlying(), InGo)
|
||||
case *types.Signature:
|
||||
fmt.Printf("t: %T, %v\n", t, t)
|
||||
ty = b.Prog.Type(b.Prog.rtType("Func").RawType().Underlying(), InGo)
|
||||
case *types.Named:
|
||||
ty = b.Prog.Type(t.Underlying(), InGo)
|
||||
default:
|
||||
return v, false
|
||||
ty = v.Type
|
||||
}
|
||||
size := b.Const(constant.MakeUint64(b.Prog.SizeOf(ty)), b.Prog.Uint64())
|
||||
p := b.Alloca(size)
|
||||
p.Type = b.Prog.Pointer(ty)
|
||||
b.Store(p, v)
|
||||
b.allocVars[v] = p
|
||||
return p, true
|
||||
// fmt.Printf("ty: %T, %v, %T, %v\n", ty.RawType(), ty.RawType(), t, t)
|
||||
dbgPtr = b.AllocaT(ty)
|
||||
dbgPtr.Type = b.Prog.Pointer(v.Type)
|
||||
b.Store(dbgPtr, v)
|
||||
dbgVal = b.Load(dbgPtr)
|
||||
b.dbgVars[v] = dbgExpr{dbgPtr, dbgVal}
|
||||
return dbgPtr, dbgVal
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -507,15 +541,13 @@ const (
|
||||
)
|
||||
|
||||
func skipType(t types.Type) bool {
|
||||
switch t := t.(type) {
|
||||
switch t.(type) {
|
||||
case *types.Slice:
|
||||
return true
|
||||
case *types.Interface:
|
||||
return true
|
||||
case *types.Basic:
|
||||
if t.Info()&types.IsString != 0 {
|
||||
return true
|
||||
}
|
||||
case *types.Signature:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -525,12 +557,9 @@ func (b Builder) DIDeclare(v Expr, dv DIVar, scope DIScope, pos token.Position,
|
||||
if skipType(t) {
|
||||
return
|
||||
}
|
||||
v, alloced := b.allocatedVar(v)
|
||||
dbgPtr, _ := b.debug(v)
|
||||
expr := b.Pkg.diBuilder().createExpression(nil)
|
||||
if alloced {
|
||||
expr = b.Pkg.diBuilder().createExpression([]uint64{opDeref})
|
||||
}
|
||||
b.Pkg.diBuilder().dbgDeclare(v, dv, scope, pos, expr, blk)
|
||||
b.Pkg.diBuilder().dbgDeclare(dbgPtr, dv, scope, pos, expr, blk)
|
||||
}
|
||||
|
||||
func (b Builder) DIValue(v Expr, dv DIVar, scope DIScope, pos token.Position, blk BasicBlock) {
|
||||
@@ -538,11 +567,7 @@ func (b Builder) DIValue(v Expr, dv DIVar, scope DIScope, pos token.Position, bl
|
||||
if skipType(t) {
|
||||
return
|
||||
}
|
||||
v, alloced := b.allocatedVar(v)
|
||||
expr := b.Pkg.diBuilder().createExpression(nil)
|
||||
if alloced {
|
||||
expr = b.Pkg.diBuilder().createExpression([]uint64{opDeref})
|
||||
}
|
||||
b.Pkg.diBuilder().dbgValue(v, dv, scope, pos, expr, blk)
|
||||
}
|
||||
|
||||
@@ -570,4 +595,12 @@ func (b Builder) DebugFunction(f Function, pos token.Position) {
|
||||
f.scopeMeta(b.Pkg.di, pos)
|
||||
}
|
||||
|
||||
func (b Builder) Param(idx int) Expr {
|
||||
p := b.Func.Param(idx)
|
||||
if v, ok := b.dbgVars[p]; ok {
|
||||
return v.val
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user