...

Source file src/pkg/go/internal/gccgoimporter/parser.go

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

View as plain text