"cmd/internal/src"
)
-func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) {
+func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) (scopes []dwarf.Scope, inlcalls dwarf.InlCalls, startPos src.XPos) {
fn := curfn.(*ir.Func)
if fn.Nname != nil {
varScopes = append(varScopes, findScope(fn.Marks, pos))
}
- scopes := assembleScopes(fnsym, fn, dwarfVars, varScopes)
- var inlcalls dwarf.InlCalls
+ scopes = assembleScopes(fnsym, fn, dwarfVars, varScopes)
if base.Flag.GenDwarfInl > 0 {
inlcalls = assembleInlines(fnsym, dwarfVars)
}
- return scopes, inlcalls
+ return scopes, inlcalls, fn.Pos()
}
func declPos(decl *ir.Name) src.XPos {
Absfn Sym
StartPC Sym
Size int64
+ StartLine int32
External bool
Scopes []Scope
InlCalls InlCalls
{DW_AT_high_pc, DW_FORM_addr},
{DW_AT_frame_base, DW_FORM_block1},
{DW_AT_decl_file, DW_FORM_data4},
+ {DW_AT_decl_line, DW_FORM_udata},
{DW_AT_external, DW_FORM_flag},
},
},
[]dwAttrForm{
{DW_AT_name, DW_FORM_string},
{DW_AT_inline, DW_FORM_data1},
+ {DW_AT_decl_line, DW_FORM_udata},
{DW_AT_external, DW_FORM_flag},
},
},
// DW_AT_inlined value
putattr(ctxt, s.Absfn, abbrev, DW_FORM_data1, DW_CLS_CONSTANT, int64(DW_INL_inlined), nil)
+ putattr(ctxt, s.Absfn, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartLine), nil)
+
var ev int64
if s.External {
ev = 1
putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0)
} else {
ctxt.AddFileRef(s.Info, s.Filesym)
+ putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartLine), nil)
+
var ev int64
if s.External {
ev = 1
var scopes []dwarf.Scope
var inlcalls dwarf.InlCalls
if ctxt.DebugInfo != nil {
- scopes, inlcalls = ctxt.DebugInfo(s, info, curfn)
+ // Don't need startPos because s.Func().StartLine is populated,
+ // as s is in this package.
+ scopes, inlcalls, _ = ctxt.DebugInfo(s, info, curfn)
}
var err error
dwctxt := dwCtxt{ctxt}
Absfn: absfunc,
StartPC: s,
Size: s.Size,
+ StartLine: s.Func().StartLine,
External: !s.Static(),
Scopes: scopes,
InlCalls: inlcalls,
if s.Func() == nil {
s.NewFuncInfo()
}
- scopes, _ := ctxt.DebugInfo(s, absfn, curfn)
+ scopes, _, startPos := ctxt.DebugInfo(s, absfn, curfn)
+ _, startLine := ctxt.getFileSymbolAndLine(startPos)
dwctxt := dwCtxt{ctxt}
+ // TODO(prattmic): this returns nil for symbols outside of the current
+ // package because s.Func() is empty. This doesn't matter because
+ // PutAbstractFunc doesn't use Filesym. Use startPos or remove.
filesym := ctxt.fileSymbol(s)
fnstate := dwarf.FnState{
Name: s.Name,
Info: absfn,
Filesym: filesym,
Absfn: absfn,
+ StartLine: startLine,
External: !s.Static(),
Scopes: scopes,
UseBASEntries: ctxt.UseBASEntries,
Imports []goobj.ImportedPkg
DiagFunc func(string, ...interface{})
DiagFlush func()
- DebugInfo func(fn *LSym, info *LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) // if non-nil, curfn is a *gc.Node
+ DebugInfo func(fn *LSym, info *LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls, src.XPos) // if non-nil, curfn is a *ir.Func
GenAbstractFunc func(fn *LSym)
Errors int
}
}
-func varDeclCoordsAndSubrogramDeclFile(t *testing.T, testpoint string, expectFile string, expectLine int, directive string) {
+// expectLine is the expected line for main.
+func varDeclCoordsAndSubprogramDeclFile(t *testing.T, testpoint string, expectFile string, expectLine int, directive string) {
t.Parallel()
prog := fmt.Sprintf("package main\n%s\nfunc main() {\n\nvar i int\ni = i\n}\n", directive)
+ const iLineOffset = 2
dir := t.TempDir()
}
// Verify line/file attributes.
- line := iEntry.Val(dwarf.AttrDeclLine)
- if line == nil || line.(int64) != int64(expectLine) {
- t.Errorf("DW_AT_decl_line for i is %v, want %d", line, expectLine)
+ line, lineOK := iEntry.Val(dwarf.AttrDeclLine).(int64)
+ if !lineOK {
+ t.Errorf("missing or invalid DW_AT_decl_line for i")
+ }
+ if line != int64(expectLine+iLineOffset) {
+ t.Errorf("DW_AT_decl_line for i is %v, want %d", line, expectLine+iLineOffset)
}
fileIdx, fileIdxOK := maindie.Val(dwarf.AttrDeclFile).(int64)
if base != expectFile {
t.Errorf("DW_AT_decl_file for main is %v, want %v", base, expectFile)
}
+
+ line, lineOK = maindie.Val(dwarf.AttrDeclLine).(int64)
+ if !lineOK {
+ t.Errorf("missing or invalid DW_AT_decl_line for main")
+ }
+ if line != int64(expectLine) {
+ t.Errorf("DW_AT_decl_line for main is %v, want %d", line, expectLine)
+ }
}
func TestVarDeclCoordsAndSubrogramDeclFile(t *testing.T) {
t.Skip("skipping on plan9; no DWARF symbol table in executables")
}
- varDeclCoordsAndSubrogramDeclFile(t, "TestVarDeclCoords", "test.go", 5, "")
+ varDeclCoordsAndSubprogramDeclFile(t, "TestVarDeclCoords", "test.go", 3, "")
}
func TestVarDeclCoordsWithLineDirective(t *testing.T) {
t.Skip("skipping on plan9; no DWARF symbol table in executables")
}
- varDeclCoordsAndSubrogramDeclFile(t, "TestVarDeclCoordsWithLineDirective",
- "foobar.go", 202, "//line /foobar.go:200")
+ varDeclCoordsAndSubprogramDeclFile(t, "TestVarDeclCoordsWithLineDirective",
+ "foobar.go", 200, "//line /foobar.go:200")
}
func TestInlinedRoutineRecords(t *testing.T) {