Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 package ssa | 1 package ssa |
2 | 2 |
3 // This file implements the String() methods for all Value and | 3 // This file implements the String() methods for all Value and |
4 // Instruction types. | 4 // Instruction types. |
5 | 5 |
6 import ( | 6 import ( |
7 "bytes" | 7 "bytes" |
8 "fmt" | 8 "fmt" |
9 "go/ast" | 9 "go/ast" |
10 "go/types" | 10 "go/types" |
11 "reflect" | |
12 ) | 11 ) |
13 | 12 |
14 func (id Id) String() string { | 13 func (id Id) String() string { |
15 if id.Pkg == nil { | 14 if id.Pkg == nil { |
16 return id.Name | 15 return id.Name |
17 } | 16 } |
18 return fmt.Sprintf("%s/%s", id.Pkg.Path, id.Name) | 17 return fmt.Sprintf("%s/%s", id.Pkg.Path, id.Name) |
19 } | 18 } |
20 | 19 |
21 // relName returns the name of v relative to i. | 20 // relName returns the name of v relative to i. |
22 // In most cases, this is identical to v.Name(), but for cross-package | 21 // In most cases, this is identical to v.Name(), but for cross-package |
23 // references to Functions (including methods) and Globals, the | 22 // references to Functions (including methods) and Globals, the |
iant
2013/01/25 05:33:02
You can have cross-package references to types and
adonovan
2013/01/25 15:04:44
Yes, but types are not SSA values and constants (L
| |
24 // package-qualified FullName is used instead. | 23 // package-qualified FullName is used instead. |
25 // | 24 // |
26 func relName(v Value, i Instruction) string { | 25 func relName(v Value, i Instruction) string { |
27 switch v := v.(type) { | 26 switch v := v.(type) { |
28 case *Global: | 27 case *Global: |
29 if v.Pkg == i.Block().Func.Pkg { | 28 if v.Pkg == i.Block().Func.Pkg { |
30 return v.Name() | 29 return v.Name() |
31 } | 30 } |
32 return v.FullName() | 31 return v.FullName() |
33 case *Function: | 32 case *Function: |
34 if v.Pkg == nil || v.Pkg == i.Block().Func.Pkg { | 33 if v.Pkg == nil || v.Pkg == i.Block().Func.Pkg { |
35 return v.Name() | 34 return v.Name() |
36 } | 35 } |
37 return v.FullName() | 36 return v.FullName() |
38 } | 37 } |
39 return v.Name() | 38 return v.Name() |
40 } | 39 } |
41 | 40 |
42 // Value.String() | 41 // Value.String() |
43 // | 42 // |
44 // This method is provided only for debugging. | 43 // This method is provided only for debugging. |
45 // It never appears in disassembly, which uses Value.Name(). | 44 // It never appears in disassembly, which uses Value.Name(). |
46 | 45 |
47 func (v *Literal) String() string { | 46 func (v *Literal) String() string { |
48 » return fmt.Sprintf("literal %s rep=%s", v.Name(), reflect.TypeOf(v.Value )) | 47 » return fmt.Sprintf("literal %s rep=%T", v.Name(), v.Value) |
iant
2013/01/25 05:33:02
suggest rep=%T and just passing v.Value rather tha
adonovan
2013/01/25 15:04:44
Oh, that's nice. Done everywhere.
| |
49 } | 48 } |
50 | 49 |
51 func (v *Parameter) String() string { | 50 func (v *Parameter) String() string { |
52 return fmt.Sprintf("parameter %s : %s", v.Name(), v.Type()) | 51 return fmt.Sprintf("parameter %s : %s", v.Name(), v.Type()) |
53 } | 52 } |
54 | 53 |
55 func (v *Capture) String() string { | 54 func (v *Capture) String() string { |
56 return fmt.Sprintf("capture %s : %s", v.Name(), v.Type()) | 55 return fmt.Sprintf("capture %s : %s", v.Name(), v.Type()) |
57 } | 56 } |
58 | 57 |
59 func (v *Global) String() string { | 58 func (v *Global) String() string { |
60 return fmt.Sprintf("global %s : %s", v.Name(), v.Type()) | 59 return fmt.Sprintf("global %s : %s", v.Name(), v.Type()) |
61 } | 60 } |
62 | 61 |
63 func (v *Builtin) String() string { | 62 func (v *Builtin) String() string { |
64 return fmt.Sprintf("builtin %s : %s", v.Name(), v.Type()) | 63 return fmt.Sprintf("builtin %s : %s", v.Name(), v.Type()) |
65 } | 64 } |
66 | 65 |
67 func (r *Function) String() string { | 66 func (r *Function) String() string { |
68 return fmt.Sprintf("function %s : %s", r.Name(), r.Type()) | 67 return fmt.Sprintf("function %s : %s", r.Name(), r.Type()) |
68 } | |
69 | |
70 // FullName returns the name of this function qualified by the | |
71 // package name, unless it is anonymous or synthetic. | |
72 // | |
73 // TODO(adonovan): move to func.go when it's submitted. | |
74 // | |
75 func (f *Function) FullName() string { | |
76 if f.Enclosing != nil || f.Pkg == nil { | |
77 return f.Name_ // anonymous or synthetic | |
78 } | |
79 return fmt.Sprintf("%s.%s", f.Pkg.ImportPath, f.Name_) | |
80 } | |
81 | |
82 // FullName returns g's package-qualified name. | |
83 func (g *Global) FullName() string { | |
84 return fmt.Sprintf("%s.%s", g.Pkg.ImportPath, g.Name_) | |
69 } | 85 } |
70 | 86 |
71 // Instruction.String() | 87 // Instruction.String() |
72 | 88 |
73 func (v *Alloc) String() string { | 89 func (v *Alloc) String() string { |
74 op := "local" | 90 op := "local" |
75 if v.Heap { | 91 if v.Heap { |
76 op = "new" | 92 op = "new" |
77 } | 93 } |
78 return fmt.Sprintf("%s %s", op, indirectType(v.Type())) | 94 return fmt.Sprintf("%s %s", op, indirectType(v.Type())) |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 } | 332 } |
317 | 333 |
318 func (s *Store) String() string { | 334 func (s *Store) String() string { |
319 return fmt.Sprintf("*%s = %s", relName(s.Addr, s), relName(s.Val, s)) | 335 return fmt.Sprintf("*%s = %s", relName(s.Addr, s), relName(s.Val, s)) |
320 } | 336 } |
321 | 337 |
322 func (s *MapUpdate) String() string { | 338 func (s *MapUpdate) String() string { |
323 return fmt.Sprintf("%s[%s] = %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s)) | 339 return fmt.Sprintf("%s[%s] = %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s)) |
324 } | 340 } |
325 | 341 |
326 // Package.String() | |
iant
2013/01/25 05:33:02
Not sure this comment adds much here.
adonovan
2013/01/25 15:04:44
Deleted.
| |
327 | |
328 func (p *Package) String() string { | 342 func (p *Package) String() string { |
329 // TODO(adonovan): prettify output. | 343 // TODO(adonovan): prettify output. |
330 var b bytes.Buffer | 344 var b bytes.Buffer |
331 fmt.Fprintf(&b, "Package %s at %s:\n", p.ImportPath, p.Prog.Files.File(p .Pos).Name()) | 345 fmt.Fprintf(&b, "Package %s at %s:\n", p.ImportPath, p.Prog.Files.File(p .Pos).Name()) |
332 | 346 |
333 // TODO(adonovan): make order deterministic. | 347 // TODO(adonovan): make order deterministic. |
334 maxname := 0 | 348 maxname := 0 |
335 for name := range p.Members { | 349 for name := range p.Members { |
336 if l := len(name); l > maxname { | 350 if l := len(name); l > maxname { |
337 maxname = l | 351 maxname = l |
(...skipping 22 matching lines...) Expand all Loading... | |
360 } | 374 } |
361 return b.String() | 375 return b.String() |
362 } | 376 } |
363 | 377 |
364 func commaOk(x bool) string { | 378 func commaOk(x bool) string { |
365 if x { | 379 if x { |
366 return ",ok" | 380 return ",ok" |
367 } | 381 } |
368 return "" | 382 return "" |
369 } | 383 } |
LEFT | RIGHT |