1
2
3
4
5 package gccgoimporter
6
7 import (
8 "errors"
9 "fmt"
10 "go/constant"
11 "go/token"
12 "go/types"
13 "io"
14 "strconv"
15 "strings"
16 "text/scanner"
17 "unicode/utf8"
18 )
19
20 type parser struct {
21 scanner *scanner.Scanner
22 version string
23 tok rune
24 lit string
25 pkgpath string
26 pkgname string
27 pkg *types.Package
28 imports map[string]*types.Package
29 typeList []types.Type
30 typeData []string
31 fixups []fixupRecord
32 initdata InitData
33 aliases map[int]string
34 }
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 type fixupRecord struct {
52 toUpdate *types.Named
53 target types.Type
54 }
55
56 func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) {
57 p.scanner = new(scanner.Scanner)
58 p.initScanner(filename, src)
59 p.imports = imports
60 p.aliases = make(map[int]string)
61 p.typeList = make([]types.Type, 1 , 16)
62 }
63
64 func (p *parser) initScanner(filename string, src io.Reader) {
65 p.scanner.Init(src)
66 p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
67 p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings
68 p.scanner.Whitespace = 1<<'\t' | 1<<' '
69 p.scanner.Filename = filename
70 p.next()
71 }
72
73 type importError struct {
74 pos scanner.Position
75 err error
76 }
77
78 func (e importError) Error() string {
79 return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
80 }
81
82 func (p *parser) error(err any) {
83 if s, ok := err.(string); ok {
84 err = errors.New(s)
85 }
86
87 panic(importError{p.scanner.Pos(), err.(error)})
88 }
89
90 func (p *parser) errorf(format string, args ...any) {
91 p.error(fmt.Errorf(format, args...))
92 }
93
94 func (p *parser) expect(tok rune) string {
95 lit := p.lit
96 if p.tok != tok {
97 p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
98 }
99 p.next()
100 return lit
101 }
102
103 func (p *parser) expectEOL() {
104 if p.version == "v1" || p.version == "v2" {
105 p.expect(';')
106 }
107 p.expect('\n')
108 }
109
110 func (p *parser) expectKeyword(keyword string) {
111 lit := p.expect(scanner.Ident)
112 if lit != keyword {
113 p.errorf("expected keyword %s, got %q", keyword, lit)
114 }
115 }
116
117 func (p *parser) parseString() string {
118 str, err := strconv.Unquote(p.expect(scanner.String))
119 if err != nil {
120 p.error(err)
121 }
122 return str
123 }
124
125
126
127 func (p *parser) parseUnquotedString() string {
128 if p.tok == scanner.EOF {
129 p.error("unexpected EOF")
130 }
131 var b strings.Builder
132 b.WriteString(p.scanner.TokenText())
133
134
135 for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
136 b.WriteRune(ch)
137 p.scanner.Next()
138 }
139 p.next()
140 return b.String()
141 }
142
143 func (p *parser) next() {
144 p.tok = p.scanner.Scan()
145 switch p.tok {
146 case scanner.Ident, scanner.Int, scanner.Float, scanner.String, 'ยท':
147 p.lit = p.scanner.TokenText()
148 default:
149 p.lit = ""
150 }
151 }
152
153 func (p *parser) parseQualifiedName() (path, name string) {
154 return p.parseQualifiedNameStr(p.parseString())
155 }
156
157 func (p *parser) parseUnquotedQualifiedName() (path, name string) {
158 return p.parseQualifiedNameStr(p.parseUnquotedString())
159 }
160
161
162
163
164 func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) {
165 parts := strings.Split(unquotedName, ".")
166 if parts[0] == "" {
167 parts = parts[1:]
168 }
169
170 switch len(parts) {
171 case 0:
172 p.errorf("malformed qualified name: %q", unquotedName)
173 case 1:
174
175 pkgpath = p.pkgpath
176 name = parts[0]
177 default:
178
179 pkgpath = strings.Join(parts[:len(parts)-1], ".")
180 name = parts[len(parts)-1]
181 }
182
183 return
184 }
185
186
187
188
189 func (p *parser) getPkg(pkgpath, name string) *types.Package {
190
191 if pkgpath == "unsafe" {
192 return types.Unsafe
193 }
194 pkg := p.imports[pkgpath]
195 if pkg == nil && name != "" {
196 pkg = types.NewPackage(pkgpath, name)
197 p.imports[pkgpath] = pkg
198 }
199 return pkg
200 }
201
202
203
204
205
206 func (p *parser) parseExportedName() (pkg *types.Package, name string) {
207 path, name := p.parseQualifiedName()
208 var pkgname string
209 if p.tok == scanner.String {
210 pkgname = p.parseString()
211 }
212 pkg = p.getPkg(path, pkgname)
213 if pkg == nil {
214 p.errorf("package %s (path = %q) not found", name, path)
215 }
216 return
217 }
218
219
220 func (p *parser) parseName() string {
221 if p.tok == '?' {
222
223 p.next()
224 return ""
225 }
226
227 _, name := p.parseUnquotedQualifiedName()
228 return name
229 }
230
231 func deref(typ types.Type) types.Type {
232 if p, _ := typ.(*types.Pointer); p != nil {
233 typ = p.Elem()
234 }
235 return typ
236 }
237
238
239 func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) {
240 name := p.parseName()
241 typ, n := p.parseTypeExtended(pkg)
242 anon := false
243 if name == "" {
244 anon = true
245
246 if aname, ok := p.aliases[n]; ok {
247 name = aname
248 } else {
249 switch typ := deref(typ).(type) {
250 case *types.Basic:
251 name = typ.Name()
252 case *types.Named:
253 name = typ.Obj().Name()
254 default:
255 p.error("embedded field expected")
256 }
257 }
258 }
259 field = types.NewField(token.NoPos, pkg, name, typ, anon)
260 if p.tok == scanner.String {
261 tag = p.parseString()
262 }
263 return
264 }
265
266
267 func (p *parser) parseParam(kind types.VarKind, pkg *types.Package) (param *types.Var, isVariadic bool) {
268 name := p.parseName()
269
270 if strings.HasPrefix(name, "p.") || strings.HasPrefix(name, "r.") || strings.HasPrefix(name, "$ret") {
271 name = ""
272 }
273 if p.tok == '<' && p.scanner.Peek() == 'e' {
274
275 p.next()
276 p.expectKeyword("esc")
277 p.expect(':')
278 p.expect(scanner.Int)
279 p.expect('>')
280 }
281 if p.tok == '.' {
282 p.next()
283 p.expect('.')
284 p.expect('.')
285 isVariadic = true
286 }
287 typ := p.parseType(pkg)
288 if isVariadic {
289 typ = types.NewSlice(typ)
290 }
291 param = types.NewParam(token.NoPos, pkg, name, typ)
292 param.SetKind(kind)
293 return
294 }
295
296
297 func (p *parser) parseVar(pkg *types.Package) *types.Var {
298 name := p.parseName()
299 v := types.NewVar(token.NoPos, pkg, name, p.parseType(pkg))
300 if name[0] == '.' || name[0] == '<' {
301
302
303
304 return nil
305 }
306 return v
307 }
308
309
310 func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) {
311 p.expectKeyword("convert")
312 p.expect('(')
313 typ = p.parseType(pkg)
314 p.expect(',')
315 val, _ = p.parseConstValue(pkg)
316 p.expect(')')
317 return
318 }
319
320
321
322 func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) {
323
324
325 if p.tok == '$' {
326 p.next()
327 if p.tok != scanner.Ident {
328 p.errorf("expected identifier after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit)
329 }
330 }
331
332 switch p.tok {
333 case scanner.String:
334 str := p.parseString()
335 val = constant.MakeString(str)
336 typ = types.Typ[types.UntypedString]
337 return
338
339 case scanner.Ident:
340 b := false
341 switch p.lit {
342 case "false":
343 case "true":
344 b = true
345
346 case "convert":
347 return p.parseConversion(pkg)
348
349 default:
350 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
351 }
352
353 p.next()
354 val = constant.MakeBool(b)
355 typ = types.Typ[types.UntypedBool]
356 return
357 }
358
359 sign := ""
360 if p.tok == '-' {
361 p.next()
362 sign = "-"
363 }
364
365 switch p.tok {
366 case scanner.Int:
367 val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0)
368 if val == nil {
369 p.error("could not parse integer literal")
370 }
371
372 p.next()
373 if p.tok == '\'' {
374 p.next()
375 typ = types.Typ[types.UntypedRune]
376 } else {
377 typ = types.Typ[types.UntypedInt]
378 }
379
380 case scanner.Float:
381 re := sign + p.lit
382 p.next()
383
384 var im string
385 switch p.tok {
386 case '+':
387 p.next()
388 im = p.expect(scanner.Float)
389
390 case '-':
391 p.next()
392 im = "-" + p.expect(scanner.Float)
393
394 case scanner.Ident:
395
396 im = re
397 re = "0"
398
399 default:
400 val = constant.MakeFromLiteral(re, token.FLOAT, 0)
401 if val == nil {
402 p.error("could not parse float literal")
403 }
404 typ = types.Typ[types.UntypedFloat]
405 return
406 }
407
408 p.expectKeyword("i")
409 reval := constant.MakeFromLiteral(re, token.FLOAT, 0)
410 if reval == nil {
411 p.error("could not parse real component of complex literal")
412 }
413 imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0)
414 if imval == nil {
415 p.error("could not parse imag component of complex literal")
416 }
417 val = constant.BinaryOp(reval, token.ADD, imval)
418 typ = types.Typ[types.UntypedComplex]
419
420 default:
421 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit)
422 }
423
424 return
425 }
426
427
428 func (p *parser) parseConst(pkg *types.Package) *types.Const {
429 name := p.parseName()
430 var typ types.Type
431 if p.tok == '<' {
432 typ = p.parseType(pkg)
433 }
434 p.expect('=')
435 val, vtyp := p.parseConstValue(pkg)
436 if typ == nil {
437 typ = vtyp
438 }
439 return types.NewConst(token.NoPos, pkg, name, typ, val)
440 }
441
442
443
444
445
446
447 var reserved = new(struct{ types.Type })
448
449
450 func (p *parser) reserve(n int) {
451
452
453
454
455
456
457
458 if len(p.typeData) == 0 {
459 if n != len(p.typeList) {
460 p.errorf("invalid type number %d (out of sync)", n)
461 }
462 p.typeList = append(p.typeList, reserved)
463 } else {
464 if p.typeList[n] != nil {
465 p.errorf("previously visited type number %d", n)
466 }
467 p.typeList[n] = reserved
468 }
469 }
470
471
472
473
474
475
476 func (p *parser) update(t types.Type, nlist []any) {
477 if t == reserved {
478 p.errorf("internal error: update(%v) invoked on reserved", nlist)
479 }
480 if t == nil {
481 p.errorf("internal error: update(%v) invoked on nil", nlist)
482 }
483 for _, n := range nlist {
484 switch n := n.(type) {
485 case int:
486 if p.typeList[n] == t {
487 continue
488 }
489 if p.typeList[n] != reserved {
490 p.errorf("internal error: update(%v): %d not reserved", nlist, n)
491 }
492 p.typeList[n] = t
493 case *types.Pointer:
494 if *n != (types.Pointer{}) {
495 elem := n.Elem()
496 if elem == t {
497 continue
498 }
499 p.errorf("internal error: update: pointer already set to %v, expected %v", elem, t)
500 }
501 *n = *types.NewPointer(t)
502 default:
503 p.errorf("internal error: %T on nlist", n)
504 }
505 }
506 }
507
508
509
510
511 func (p *parser) parseNamedType(nlist []any) types.Type {
512 pkg, name := p.parseExportedName()
513 scope := pkg.Scope()
514 obj := scope.Lookup(name)
515 if obj != nil && obj.Type() == nil {
516 p.errorf("%v has nil type", obj)
517 }
518
519 if p.tok == scanner.Ident && p.lit == "notinheap" {
520 p.next()
521
522
523
524 }
525
526
527 if p.tok == '=' {
528 p.next()
529 p.aliases[nlist[len(nlist)-1].(int)] = name
530 if obj != nil {
531
532 t := obj.Type()
533 p.update(t, nlist)
534 p.parseType(pkg)
535 return t
536 }
537 t := p.parseType(pkg, nlist...)
538 obj = types.NewTypeName(token.NoPos, pkg, name, t)
539 scope.Insert(obj)
540 return t
541 }
542
543
544 if obj == nil {
545
546
547 tname := types.NewTypeName(token.NoPos, pkg, name, nil)
548 types.NewNamed(tname, nil, nil)
549 scope.Insert(tname)
550 obj = tname
551 }
552
553
554 t := obj.Type()
555 p.update(t, nlist)
556
557 nt, ok := t.(*types.Named)
558 if !ok {
559
560 pt := p.parseType(pkg)
561 if pt != t {
562 p.error("unexpected underlying type for non-named TypeName")
563 }
564 return t
565 }
566
567 underlying := p.parseType(pkg)
568 if nt.Underlying() == nil {
569 if underlying.Underlying() == nil {
570 fix := fixupRecord{toUpdate: nt, target: underlying}
571 p.fixups = append(p.fixups, fix)
572 } else {
573 nt.SetUnderlying(underlying.Underlying())
574 }
575 }
576
577 if p.tok == '\n' {
578 p.next()
579
580 for p.tok == scanner.Ident {
581 p.expectKeyword("func")
582 if p.tok == '/' {
583
584 p.expect('/')
585 p.expect('*')
586 if p.expect(scanner.Ident) == "asm" {
587 p.parseUnquotedString()
588 }
589 p.expect('*')
590 p.expect('/')
591 }
592 p.expect('(')
593 receiver, _ := p.parseParam(types.RecvVar, pkg)
594 p.expect(')')
595 name := p.parseName()
596 params, isVariadic := p.parseParamList(types.ParamVar, pkg)
597 results := p.parseResultList(pkg)
598 p.skipInlineBody()
599 p.expectEOL()
600
601 sig := types.NewSignatureType(receiver, nil, nil, params, results, isVariadic)
602 nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
603 }
604 }
605
606 return nt
607 }
608
609 func (p *parser) parseInt64() int64 {
610 lit := p.expect(scanner.Int)
611 n, err := strconv.ParseInt(lit, 10, 64)
612 if err != nil {
613 p.error(err)
614 }
615 return n
616 }
617
618 func (p *parser) parseInt() int {
619 lit := p.expect(scanner.Int)
620 n, err := strconv.ParseInt(lit, 10, 0 )
621 if err != nil {
622 p.error(err)
623 }
624 return int(n)
625 }
626
627
628 func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []any) types.Type {
629 p.expect('[')
630 if p.tok == ']' {
631 p.next()
632
633 t := new(types.Slice)
634 p.update(t, nlist)
635
636 *t = *types.NewSlice(p.parseType(pkg))
637 return t
638 }
639
640 t := new(types.Array)
641 p.update(t, nlist)
642
643 len := p.parseInt64()
644 p.expect(']')
645
646 *t = *types.NewArray(p.parseType(pkg), len)
647 return t
648 }
649
650
651 func (p *parser) parseMapType(pkg *types.Package, nlist []any) types.Type {
652 p.expectKeyword("map")
653
654 t := new(types.Map)
655 p.update(t, nlist)
656
657 p.expect('[')
658 key := p.parseType(pkg)
659 p.expect(']')
660 elem := p.parseType(pkg)
661
662 *t = *types.NewMap(key, elem)
663 return t
664 }
665
666
667 func (p *parser) parseChanType(pkg *types.Package, nlist []any) types.Type {
668 p.expectKeyword("chan")
669
670 t := new(types.Chan)
671 p.update(t, nlist)
672
673 dir := types.SendRecv
674 switch p.tok {
675 case '-':
676 p.next()
677 p.expect('<')
678 dir = types.SendOnly
679
680 case '<':
681
682 if p.scanner.Peek() == '-' {
683 p.next()
684 p.expect('-')
685 dir = types.RecvOnly
686 }
687 }
688
689 *t = *types.NewChan(dir, p.parseType(pkg))
690 return t
691 }
692
693
694 func (p *parser) parseStructType(pkg *types.Package, nlist []any) types.Type {
695 p.expectKeyword("struct")
696
697 t := new(types.Struct)
698 p.update(t, nlist)
699
700 var fields []*types.Var
701 var tags []string
702
703 p.expect('{')
704 for p.tok != '}' && p.tok != scanner.EOF {
705 field, tag := p.parseField(pkg)
706 p.expect(';')
707 fields = append(fields, field)
708 tags = append(tags, tag)
709 }
710 p.expect('}')
711
712 *t = *types.NewStruct(fields, tags)
713 return t
714 }
715
716
717 func (p *parser) parseParamList(kind types.VarKind, pkg *types.Package) (*types.Tuple, bool) {
718 var list []*types.Var
719 isVariadic := false
720
721 p.expect('(')
722 for p.tok != ')' && p.tok != scanner.EOF {
723 if len(list) > 0 {
724 p.expect(',')
725 }
726 par, variadic := p.parseParam(kind, pkg)
727 list = append(list, par)
728 if variadic {
729 if isVariadic {
730 p.error("... not on final argument")
731 }
732 isVariadic = true
733 }
734 }
735 p.expect(')')
736
737 return types.NewTuple(list...), isVariadic
738 }
739
740
741 func (p *parser) parseResultList(pkg *types.Package) *types.Tuple {
742 switch p.tok {
743 case '<':
744 p.next()
745 if p.tok == scanner.Ident && p.lit == "inl" {
746 return nil
747 }
748 taa, _ := p.parseTypeAfterAngle(pkg)
749 param := types.NewParam(token.NoPos, pkg, "", taa)
750 param.SetKind(types.ResultVar)
751 return types.NewTuple(param)
752
753 case '(':
754 params, _ := p.parseParamList(types.ResultVar, pkg)
755 return params
756
757 default:
758 return nil
759 }
760 }
761
762
763 func (p *parser) parseFunctionType(pkg *types.Package, nlist []any) *types.Signature {
764 t := new(types.Signature)
765 p.update(t, nlist)
766
767 params, isVariadic := p.parseParamList(types.ParamVar, pkg)
768 results := p.parseResultList(pkg)
769
770 *t = *types.NewSignatureType(nil, nil, nil, params, results, isVariadic)
771 return t
772 }
773
774
775 func (p *parser) parseFunc(pkg *types.Package) *types.Func {
776 if p.tok == '/' {
777
778 p.expect('/')
779 p.expect('*')
780 if p.expect(scanner.Ident) == "asm" {
781 p.parseUnquotedString()
782 }
783 p.expect('*')
784 p.expect('/')
785 }
786
787 name := p.parseName()
788 f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil))
789 p.skipInlineBody()
790
791 if name[0] == '.' || name[0] == '<' || strings.ContainsRune(name, '$') {
792
793
794
795
796 return nil
797 }
798
799 return f
800 }
801
802
803 func (p *parser) parseInterfaceType(pkg *types.Package, nlist []any) types.Type {
804 p.expectKeyword("interface")
805
806 t := new(types.Interface)
807 p.update(t, nlist)
808
809 var methods []*types.Func
810 var embeddeds []types.Type
811
812 p.expect('{')
813 for p.tok != '}' && p.tok != scanner.EOF {
814 if p.tok == '?' {
815 p.next()
816 embeddeds = append(embeddeds, p.parseType(pkg))
817 } else {
818 method := p.parseFunc(pkg)
819 if method != nil {
820 methods = append(methods, method)
821 }
822 }
823 p.expect(';')
824 }
825 p.expect('}')
826
827 *t = *types.NewInterfaceType(methods, embeddeds)
828 return t
829 }
830
831
832 func (p *parser) parsePointerType(pkg *types.Package, nlist []any) types.Type {
833 p.expect('*')
834 if p.tok == scanner.Ident {
835 p.expectKeyword("any")
836 t := types.Typ[types.UnsafePointer]
837 p.update(t, nlist)
838 return t
839 }
840
841 t := new(types.Pointer)
842 p.update(t, nlist)
843
844 *t = *types.NewPointer(p.parseType(pkg, t))
845
846 return t
847 }
848
849
850 func (p *parser) parseTypeSpec(pkg *types.Package, nlist []any) types.Type {
851 switch p.tok {
852 case scanner.String:
853 return p.parseNamedType(nlist)
854
855 case scanner.Ident:
856 switch p.lit {
857 case "map":
858 return p.parseMapType(pkg, nlist)
859
860 case "chan":
861 return p.parseChanType(pkg, nlist)
862
863 case "struct":
864 return p.parseStructType(pkg, nlist)
865
866 case "interface":
867 return p.parseInterfaceType(pkg, nlist)
868 }
869
870 case '*':
871 return p.parsePointerType(pkg, nlist)
872
873 case '[':
874 return p.parseArrayOrSliceType(pkg, nlist)
875
876 case '(':
877 return p.parseFunctionType(pkg, nlist)
878 }
879
880 p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok))
881 return nil
882 }
883
884 const (
885
886
887
888 gccgoBuiltinINT8 = 1
889 gccgoBuiltinINT16 = 2
890 gccgoBuiltinINT32 = 3
891 gccgoBuiltinINT64 = 4
892 gccgoBuiltinUINT8 = 5
893 gccgoBuiltinUINT16 = 6
894 gccgoBuiltinUINT32 = 7
895 gccgoBuiltinUINT64 = 8
896 gccgoBuiltinFLOAT32 = 9
897 gccgoBuiltinFLOAT64 = 10
898 gccgoBuiltinINT = 11
899 gccgoBuiltinUINT = 12
900 gccgoBuiltinUINTPTR = 13
901 gccgoBuiltinBOOL = 15
902 gccgoBuiltinSTRING = 16
903 gccgoBuiltinCOMPLEX64 = 17
904 gccgoBuiltinCOMPLEX128 = 18
905 gccgoBuiltinERROR = 19
906 gccgoBuiltinBYTE = 20
907 gccgoBuiltinRUNE = 21
908 gccgoBuiltinANY = 22
909 )
910
911 func lookupBuiltinType(typ int) types.Type {
912 return [...]types.Type{
913 gccgoBuiltinINT8: types.Typ[types.Int8],
914 gccgoBuiltinINT16: types.Typ[types.Int16],
915 gccgoBuiltinINT32: types.Typ[types.Int32],
916 gccgoBuiltinINT64: types.Typ[types.Int64],
917 gccgoBuiltinUINT8: types.Typ[types.Uint8],
918 gccgoBuiltinUINT16: types.Typ[types.Uint16],
919 gccgoBuiltinUINT32: types.Typ[types.Uint32],
920 gccgoBuiltinUINT64: types.Typ[types.Uint64],
921 gccgoBuiltinFLOAT32: types.Typ[types.Float32],
922 gccgoBuiltinFLOAT64: types.Typ[types.Float64],
923 gccgoBuiltinINT: types.Typ[types.Int],
924 gccgoBuiltinUINT: types.Typ[types.Uint],
925 gccgoBuiltinUINTPTR: types.Typ[types.Uintptr],
926 gccgoBuiltinBOOL: types.Typ[types.Bool],
927 gccgoBuiltinSTRING: types.Typ[types.String],
928 gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64],
929 gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128],
930 gccgoBuiltinERROR: types.Universe.Lookup("error").Type(),
931 gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(),
932 gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(),
933 gccgoBuiltinANY: types.Universe.Lookup("any").Type(),
934 }[typ]
935 }
936
937
938
939
940 func (p *parser) parseType(pkg *types.Package, n ...any) types.Type {
941 p.expect('<')
942 t, _ := p.parseTypeAfterAngle(pkg, n...)
943 return t
944 }
945
946
947 func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...any) (t types.Type, n1 int) {
948 p.expectKeyword("type")
949
950 n1 = 0
951 switch p.tok {
952 case scanner.Int:
953 n1 = p.parseInt()
954 if p.tok == '>' {
955 if len(p.typeData) > 0 && p.typeList[n1] == nil {
956 p.parseSavedType(pkg, n1, n)
957 }
958 t = p.typeList[n1]
959 if len(p.typeData) == 0 && t == reserved {
960 p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n)
961 }
962 p.update(t, n)
963 } else {
964 p.reserve(n1)
965 t = p.parseTypeSpec(pkg, append(n, n1))
966 }
967
968 case '-':
969 p.next()
970 n1 := p.parseInt()
971 t = lookupBuiltinType(n1)
972 p.update(t, n)
973
974 default:
975 p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit)
976 return nil, 0
977 }
978
979 if t == nil || t == reserved {
980 p.errorf("internal error: bad return from parseType(%v)", n)
981 }
982
983 p.expect('>')
984 return
985 }
986
987
988
989
990 func (p *parser) parseTypeExtended(pkg *types.Package, n ...any) (t types.Type, n1 int) {
991 p.expect('<')
992 t, n1 = p.parseTypeAfterAngle(pkg, n...)
993 return
994 }
995
996
997
998 func (p *parser) skipInlineBody() {
999
1000
1001 if p.tok == '<' {
1002 p.next()
1003 p.expectKeyword("inl")
1004 } else if p.tok != scanner.Ident || p.lit != "inl" {
1005 return
1006 } else {
1007 p.next()
1008 }
1009
1010 p.expect(':')
1011 want := p.parseInt()
1012 p.expect('>')
1013
1014 defer func(w uint64) {
1015 p.scanner.Whitespace = w
1016 }(p.scanner.Whitespace)
1017 p.scanner.Whitespace = 0
1018
1019 got := 0
1020 for got < want {
1021 r := p.scanner.Next()
1022 if r == scanner.EOF {
1023 p.error("unexpected EOF")
1024 }
1025 got += utf8.RuneLen(r)
1026 }
1027 }
1028
1029
1030 func (p *parser) parseTypes(pkg *types.Package) {
1031 maxp1 := p.parseInt()
1032 exportedp1 := p.parseInt()
1033 p.typeList = make([]types.Type, maxp1, maxp1)
1034
1035 type typeOffset struct {
1036 offset int
1037 length int
1038 }
1039 var typeOffsets []typeOffset
1040
1041 total := 0
1042 for i := 1; i < maxp1; i++ {
1043 len := p.parseInt()
1044 typeOffsets = append(typeOffsets, typeOffset{total, len})
1045 total += len
1046 }
1047
1048 defer func(w uint64) {
1049 p.scanner.Whitespace = w
1050 }(p.scanner.Whitespace)
1051 p.scanner.Whitespace = 0
1052
1053
1054
1055
1056 var sb strings.Builder
1057 for sb.Len() < total {
1058 r := p.scanner.Next()
1059 if r == scanner.EOF {
1060 p.error("unexpected EOF")
1061 }
1062 sb.WriteRune(r)
1063 }
1064 allTypeData := sb.String()
1065
1066 p.typeData = []string{""}
1067 for _, to := range typeOffsets {
1068 p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length])
1069 }
1070
1071 for i := 1; i < exportedp1; i++ {
1072 p.parseSavedType(pkg, i, nil)
1073 }
1074 }
1075
1076
1077 func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []any) {
1078 defer func(s *scanner.Scanner, tok rune, lit string) {
1079 p.scanner = s
1080 p.tok = tok
1081 p.lit = lit
1082 }(p.scanner, p.tok, p.lit)
1083
1084 p.scanner = new(scanner.Scanner)
1085 p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i]))
1086 p.expectKeyword("type")
1087 id := p.parseInt()
1088 if id != i {
1089 p.errorf("type ID mismatch: got %d, want %d", id, i)
1090 }
1091 if p.typeList[i] == reserved {
1092 p.errorf("internal error: %d already reserved in parseSavedType", i)
1093 }
1094 if p.typeList[i] == nil {
1095 p.reserve(i)
1096 p.parseTypeSpec(pkg, append(nlist, i))
1097 }
1098 if p.typeList[i] == nil || p.typeList[i] == reserved {
1099 p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist)
1100 }
1101 }
1102
1103
1104 func (p *parser) parsePackageInit() PackageInit {
1105 name := p.parseUnquotedString()
1106 initfunc := p.parseUnquotedString()
1107 priority := -1
1108 if p.version == "v1" {
1109 priority = p.parseInt()
1110 }
1111 return PackageInit{Name: name, InitFunc: initfunc, Priority: priority}
1112 }
1113
1114
1115 func (p *parser) maybeCreatePackage() {
1116 if p.pkgname != "" && p.pkgpath != "" {
1117 p.pkg = p.getPkg(p.pkgpath, p.pkgname)
1118 }
1119 }
1120
1121
1122
1123
1124
1125
1126 func (p *parser) parseInitDataDirective() {
1127 if p.tok != scanner.Ident {
1128
1129 p.expect(scanner.Ident)
1130 }
1131
1132 switch p.lit {
1133 case "v1", "v2", "v3":
1134 p.version = p.lit
1135 p.next()
1136 p.expect(';')
1137 p.expect('\n')
1138
1139 case "priority":
1140 p.next()
1141 p.initdata.Priority = p.parseInt()
1142 p.expectEOL()
1143
1144 case "init":
1145 p.next()
1146 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
1147 p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit())
1148 }
1149 p.expectEOL()
1150
1151 case "init_graph":
1152 p.next()
1153
1154 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF {
1155 p.parseInt64()
1156 p.parseInt64()
1157 }
1158 p.expectEOL()
1159
1160 case "checksum":
1161
1162 defer func(mode uint) {
1163 p.scanner.Mode = mode
1164 }(p.scanner.Mode)
1165 p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats
1166 p.next()
1167 p.parseUnquotedString()
1168 p.expectEOL()
1169
1170 default:
1171 p.errorf("unexpected identifier: %q", p.lit)
1172 }
1173 }
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186 func (p *parser) parseDirective() {
1187 if p.tok != scanner.Ident {
1188
1189 p.expect(scanner.Ident)
1190 }
1191
1192 switch p.lit {
1193 case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum":
1194 p.parseInitDataDirective()
1195
1196 case "package":
1197 p.next()
1198 p.pkgname = p.parseUnquotedString()
1199 p.maybeCreatePackage()
1200 if p.version != "v1" && p.tok != '\n' && p.tok != ';' {
1201 p.parseUnquotedString()
1202 p.parseUnquotedString()
1203 }
1204 p.expectEOL()
1205
1206 case "pkgpath":
1207 p.next()
1208 p.pkgpath = p.parseUnquotedString()
1209 p.maybeCreatePackage()
1210 p.expectEOL()
1211
1212 case "prefix":
1213 p.next()
1214 p.pkgpath = p.parseUnquotedString()
1215 p.expectEOL()
1216
1217 case "import":
1218 p.next()
1219 pkgname := p.parseUnquotedString()
1220 pkgpath := p.parseUnquotedString()
1221 p.getPkg(pkgpath, pkgname)
1222 p.parseString()
1223 p.expectEOL()
1224
1225 case "indirectimport":
1226 p.next()
1227 pkgname := p.parseUnquotedString()
1228 pkgpath := p.parseUnquotedString()
1229 p.getPkg(pkgpath, pkgname)
1230 p.expectEOL()
1231
1232 case "types":
1233 p.next()
1234 p.parseTypes(p.pkg)
1235 p.expectEOL()
1236
1237 case "func":
1238 p.next()
1239 fun := p.parseFunc(p.pkg)
1240 if fun != nil {
1241 p.pkg.Scope().Insert(fun)
1242 }
1243 p.expectEOL()
1244
1245 case "type":
1246 p.next()
1247 p.parseType(p.pkg)
1248 p.expectEOL()
1249
1250 case "var":
1251 p.next()
1252 v := p.parseVar(p.pkg)
1253 if v != nil {
1254 p.pkg.Scope().Insert(v)
1255 }
1256 p.expectEOL()
1257
1258 case "const":
1259 p.next()
1260 c := p.parseConst(p.pkg)
1261 p.pkg.Scope().Insert(c)
1262 p.expectEOL()
1263
1264 default:
1265 p.errorf("unexpected identifier: %q", p.lit)
1266 }
1267 }
1268
1269
1270 func (p *parser) parsePackage() *types.Package {
1271 for p.tok != scanner.EOF {
1272 p.parseDirective()
1273 }
1274 for _, f := range p.fixups {
1275 if f.target.Underlying() == nil {
1276 p.errorf("internal error: fixup can't be applied, loop required")
1277 }
1278 f.toUpdate.SetUnderlying(f.target.Underlying())
1279 }
1280 p.fixups = nil
1281 for _, typ := range p.typeList {
1282 if it, ok := typ.(*types.Interface); ok {
1283 it.Complete()
1284 }
1285 }
1286 p.pkg.MarkComplete()
1287 return p.pkg
1288 }
1289
View as plain text