func (d *GlobalVariableDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), uint64(d.Tag())+llvm.LLVMDebugVersion, false), llvm.ConstNull(llvm.Int32Type()), info.MDNode(d.Context), llvm.MDString(d.Name), llvm.MDString(d.DisplayName), llvm.MDNode(nil), info.mdFileNode(d.File), llvm.ConstInt(llvm.Int32Type(), uint64(d.Line), false), info.MDNode(d.Type), constInt1(d.Local), constInt1(!d.External), d.Value}) }
func (d FileDescriptor) path() llvm.Value { dirname, filename := path.Split(string(d)) if l := len(dirname); l > 0 && dirname[l-1] == '/' { dirname = dirname[:l-1] } return llvm.MDNode([]llvm.Value{llvm.MDString(filename), llvm.MDString(dirname)}) }
func (d subrangeDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), uint64(d.Tag())+llvm.LLVMDebugVersion, false), llvm.ConstInt(llvm.Int64Type(), uint64(d.low), true), llvm.ConstInt(llvm.Int64Type(), uint64(d.high), true), }) }
func (d *CompositeTypeDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), llvm.LLVMDebugVersion+uint64(d.Tag()), false), FileDescriptor(d.File).path(), info.MDNode(d.Context), llvm.MDString(d.Name), llvm.ConstInt(llvm.Int32Type(), uint64(d.Line), false), llvm.ConstInt(llvm.Int64Type(), d.Size, false), llvm.ConstInt(llvm.Int64Type(), d.Alignment, false), llvm.ConstInt(llvm.Int64Type(), d.Offset, false), llvm.ConstInt(llvm.Int32Type(), uint64(d.Flags), false), info.MDNode(d.Base), // reference type derived from llvm.MDNode(info.MDNodes(d.Members)), llvm.ConstInt(llvm.Int32Type(), uint64(0), false), // Runtime language llvm.ConstInt(llvm.Int32Type(), uint64(0), false), // Base type containing the vtable pointer for this type }) }
func (d *debugInfo) setLocation(b llvm.Builder, pos token.Pos) { position := d.Fset.Position(pos) b.SetCurrentDebugLocation(llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), uint64(position.Line), true), llvm.ConstInt(llvm.Int32Type(), uint64(position.Column), true), d.MDNode(d.context()), llvm.Value{}, })) }
func (d FileDescriptor) mdNode(info *DebugInfo) llvm.Value { if d == "" { return llvm.Value{} } return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), llvm.LLVMDebugVersion+uint64(d.Tag()), false), d.path(), }) }
func (d *BlockDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), uint64(d.Tag())+llvm.LLVMDebugVersion, false), info.mdFileNode(d.File), info.MDNode(d.Context), llvm.ConstInt(llvm.Int32Type(), uint64(d.Line), false), llvm.ConstInt(llvm.Int32Type(), uint64(d.Column), false), llvm.ConstInt(llvm.Int32Type(), uint64(d.Id), false), }) }
func (d *LocalVariableDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), uint64(d.Tag())+llvm.LLVMDebugVersion, false), info.MDNode(d.Context), llvm.MDString(d.Name), info.mdFileNode(d.File), llvm.ConstInt(llvm.Int32Type(), uint64(d.Line)|(uint64(d.Argument)<<24), false), info.MDNode(d.Type), llvm.ConstNull(llvm.Int32Type()), // flags llvm.ConstNull(llvm.Int32Type()), // optional reference to inline location }) }
func (c *compiler) newStackVarEx(argument int, stackf *LLVMValue, v types.Object, value llvm.Value, name string) (stackvalue llvm.Value, stackvar *LLVMValue) { typ := v.Type() // We need to put alloca instructions in the top block or the values // displayed when inspecting these variables in a debugger will be // completely messed up. curBlock := c.builder.GetInsertBlock() if p := curBlock.Parent(); !p.IsNil() { fb := p.FirstBasicBlock() fi := fb.FirstInstruction() if !fb.IsNil() && !fi.IsNil() { c.builder.SetInsertPointBefore(fi) } } old := c.builder.CurrentDebugLocation() c.builder.SetCurrentDebugLocation(llvm.Value{}) stackvalue = c.builder.CreateAlloca(c.types.ToLLVM(typ), name) // For arguments we want to insert the store instruction // without debug information to ensure that they are executed // (and hence have proper values) before the debugger hits the // first line in a function. if argument == 0 { c.builder.SetCurrentDebugLocation(old) c.builder.SetInsertPointAtEnd(curBlock) } if !value.IsNil() { c.builder.CreateStore(value, stackvalue) } c.builder.SetCurrentDebugLocation(old) c.builder.SetInsertPointAtEnd(curBlock) ptrvalue := c.NewValue(stackvalue, types.NewPointer(typ)) stackvar = ptrvalue.makePointee() stackvar.stack = stackf c.objectdata[v].Value = stackvar file := c.fileset.File(v.Pos()) tag := llvm.DW_TAG_auto_variable if argument > 0 { tag = llvm.DW_TAG_arg_variable } ld := llvm.NewLocalVariableDescriptor(tag) ld.Argument = uint32(argument) ld.Line = uint32(file.Line(v.Pos())) ld.Name = name ld.File = &llvm.ContextDescriptor{llvm.FileDescriptor(file.Name())} ld.Type = c.tollvmDebugDescriptor(typ) ld.Context = c.currentDebugContext() c.builder.InsertDeclare(c.module.Module, llvm.MDNode([]llvm.Value{stackvalue}), c.debug_info.MDNode(ld)) return stackvalue, stackvar }
func (d *DerivedTypeDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), llvm.LLVMDebugVersion+uint64(d.Tag()), false), FileDescriptor(d.File).path(), info.MDNode(d.Context), llvm.MDString(d.Name), llvm.ConstInt(llvm.Int32Type(), uint64(d.Line), false), llvm.ConstInt(llvm.Int64Type(), d.Size, false), llvm.ConstInt(llvm.Int64Type(), d.Alignment, false), llvm.ConstInt(llvm.Int64Type(), d.Offset, false), llvm.ConstInt(llvm.Int32Type(), uint64(d.Flags), false), info.MDNode(d.Base)}) }
func (c *compiler) newStackVarEx(argument int, stackf *LLVMValue, v types.Object, value llvm.Value, name string) (stackvalue llvm.Value, stackvar *LLVMValue) { typ := v.Type() // We need to put alloca instructions in the top block or the values // displayed when inspecting these variables in a debugger will be // completely messed up. curBlock := c.builder.GetInsertBlock() if p := curBlock.Parent(); !p.IsNil() { fb := p.FirstBasicBlock() fi := fb.FirstInstruction() if !fb.IsNil() && !fi.IsNil() { c.builder.SetInsertPointBefore(fi) } } old := c.builder.CurrentDebugLocation() c.builder.SetCurrentDebugLocation(llvm.Value{}) stackvalue = c.builder.CreateAlloca(c.types.ToLLVM(typ), name) // For arguments we want to insert the store instruction // without debug information to ensure that they are executed // (and hence have proper values) before the debugger hits the // first line in a function. if argument == 0 { c.builder.SetCurrentDebugLocation(old) c.builder.SetInsertPointAtEnd(curBlock) } if !value.IsNil() { c.builder.CreateStore(value, stackvalue) } c.builder.SetCurrentDebugLocation(old) c.builder.SetInsertPointAtEnd(curBlock) ptrvalue := c.NewValue(stackvalue, types.NewPointer(typ)) stackvar = ptrvalue.makePointee() stackvar.stack = stackf c.objectdata[v].Value = stackvar // Generate debug metadata (will return nil // if debug-data generation is disabled). if descriptor := c.createLocalVariableMetadata(v, argument); descriptor != nil { c.builder.InsertDeclare( c.module.Module, llvm.MDNode([]llvm.Value{stackvalue}), c.debug_info.MDNode(descriptor), ) } return stackvalue, stackvar }
func (d *SubprogramDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), llvm.LLVMDebugVersion+uint64(d.Tag()), false), FileDescriptor(d.File).path(), info.MDNode(d.Context), llvm.MDString(d.Name), llvm.MDString(d.DisplayName), llvm.MDString(""), // mips linkage name llvm.ConstInt(llvm.Int32Type(), uint64(d.Line), false), info.MDNode(d.Type), llvm.ConstNull(llvm.Int1Type()), // not static llvm.ConstAllOnes(llvm.Int1Type()), // locally defined (not extern) llvm.ConstNull(llvm.Int32Type()), // virtuality llvm.ConstNull(llvm.Int32Type()), // index into a virtual function info.MDNode(nil), // basetype containing the vtable pointer llvm.ConstInt(llvm.Int32Type(), 0, false), // flags llvm.ConstNull(llvm.Int1Type()), // not optimised d.Function, info.MDNode(nil), // Template parameters info.MDNode(nil), // function declaration descriptor llvm.MDNode(nil), // function variables llvm.ConstInt(llvm.Int32Type(), uint64(d.ScopeLine), false), // Line number where the scope of the subprogram begins }) }
// declare creates an llvm.dbg.declare call for the specified function // parameter or local variable. func (d *debugInfo) declare(b llvm.Builder, v ssa.Value, llv llvm.Value, paramIndex int) { tag := tagAutoVariable if paramIndex >= 0 { tag = tagArgVariable } ld := debug.NewLocalVariableDescriptor(tag) ld.Argument = uint32(paramIndex + 1) ld.Name = llv.Name() if file := d.Fset.File(v.Pos()); file != nil { ld.Line = uint32(file.Position(v.Pos()).Line) ld.File = &d.getCompileUnit(file).Path } ld.Type = d.TypeDebugDescriptor(deref(v.Type())) ld.Context = d.context() b.InsertDeclare(d.module, llvm.MDNode([]llvm.Value{llv}), d.MDNode(ld)) }
func (d *CompileUnitDescriptor) mdNode(info *DebugInfo) llvm.Value { return llvm.MDNode([]llvm.Value{ llvm.ConstInt(llvm.Int32Type(), uint64(d.Tag())+llvm.LLVMDebugVersion, false), d.Path.path(), llvm.ConstInt(llvm.Int32Type(), uint64(d.Language), false), llvm.MDString(d.Producer), constInt1(d.Optimized), llvm.MDString(d.CompilerFlags), llvm.ConstInt(llvm.Int32Type(), uint64(d.Runtime), false), d.mdNodeList(info, d.EnumTypes), d.mdNodeList(info, d.RetainedTypes), d.mdNodeList(info, d.Subprograms), d.mdNodeList(info, d.GlobalVariables), d.mdNodeList(info, nil), // List of imported entities llvm.MDString(""), // Split debug filename }) }
func (d *CompileUnitDescriptor) mdNodeList(info *DebugInfo, list []DebugDescriptor) llvm.Value { if len(list) > 0 { return llvm.MDNode(info.MDNodes(list)) } return llvm.MDNode([]llvm.Value{llvm.ConstNull(llvm.Int32Type())}) }