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