github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/go/internal/gccgoimporter/parser.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gccgoimporter 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "go/constant" 12 "go/token" 13 "go/types" 14 "io" 15 "strconv" 16 "strings" 17 "text/scanner" 18 ) 19 20 type parser struct { 21 scanner scanner.Scanner 22 version string // format version 23 tok rune // current token 24 lit string // literal string; only valid for Ident, Int, String tokens 25 pkgpath string // package path of imported package 26 pkgname string // name of imported package 27 pkg *types.Package // reference to imported package 28 imports map[string]*types.Package // package path -> package object 29 typeList []types.Type // type number -> type 30 initdata InitData // package init priority data 31 } 32 33 func (p *parser) init(filename string, src io.Reader, imports map[string]*types.Package) { 34 p.scanner.Init(src) 35 p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) } 36 p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments 37 p.scanner.Whitespace = 1<<'\t' | 1<<'\n' | 1<<' ' 38 p.scanner.Filename = filename // for good error messages 39 p.next() 40 p.imports = imports 41 p.typeList = make([]types.Type, 1 /* type numbers start at 1 */, 16) 42 } 43 44 type importError struct { 45 pos scanner.Position 46 err error 47 } 48 49 func (e importError) Error() string { 50 return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err) 51 } 52 53 func (p *parser) error(err interface{}) { 54 if s, ok := err.(string); ok { 55 err = errors.New(s) 56 } 57 // panic with a runtime.Error if err is not an error 58 panic(importError{p.scanner.Pos(), err.(error)}) 59 } 60 61 func (p *parser) errorf(format string, args ...interface{}) { 62 p.error(fmt.Errorf(format, args...)) 63 } 64 65 func (p *parser) expect(tok rune) string { 66 lit := p.lit 67 if p.tok != tok { 68 p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit) 69 } 70 p.next() 71 return lit 72 } 73 74 func (p *parser) expectKeyword(keyword string) { 75 lit := p.expect(scanner.Ident) 76 if lit != keyword { 77 p.errorf("expected keyword %s, got %q", keyword, lit) 78 } 79 } 80 81 func (p *parser) parseString() string { 82 str, err := strconv.Unquote(p.expect(scanner.String)) 83 if err != nil { 84 p.error(err) 85 } 86 return str 87 } 88 89 // unquotedString = { unquotedStringChar } . 90 // unquotedStringChar = <neither a whitespace nor a ';' char> . 91 func (p *parser) parseUnquotedString() string { 92 if p.tok == scanner.EOF { 93 p.error("unexpected EOF") 94 } 95 var buf bytes.Buffer 96 buf.WriteString(p.scanner.TokenText()) 97 // This loop needs to examine each character before deciding whether to consume it. If we see a semicolon, 98 // we need to let it be consumed by p.next(). 99 for ch := p.scanner.Peek(); ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() { 100 buf.WriteRune(ch) 101 p.scanner.Next() 102 } 103 p.next() 104 return buf.String() 105 } 106 107 func (p *parser) next() { 108 p.tok = p.scanner.Scan() 109 switch p.tok { 110 case scanner.Ident, scanner.Int, scanner.Float, scanner.String, 'ยท': 111 p.lit = p.scanner.TokenText() 112 default: 113 p.lit = "" 114 } 115 } 116 117 func (p *parser) parseQualifiedName() (path, name string) { 118 return p.parseQualifiedNameStr(p.parseString()) 119 } 120 121 func (p *parser) parseUnquotedQualifiedName() (path, name string) { 122 return p.parseQualifiedNameStr(p.parseUnquotedString()) 123 } 124 125 // qualifiedName = [ ["."] unquotedString "." ] unquotedString . 126 // 127 // The above production uses greedy matching. 128 func (p *parser) parseQualifiedNameStr(unquotedName string) (pkgpath, name string) { 129 parts := strings.Split(unquotedName, ".") 130 if parts[0] == "" { 131 parts = parts[1:] 132 } 133 134 switch len(parts) { 135 case 0: 136 p.errorf("malformed qualified name: %q", unquotedName) 137 case 1: 138 // unqualified name 139 pkgpath = p.pkgpath 140 name = parts[0] 141 default: 142 // qualified name, which may contain periods 143 pkgpath = strings.Join(parts[0:len(parts)-1], ".") 144 name = parts[len(parts)-1] 145 } 146 147 return 148 } 149 150 // getPkg returns the package for a given path. If the package is 151 // not found but we have a package name, create the package and 152 // add it to the p.imports map. 153 // 154 func (p *parser) getPkg(pkgpath, name string) *types.Package { 155 // package unsafe is not in the imports map - handle explicitly 156 if pkgpath == "unsafe" { 157 return types.Unsafe 158 } 159 pkg := p.imports[pkgpath] 160 if pkg == nil && name != "" { 161 pkg = types.NewPackage(pkgpath, name) 162 p.imports[pkgpath] = pkg 163 } 164 return pkg 165 } 166 167 // parseExportedName is like parseQualifiedName, but 168 // the package path is resolved to an imported *types.Package. 169 // 170 // ExportedName = string [string] . 171 func (p *parser) parseExportedName() (pkg *types.Package, name string) { 172 path, name := p.parseQualifiedName() 173 var pkgname string 174 if p.tok == scanner.String { 175 pkgname = p.parseString() 176 } 177 pkg = p.getPkg(path, pkgname) 178 if pkg == nil { 179 p.errorf("package %s (path = %q) not found", name, path) 180 } 181 return 182 } 183 184 // Name = QualifiedName | "?" . 185 func (p *parser) parseName() string { 186 if p.tok == '?' { 187 // Anonymous. 188 p.next() 189 return "" 190 } 191 // The package path is redundant for us. Don't try to parse it. 192 _, name := p.parseUnquotedQualifiedName() 193 return name 194 } 195 196 func deref(typ types.Type) types.Type { 197 if p, _ := typ.(*types.Pointer); p != nil { 198 typ = p.Elem() 199 } 200 return typ 201 } 202 203 // Field = Name Type [string] . 204 func (p *parser) parseField(pkg *types.Package) (field *types.Var, tag string) { 205 name := p.parseName() 206 typ := p.parseType(pkg) 207 anon := false 208 if name == "" { 209 anon = true 210 switch typ := deref(typ).(type) { 211 case *types.Basic: 212 name = typ.Name() 213 case *types.Named: 214 name = typ.Obj().Name() 215 default: 216 p.error("anonymous field expected") 217 } 218 } 219 field = types.NewField(token.NoPos, pkg, name, typ, anon) 220 if p.tok == scanner.String { 221 tag = p.parseString() 222 } 223 return 224 } 225 226 // Param = Name ["..."] Type . 227 func (p *parser) parseParam(pkg *types.Package) (param *types.Var, isVariadic bool) { 228 name := p.parseName() 229 if p.tok == '<' && p.scanner.Peek() == 'e' { 230 // EscInfo = "<esc:" int ">" . (optional and ignored) 231 p.next() 232 p.expectKeyword("esc") 233 p.expect(':') 234 p.expect(scanner.Int) 235 p.expect('>') 236 } 237 if p.tok == '.' { 238 p.next() 239 p.expect('.') 240 p.expect('.') 241 isVariadic = true 242 } 243 typ := p.parseType(pkg) 244 if isVariadic { 245 typ = types.NewSlice(typ) 246 } 247 param = types.NewParam(token.NoPos, pkg, name, typ) 248 return 249 } 250 251 // Var = Name Type . 252 func (p *parser) parseVar(pkg *types.Package) *types.Var { 253 name := p.parseName() 254 return types.NewVar(token.NoPos, pkg, name, p.parseType(pkg)) 255 } 256 257 // Conversion = "convert" "(" Type "," ConstValue ")" . 258 func (p *parser) parseConversion(pkg *types.Package) (val constant.Value, typ types.Type) { 259 p.expectKeyword("convert") 260 p.expect('(') 261 typ = p.parseType(pkg) 262 p.expect(',') 263 val, _ = p.parseConstValue(pkg) 264 p.expect(')') 265 return 266 } 267 268 // ConstValue = string | "false" | "true" | ["-"] (int ["'"] | FloatOrComplex) | Conversion . 269 // FloatOrComplex = float ["i" | ("+"|"-") float "i"] . 270 func (p *parser) parseConstValue(pkg *types.Package) (val constant.Value, typ types.Type) { 271 switch p.tok { 272 case scanner.String: 273 str := p.parseString() 274 val = constant.MakeString(str) 275 typ = types.Typ[types.UntypedString] 276 return 277 278 case scanner.Ident: 279 b := false 280 switch p.lit { 281 case "false": 282 case "true": 283 b = true 284 285 case "convert": 286 return p.parseConversion(pkg) 287 288 default: 289 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 290 } 291 292 p.next() 293 val = constant.MakeBool(b) 294 typ = types.Typ[types.UntypedBool] 295 return 296 } 297 298 sign := "" 299 if p.tok == '-' { 300 p.next() 301 sign = "-" 302 } 303 304 switch p.tok { 305 case scanner.Int: 306 val = constant.MakeFromLiteral(sign+p.lit, token.INT, 0) 307 if val == nil { 308 p.error("could not parse integer literal") 309 } 310 311 p.next() 312 if p.tok == '\'' { 313 p.next() 314 typ = types.Typ[types.UntypedRune] 315 } else { 316 typ = types.Typ[types.UntypedInt] 317 } 318 319 case scanner.Float: 320 re := sign + p.lit 321 p.next() 322 323 var im string 324 switch p.tok { 325 case '+': 326 p.next() 327 im = p.expect(scanner.Float) 328 329 case '-': 330 p.next() 331 im = "-" + p.expect(scanner.Float) 332 333 case scanner.Ident: 334 // re is in fact the imaginary component. Expect "i" below. 335 im = re 336 re = "0" 337 338 default: 339 val = constant.MakeFromLiteral(re, token.FLOAT, 0) 340 if val == nil { 341 p.error("could not parse float literal") 342 } 343 typ = types.Typ[types.UntypedFloat] 344 return 345 } 346 347 p.expectKeyword("i") 348 reval := constant.MakeFromLiteral(re, token.FLOAT, 0) 349 if reval == nil { 350 p.error("could not parse real component of complex literal") 351 } 352 imval := constant.MakeFromLiteral(im+"i", token.IMAG, 0) 353 if imval == nil { 354 p.error("could not parse imag component of complex literal") 355 } 356 val = constant.BinaryOp(reval, token.ADD, imval) 357 typ = types.Typ[types.UntypedComplex] 358 359 default: 360 p.errorf("expected const value, got %s (%q)", scanner.TokenString(p.tok), p.lit) 361 } 362 363 return 364 } 365 366 // Const = Name [Type] "=" ConstValue . 367 func (p *parser) parseConst(pkg *types.Package) *types.Const { 368 name := p.parseName() 369 var typ types.Type 370 if p.tok == '<' { 371 typ = p.parseType(pkg) 372 } 373 p.expect('=') 374 val, vtyp := p.parseConstValue(pkg) 375 if typ == nil { 376 typ = vtyp 377 } 378 return types.NewConst(token.NoPos, pkg, name, typ, val) 379 } 380 381 // reserved is a singleton type used to fill type map slots that have 382 // been reserved (i.e., for which a type number has been parsed) but 383 // which don't have their actual type yet. When the type map is updated, 384 // the actual type must replace a reserved entry (or we have an internal 385 // error). Used for self-verification only - not required for correctness. 386 var reserved = new(struct{ types.Type }) 387 388 // reserve reserves the type map entry n for future use. 389 func (p *parser) reserve(n int) { 390 if n != len(p.typeList) { 391 p.errorf("invalid type number %d (out of sync)", n) 392 } 393 p.typeList = append(p.typeList, reserved) 394 } 395 396 // update sets the type map entries for the given type numbers nlist to t. 397 func (p *parser) update(t types.Type, nlist []int) { 398 for _, n := range nlist { 399 if p.typeList[n] != reserved { 400 p.errorf("typeMap[%d] not reserved", n) 401 } 402 p.typeList[n] = t 403 } 404 } 405 406 // NamedType = TypeName [ "=" ] Type { Method } . 407 // TypeName = ExportedName . 408 // Method = "func" "(" Param ")" Name ParamList ResultList ";" . 409 func (p *parser) parseNamedType(nlist []int) types.Type { 410 pkg, name := p.parseExportedName() 411 scope := pkg.Scope() 412 obj := scope.Lookup(name) 413 if obj != nil && obj.Type() == nil { 414 p.errorf("%v has nil type", obj) 415 } 416 417 // type alias 418 if p.tok == '=' { 419 p.next() 420 if obj != nil { 421 // use the previously imported (canonical) type 422 t := obj.Type() 423 p.update(t, nlist) 424 p.parseType(pkg) // discard 425 return t 426 } 427 t := p.parseType(pkg, nlist...) 428 obj = types.NewTypeName(token.NoPos, pkg, name, t) 429 scope.Insert(obj) 430 return t 431 } 432 433 // defined type 434 if obj == nil { 435 // A named type may be referred to before the underlying type 436 // is known - set it up. 437 tname := types.NewTypeName(token.NoPos, pkg, name, nil) 438 types.NewNamed(tname, nil, nil) 439 scope.Insert(tname) 440 obj = tname 441 } 442 443 // use the previously imported (canonical), or newly created type 444 t := obj.Type() 445 p.update(t, nlist) 446 447 nt, ok := t.(*types.Named) 448 if !ok { 449 // This can happen for unsafe.Pointer, which is a TypeName holding a Basic type. 450 pt := p.parseType(pkg) 451 if pt != t { 452 p.error("unexpected underlying type for non-named TypeName") 453 } 454 return t 455 } 456 457 underlying := p.parseType(pkg) 458 if nt.Underlying() == nil { 459 nt.SetUnderlying(underlying.Underlying()) 460 } 461 462 // collect associated methods 463 for p.tok == scanner.Ident { 464 p.expectKeyword("func") 465 p.expect('(') 466 receiver, _ := p.parseParam(pkg) 467 p.expect(')') 468 name := p.parseName() 469 params, isVariadic := p.parseParamList(pkg) 470 results := p.parseResultList(pkg) 471 p.expect(';') 472 473 sig := types.NewSignature(receiver, params, results, isVariadic) 474 nt.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig)) 475 } 476 477 return nt 478 } 479 480 func (p *parser) parseInt64() int64 { 481 lit := p.expect(scanner.Int) 482 n, err := strconv.ParseInt(lit, 10, 64) 483 if err != nil { 484 p.error(err) 485 } 486 return n 487 } 488 489 func (p *parser) parseInt() int { 490 lit := p.expect(scanner.Int) 491 n, err := strconv.ParseInt(lit, 10, 0 /* int */) 492 if err != nil { 493 p.error(err) 494 } 495 return int(n) 496 } 497 498 // ArrayOrSliceType = "[" [ int ] "]" Type . 499 func (p *parser) parseArrayOrSliceType(pkg *types.Package, nlist []int) types.Type { 500 p.expect('[') 501 if p.tok == ']' { 502 p.next() 503 504 t := new(types.Slice) 505 p.update(t, nlist) 506 507 *t = *types.NewSlice(p.parseType(pkg)) 508 return t 509 } 510 511 t := new(types.Array) 512 p.update(t, nlist) 513 514 len := p.parseInt64() 515 p.expect(']') 516 517 *t = *types.NewArray(p.parseType(pkg), len) 518 return t 519 } 520 521 // MapType = "map" "[" Type "]" Type . 522 func (p *parser) parseMapType(pkg *types.Package, nlist []int) types.Type { 523 p.expectKeyword("map") 524 525 t := new(types.Map) 526 p.update(t, nlist) 527 528 p.expect('[') 529 key := p.parseType(pkg) 530 p.expect(']') 531 elem := p.parseType(pkg) 532 533 *t = *types.NewMap(key, elem) 534 return t 535 } 536 537 // ChanType = "chan" ["<-" | "-<"] Type . 538 func (p *parser) parseChanType(pkg *types.Package, nlist []int) types.Type { 539 p.expectKeyword("chan") 540 541 t := new(types.Chan) 542 p.update(t, nlist) 543 544 dir := types.SendRecv 545 switch p.tok { 546 case '-': 547 p.next() 548 p.expect('<') 549 dir = types.SendOnly 550 551 case '<': 552 // don't consume '<' if it belongs to Type 553 if p.scanner.Peek() == '-' { 554 p.next() 555 p.expect('-') 556 dir = types.RecvOnly 557 } 558 } 559 560 *t = *types.NewChan(dir, p.parseType(pkg)) 561 return t 562 } 563 564 // StructType = "struct" "{" { Field } "}" . 565 func (p *parser) parseStructType(pkg *types.Package, nlist []int) types.Type { 566 p.expectKeyword("struct") 567 568 t := new(types.Struct) 569 p.update(t, nlist) 570 571 var fields []*types.Var 572 var tags []string 573 574 p.expect('{') 575 for p.tok != '}' && p.tok != scanner.EOF { 576 field, tag := p.parseField(pkg) 577 p.expect(';') 578 fields = append(fields, field) 579 tags = append(tags, tag) 580 } 581 p.expect('}') 582 583 *t = *types.NewStruct(fields, tags) 584 return t 585 } 586 587 // ParamList = "(" [ { Parameter "," } Parameter ] ")" . 588 func (p *parser) parseParamList(pkg *types.Package) (*types.Tuple, bool) { 589 var list []*types.Var 590 isVariadic := false 591 592 p.expect('(') 593 for p.tok != ')' && p.tok != scanner.EOF { 594 if len(list) > 0 { 595 p.expect(',') 596 } 597 par, variadic := p.parseParam(pkg) 598 list = append(list, par) 599 if variadic { 600 if isVariadic { 601 p.error("... not on final argument") 602 } 603 isVariadic = true 604 } 605 } 606 p.expect(')') 607 608 return types.NewTuple(list...), isVariadic 609 } 610 611 // ResultList = Type | ParamList . 612 func (p *parser) parseResultList(pkg *types.Package) *types.Tuple { 613 switch p.tok { 614 case '<': 615 return types.NewTuple(types.NewParam(token.NoPos, pkg, "", p.parseType(pkg))) 616 617 case '(': 618 params, _ := p.parseParamList(pkg) 619 return params 620 621 default: 622 return nil 623 } 624 } 625 626 // FunctionType = ParamList ResultList . 627 func (p *parser) parseFunctionType(pkg *types.Package, nlist []int) *types.Signature { 628 t := new(types.Signature) 629 p.update(t, nlist) 630 631 params, isVariadic := p.parseParamList(pkg) 632 results := p.parseResultList(pkg) 633 634 *t = *types.NewSignature(nil, params, results, isVariadic) 635 return t 636 } 637 638 // Func = Name FunctionType . 639 func (p *parser) parseFunc(pkg *types.Package) *types.Func { 640 name := p.parseName() 641 if strings.ContainsRune(name, '$') { 642 // This is a Type$equal or Type$hash function, which we don't want to parse, 643 // except for the types. 644 p.discardDirectiveWhileParsingTypes(pkg) 645 return nil 646 } 647 return types.NewFunc(token.NoPos, pkg, name, p.parseFunctionType(pkg, nil)) 648 } 649 650 // InterfaceType = "interface" "{" { ("?" Type | Func) ";" } "}" . 651 func (p *parser) parseInterfaceType(pkg *types.Package, nlist []int) types.Type { 652 p.expectKeyword("interface") 653 654 t := new(types.Interface) 655 p.update(t, nlist) 656 657 var methods []*types.Func 658 var embeddeds []types.Type 659 660 p.expect('{') 661 for p.tok != '}' && p.tok != scanner.EOF { 662 if p.tok == '?' { 663 p.next() 664 embeddeds = append(embeddeds, p.parseType(pkg)) 665 } else { 666 method := p.parseFunc(pkg) 667 methods = append(methods, method) 668 } 669 p.expect(';') 670 } 671 p.expect('}') 672 673 *t = *types.NewInterfaceType(methods, embeddeds) 674 return t 675 } 676 677 // PointerType = "*" ("any" | Type) . 678 func (p *parser) parsePointerType(pkg *types.Package, nlist []int) types.Type { 679 p.expect('*') 680 if p.tok == scanner.Ident { 681 p.expectKeyword("any") 682 t := types.Typ[types.UnsafePointer] 683 p.update(t, nlist) 684 return t 685 } 686 687 t := new(types.Pointer) 688 p.update(t, nlist) 689 690 *t = *types.NewPointer(p.parseType(pkg)) 691 692 return t 693 } 694 695 // TypeSpec = NamedType | MapType | ChanType | StructType | InterfaceType | PointerType | ArrayOrSliceType | FunctionType . 696 func (p *parser) parseTypeSpec(pkg *types.Package, nlist []int) types.Type { 697 switch p.tok { 698 case scanner.String: 699 return p.parseNamedType(nlist) 700 701 case scanner.Ident: 702 switch p.lit { 703 case "map": 704 return p.parseMapType(pkg, nlist) 705 706 case "chan": 707 return p.parseChanType(pkg, nlist) 708 709 case "struct": 710 return p.parseStructType(pkg, nlist) 711 712 case "interface": 713 return p.parseInterfaceType(pkg, nlist) 714 } 715 716 case '*': 717 return p.parsePointerType(pkg, nlist) 718 719 case '[': 720 return p.parseArrayOrSliceType(pkg, nlist) 721 722 case '(': 723 return p.parseFunctionType(pkg, nlist) 724 } 725 726 p.errorf("expected type name or literal, got %s", scanner.TokenString(p.tok)) 727 return nil 728 } 729 730 const ( 731 // From gofrontend/go/export.h 732 // Note that these values are negative in the gofrontend and have been made positive 733 // in the gccgoimporter. 734 gccgoBuiltinINT8 = 1 735 gccgoBuiltinINT16 = 2 736 gccgoBuiltinINT32 = 3 737 gccgoBuiltinINT64 = 4 738 gccgoBuiltinUINT8 = 5 739 gccgoBuiltinUINT16 = 6 740 gccgoBuiltinUINT32 = 7 741 gccgoBuiltinUINT64 = 8 742 gccgoBuiltinFLOAT32 = 9 743 gccgoBuiltinFLOAT64 = 10 744 gccgoBuiltinINT = 11 745 gccgoBuiltinUINT = 12 746 gccgoBuiltinUINTPTR = 13 747 gccgoBuiltinBOOL = 15 748 gccgoBuiltinSTRING = 16 749 gccgoBuiltinCOMPLEX64 = 17 750 gccgoBuiltinCOMPLEX128 = 18 751 gccgoBuiltinERROR = 19 752 gccgoBuiltinBYTE = 20 753 gccgoBuiltinRUNE = 21 754 ) 755 756 func lookupBuiltinType(typ int) types.Type { 757 return [...]types.Type{ 758 gccgoBuiltinINT8: types.Typ[types.Int8], 759 gccgoBuiltinINT16: types.Typ[types.Int16], 760 gccgoBuiltinINT32: types.Typ[types.Int32], 761 gccgoBuiltinINT64: types.Typ[types.Int64], 762 gccgoBuiltinUINT8: types.Typ[types.Uint8], 763 gccgoBuiltinUINT16: types.Typ[types.Uint16], 764 gccgoBuiltinUINT32: types.Typ[types.Uint32], 765 gccgoBuiltinUINT64: types.Typ[types.Uint64], 766 gccgoBuiltinFLOAT32: types.Typ[types.Float32], 767 gccgoBuiltinFLOAT64: types.Typ[types.Float64], 768 gccgoBuiltinINT: types.Typ[types.Int], 769 gccgoBuiltinUINT: types.Typ[types.Uint], 770 gccgoBuiltinUINTPTR: types.Typ[types.Uintptr], 771 gccgoBuiltinBOOL: types.Typ[types.Bool], 772 gccgoBuiltinSTRING: types.Typ[types.String], 773 gccgoBuiltinCOMPLEX64: types.Typ[types.Complex64], 774 gccgoBuiltinCOMPLEX128: types.Typ[types.Complex128], 775 gccgoBuiltinERROR: types.Universe.Lookup("error").Type(), 776 gccgoBuiltinBYTE: types.Universe.Lookup("byte").Type(), 777 gccgoBuiltinRUNE: types.Universe.Lookup("rune").Type(), 778 }[typ] 779 } 780 781 // Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" . 782 // 783 // parseType updates the type map to t for all type numbers n. 784 // 785 func (p *parser) parseType(pkg *types.Package, n ...int) (t types.Type) { 786 p.expect('<') 787 p.expectKeyword("type") 788 789 switch p.tok { 790 case scanner.Int: 791 n1 := p.parseInt() 792 if p.tok == '>' { 793 t = p.typeList[n1] 794 if t == reserved { 795 p.errorf("invalid type cycle, type %d not yet defined", n1) 796 } 797 p.update(t, n) 798 } else { 799 p.reserve(n1) 800 t = p.parseTypeSpec(pkg, append(n, n1)) 801 } 802 803 case '-': 804 p.next() 805 n1 := p.parseInt() 806 t = lookupBuiltinType(n1) 807 p.update(t, n) 808 809 default: 810 p.errorf("expected type number, got %s (%q)", scanner.TokenString(p.tok), p.lit) 811 } 812 813 p.expect('>') 814 return 815 } 816 817 // PackageInit = unquotedString unquotedString int . 818 func (p *parser) parsePackageInit() PackageInit { 819 name := p.parseUnquotedString() 820 initfunc := p.parseUnquotedString() 821 priority := -1 822 if p.version == "v1" { 823 priority = p.parseInt() 824 } 825 return PackageInit{Name: name, InitFunc: initfunc, Priority: priority} 826 } 827 828 // Throw away tokens until we see a ';'. If we see a '<', attempt to parse as a type. 829 func (p *parser) discardDirectiveWhileParsingTypes(pkg *types.Package) { 830 for { 831 switch p.tok { 832 case ';': 833 return 834 case '<': 835 p.parseType(pkg) 836 case scanner.EOF: 837 p.error("unexpected EOF") 838 default: 839 p.next() 840 } 841 } 842 } 843 844 // Create the package if we have parsed both the package path and package name. 845 func (p *parser) maybeCreatePackage() { 846 if p.pkgname != "" && p.pkgpath != "" { 847 p.pkg = p.getPkg(p.pkgpath, p.pkgname) 848 } 849 } 850 851 // InitDataDirective = ( "v1" | "v2" ) ";" | 852 // "priority" int ";" | 853 // "init" { PackageInit } ";" | 854 // "checksum" unquotedString ";" . 855 func (p *parser) parseInitDataDirective() { 856 if p.tok != scanner.Ident { 857 // unexpected token kind; panic 858 p.expect(scanner.Ident) 859 } 860 861 switch p.lit { 862 case "v1", "v2": 863 p.version = p.lit 864 p.next() 865 p.expect(';') 866 867 case "priority": 868 p.next() 869 p.initdata.Priority = p.parseInt() 870 p.expect(';') 871 872 case "init": 873 p.next() 874 for p.tok != ';' && p.tok != scanner.EOF { 875 p.initdata.Inits = append(p.initdata.Inits, p.parsePackageInit()) 876 } 877 p.expect(';') 878 879 case "init_graph": 880 p.next() 881 // The graph data is thrown away for now. 882 for p.tok != ';' && p.tok != scanner.EOF { 883 p.parseInt64() 884 p.parseInt64() 885 } 886 p.expect(';') 887 888 case "checksum": 889 // Don't let the scanner try to parse the checksum as a number. 890 defer func(mode uint) { 891 p.scanner.Mode = mode 892 }(p.scanner.Mode) 893 p.scanner.Mode &^= scanner.ScanInts | scanner.ScanFloats 894 p.next() 895 p.parseUnquotedString() 896 p.expect(';') 897 898 default: 899 p.errorf("unexpected identifier: %q", p.lit) 900 } 901 } 902 903 // Directive = InitDataDirective | 904 // "package" unquotedString [ unquotedString ] [ unquotedString ] ";" | 905 // "pkgpath" unquotedString ";" | 906 // "prefix" unquotedString ";" | 907 // "import" unquotedString unquotedString string ";" | 908 // "func" Func ";" | 909 // "type" Type ";" | 910 // "var" Var ";" | 911 // "const" Const ";" . 912 func (p *parser) parseDirective() { 913 if p.tok != scanner.Ident { 914 // unexpected token kind; panic 915 p.expect(scanner.Ident) 916 } 917 918 switch p.lit { 919 case "v1", "v2", "priority", "init", "init_graph", "checksum": 920 p.parseInitDataDirective() 921 922 case "package": 923 p.next() 924 p.pkgname = p.parseUnquotedString() 925 p.maybeCreatePackage() 926 if p.version == "v2" && p.tok != ';' { 927 p.parseUnquotedString() 928 p.parseUnquotedString() 929 } 930 p.expect(';') 931 932 case "pkgpath": 933 p.next() 934 p.pkgpath = p.parseUnquotedString() 935 p.maybeCreatePackage() 936 p.expect(';') 937 938 case "prefix": 939 p.next() 940 p.pkgpath = p.parseUnquotedString() 941 p.expect(';') 942 943 case "import": 944 p.next() 945 pkgname := p.parseUnquotedString() 946 pkgpath := p.parseUnquotedString() 947 p.getPkg(pkgpath, pkgname) 948 p.parseString() 949 p.expect(';') 950 951 case "func": 952 p.next() 953 fun := p.parseFunc(p.pkg) 954 if fun != nil { 955 p.pkg.Scope().Insert(fun) 956 } 957 p.expect(';') 958 959 case "type": 960 p.next() 961 p.parseType(p.pkg) 962 p.expect(';') 963 964 case "var": 965 p.next() 966 v := p.parseVar(p.pkg) 967 p.pkg.Scope().Insert(v) 968 p.expect(';') 969 970 case "const": 971 p.next() 972 c := p.parseConst(p.pkg) 973 p.pkg.Scope().Insert(c) 974 p.expect(';') 975 976 default: 977 p.errorf("unexpected identifier: %q", p.lit) 978 } 979 } 980 981 // Package = { Directive } . 982 func (p *parser) parsePackage() *types.Package { 983 for p.tok != scanner.EOF { 984 p.parseDirective() 985 } 986 for _, typ := range p.typeList { 987 if it, ok := typ.(*types.Interface); ok { 988 it.Complete() 989 } 990 } 991 p.pkg.MarkComplete() 992 return p.pkg 993 }