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