Abbrev: abbrev,
StackOffset: int32(offs),
Type: Ctxt.Lookup(typename),
+ DeclLine: n.Pos.Line(),
})
}
return decls, vars
Abbrev: abbrev,
Type: Ctxt.Lookup(typename),
StackOffset: int32(stackOffset),
+ DeclLine: n.Pos.Line(),
}
if Debug_locationlist != 0 {
LocationList []Location
Scope int32
Type Sym
+ DeclLine uint
}
// A Scope represents a lexical scope. All variables declared within a
DW_CHILDREN_no,
[]dwAttrForm{
{DW_AT_name, DW_FORM_string},
+ {DW_AT_decl_line, DW_FORM_udata},
{DW_AT_location, DW_FORM_block1},
{DW_AT_type, DW_FORM_ref_addr},
},
DW_CHILDREN_no,
[]dwAttrForm{
{DW_AT_name, DW_FORM_string},
+ {DW_AT_decl_line, DW_FORM_udata},
{DW_AT_location, DW_FORM_block1},
{DW_AT_type, DW_FORM_ref_addr},
},
Uleb128put(ctxt, info, int64(v.Abbrev))
putattr(ctxt, info, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
+ putattr(ctxt, info, v.Abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
if v.Abbrev == DW_ABRV_AUTO_LOCLIST || v.Abbrev == DW_ABRV_PARAM_LOCLIST {
putattr(ctxt, info, v.Abbrev, DW_FORM_sec_offset, DW_CLS_PTR, int64(loc.Len()), loc)
addLocList(ctxt, loc, startPC, v, encbuf)
t.Fatal(err)
}
- cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
+ cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-N -l", "-o", dst, src)
if b, err := cmd.CombinedOutput(); err != nil {
t.Logf("build: %s\n", b)
t.Fatalf("build error: %v", err)
}
}
}
+
+func TestVarDeclCoords(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+
+ if runtime.GOOS == "plan9" {
+ t.Skip("skipping on plan9; no DWARF symbol table in executables")
+ }
+
+ const prog = `
+package main
+
+func main() {
+ var i int
+ i = i
+}
+`
+ dir, err := ioutil.TempDir("", "TestVarDeclCoords")
+ if err != nil {
+ t.Fatalf("could not create directory: %v", err)
+ }
+ defer os.RemoveAll(dir)
+
+ f := gobuild(t, dir, prog)
+
+ d, err := f.DWARF()
+ if err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+
+ rdr := d.Reader()
+ var iEntry *dwarf.Entry
+ foundMain := false
+ for entry, err := rdr.Next(); entry != nil; entry, err = rdr.Next() {
+ if err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+ if entry.Tag == dwarf.TagSubprogram && entry.Val(dwarf.AttrName).(string) == "main.main" {
+ foundMain = true
+ continue
+ }
+ if !foundMain {
+ continue
+ }
+ if entry.Tag == dwarf.TagSubprogram {
+ t.Fatalf("didn't find DW_TAG_variable for i in main.main")
+ }
+ if foundMain && entry.Tag == dwarf.TagVariable && entry.Val(dwarf.AttrName).(string) == "i" {
+ iEntry = entry
+ break
+ }
+ }
+
+ line := iEntry.Val(dwarf.AttrDeclLine)
+ if line == nil || line.(int64) != 5 {
+ t.Errorf("DW_AT_decl_line for i is %v, want 5", line)
+ }
+}