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 switch builtin := n.Fun.(type) {
59 case *syntax.Name:
60 g.validateBuiltin(builtin.Value, n)
61 case *syntax.SelectorExpr:
62 g.validateBuiltin(builtin.Sel.Value, n)
63 default:
64 g.unhandled("builtin", n)
65 }
66 }
67 }
68 }
69
70 func (g *irgen) validateBuiltin(name string, call *syntax.CallExpr) {
71 switch name {
72 case "Alignof", "Offsetof", "Sizeof":
73
74
75
76 got, ok := constant.Int64Val(g.info.Types[call].Value)
77 if !ok {
78 base.FatalfAt(g.pos(call), "expected int64 constant value")
79 }
80
81 want := g.unsafeExpr(name, call.ArgList[0])
82 if got != want {
83 base.FatalfAt(g.pos(call), "got %v from types2, but want %v", got, want)
84 }
85 }
86 }
87
88
89 func (g *irgen) unsafeExpr(name string, arg syntax.Expr) int64 {
90 switch name {
91 case "Alignof":
92 return g.typ(g.info.Types[arg].Type).Alignment()
93 case "Sizeof":
94 return g.typ(g.info.Types[arg].Type).Size()
95 }
96
97
98
99 sel := arg.(*syntax.SelectorExpr)
100 selection := g.info.Selections[sel]
101
102 typ := g.typ(g.info.Types[sel.X].Type)
103 typ = deref(typ)
104
105 var offset int64
106 for _, i := range selection.Index() {
107
108 types.CalcSize(typ)
109
110 f := typ.Field(i)
111 offset += f.Offset
112 typ = f.Type
113 }
114 return offset
115 }
116
View as plain text