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