1
2
3
4
5 package test
6
7
8
9
10 import (
11 "cmd/compile/internal/abi"
12 "cmd/compile/internal/ir"
13 "cmd/compile/internal/typecheck"
14 "cmd/compile/internal/types"
15 "cmd/internal/src"
16 "fmt"
17 "strings"
18 "testing"
19 "text/scanner"
20 )
21
22 func mkParamResultField(t *types.Type, s *types.Sym, which ir.Class) *types.Field {
23 field := types.NewField(src.NoXPos, s, t)
24 n := ir.NewNameAt(src.NoXPos, s, t)
25 n.Class = which
26 field.Nname = n
27 return field
28 }
29
30
31
32 func mkstruct(fieldtypes ...*types.Type) *types.Type {
33 fields := make([]*types.Field, len(fieldtypes))
34 for k, t := range fieldtypes {
35 if t == nil {
36 panic("bad -- field has no type")
37 }
38 f := types.NewField(src.NoXPos, nil, t)
39 fields[k] = f
40 }
41 s := types.NewStruct(fields)
42 return s
43 }
44
45 func mkFuncType(rcvr *types.Type, ins []*types.Type, outs []*types.Type) *types.Type {
46 q := typecheck.Lookup("?")
47 inf := []*types.Field{}
48 for _, it := range ins {
49 inf = append(inf, mkParamResultField(it, q, ir.PPARAM))
50 }
51 outf := []*types.Field{}
52 for _, ot := range outs {
53 outf = append(outf, mkParamResultField(ot, q, ir.PPARAMOUT))
54 }
55 var rf *types.Field
56 if rcvr != nil {
57 rf = mkParamResultField(rcvr, q, ir.PPARAM)
58 }
59 return types.NewSignature(rf, inf, outf)
60 }
61
62 type expectedDump struct {
63 dump string
64 file string
65 line int
66 }
67
68 func tokenize(src string) []string {
69 var s scanner.Scanner
70 s.Init(strings.NewReader(src))
71 res := []string{}
72 for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
73 res = append(res, s.TokenText())
74 }
75 return res
76 }
77
78 func verifyParamResultOffset(t *testing.T, f *types.Field, r abi.ABIParamAssignment, which string, idx int) int {
79 n := f.Nname.(*ir.Name)
80 if n.FrameOffset() != int64(r.Offset()) {
81 t.Errorf("%s %d: got offset %d wanted %d t=%v",
82 which, idx, r.Offset(), n.Offset_, f.Type)
83 return 1
84 }
85 return 0
86 }
87
88 func makeExpectedDump(e string) expectedDump {
89 return expectedDump{dump: e}
90 }
91
92 func difftokens(atoks []string, etoks []string) string {
93 if len(atoks) != len(etoks) {
94 return fmt.Sprintf("expected %d tokens got %d",
95 len(etoks), len(atoks))
96 }
97 for i := 0; i < len(etoks); i++ {
98 if etoks[i] == atoks[i] {
99 continue
100 }
101
102 return fmt.Sprintf("diff at token %d: expected %q got %q",
103 i, etoks[i], atoks[i])
104 }
105 return ""
106 }
107
108 func nrtest(t *testing.T, ft *types.Type, expected int) {
109 types.CalcSize(ft)
110 got := configAMD64.NumParamRegs(ft)
111 if got != expected {
112 t.Errorf("]\nexpected num regs = %d, got %d, type %v", expected, got, ft)
113 }
114 }
115
116 func abitest(t *testing.T, ft *types.Type, exp expectedDump) {
117
118 types.CalcSize(ft)
119
120
121 regRes := configAMD64.ABIAnalyze(ft, false)
122 regResString := strings.TrimSpace(regRes.String())
123
124
125 reason := difftokens(tokenize(regResString), tokenize(exp.dump))
126 if reason != "" {
127 t.Errorf("\nexpected:\n%s\ngot:\n%s\nreason: %s",
128 strings.TrimSpace(exp.dump), regResString, reason)
129 }
130
131 }
132
View as plain text