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