1
2
3
4
5 package noder
6
7 import (
8 "go/constant"
9
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/syntax"
12 "cmd/compile/internal/types"
13 "cmd/compile/internal/types2"
14 )
15
16
17
18 func (g *irgen) match(t1 *types.Type, t2 types2.Type, hasOK bool) bool {
19 tuple, ok := t2.(*types2.Tuple)
20 if !ok {
21
22 return types.Identical(t1, g.typ(t2))
23 }
24
25 if hasOK {
26
27
28
29
30 if tuple.Len() == 2 && types.Identical(t1, g.typ(tuple.At(0).Type())) {
31 return true
32 }
33 return types.Identical(t1, g.typ(t2))
34 }
35
36 if t1 == nil || tuple == nil {
37 return t1 == nil && tuple == nil
38 }
39 if !t1.IsFuncArgStruct() {
40 return false
41 }
42 if t1.NumFields() != tuple.Len() {
43 return false
44 }
45 for i, result := range t1.FieldSlice() {
46 if !types.Identical(result.Type, g.typ(tuple.At(i).Type())) {
47 return false
48 }
49 }
50 return true
51 }
52
53 func (g *irgen) validate(n syntax.Node) {
54 switch n := n.(type) {
55 case *syntax.CallExpr:
56 tv := g.info.Types[n.Fun]
57 if tv.IsBuiltin() {
58 fun := n.Fun
59 for {
60 builtin, ok := fun.(*syntax.ParenExpr)
61 if !ok {
62 break
63 }
64 fun = builtin.X
65 }
66 switch builtin := fun.(type) {
67 case *syntax.Name:
68 g.validateBuiltin(builtin.Value, n)
69 case *syntax.SelectorExpr:
70 g.validateBuiltin(builtin.Sel.Value, n)
71 default:
72 g.unhandled("builtin", n)
73 }
74 }
75 }
76 }
77
78 func (g *irgen) validateBuiltin(name string, call *syntax.CallExpr) {
79 switch name {
80 case "Alignof", "Offsetof", "Sizeof":
81
82
83
84 tv := g.info.Types[call]
85 if !tv.IsValue() {
86 base.FatalfAt(g.pos(call), "expected a value")
87 }
88
89 if tv.Value == nil {
90 break
91 }
92
93 got, ok := constant.Int64Val(tv.Value)
94 if !ok {
95 base.FatalfAt(g.pos(call), "expected int64 constant value")
96 }
97
98 want := g.unsafeExpr(name, call.ArgList[0])
99 if got != want {
100 base.FatalfAt(g.pos(call), "got %v from types2, but want %v", got, want)
101 }
102 }
103 }
104
105
106 func (g *irgen) unsafeExpr(name string, arg syntax.Expr) int64 {
107 switch name {
108 case "Alignof":
109 return g.typ(g.info.Types[arg].Type).Alignment()
110 case "Sizeof":
111 return g.typ(g.info.Types[arg].Type).Size()
112 }
113
114
115
116 sel := arg.(*syntax.SelectorExpr)
117 selection := g.info.Selections[sel]
118
119 typ := g.typ(g.info.Types[sel.X].Type)
120 typ = deref(typ)
121
122 var offset int64
123 for _, i := range selection.Index() {
124
125 types.CalcSize(typ)
126
127 f := typ.Field(i)
128 offset += f.Offset
129 typ = f.Type
130 }
131 return offset
132 }
133
View as plain text