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 5package gccgoimporter 6 7import ( 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 20type 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 51type 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 56func (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 64func (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 73type importError struct { 74 pos scanner.Position 75 err error 76} 77 78func (e importError) Error() string { 79 return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err) 80} 81 82func (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 90func (p *parser) errorf(format string, args ...any) { 91 p.error(fmt.Errorf(format, args...)) 92} 93 94func (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 103func (p *parser) expectEOL() { 104 if p.version == "v1" || p.version == "v2" { 105 p.expect(';') 106 } 107 p.expect('\n') 108} 109 110func (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 117func (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> . 127func (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 143func (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 153func (p *parser) parseQualifiedName() (path, name string) { 154 return p.parseQualifiedNameStr(p.parseString()) 155} 156 157func (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. 164func (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. 189func (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] . 206func (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 | "?" . 220func (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 231func 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] . 239func (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 . 267func (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 . 296func (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 ")" . 309func (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"] . 321func (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 . 427func (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. 446var reserved = new(struct{ types.Type }) 447 448// reserve reserves the type map entry n for future use. 449func (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. 475func (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] ";" . 510func (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 608func (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 617func (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 . 627func (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 . 650func (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 . 666func (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 } "}" . 693func (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 ] ")" . 716func (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 . 740func (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 . 760func (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] . 772func (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) ";" } "}" . 800func (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) . 829func (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 . 847func (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 881const ( 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 gccgoBuiltinANY = 22 906) 907 908func lookupBuiltinType(typ int) types.Type { 909 return [...]types.Type{ 910 gccgoBuiltinINT8: types.Typ[types.Int8], 911 gccgoBuiltinINT16: types.Typ[types.Int16], 912 gccgoBuiltinINT32: types.Typ[types.Int32], 913 gccgoBuiltinINT64: types.Typ[types.Int64], 914 gccgoBuiltinUINT8: types.Typ[types.Uint8], 915 gccgoBuiltinUINT16: types.Typ[types.Uint16], 916 gccgoBuiltinUINT32: types.Typ[types.Uint32], 917 gccgoBuiltinUINT64: types.Typ[types.Uint64], 918 gccgoBuiltinFLOAT32: types.Typ[types.Float32], 919 gccgoBuiltinFLOAT64: types.Typ[types.Float64], 920 gccgoBuiltinINT: types.Typ[types.Int], 921 gccgoBuiltinUINT: types.Typ[types.Uint], 922 gccgoBuiltinUINTPTR: types.Typ[types.Uintptr], 923 gccgoBuiltinBOOL: types.Typ[types.Bool], 924 gccgoBuiltinSTRING: types.Typ[types.String], 925 gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64], 926 gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128], 927 gccgoBuiltinERROR: types.Universe.Lookup("error").Type(), 928 gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(), 929 gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(), 930 gccgoBuiltinANY: types.Universe.Lookup("any").Type(), 931 }[typ] 932} 933 934// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" . 935// 936// parseType updates the type map to t for all type numbers n. 937func (p *parser) parseType(pkg *types.Package, n ...any) types.Type { 938 p.expect('<') 939 t, _ := p.parseTypeAfterAngle(pkg, n...) 940 return t 941} 942 943// (*parser).Type after reading the "<". 944func (p *parser) parseTypeAfterAngle(pkg *types.Package, n ...any) (t types.Type, n1 int) { 945 p.expectKeyword("type") 946 947 n1 = 0 948 switch p.tok { 949 case scanner.Int: 950 n1 = p.parseInt() 951 if p.tok == '>' { 952 if len(p.typeData) > 0 && p.typeList[n1] == nil { 953 p.parseSavedType(pkg, n1, n) 954 } 955 t = p.typeList[n1] 956 if len(p.typeData) == 0 && t == reserved { 957 p.errorf("invalid type cycle, type %d not yet defined (nlist=%v)", n1, n) 958 } 959 p.update(t, n) 960 } else { 961 p.reserve(n1) 962 t = p.parseTypeSpec(pkg, append(n, n1)) 963 } 964 965 case '-': 966 p.next() 967 n1 := p.parseInt() 968 t = lookupBuiltinType(n1) 969 p.update(t, n) 970 971 default: 972 p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit) 973 return nil, 0 974 } 975 976 if t == nil || t == reserved { 977 p.errorf("internal error: bad return from parseType(%v)", n) 978 } 979 980 p.expect('>') 981 return 982} 983 984// parseTypeExtended is identical to parseType, but if the type in 985// question is a saved type, returns the index as well as the type 986// pointer (index returned is zero if we parsed a builtin). 987func (p *parser) parseTypeExtended(pkg *types.Package, n ...any) (t types.Type, n1 int) { 988 p.expect('<') 989 t, n1 = p.parseTypeAfterAngle(pkg, n...) 990 return 991} 992 993// InlineBody = "<inl:NN>" .{NN} 994// Reports whether a body was skipped. 995func (p *parser) skipInlineBody() { 996 // We may or may not have seen the '<' already, depending on 997 // whether the function had a result type or not. 998 if p.tok == '<' { 999 p.next() 1000 p.expectKeyword("inl") 1001 } else if p.tok != scanner.Ident || p.lit != "inl" { 1002 return 1003 } else { 1004 p.next() 1005 } 1006 1007 p.expect(':') 1008 want := p.parseInt() 1009 p.expect('>') 1010 1011 defer func(w uint64) { 1012 p.scanner.Whitespace = w 1013 }(p.scanner.Whitespace) 1014 p.scanner.Whitespace = 0 1015 1016 got := 0 1017 for got < want { 1018 r := p.scanner.Next() 1019 if r == scanner.EOF { 1020 p.error("unexpected EOF") 1021 } 1022 got += utf8.RuneLen(r) 1023 } 1024} 1025 1026// Types = "types" maxp1 exportedp1 (offset length)* . 1027func (p *parser) parseTypes(pkg *types.Package) { 1028 maxp1 := p.parseInt() 1029 exportedp1 := p.parseInt() 1030 p.typeList = make([]types.Type, maxp1, maxp1) 1031 1032 type typeOffset struct { 1033 offset int 1034 length int 1035 } 1036 var typeOffsets []typeOffset 1037 1038 total := 0 1039 for i := 1; i < maxp1; i++ { 1040 len := p.parseInt() 1041 typeOffsets = append(typeOffsets, typeOffset{total, len}) 1042 total += len 1043 } 1044 1045 defer func(w uint64) { 1046 p.scanner.Whitespace = w 1047 }(p.scanner.Whitespace) 1048 p.scanner.Whitespace = 0 1049 1050 // We should now have p.tok pointing to the final newline. 1051 // The next runes from the scanner should be the type data. 1052 1053 var sb strings.Builder 1054 for sb.Len() < total { 1055 r := p.scanner.Next() 1056 if r == scanner.EOF { 1057 p.error("unexpected EOF") 1058 } 1059 sb.WriteRune(r) 1060 } 1061 allTypeData := sb.String() 1062 1063 p.typeData = []string{""} // type 0, unused 1064 for _, to := range typeOffsets { 1065 p.typeData = append(p.typeData, allTypeData[to.offset:to.offset+to.length]) 1066 } 1067 1068 for i := 1; i < exportedp1; i++ { 1069 p.parseSavedType(pkg, i, nil) 1070 } 1071} 1072 1073// parseSavedType parses one saved type definition. 1074func (p *parser) parseSavedType(pkg *types.Package, i int, nlist []any) { 1075 defer func(s *scanner.Scanner, tok rune, lit string) { 1076 p.scanner = s 1077 p.tok = tok 1078 p.lit = lit 1079 }(p.scanner, p.tok, p.lit) 1080 1081 p.scanner = new(scanner.Scanner) 1082 p.initScanner(p.scanner.Filename, strings.NewReader(p.typeData[i])) 1083 p.expectKeyword("type") 1084 id := p.parseInt() 1085 if id != i { 1086 p.errorf("type ID mismatch: got %d, want %d", id, i) 1087 } 1088 if p.typeList[i] == reserved { 1089 p.errorf("internal error: %d already reserved in parseSavedType", i) 1090 } 1091 if p.typeList[i] == nil { 1092 p.reserve(i) 1093 p.parseTypeSpec(pkg, append(nlist, i)) 1094 } 1095 if p.typeList[i] == nil || p.typeList[i] == reserved { 1096 p.errorf("internal error: parseSavedType(%d,%v) reserved/nil", i, nlist) 1097 } 1098} 1099 1100// PackageInit = unquotedString unquotedString int . 1101func (p *parser) parsePackageInit() PackageInit { 1102 name := p.parseUnquotedString() 1103 initfunc := p.parseUnquotedString() 1104 priority := -1 1105 if p.version == "v1" { 1106 priority = p.parseInt() 1107 } 1108 return PackageInit{Name: name, InitFunc: initfunc, Priority: priority} 1109} 1110 1111// Create the package if we have parsed both the package path and package name. 1112func (p *parser) maybeCreatePackage() { 1113 if p.pkgname != "" && p.pkgpath != "" { 1114 p.pkg = p.getPkg(p.pkgpath, p.pkgname) 1115 } 1116} 1117 1118// InitDataDirective = ( "v1" | "v2" | "v3" ) ";" | 1119// 1120// "priority" int ";" | 1121// "init" { PackageInit } ";" | 1122// "checksum" unquotedString ";" . 1123func (p *parser) parseInitDataDirective() { 1124 if p.tok != scanner.Ident { 1125 // unexpected token kind; panic 1126 p.expect(scanner.Ident) 1127 } 1128 1129 switch p.lit { 1130 case "v1", "v2", "v3": 1131 p.version = p.lit 1132 p.next() 1133 p.expect(';') 1134 p.expect('\n') 1135 1136 case "priority": 1137 p.next() 1138 p.initdata.Priority = p.parseInt() 1139 p.expectEOL() 1140 1141 case "init": 1142 p.next() 1143 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF { 1144 p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit()) 1145 } 1146 p.expectEOL() 1147 1148 case "init_graph": 1149 p.next() 1150 // The graph data is thrown away for now. 1151 for p.tok != '\n' && p.tok != ';' && p.tok != scanner.EOF { 1152 p.parseInt64() 1153 p.parseInt64() 1154 } 1155 p.expectEOL() 1156 1157 case "checksum": 1158 // Don't let the scanner try to parse the checksum as a number. 1159 defer func(mode uint) { 1160 p.scanner.Mode = mode 1161 }(p.scanner.Mode) 1162 p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats 1163 p.next() 1164 p.parseUnquotedString() 1165 p.expectEOL() 1166 1167 default: 1168 p.errorf("unexpected identifier: %q", p.lit) 1169 } 1170} 1171 1172// Directive = InitDataDirective | 1173// 1174// "package" unquotedString [ unquotedString ] [ unquotedString ] ";" | 1175// "pkgpath" unquotedString ";" | 1176// "prefix" unquotedString ";" | 1177// "import" unquotedString unquotedString string ";" | 1178// "indirectimport" unquotedString unquotedstring ";" | 1179// "func" Func ";" | 1180// "type" Type ";" | 1181// "var" Var ";" | 1182// "const" Const ";" . 1183func (p *parser) parseDirective() { 1184 if p.tok != scanner.Ident { 1185 // unexpected token kind; panic 1186 p.expect(scanner.Ident) 1187 } 1188 1189 switch p.lit { 1190 case "v1", "v2", "v3", "priority", "init", "init_graph", "checksum": 1191 p.parseInitDataDirective() 1192 1193 case "package": 1194 p.next() 1195 p.pkgname = p.parseUnquotedString() 1196 p.maybeCreatePackage() 1197 if p.version != "v1" && p.tok != '\n' && p.tok != ';' { 1198 p.parseUnquotedString() 1199 p.parseUnquotedString() 1200 } 1201 p.expectEOL() 1202 1203 case "pkgpath": 1204 p.next() 1205 p.pkgpath = p.parseUnquotedString() 1206 p.maybeCreatePackage() 1207 p.expectEOL() 1208 1209 case "prefix": 1210 p.next() 1211 p.pkgpath = p.parseUnquotedString() 1212 p.expectEOL() 1213 1214 case "import": 1215 p.next() 1216 pkgname := p.parseUnquotedString() 1217 pkgpath := p.parseUnquotedString() 1218 p.getPkg(pkgpath, pkgname) 1219 p.parseString() 1220 p.expectEOL() 1221 1222 case "indirectimport": 1223 p.next() 1224 pkgname := p.parseUnquotedString() 1225 pkgpath := p.parseUnquotedString() 1226 p.getPkg(pkgpath, pkgname) 1227 p.expectEOL() 1228 1229 case "types": 1230 p.next() 1231 p.parseTypes(p.pkg) 1232 p.expectEOL() 1233 1234 case "func": 1235 p.next() 1236 fun := p.parseFunc(p.pkg) 1237 if fun != nil { 1238 p.pkg.Scope().Insert(fun) 1239 } 1240 p.expectEOL() 1241 1242 case "type": 1243 p.next() 1244 p.parseType(p.pkg) 1245 p.expectEOL() 1246 1247 case "var": 1248 p.next() 1249 v := p.parseVar(p.pkg) 1250 if v != nil { 1251 p.pkg.Scope().Insert(v) 1252 } 1253 p.expectEOL() 1254 1255 case "const": 1256 p.next() 1257 c := p.parseConst(p.pkg) 1258 p.pkg.Scope().Insert(c) 1259 p.expectEOL() 1260 1261 default: 1262 p.errorf("unexpected identifier: %q", p.lit) 1263 } 1264} 1265 1266// Package = { Directive } . 1267func (p *parser) parsePackage() *types.Package { 1268 for p.tok != scanner.EOF { 1269 p.parseDirective() 1270 } 1271 for _, f := range p.fixups { 1272 if f.target.Underlying() == nil { 1273 p.errorf("internal error: fixup can't be applied, loop required") 1274 } 1275 f.toUpdate.SetUnderlying(f.target.Underlying()) 1276 } 1277 p.fixups = nil 1278 for _, typ := range p.typeList { 1279 if it, ok := typ.(*types.Interface); ok { 1280 it.Complete() 1281 } 1282 } 1283 p.pkg.MarkComplete() 1284 return p.pkg 1285} 1286