github.com/bir3/gocompiler@v0.9.2202/src/go/internal/gccgoimporter/parser.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gccgoimporter 6 7 import ( 8 "errors" 9 "fmt" 10 "github.com/bir3/gocompiler/src/go/constant" 11 "github.com/bir3/gocompiler/src/go/token" 12 "github.com/bir3/gocompiler/src/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 // format version 23 tok rune // current token 24 lit string // literal string; only valid for Ident, Int, String tokens 25 pkgpath string // package path of imported package 26 pkgname string // name of imported package 27 pkg *types.Package // reference to imported package 28 imports map[string]*types.Package // package path -> package object 29 typeList []types.Type // type number -> type 30 typeData []string // unparsed type data (v3 and later) 31 fixups []fixupRecord // fixups to apply at end of parsing 32 initdata InitData // package init priority data 33 aliases map[int]string // maps saved type number to alias name 34 } 35 36 // When reading export data it's possible to encounter a defined type 37 // N1 with an underlying defined type N2 while we are still reading in 38 // that defined type N2; see issues #29006 and #29198 for instances 39 // of this. Example: 40 // 41 // type N1 N2 42 // type N2 struct { 43 // ... 44 // p *N1 45 // } 46 // 47 // To handle such cases, the parser generates a fixup record (below) and 48 // delays setting of N1's underlying type until parsing is complete, at 49 // which point fixups are applied. 50 51 type fixupRecord struct { 52 toUpdate *types.Named // type to modify when fixup is processed 53 target types.Type // type that was incomplete when fixup was created 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 /* type numbers start at 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 // for good error messages 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 // panic with a runtime.Error if err is not an error 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 // unquotedString = { unquotedStringChar } . 126 // unquotedStringChar = <neither a whitespace nor a ';' char> . 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 // This loop needs to examine each character before deciding whether to consume it. If we see a semicolon, 134 // we need to let it be consumed by p.next(). 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 // qualifiedName = [ ["."] unquotedString "." ] unquotedString . 162 // 163 // The above production uses greedy matching. 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 // unqualified name 175 pkgpath = p.pkgpath 176 name = parts[0] 177 default: 178 // qualified name, which may contain periods 179 pkgpath = strings.Join(parts[0:len(parts)-1], ".") 180 name = parts[len(parts)-1] 181 } 182 183 return 184 } 185 186 // getPkg returns the package for a given path. If the package is 187 // not found but we have a package name, create the package and 188 // add it to the p.imports map. 189 func (p *parser) getPkg(pkgpath, name string) *types.Package { 190 // package unsafe is not in the imports map - handle explicitly 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 // parseExportedName is like parseQualifiedName, but 203 // the package path is resolved to an imported *types.Package. 204 // 205 // ExportedName = string [string] . 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 // Name = QualifiedName | "?" . 220 func (p *parser) parseName() string { 221 if p.tok == '?' { 222 // Anonymous. 223 p.next() 224 return "" 225 } 226 // The package path is redundant for us. Don't try to parse it. 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 // Field = Name Type [string] . 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 // Alias? 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 // Param = Name ["..."] Type . 267 func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) { 268 name := p.parseName() 269 // Ignore names invented for inlinable functions. 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 // EscInfo = "<esc:" int ">" . (optional and ignored) 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 return 293 } 294 295 // Var = Name Type . 296 func (p *parser) parseVar(pkg *types.Package) *types.Var { 297 name := p.parseName() 298 v := types.NewVar(token.NoPos, pkg, name, p.parseType(pkg)) 299 if name[0] == '.' || name[0] == '<' { 300 // This is an unexported variable, 301 // or a variable defined in a different package. 302 // We only want to record exported variables. 303 return nil 304 } 305 return v 306 } 307 308 // Conversion = "convert" "(" Type "," ConstValue ")" . 309 func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) { 310 p.expectKeyword("convert") 311 p.expect('(') 312 typ = p.parseType(pkg) 313 p.expect(',') 314 val, _ = p.parseConstValue(pkg) 315 p.expect(')') 316 return 317 } 318 319 // ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion . 320 // FloatOrComplex = float ["i" | ("+"|"-") float "i"] . 321 func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) { 322 // v3 changed to $false, $true, $convert, to avoid confusion 323 // with variable names in inline function bodies. 324 if p.tok == '$' { 325 p.next() 326 if p.tok != scanner.Ident { 327 p.errorf("expected identifier after '$', got %s (%q)", scanner.TokenString(p.tok), p.lit) 328 } 329 } 330 331 switch p.tok { 332 case scanner.String: 333 str := p.parseString() 334 val = constant.MakeString(str) 335 typ = types.Typ[types.UntypedString] 336 return 337 338 case scanner.Ident: 339 b := false 340 switch p.lit { 341 case "false": 342 case "true": 343 b = true 344 345 case "convert": 346 return p.parseConversion(pkg) 347 348 default: 349 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 350 } 351 352 p.next() 353 val = constant.MakeBool(b) 354 typ = types.Typ[types.UntypedBool] 355 return 356 } 357 358 sign := "" 359 if p.tok == '-' { 360 p.next() 361 sign = "-" 362 } 363 364 switch p.tok { 365 case scanner.Int: 366 val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0) 367 if val == nil { 368 p.error("could not parse integer literal") 369 } 370 371 p.next() 372 if p.tok == '\'' { 373 p.next() 374 typ = types.Typ[types.UntypedRune] 375 } else { 376 typ = types.Typ[types.UntypedInt] 377 } 378 379 case scanner.Float: 380 re := sign + p.lit 381 p.next() 382 383 var im string 384 switch p.tok { 385 case '+': 386 p.next() 387 im = p.expect(scanner.Float) 388 389 case '-': 390 p.next() 391 im = "-" + p.expect(scanner.Float) 392 393 case scanner.Ident: 394 // re is in fact the imaginary component. Expect "i" below. 395 im = re 396 re = "0" 397 398 default: 399 val = constant.MakeFromLiteral(re, token.FLOAT, 0) 400 if val == nil { 401 p.error("could not parse float literal") 402 } 403 typ = types.Typ[types.UntypedFloat] 404 return 405 } 406 407 p.expectKeyword("i") 408 reval := constant.MakeFromLiteral(re, token.FLOAT, 0) 409 if reval == nil { 410 p.error("could not parse real component of complex literal") 411 } 412 imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0) 413 if imval == nil { 414 p.error("could not parse imag component of complex literal") 415 } 416 val = constant.BinaryOp(reval, token.ADD, imval) 417 typ = types.Typ[types.UntypedComplex] 418 419 default: 420 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 421 } 422 423 return 424 } 425 426 // Const = Name [Type] "=" ConstValue . 427 func (p *parser) parseConst(pkg *types.Package) *types.Const { 428 name := p.parseName() 429 var typ types.Type 430 if p.tok == '<' { 431 typ = p.parseType(pkg) 432 } 433 p.expect('=') 434 val, vtyp := p.parseConstValue(pkg) 435 if typ == nil { 436 typ = vtyp 437 } 438 return types.NewConst(token.NoPos, pkg, name, typ, val) 439 } 440 441 // reserved is a singleton type used to fill type map slots that have 442 // been reserved (i.e., for which a type number has been parsed) but 443 // which don't have their actual type yet. When the type map is updated, 444 // the actual type must replace a reserved entry (or we have an internal 445 // error). Used for self-verification only - not required for correctness. 446 var reserved = new(struct{ types.Type }) 447 448 // reserve reserves the type map entry n for future use. 449 func (p *parser) reserve(n int) { 450 // Notes: 451 // - for pre-V3 export data, the type numbers we see are 452 // guaranteed to be in increasing order, so we append a 453 // reserved entry onto the list. 454 // - for V3+ export data, type numbers can appear in 455 // any order, however the 'types' section tells us the 456 // total number of types, hence typeList is pre-allocated. 457 if len(p.typeData) == 0 { 458 if n != len(p.typeList) { 459 p.errorf("invalid type number %d (out of sync)", n) 460 } 461 p.typeList = append(p.typeList, reserved) 462 } else { 463 if p.typeList[n] != nil { 464 p.errorf("previously visited type number %d", n) 465 } 466 p.typeList[n] = reserved 467 } 468 } 469 470 // update sets the type map entries for the entries in nlist to t. 471 // An entry in nlist can be a type number in p.typeList, 472 // used to resolve named types, or it can be a *types.Pointer, 473 // used to resolve pointers to named types in case they are referenced 474 // by embedded fields. 475 func (p *parser) update(t types.Type, nlist []any) { 476 if t == reserved { 477 p.errorf("internal error: update(%v) invoked on reserved", nlist) 478 } 479 if t == nil { 480 p.errorf("internal error: update(%v) invoked on nil", nlist) 481 } 482 for _, n := range nlist { 483 switch n := n.(type) { 484 case int: 485 if p.typeList[n] == t { 486 continue 487 } 488 if p.typeList[n] != reserved { 489 p.errorf("internal error: update(%v): %d not reserved", nlist, n) 490 } 491 p.typeList[n] = t 492 case *types.Pointer: 493 if *n != (types.Pointer{}) { 494 elem := n.Elem() 495 if elem == t { 496 continue 497 } 498 p.errorf("internal error: update: pointer already set to %v, expected %v", elem, t) 499 } 500 *n = *types.NewPointer(t) 501 default: 502 p.errorf("internal error: %T on nlist", n) 503 } 504 } 505 } 506 507 // NamedType = TypeName [ "=" ] Type { Method } . 508 // TypeName = ExportedName . 509 // Method = "func" "(" Param ")" Name ParamList ResultList [InlineBody] ";" . 510 func (p *parser) parseNamedType(nlist []any) types.Type { 511 pkg, name := p.parseExportedName() 512 scope := pkg.Scope() 513 obj := scope.Lookup(name) 514 if obj != nil && obj.Type() == nil { 515 p.errorf("%v has nil type", obj) 516 } 517 518 if p.tok == scanner.Ident && p.lit == "notinheap" { 519 p.next() 520 // The go/types package has no way of recording that 521 // this type is marked notinheap. Presumably no user 522 // of this package actually cares. 523 } 524 525 // type alias 526 if p.tok == '=' { 527 p.next() 528 p.aliases[nlist[len(nlist)-1].(int)] = name 529 if obj != nil { 530 // use the previously imported (canonical) type 531 t := obj.Type() 532 p.update(t, nlist) 533 p.parseType(pkg) // discard 534 return t 535 } 536 t := p.parseType(pkg, nlist...) 537 obj = types.NewTypeName(token.NoPos, pkg, name, t) 538 scope.Insert(obj) 539 return t 540 } 541 542 // defined type 543 if obj == nil { 544 // A named type may be referred to before the underlying type 545 // is known - set it up. 546 tname := types.NewTypeName(token.NoPos, pkg, name, nil) 547 types.NewNamed(tname, nil, nil) 548 scope.Insert(tname) 549 obj = tname 550 } 551 552 // use the previously imported (canonical), or newly created type 553 t := obj.Type() 554 p.update(t, nlist) 555 556 nt, ok := t.(*types.Named) 557 if !ok { 558 // This can happen for unsafe.Pointer, which is a TypeName holding a Basic type. 559 pt := p.parseType(pkg) 560 if pt != t { 561 p.error("unexpected underlying type for non-named TypeName") 562 } 563 return t 564 } 565 566 underlying := p.parseType(pkg) 567 if nt.Underlying() == nil { 568 if underlying.Underlying() == nil { 569 fix := fixupRecord{toUpdate: nt, target: underlying} 570 p.fixups = append(p.fixups, fix) 571 } else { 572 nt.SetUnderlying(underlying.Underlying()) 573 } 574 } 575 576 if p.tok == '\n' { 577 p.next() 578 // collect associated methods 579 for p.tok == scanner.Ident { 580 p.expectKeyword("func") 581 if p.tok == '/' { 582 // Skip a /*nointerface*/ or /*asm ID */ comment. 583 p.expect('/') 584 p.expect('*') 585 if p.expect(scanner.Ident) == "asm" { 586 p.parseUnquotedString() 587 } 588 p.expect('*') 589 p.expect('/') 590 } 591 p.expect('(') 592 receiver, _ := p.parseParam(pkg) 593 p.expect(')') 594 name := p.parseName() 595 params, isVariadic := p.parseParamList(pkg) 596 results := p.parseResultList(pkg) 597 p.skipInlineBody() 598 p.expectEOL() 599 600 sig := types.NewSignatureType(receiver, nil, nil, params, results, isVariadic) 601 nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) 602 } 603 } 604 605 return nt 606 } 607 608 func (p *parser) parseInt64() int64 { 609 lit := p.expect(scanner.Int) 610 n, err := strconv.ParseInt(lit, 10, 64) 611 if err != nil { 612 p.error(err) 613 } 614 return n 615 } 616 617 func (p *parser) parseInt() int { 618 lit := p.expect(scanner.Int) 619 n, err := strconv.ParseInt(lit, 10, 0 /* int */) 620 if err != nil { 621 p.error(err) 622 } 623 return int(n) 624 } 625 626 // ArrayOrSliceType = "[" [ int ] "]" Type . 627 func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []any) types.Type { 628 p.expect('[') 629 if p.tok == ']' { 630 p.next() 631 632 t := new(types.Slice) 633 p.update(t, nlist) 634 635 *t = *types.NewSlice(p.parseType(pkg)) 636 return t 637 } 638 639 t := new(types.Array) 640 p.update(t, nlist) 641 642 len := p.parseInt64() 643 p.expect(']') 644 645 *t = *types.NewArray(p.parseType(pkg), len) 646 return t 647 } 648 649 // MapType = "map" "[" Type "]" Type . 650 func (p *parser) parseMapType(pkg *types.Package, nlist []any) types.Type { 651 p.expectKeyword("map") 652 653 t := new(types.Map) 654 p.update(t, nlist) 655 656 p.expect('[') 657 key := p.parseType(pkg) 658 p.expect(']') 659 elem := p.parseType(pkg) 660 661 *t = *types.NewMap(key, elem) 662 return t 663 } 664 665 // ChanType = "chan" ["<-" | "-<"] Type . 666 func (p *parser) parseChanType(pkg *types.Package, nlist []any) types.Type { 667 p.expectKeyword("chan") 668 669 t := new(types.Chan) 670 p.update(t, nlist) 671 672 dir := types.SendRecv 673 switch p.tok { 674 case '-': 675 p.next() 676 p.expect('<') 677 dir = types.SendOnly 678 679 case '<': 680 // don't consume '<' if it belongs to Type 681 if p.scanner.Peek() == '-' { 682 p.next() 683 p.expect('-') 684 dir = types.RecvOnly 685 } 686 } 687 688 *t = *types.NewChan(dir, p.parseType(pkg)) 689 return t 690 } 691 692 // StructType = "struct" "{" { Field } "}" . 693 func (p *parser) parseStructType(pkg *types.Package, nlist []any) types.Type { 694 p.expectKeyword("struct") 695 696 t := new(types.Struct) 697 p.update(t, nlist) 698 699 var fields []*types.Var 700 var tags []string 701 702 p.expect('{') 703 for p.tok != '}' && p.tok != scanner.EOF { 704 field, tag := p.parseField(pkg) 705 p.expect(';') 706 fields = append(fields, field) 707 tags = append(tags, tag) 708 } 709 p.expect('}') 710 711 *t = *types.NewStruct(fields, tags) 712 return t 713 } 714 715 // ParamList = "(" [ { Parameter "," } Parameter ] ")" . 716 func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) { 717 var list []*types.Var 718 isVariadic := false 719 720 p.expect('(') 721 for p.tok != ')' && p.tok != scanner.EOF { 722 if len(list) > 0 { 723 p.expect(',') 724 } 725 par, variadic := p.parseParam(pkg) 726 list = append(list, par) 727 if variadic { 728 if isVariadic { 729 p.error("... not on final argument") 730 } 731 isVariadic = true 732 } 733 } 734 p.expect(')') 735 736 return types.NewTuple(list...), isVariadic 737 } 738 739 // ResultList = Type | ParamList . 740 func (p *parser) parseResultList(pkg *types.Package) *types.Tuple { 741 switch p.tok { 742 case '<': 743 p.next() 744 if p.tok == scanner.Ident && p.lit == "inl" { 745 return nil 746 } 747 taa, _ := p.parseTypeAfterAngle(pkg) 748 return types.NewTuple(types.NewParam(token.NoPos, pkg, "", taa)) 749 750 case '(': 751 params, _ := p.parseParamList(pkg) 752 return params 753 754 default: 755 return nil 756 } 757 } 758 759 // FunctionType = ParamList ResultList . 760 func (p *parser) parseFunctionType(pkg *types.Package, nlist []any) *types.Signature { 761 t := new(types.Signature) 762 p.update(t, nlist) 763 764 params, isVariadic := p.parseParamList(pkg) 765 results := p.parseResultList(pkg) 766 767 *t = *types.NewSignatureType(nil, nil, nil, params, results, isVariadic) 768 return t 769 } 770 771 // Func = Name FunctionType [InlineBody] . 772 func (p *parser) parseFunc(pkg *types.Package) *types.Func { 773 if p.tok == '/' { 774 // Skip an /*asm ID */ comment. 775 p.expect('/') 776 p.expect('*') 777 if p.expect(scanner.Ident) == "asm" { 778 p.parseUnquotedString() 779 } 780 p.expect('*') 781 p.expect('/') 782 } 783 784 name := p.parseName() 785 f := types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil)) 786 p.skipInlineBody() 787 788 if name[0] == '.' || name[0] == '<' || strings.ContainsRune(name, '$') { 789 // This is an unexported function, 790 // or a function defined in a different package, 791 // or a type$equal or type$hash function. 792 // We only want to record exported functions. 793 return nil 794 } 795 796 return f 797 } 798 799 // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" . 800 func (p *parser) parseInterfaceType(pkg *types.Package, nlist []any) types.Type { 801 p.expectKeyword("interface") 802 803 t := new(types.Interface) 804 p.update(t, nlist) 805 806 var methods []*types.Func 807 var embeddeds []types.Type 808 809 p.expect('{') 810 for p.tok != '}' && p.tok != scanner.EOF { 811 if p.tok == '?' { 812 p.next() 813 embeddeds = append(embeddeds, p.parseType(pkg)) 814 } else { 815 method := p.parseFunc(pkg) 816 if method != nil { 817 methods = append(methods, method) 818 } 819 } 820 p.expect(';') 821 } 822 p.expect('}') 823 824 *t = *types.NewInterfaceType(methods, embeddeds) 825 return t 826 } 827 828 // PointerType = "*" ("any" | Type) . 829 func (p *parser) parsePointerType(pkg *types.Package, nlist []any) types.Type { 830 p.expect('*') 831 if p.tok == scanner.Ident { 832 p.expectKeyword("any") 833 t := types.Typ[types.UnsafePointer] 834 p.update(t, nlist) 835 return t 836 } 837 838 t := new(types.Pointer) 839 p.update(t, nlist) 840 841 *t = *types.NewPointer(p.parseType(pkg, t)) 842 843 return t 844 } 845 846 // TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType . 847 func (p *parser) parseTypeSpec(pkg *types.Package, nlist []any) types.Type { 848 switch p.tok { 849 case scanner.String: 850 return p.parseNamedType(nlist) 851 852 case scanner.Ident: 853 switch p.lit { 854 case "map": 855 return p.parseMapType(pkg, nlist) 856 857 case "chan": 858 return p.parseChanType(pkg, nlist) 859 860 case "struct": 861 return p.parseStructType(pkg, nlist) 862 863 case "interface": 864 return p.parseInterfaceType(pkg, nlist) 865 } 866 867 case '*': 868 return p.parsePointerType(pkg, nlist) 869 870 case '[': 871 return p.parseArrayOrSliceType(pkg, nlist) 872 873 case '(': 874 return p.parseFunctionType(pkg, nlist) 875 } 876 877 p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok)) 878 return nil 879 } 880 881 const ( 882 // From gofrontend/go/export.h 883 // Note that these values are negative in the gofrontend and have been made positive 884 // in the gccgoimporter. 885 gccgoBuiltinINT8 = 1 886 gccgoBuiltinINT16 = 2 887 gccgoBuiltinINT32 = 3 888 gccgoBuiltinINT64 = 4 889 gccgoBuiltinUINT8 = 5 890 gccgoBuiltinUINT16 = 6 891 gccgoBuiltinUINT32 = 7 892 gccgoBuiltinUINT64 = 8 893 gccgoBuiltinFLOAT32 = 9 894 gccgoBuiltinFLOAT64 = 10 895 gccgoBuiltinINT = 11 896 gccgoBuiltinUINT = 12 897 gccgoBuiltinUINTPTR = 13 898 gccgoBuiltinBOOL = 15 899 gccgoBuiltinSTRING = 16 900 gccgoBuiltinCOMPLEX64 = 17 901 gccgoBuiltinCOMPLEX128 = 18 902 gccgoBuiltinERROR = 19 903 gccgoBuiltinBYTE = 20 904 gccgoBuiltinRUNE = 21 905 ) 906 907 func lookupBuiltinType(typ int) types.Type { 908 return [...]types.Type{ 909 gccgoBuiltinINT8: types.Typ[types.Int8], 910 gccgoBuiltinINT16: types.Typ[types.Int16], 911 gccgoBuiltinINT32: types.Typ[types.Int32], 912 gccgoBuiltinINT64: types.Typ[types.Int64], 913 gccgoBuiltinUINT8: types.Typ[types.Uint8], 914 gccgoBuiltinUINT16: types.Typ[types.Uint16], 915 gccgoBuiltinUINT32: types.Typ[types.Uint32], 916 gccgoBuiltinUINT64: types.Typ[types.Uint64], 917 gccgoBuiltinFLOAT32: types.Typ[types.Float32], 918 gccgoBuiltinFLOAT64: types.Typ[types.Float64], 919 gccgoBuiltinINT: types.Typ[types.Int], 920 gccgoBuiltinUINT: types.Typ[types.Uint], 921 gccgoBuiltinUINTPTR: types.Typ[types.Uintptr], 922 gccgoBuiltinBOOL: types.Typ[types.Bool], 923 gccgoBuiltinSTRING: types.Typ[types.String], 924 gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64], 925 gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128], 926 gccgoBuiltinERROR: types.Universe.Lookup("error").Type(), 927 gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(), 928 gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(), 929 }[typ] 930 } 931 932 // Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" . 933 // 934 // parseType updates the type map to t for all type numbers n. 935 func (p *parser) parseType(pkg *types.Package, n ...any) types.Type { 936 p.expect('<') 937 t, _ := p.parseTypeAfterAngle(pkg, n...) 938 return t 939 } 940 941 // (*parser).Type after reading the "<". 942 func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...any) (t types.Type, n1 int) { 943 p.expectKeyword("type") 944 945 n1 = 0 946 switch p.tok { 947 case scanner.Int: 948 n1 = p.parseInt() 949 if p.tok == '>' { 950 if len(p.typeData) > 0 && p.typeList[n1] == nil { 951 p.parseSavedType(pkg, n1, n) 952 } 953 t = p.typeList[n1] 954 if len(p.typeData) == 0 && t == reserved { 955 p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n) 956 } 957 p.update(t, n) 958 } else { 959 p.reserve(n1) 960 t = p.parseTypeSpec(pkg, append(n, n1)) 961 } 962 963 case '-': 964 p.next() 965 n1 := p.parseInt() 966 t = lookupBuiltinType(n1) 967 p.update(t, n) 968 969 default: 970 p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit) 971 return nil, 0 972 } 973 974 if t == nil || t == reserved { 975 p.errorf("internal error: bad return from parseType(%v)", n) 976 } 977 978 p.expect('>') 979 return 980 } 981 982 // parseTypeExtended is identical to parseType, but if the type in 983 // question is a saved type, returns the index as well as the type 984 // pointer (index returned is zero if we parsed a builtin). 985 func (p *parser) parseTypeExtended(pkg *types.Package, n ...any) (t types.Type, n1 int) { 986 p.expect('<') 987 t, n1 = p.parseTypeAfterAngle(pkg, n...) 988 return 989 } 990 991 // InlineBody = "<inl:NN>" .{NN} 992 // Reports whether a body was skipped. 993 func (p *parser) skipInlineBody() { 994 // We may or may not have seen the '<' already, depending on 995 // whether the function had a result type or not. 996 if p.tok == '<' { 997 p.next() 998 p.expectKeyword("inl") 999 } else if p.tok != scanner.Ident || p.lit != "inl" { 1000 return 1001 } else { 1002 p.next() 1003 } 1004 1005 p.expect(':') 1006 want := p.parseInt() 1007 p.expect('>') 1008 1009 defer func(w uint64) { 1010 p.scanner.Whitespace = w 1011 }(p.scanner.Whitespace) 1012 p.scanner.Whitespace = 0 1013 1014 got := 0 1015 for got < want { 1016 r := p.scanner.Next() 1017 if r == scanner.EOF { 1018 p.error("unexpected EOF") 1019 } 1020 got += utf8.RuneLen(r) 1021 } 1022 } 1023 1024 // Types = "types" maxp1 exportedp1 (offset length)* . 1025 func (p *parser) parseTypes(pkg *types.Package) { 1026 maxp1 := p.parseInt() 1027 exportedp1 := p.parseInt() 1028 p.typeList = make([]types.Type, maxp1, maxp1) 1029 1030 type typeOffset struct { 1031 offset int 1032 length int 1033 } 1034 var typeOffsets []typeOffset 1035 1036 total := 0 1037 for i := 1; i < maxp1; i++ { 1038 len := p.parseInt() 1039 typeOffsets = append(typeOffsets, typeOffset{total, len}) 1040 total += len 1041 } 1042 1043 defer func(w uint64) { 1044 p.scanner.Whitespace = w 1045 }(p.scanner.Whitespace) 1046 p.scanner.Whitespace = 0 1047 1048 // We should now have p.tok pointing to the final newline. 1049 // The next runes from the scanner should be the type data. 1050 1051 var sb strings.Builder 1052 for sb.Len() < total { 1053 r := p.scanner.Next() 1054 if r == scanner.EOF { 1055 p.error("unexpected EOF") 1056 } 1057 sb.WriteRune(r) 1058 } 1059 allTypeData := sb.String() 1060 1061 p.typeData = []string{""} // type 0, unused 1062 for _, to := range typeOffsets { 1063 p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length]) 1064 } 1065 1066 for i := 1; i < exportedp1; i++ { 1067 p.parseSavedType(pkg, i, nil) 1068 } 1069 } 1070 1071 // parseSavedType parses one saved type definition. 1072 func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []any) { 1073 defer func(s *scanner.Scanner, tok rune, lit string) { 1074 p.scanner = s 1075 p.tok = tok 1076 p.lit = lit 1077 }(p.scanner, p.tok, p.lit) 1078 1079 p.scanner = new(scanner.Scanner) 1080 p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i])) 1081 p.expectKeyword("type") 1082 id := p.parseInt() 1083 if id != i { 1084 p.errorf("type ID mismatch: got %d, want %d", id, i) 1085 } 1086 if p.typeList[i] == reserved { 1087 p.errorf("internal error: %d already reserved in parseSavedType", i) 1088 } 1089 if p.typeList[i] == nil { 1090 p.reserve(i) 1091 p.parseTypeSpec(pkg, append(nlist, i)) 1092 } 1093 if p.typeList[i] == nil || p.typeList[i] == reserved { 1094 p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist) 1095 } 1096 } 1097 1098 // PackageInit = unquotedString unquotedString int . 1099 func (p *parser) parsePackageInit() PackageInit { 1100 name := p.parseUnquotedString() 1101 initfunc := p.parseUnquotedString() 1102 priority := -1 1103 if p.version == "v1" { 1104 priority = p.parseInt() 1105 } 1106 return PackageInit{Name: name, InitFunc: initfunc, Priority: priority} 1107 } 1108 1109 // Create the package if we have parsed both the package path and package name. 1110 func (p *parser) maybeCreatePackage() { 1111 if p.pkgname != "" && p.pkgpath != "" { 1112 p.pkg = p.getPkg(p.pkgpath, p.pkgname) 1113 } 1114 } 1115 1116 // InitDataDirective = ( "v1" | "v2" | "v3" ) ";" | 1117 // 1118 // "priority" int ";" | 1119 // "init" { PackageInit } ";" | 1120 // "checksum" unquotedString ";" . 1121 func (p *parser) parseInitDataDirective() { 1122 if p.tok != scanner.Ident { 1123 // unexpected token kind; panic 1124 p.expect(scanner.Ident) 1125 } 1126 1127 switch p.lit { 1128 case "v1", "v2", "v3": 1129 p.version = p.lit 1130 p.next() 1131 p.expect(';') 1132 p.expect('\n') 1133 1134 case "priority": 1135 p.next() 1136 p.initdata.Priority = p.parseInt() 1137 p.expectEOL() 1138 1139 case "init": 1140 p.next() 1141 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF { 1142 p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit()) 1143 } 1144 p.expectEOL() 1145 1146 case "init_graph": 1147 p.next() 1148 // The graph data is thrown away for now. 1149 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF { 1150 p.parseInt64() 1151 p.parseInt64() 1152 } 1153 p.expectEOL() 1154 1155 case "checksum": 1156 // Don't let the scanner try to parse the checksum as a number. 1157 defer func(mode uint) { 1158 p.scanner.Mode = mode 1159 }(p.scanner.Mode) 1160 p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats 1161 p.next() 1162 p.parseUnquotedString() 1163 p.expectEOL() 1164 1165 default: 1166 p.errorf("unexpected identifier: %q", p.lit) 1167 } 1168 } 1169 1170 // Directive = InitDataDirective | 1171 // 1172 // "package" unquotedString [ unquotedString ] [ unquotedString ] ";" | 1173 // "pkgpath" unquotedString ";" | 1174 // "prefix" unquotedString ";" | 1175 // "import" unquotedString unquotedString string ";" | 1176 // "indirectimport" unquotedString unquotedstring ";" | 1177 // "func" Func ";" | 1178 // "type" Type ";" | 1179 // "var" Var ";" | 1180 // "const" Const ";" . 1181 func (p *parser) parseDirective() { 1182 if p.tok != scanner.Ident { 1183 // unexpected token kind; panic 1184 p.expect(scanner.Ident) 1185 } 1186 1187 switch p.lit { 1188 case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum": 1189 p.parseInitDataDirective() 1190 1191 case "package": 1192 p.next() 1193 p.pkgname = p.parseUnquotedString() 1194 p.maybeCreatePackage() 1195 if p.version != "v1" && p.tok != '\n' && p.tok != ';' { 1196 p.parseUnquotedString() 1197 p.parseUnquotedString() 1198 } 1199 p.expectEOL() 1200 1201 case "pkgpath": 1202 p.next() 1203 p.pkgpath = p.parseUnquotedString() 1204 p.maybeCreatePackage() 1205 p.expectEOL() 1206 1207 case "prefix": 1208 p.next() 1209 p.pkgpath = p.parseUnquotedString() 1210 p.expectEOL() 1211 1212 case "import": 1213 p.next() 1214 pkgname := p.parseUnquotedString() 1215 pkgpath := p.parseUnquotedString() 1216 p.getPkg(pkgpath, pkgname) 1217 p.parseString() 1218 p.expectEOL() 1219 1220 case "indirectimport": 1221 p.next() 1222 pkgname := p.parseUnquotedString() 1223 pkgpath := p.parseUnquotedString() 1224 p.getPkg(pkgpath, pkgname) 1225 p.expectEOL() 1226 1227 case "types": 1228 p.next() 1229 p.parseTypes(p.pkg) 1230 p.expectEOL() 1231 1232 case "func": 1233 p.next() 1234 fun := p.parseFunc(p.pkg) 1235 if fun != nil { 1236 p.pkg.Scope().Insert(fun) 1237 } 1238 p.expectEOL() 1239 1240 case "type": 1241 p.next() 1242 p.parseType(p.pkg) 1243 p.expectEOL() 1244 1245 case "var": 1246 p.next() 1247 v := p.parseVar(p.pkg) 1248 if v != nil { 1249 p.pkg.Scope().Insert(v) 1250 } 1251 p.expectEOL() 1252 1253 case "const": 1254 p.next() 1255 c := p.parseConst(p.pkg) 1256 p.pkg.Scope().Insert(c) 1257 p.expectEOL() 1258 1259 default: 1260 p.errorf("unexpected identifier: %q", p.lit) 1261 } 1262 } 1263 1264 // Package = { Directive } . 1265 func (p *parser) parsePackage() *types.Package { 1266 for p.tok != scanner.EOF { 1267 p.parseDirective() 1268 } 1269 for _, f := range p.fixups { 1270 if f.target.Underlying() == nil { 1271 p.errorf("internal error: fixup can't be applied, loop required") 1272 } 1273 f.toUpdate.SetUnderlying(f.target.Underlying()) 1274 } 1275 p.fixups = nil 1276 for _, typ := range p.typeList { 1277 if it, ok := typ.(*types.Interface); ok { 1278 it.Complete() 1279 } 1280 } 1281 p.pkg.MarkComplete() 1282 return p.pkg 1283 }