...
Source file src/pkg/cmd/compile/internal/gc/lex.go
1
2
3
4
5 package gc
6
7 import (
8 "cmd/compile/internal/syntax"
9 "cmd/internal/objabi"
10 "cmd/internal/src"
11 "fmt"
12 "strings"
13 )
14
15
16
17 var lineno src.XPos
18
19 func makePos(base *src.PosBase, line, col uint) src.XPos {
20 return Ctxt.PosTable.XPos(src.MakePos(base, line, col))
21 }
22
23 func isSpace(c rune) bool {
24 return c == ' ' || c == '\t' || c == '\n' || c == '\r'
25 }
26
27 func isQuoted(s string) bool {
28 return len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"'
29 }
30
31 const (
32
33 Nointerface syntax.Pragma = 1 << iota
34 Noescape
35 Norace
36 Nosplit
37 Noinline
38 CgoUnsafeArgs
39 UintptrEscapes
40
41
42
43 Systemstack
44 Nowritebarrier
45 Nowritebarrierrec
46 Yeswritebarrierrec
47
48
49 NotInHeap
50 )
51
52 func pragmaValue(verb string) syntax.Pragma {
53 switch verb {
54 case "go:nointerface":
55 if objabi.Fieldtrack_enabled != 0 {
56 return Nointerface
57 }
58 case "go:noescape":
59 return Noescape
60 case "go:norace":
61 return Norace
62 case "go:nosplit":
63 return Nosplit
64 case "go:noinline":
65 return Noinline
66 case "go:systemstack":
67 return Systemstack
68 case "go:nowritebarrier":
69 return Nowritebarrier
70 case "go:nowritebarrierrec":
71 return Nowritebarrierrec | Nowritebarrier
72 case "go:yeswritebarrierrec":
73 return Yeswritebarrierrec
74 case "go:cgo_unsafe_args":
75 return CgoUnsafeArgs
76 case "go:uintptrescapes":
77
78
79
80
81
82
83
84
85
86
87
88 return UintptrEscapes
89 case "go:notinheap":
90 return NotInHeap
91 }
92 return 0
93 }
94
95
96 func (p *noder) pragcgo(pos syntax.Pos, text string) {
97 f := pragmaFields(text)
98
99 verb := strings.TrimPrefix(f[0], "go:")
100 f[0] = verb
101
102 switch verb {
103 case "cgo_export_static", "cgo_export_dynamic":
104 switch {
105 case len(f) == 2 && !isQuoted(f[1]):
106 case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
107 default:
108 p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf(`usage: //go:%s local [remote]`, verb)})
109 return
110 }
111 case "cgo_import_dynamic":
112 switch {
113 case len(f) == 2 && !isQuoted(f[1]):
114 case len(f) == 3 && !isQuoted(f[1]) && !isQuoted(f[2]):
115 case len(f) == 4 && !isQuoted(f[1]) && !isQuoted(f[2]) && isQuoted(f[3]):
116 f[3] = strings.Trim(f[3], `"`)
117 if objabi.GOOS == "aix" && f[3] != "" {
118
119
120 n := strings.Split(f[3], "/")
121 if len(n) != 2 || !strings.HasSuffix(n[0], ".a") || (!strings.HasSuffix(n[1], ".o") && !strings.Contains(n[1], ".so.")) {
122 p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["lib.a/object.o"]]`})
123 return
124 }
125 }
126 default:
127 p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_dynamic local [remote ["library"]]`})
128 return
129 }
130 case "cgo_import_static":
131 switch {
132 case len(f) == 2 && !isQuoted(f[1]):
133 default:
134 p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_import_static local`})
135 return
136 }
137 case "cgo_dynamic_linker":
138 switch {
139 case len(f) == 2 && isQuoted(f[1]):
140 f[1] = strings.Trim(f[1], `"`)
141 default:
142 p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_dynamic_linker "path"`})
143 return
144 }
145 case "cgo_ldflag":
146 switch {
147 case len(f) == 2 && isQuoted(f[1]):
148 f[1] = strings.Trim(f[1], `"`)
149 default:
150 p.error(syntax.Error{Pos: pos, Msg: `usage: //go:cgo_ldflag "arg"`})
151 return
152 }
153 default:
154 return
155 }
156 p.pragcgobuf = append(p.pragcgobuf, f)
157 }
158
159
160
161
162
163
164 func pragmaFields(s string) []string {
165 var a []string
166 inQuote := false
167 fieldStart := -1
168 for i, c := range s {
169 switch {
170 case c == '"':
171 if inQuote {
172 inQuote = false
173 a = append(a, s[fieldStart:i+1])
174 fieldStart = -1
175 } else {
176 inQuote = true
177 if fieldStart >= 0 {
178 a = append(a, s[fieldStart:i])
179 }
180 fieldStart = i
181 }
182 case !inQuote && isSpace(c):
183 if fieldStart >= 0 {
184 a = append(a, s[fieldStart:i])
185 fieldStart = -1
186 }
187 default:
188 if fieldStart == -1 {
189 fieldStart = i
190 }
191 }
192 }
193 if !inQuote && fieldStart >= 0 {
194 a = append(a, s[fieldStart:])
195 }
196 return a
197 }
198
View as plain text