]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: distinguish args and return values in DWARF
authorHeschi Kreinick <heschi@google.com>
Wed, 18 Oct 2017 17:45:03 +0000 (13:45 -0400)
committerHeschi Kreinick <heschi@google.com>
Wed, 18 Oct 2017 18:46:04 +0000 (18:46 +0000)
Set DW_AT_variable_parameter on DW_TAG_formal_parameters that are
actually return values. variable_parameter is supposed to indicate inout
parameters, but Go doesn't really have those, and DWARF doesn't have
explicit support for multiple return values. This seems to be the best
compromise, especially since the implementation of the two is very
similar -- both are stack slots.

Fixes #21100

Change-Id: Icebabc92b7b397e0aa00a7237478cce84ad1a670
Reviewed-on: https://go-review.googlesource.com/71670
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/gc/pgen.go
src/cmd/internal/dwarf/dwarf.go

index 84d06a00e73d59b7c08a4f0b8b01f9dd6f0dca12..9a91fe40ce1601a42667344ccce4638188a7fa2d 100644 (file)
@@ -400,11 +400,12 @@ func createSimpleVars(automDecls []*Node) ([]*Node, []*dwarf.Var) {
                typename := dwarf.InfoPrefix + typesymname(n.Type)
                decls = append(decls, n)
                vars = append(vars, &dwarf.Var{
-                       Name:        n.Sym.Name,
-                       Abbrev:      abbrev,
-                       StackOffset: int32(offs),
-                       Type:        Ctxt.Lookup(typename),
-                       DeclLine:    n.Pos.Line(),
+                       Name:          n.Sym.Name,
+                       IsReturnValue: n.Class() == PPARAMOUT,
+                       Abbrev:        abbrev,
+                       StackOffset:   int32(offs),
+                       Type:          Ctxt.Lookup(typename),
+                       DeclLine:      n.Pos.Line(),
                })
        }
        return decls, vars
index f840828b6217160130385681027fe8d03ecb26bc..149cfc790d9051ae5727e5b29a3f0512bceb26c0 100644 (file)
@@ -49,13 +49,14 @@ type Piece struct {
 
 // A Var represents a local variable or a function parameter.
 type Var struct {
-       Name         string
-       Abbrev       int // Either DW_ABRV_AUTO or DW_ABRV_PARAM
-       StackOffset  int32
-       LocationList []Location
-       Scope        int32
-       Type         Sym
-       DeclLine     uint
+       Name          string
+       Abbrev        int // Either DW_ABRV_AUTO[_LOCLIST] or DW_ABRV_PARAM[_LOCLIST]
+       IsReturnValue bool
+       StackOffset   int32
+       LocationList  []Location
+       Scope         int32
+       Type          Sym
+       DeclLine      uint
 }
 
 // A Scope represents a lexical scope. All variables declared within a
@@ -355,6 +356,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
                DW_CHILDREN_no,
                []dwAttrForm{
                        {DW_AT_name, DW_FORM_string},
+                       {DW_AT_variable_parameter, DW_FORM_flag},
                        {DW_AT_decl_line, DW_FORM_udata},
                        {DW_AT_location, DW_FORM_block1},
                        {DW_AT_type, DW_FORM_ref_addr},
@@ -367,6 +369,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{
                DW_CHILDREN_no,
                []dwAttrForm{
                        {DW_AT_name, DW_FORM_string},
+                       {DW_AT_variable_parameter, DW_FORM_flag},
                        {DW_AT_decl_line, DW_FORM_udata},
                        {DW_AT_location, DW_FORM_sec_offset},
                        {DW_AT_type, DW_FORM_ref_addr},
@@ -833,8 +836,6 @@ func putscope(ctxt Context, info, loc, ranges, startPC Sym, curscope int32, scop
 }
 
 func putvar(ctxt Context, info, loc Sym, v *Var, startPC Sym, encbuf []byte) {
-       n := v.Name
-
        // If the variable was entirely optimized out, don't emit a location list;
        // convert to an inline abbreviation and emit an empty location.
        missing := false
@@ -848,7 +849,14 @@ func putvar(ctxt Context, info, loc Sym, v *Var, startPC Sym, encbuf []byte) {
        }
 
        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_string, DW_CLS_STRING, int64(len(v.Name)), v.Name)
+       if v.Abbrev == DW_ABRV_PARAM || v.Abbrev == DW_ABRV_PARAM_LOCLIST {
+               var isReturn int64
+               if v.IsReturnValue {
+                       isReturn = 1
+               }
+               putattr(ctxt, info, v.Abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil)
+       }
        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)