1
2
3
4
5 package gc
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/inline"
10 "cmd/compile/internal/ir"
11 "cmd/compile/internal/typecheck"
12 "cmd/compile/internal/types"
13 "cmd/internal/bio"
14 "fmt"
15 "go/constant"
16 )
17
18 func exportf(bout *bio.Writer, format string, args ...interface{}) {
19 fmt.Fprintf(bout, format, args...)
20 if base.Debug.Export != 0 {
21 fmt.Printf(format, args...)
22 }
23 }
24
25 func dumpexport(bout *bio.Writer) {
26 p := &exporter{marked: make(map[*types.Type]bool)}
27 for _, n := range typecheck.Target.Exports {
28
29
30 if n.Type() != nil && n.Type().HasTParam() {
31 base.Fatalf("Cannot (yet) export a generic type: %v", n)
32 }
33 p.markObject(n)
34 }
35
36
37 exportf(bout, "\n$$B\n")
38 off := bout.Offset()
39 typecheck.WriteExports(bout.Writer)
40 size := bout.Offset() - off
41 exportf(bout, "\n$$\n")
42
43 if base.Debug.Export != 0 {
44 fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", base.Ctxt.Pkgpath, size)
45 }
46 }
47
48 func dumpasmhdr() {
49 b, err := bio.Create(base.Flag.AsmHdr)
50 if err != nil {
51 base.Fatalf("%v", err)
52 }
53 fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", types.LocalPkg.Name)
54 for _, n := range typecheck.Target.Asms {
55 if n.Sym().IsBlank() {
56 continue
57 }
58 switch n.Op() {
59 case ir.OLITERAL:
60 t := n.Val().Kind()
61 if t == constant.Float || t == constant.Complex {
62 break
63 }
64 fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym().Name, n.Val())
65
66 case ir.OTYPE:
67 t := n.Type()
68 if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() {
69 break
70 }
71 fmt.Fprintf(b, "#define %s__size %d\n", n.Sym().Name, int(t.Width))
72 for _, f := range t.Fields().Slice() {
73 if !f.Sym.IsBlank() {
74 fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym().Name, f.Sym.Name, int(f.Offset))
75 }
76 }
77 }
78 }
79
80 b.Close()
81 }
82
83 type exporter struct {
84 marked map[*types.Type]bool
85 }
86
87
88 func (p *exporter) markObject(n ir.Node) {
89 if n.Op() == ir.ONAME {
90 n := n.(*ir.Name)
91 if n.Class == ir.PFUNC {
92 inline.Inline_Flood(n, typecheck.Export)
93 }
94 }
95
96 p.markType(n.Type())
97 }
98
99
100
101 func (p *exporter) markType(t *types.Type) {
102 if p.marked[t] {
103 return
104 }
105 p.marked[t] = true
106
107
108
109
110
111
112 if t.Sym() != nil && t.Kind() != types.TINTER {
113 for _, m := range t.Methods().Slice() {
114 if types.IsExported(m.Sym.Name) {
115 p.markObject(ir.AsNode(m.Nname))
116 }
117 }
118 }
119
120
121
122
123
124
125
126
127
128
129 switch t.Kind() {
130 case types.TPTR, types.TARRAY, types.TSLICE:
131 p.markType(t.Elem())
132
133 case types.TCHAN:
134 if t.ChanDir().CanRecv() {
135 p.markType(t.Elem())
136 }
137
138 case types.TMAP:
139 p.markType(t.Key())
140 p.markType(t.Elem())
141
142 case types.TSTRUCT:
143 for _, f := range t.FieldSlice() {
144 if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
145 p.markType(f.Type)
146 }
147 }
148
149 case types.TFUNC:
150 for _, f := range t.Results().FieldSlice() {
151 p.markType(f.Type)
152 }
153
154 case types.TINTER:
155 for _, f := range t.AllMethods().Slice() {
156 if types.IsExported(f.Sym.Name) {
157 p.markType(f.Type)
158 }
159 }
160 }
161 }
162
View as plain text