Imported Upstream version 4.7.3
[platform/upstream/gcc48.git] / libgo / go / exp / types / gcimporter.go
1 // Copyright 2011 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 // This file implements an ast.Importer for gc-generated object files.
6 // TODO(gri) Eventually move this into a separate package outside types.
7
8 package types
9
10 import (
11         "bufio"
12         "errors"
13         "fmt"
14         "go/ast"
15         "go/build"
16         "go/token"
17         "io"
18         "math/big"
19         "os"
20         "path/filepath"
21         "strconv"
22         "strings"
23         "text/scanner"
24 )
25
26 const trace = false // set to true for debugging
27
28 var pkgExts = [...]string{".a", ".5", ".6", ".8"}
29
30 // FindPkg returns the filename and unique package id for an import
31 // path based on package information provided by build.Import (using
32 // the build.Default build.Context).
33 // If no file was found, an empty filename is returned.
34 //
35 func FindPkg(path, srcDir string) (filename, id string) {
36         if len(path) == 0 {
37                 return
38         }
39
40         id = path
41         var noext string
42         switch {
43         default:
44                 // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
45                 bp, _ := build.Import(path, srcDir, build.FindOnly)
46                 if bp.PkgObj == "" {
47                         return
48                 }
49                 noext = bp.PkgObj
50                 if strings.HasSuffix(noext, ".a") {
51                         noext = noext[:len(noext)-len(".a")]
52                 }
53
54         case build.IsLocalImport(path):
55                 // "./x" -> "/this/directory/x.ext", "/this/directory/x"
56                 noext = filepath.Join(srcDir, path)
57                 id = noext
58
59         case filepath.IsAbs(path):
60                 // for completeness only - go/build.Import
61                 // does not support absolute imports
62                 // "/x" -> "/x.ext", "/x"
63                 noext = path
64         }
65
66         // try extensions
67         for _, ext := range pkgExts {
68                 filename = noext + ext
69                 if f, err := os.Stat(filename); err == nil && !f.IsDir() {
70                         return
71                 }
72         }
73
74         filename = "" // not found
75         return
76 }
77
78 // GcImportData imports a package by reading the gc-generated export data,
79 // adds the corresponding package object to the imports map indexed by id,
80 // and returns the object.
81 //
82 // The imports map must contains all packages already imported, and no map
83 // entry with id as the key must be present. The data reader position must
84 // be the beginning of the export data section. The filename is only used
85 // in error messages.
86 //
87 func GcImportData(imports map[string]*ast.Object, filename, id string, data *bufio.Reader) (pkg *ast.Object, err error) {
88         if trace {
89                 fmt.Printf("importing %s (%s)\n", id, filename)
90         }
91
92         if imports[id] != nil {
93                 panic(fmt.Sprintf("package %s already imported", id))
94         }
95
96         // support for gcParser error handling
97         defer func() {
98                 if r := recover(); r != nil {
99                         err = r.(importError) // will re-panic if r is not an importError
100                 }
101         }()
102
103         var p gcParser
104         p.init(filename, id, data, imports)
105         pkg = p.parseExport()
106
107         return
108 }
109
110 // GcImport imports a gc-generated package given its import path, adds the
111 // corresponding package object to the imports map, and returns the object.
112 // Local import paths are interpreted relative to the current working directory.
113 // The imports map must contains all packages already imported.
114 // GcImport satisfies the ast.Importer signature.
115 //
116 func GcImport(imports map[string]*ast.Object, path string) (pkg *ast.Object, err error) {
117         if path == "unsafe" {
118                 return Unsafe, nil
119         }
120
121         srcDir, err := os.Getwd()
122         if err != nil {
123                 return
124         }
125         filename, id := FindPkg(path, srcDir)
126         if filename == "" {
127                 err = errors.New("can't find import: " + id)
128                 return
129         }
130
131         if pkg = imports[id]; pkg != nil {
132                 return // package was imported before
133         }
134
135         // open file
136         f, err := os.Open(filename)
137         if err != nil {
138                 return
139         }
140         defer func() {
141                 f.Close()
142                 if err != nil {
143                         // Add file name to error.
144                         err = fmt.Errorf("reading export data: %s: %v", filename, err)
145                 }
146         }()
147
148         buf := bufio.NewReader(f)
149         if err = FindGcExportData(buf); err != nil {
150                 return
151         }
152
153         pkg, err = GcImportData(imports, filename, id, buf)
154
155         return
156 }
157
158 // ----------------------------------------------------------------------------
159 // gcParser
160
161 // gcParser parses the exports inside a gc compiler-produced
162 // object/archive file and populates its scope with the results.
163 type gcParser struct {
164         scanner scanner.Scanner
165         tok     rune                   // current token
166         lit     string                 // literal string; only valid for Ident, Int, String tokens
167         id      string                 // package id of imported package
168         imports map[string]*ast.Object // package id -> package object
169 }
170
171 func (p *gcParser) init(filename, id string, src io.Reader, imports map[string]*ast.Object) {
172         p.scanner.Init(src)
173         p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
174         p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
175         p.scanner.Whitespace = 1<<'\t' | 1<<' '
176         p.scanner.Filename = filename // for good error messages
177         p.next()
178         p.id = id
179         p.imports = imports
180 }
181
182 func (p *gcParser) next() {
183         p.tok = p.scanner.Scan()
184         switch p.tok {
185         case scanner.Ident, scanner.Int, scanner.String:
186                 p.lit = p.scanner.TokenText()
187         default:
188                 p.lit = ""
189         }
190         if trace {
191                 fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
192         }
193 }
194
195 // Declare inserts a named object of the given kind in scope.
196 func (p *gcParser) declare(scope *ast.Scope, kind ast.ObjKind, name string) *ast.Object {
197         // the object may have been imported before - if it exists
198         // already in the respective package scope, return that object
199         if obj := scope.Lookup(name); obj != nil {
200                 assert(obj.Kind == kind)
201                 return obj
202         }
203
204         // otherwise create a new object and insert it into the package scope
205         obj := ast.NewObj(kind, name)
206         if scope.Insert(obj) != nil {
207                 p.errorf("already declared: %v %s", kind, obj.Name)
208         }
209
210         // a new type object is a named type and may be referred
211         // to before the underlying type is known - set it up
212         if kind == ast.Typ {
213                 obj.Type = &Name{Obj: obj}
214         }
215
216         return obj
217 }
218
219 // ----------------------------------------------------------------------------
220 // Error handling
221
222 // Internal errors are boxed as importErrors.
223 type importError struct {
224         pos scanner.Position
225         err error
226 }
227
228 func (e importError) Error() string {
229         return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
230 }
231
232 func (p *gcParser) error(err interface{}) {
233         if s, ok := err.(string); ok {
234                 err = errors.New(s)
235         }
236         // panic with a runtime.Error if err is not an error
237         panic(importError{p.scanner.Pos(), err.(error)})
238 }
239
240 func (p *gcParser) errorf(format string, args ...interface{}) {
241         p.error(fmt.Sprintf(format, args...))
242 }
243
244 func (p *gcParser) expect(tok rune) string {
245         lit := p.lit
246         if p.tok != tok {
247                 panic(1)
248                 p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
249         }
250         p.next()
251         return lit
252 }
253
254 func (p *gcParser) expectSpecial(tok string) {
255         sep := 'x' // not white space
256         i := 0
257         for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
258                 sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
259                 p.next()
260                 i++
261         }
262         if i < len(tok) {
263                 p.errorf("expected %q, got %q", tok, tok[0:i])
264         }
265 }
266
267 func (p *gcParser) expectKeyword(keyword string) {
268         lit := p.expect(scanner.Ident)
269         if lit != keyword {
270                 p.errorf("expected keyword %s, got %q", keyword, lit)
271         }
272 }
273
274 // ----------------------------------------------------------------------------
275 // Import declarations
276
277 // ImportPath = string_lit .
278 //
279 func (p *gcParser) parsePkgId() *ast.Object {
280         id, err := strconv.Unquote(p.expect(scanner.String))
281         if err != nil {
282                 p.error(err)
283         }
284
285         switch id {
286         case "":
287                 // id == "" stands for the imported package id
288                 // (only known at time of package installation)
289                 id = p.id
290         case "unsafe":
291                 // package unsafe is not in the imports map - handle explicitly
292                 return Unsafe
293         }
294
295         pkg := p.imports[id]
296         if pkg == nil {
297                 scope = ast.NewScope(nil)
298                 pkg = ast.NewObj(ast.Pkg, "")
299                 pkg.Data = scope
300                 p.imports[id] = pkg
301         }
302
303         return pkg
304 }
305
306 // dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
307 func (p *gcParser) parseDotIdent() string {
308         ident := ""
309         if p.tok != scanner.Int {
310                 sep := 'x' // not white space
311                 for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
312                         ident += p.lit
313                         sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
314                         p.next()
315                 }
316         }
317         if ident == "" {
318                 p.expect(scanner.Ident) // use expect() for error handling
319         }
320         return ident
321 }
322
323 // ExportedName = "@" ImportPath "." dotIdentifier .
324 //
325 func (p *gcParser) parseExportedName() (*ast.Object, string) {
326         p.expect('@')
327         pkg := p.parsePkgId()
328         p.expect('.')
329         name := p.parseDotIdent()
330         return pkg, name
331 }
332
333 // ----------------------------------------------------------------------------
334 // Types
335
336 // BasicType = identifier .
337 //
338 func (p *gcParser) parseBasicType() Type {
339         id := p.expect(scanner.Ident)
340         obj := Universe.Lookup(id)
341         if obj == nil || obj.Kind != ast.Typ {
342                 p.errorf("not a basic type: %s", id)
343         }
344         return obj.Type.(Type)
345 }
346
347 // ArrayType = "[" int_lit "]" Type .
348 //
349 func (p *gcParser) parseArrayType() Type {
350         // "[" already consumed and lookahead known not to be "]"
351         lit := p.expect(scanner.Int)
352         p.expect(']')
353         elt := p.parseType()
354         n, err := strconv.ParseUint(lit, 10, 64)
355         if err != nil {
356                 p.error(err)
357         }
358         return &Array{Len: n, Elt: elt}
359 }
360
361 // MapType = "map" "[" Type "]" Type .
362 //
363 func (p *gcParser) parseMapType() Type {
364         p.expectKeyword("map")
365         p.expect('[')
366         key := p.parseType()
367         p.expect(']')
368         elt := p.parseType()
369         return &Map{Key: key, Elt: elt}
370 }
371
372 // Name = identifier | "?" | ExportedName  .
373 //
374 func (p *gcParser) parseName() (name string) {
375         switch p.tok {
376         case scanner.Ident:
377                 name = p.lit
378                 p.next()
379         case '?':
380                 // anonymous
381                 p.next()
382         case '@':
383                 // exported name prefixed with package path
384                 _, name = p.parseExportedName()
385         default:
386                 p.error("name expected")
387         }
388         return
389 }
390
391 // Field = Name Type [ string_lit ] .
392 //
393 func (p *gcParser) parseField() (fld *ast.Object, tag string) {
394         name := p.parseName()
395         ftyp := p.parseType()
396         if name == "" {
397                 // anonymous field - ftyp must be T or *T and T must be a type name
398                 if _, ok := Deref(ftyp).(*Name); !ok {
399                         p.errorf("anonymous field expected")
400                 }
401         }
402         if p.tok == scanner.String {
403                 tag = p.expect(scanner.String)
404         }
405         fld = ast.NewObj(ast.Var, name)
406         fld.Type = ftyp
407         return
408 }
409
410 // StructType = "struct" "{" [ FieldList ] "}" .
411 // FieldList  = Field { ";" Field } .
412 //
413 func (p *gcParser) parseStructType() Type {
414         var fields []*ast.Object
415         var tags []string
416
417         parseField := func() {
418                 fld, tag := p.parseField()
419                 fields = append(fields, fld)
420                 tags = append(tags, tag)
421         }
422
423         p.expectKeyword("struct")
424         p.expect('{')
425         if p.tok != '}' {
426                 parseField()
427                 for p.tok == ';' {
428                         p.next()
429                         parseField()
430                 }
431         }
432         p.expect('}')
433
434         return &Struct{Fields: fields, Tags: tags}
435 }
436
437 // Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
438 //
439 func (p *gcParser) parseParameter() (par *ast.Object, isVariadic bool) {
440         name := p.parseName()
441         if name == "" {
442                 name = "_" // cannot access unnamed identifiers
443         }
444         if p.tok == '.' {
445                 p.expectSpecial("...")
446                 isVariadic = true
447         }
448         ptyp := p.parseType()
449         // ignore argument tag
450         if p.tok == scanner.String {
451                 p.expect(scanner.String)
452         }
453         par = ast.NewObj(ast.Var, name)
454         par.Type = ptyp
455         return
456 }
457
458 // Parameters    = "(" [ ParameterList ] ")" .
459 // ParameterList = { Parameter "," } Parameter .
460 //
461 func (p *gcParser) parseParameters() (list []*ast.Object, isVariadic bool) {
462         parseParameter := func() {
463                 par, variadic := p.parseParameter()
464                 list = append(list, par)
465                 if variadic {
466                         if isVariadic {
467                                 p.error("... not on final argument")
468                         }
469                         isVariadic = true
470                 }
471         }
472
473         p.expect('(')
474         if p.tok != ')' {
475                 parseParameter()
476                 for p.tok == ',' {
477                         p.next()
478                         parseParameter()
479                 }
480         }
481         p.expect(')')
482
483         return
484 }
485
486 // Signature = Parameters [ Result ] .
487 // Result    = Type | Parameters .
488 //
489 func (p *gcParser) parseSignature() *Func {
490         params, isVariadic := p.parseParameters()
491
492         // optional result type
493         var results []*ast.Object
494         switch p.tok {
495         case scanner.Ident, '[', '*', '<', '@':
496                 // single, unnamed result
497                 result := ast.NewObj(ast.Var, "_")
498                 result.Type = p.parseType()
499                 results = []*ast.Object{result}
500         case '(':
501                 // named or multiple result(s)
502                 var variadic bool
503                 results, variadic = p.parseParameters()
504                 if variadic {
505                         p.error("... not permitted on result type")
506                 }
507         }
508
509         return &Func{Params: params, Results: results, IsVariadic: isVariadic}
510 }
511
512 // MethodOrEmbedSpec = Name [ Signature ] .
513 //
514 func (p *gcParser) parseMethodOrEmbedSpec() *ast.Object {
515         p.parseName()
516         if p.tok == '(' {
517                 p.parseSignature()
518                 // TODO(gri) compute method object
519                 return ast.NewObj(ast.Fun, "_")
520         }
521         // TODO lookup name and return that type
522         return ast.NewObj(ast.Typ, "_")
523 }
524
525 // InterfaceType = "interface" "{" [ MethodOrEmbedList ] "}" .
526 // MethodOrEmbedList = MethodOrEmbedSpec { ";" MethodOrEmbedSpec } .
527 //
528 func (p *gcParser) parseInterfaceType() Type {
529         var methods ObjList
530
531         parseMethod := func() {
532                 switch m := p.parseMethodOrEmbedSpec(); m.Kind {
533                 case ast.Typ:
534                         // TODO expand embedded methods
535                 case ast.Fun:
536                         methods = append(methods, m)
537                 }
538         }
539
540         p.expectKeyword("interface")
541         p.expect('{')
542         if p.tok != '}' {
543                 parseMethod()
544                 for p.tok == ';' {
545                         p.next()
546                         parseMethod()
547                 }
548         }
549         p.expect('}')
550
551         methods.Sort()
552         return &Interface{Methods: methods}
553 }
554
555 // ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
556 //
557 func (p *gcParser) parseChanType() Type {
558         dir := ast.SEND | ast.RECV
559         if p.tok == scanner.Ident {
560                 p.expectKeyword("chan")
561                 if p.tok == '<' {
562                         p.expectSpecial("<-")
563                         dir = ast.SEND
564                 }
565         } else {
566                 p.expectSpecial("<-")
567                 p.expectKeyword("chan")
568                 dir = ast.RECV
569         }
570         elt := p.parseType()
571         return &Chan{Dir: dir, Elt: elt}
572 }
573
574 // Type =
575 //      BasicType | TypeName | ArrayType | SliceType | StructType |
576 //      PointerType | FuncType | InterfaceType | MapType | ChanType |
577 //      "(" Type ")" .
578 // BasicType = ident .
579 // TypeName = ExportedName .
580 // SliceType = "[" "]" Type .
581 // PointerType = "*" Type .
582 // FuncType = "func" Signature .
583 //
584 func (p *gcParser) parseType() Type {
585         switch p.tok {
586         case scanner.Ident:
587                 switch p.lit {
588                 default:
589                         return p.parseBasicType()
590                 case "struct":
591                         return p.parseStructType()
592                 case "func":
593                         // FuncType
594                         p.next()
595                         return p.parseSignature()
596                 case "interface":
597                         return p.parseInterfaceType()
598                 case "map":
599                         return p.parseMapType()
600                 case "chan":
601                         return p.parseChanType()
602                 }
603         case '@':
604                 // TypeName
605                 pkg, name := p.parseExportedName()
606                 return p.declare(pkg.Data.(*ast.Scope), ast.Typ, name).Type.(Type)
607         case '[':
608                 p.next() // look ahead
609                 if p.tok == ']' {
610                         // SliceType
611                         p.next()
612                         return &Slice{Elt: p.parseType()}
613                 }
614                 return p.parseArrayType()
615         case '*':
616                 // PointerType
617                 p.next()
618                 return &Pointer{Base: p.parseType()}
619         case '<':
620                 return p.parseChanType()
621         case '(':
622                 // "(" Type ")"
623                 p.next()
624                 typ := p.parseType()
625                 p.expect(')')
626                 return typ
627         }
628         p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
629         return nil
630 }
631
632 // ----------------------------------------------------------------------------
633 // Declarations
634
635 // ImportDecl = "import" identifier string_lit .
636 //
637 func (p *gcParser) parseImportDecl() {
638         p.expectKeyword("import")
639         // The identifier has no semantic meaning in the import data.
640         // It exists so that error messages can print the real package
641         // name: binary.ByteOrder instead of "encoding/binary".ByteOrder.
642         name := p.expect(scanner.Ident)
643         pkg := p.parsePkgId()
644         assert(pkg.Name == "" || pkg.Name == name)
645         pkg.Name = name
646 }
647
648 // int_lit = [ "+" | "-" ] { "0" ... "9" } .
649 //
650 func (p *gcParser) parseInt() (sign, val string) {
651         switch p.tok {
652         case '-':
653                 p.next()
654                 sign = "-"
655         case '+':
656                 p.next()
657         }
658         val = p.expect(scanner.Int)
659         return
660 }
661
662 // number = int_lit [ "p" int_lit ] .
663 //
664 func (p *gcParser) parseNumber() Const {
665         // mantissa
666         sign, val := p.parseInt()
667         mant, ok := new(big.Int).SetString(sign+val, 10)
668         assert(ok)
669
670         if p.lit == "p" {
671                 // exponent (base 2)
672                 p.next()
673                 sign, val = p.parseInt()
674                 exp64, err := strconv.ParseUint(val, 10, 0)
675                 if err != nil {
676                         p.error(err)
677                 }
678                 exp := uint(exp64)
679                 if sign == "-" {
680                         denom := big.NewInt(1)
681                         denom.Lsh(denom, exp)
682                         return Const{new(big.Rat).SetFrac(mant, denom)}
683                 }
684                 if exp > 0 {
685                         mant.Lsh(mant, exp)
686                 }
687                 return Const{new(big.Rat).SetInt(mant)}
688         }
689
690         return Const{mant}
691 }
692
693 // ConstDecl   = "const" ExportedName [ Type ] "=" Literal .
694 // Literal     = bool_lit | int_lit | float_lit | complex_lit | string_lit .
695 // bool_lit    = "true" | "false" .
696 // complex_lit = "(" float_lit "+" float_lit ")" .
697 // rune_lit = "(" int_lit "+" int_lit ")" .
698 // string_lit  = `"` { unicode_char } `"` .
699 //
700 func (p *gcParser) parseConstDecl() {
701         p.expectKeyword("const")
702         pkg, name := p.parseExportedName()
703         obj := p.declare(pkg.Data.(*ast.Scope), ast.Con, name)
704         var x Const
705         var typ Type
706         if p.tok != '=' {
707                 obj.Type = p.parseType()
708         }
709         p.expect('=')
710         switch p.tok {
711         case scanner.Ident:
712                 // bool_lit
713                 if p.lit != "true" && p.lit != "false" {
714                         p.error("expected true or false")
715                 }
716                 x = Const{p.lit == "true"}
717                 typ = Bool.Underlying
718                 p.next()
719         case '-', scanner.Int:
720                 // int_lit
721                 x = p.parseNumber()
722                 typ = Int.Underlying
723                 if _, ok := x.val.(*big.Rat); ok {
724                         typ = Float64.Underlying
725                 }
726         case '(':
727                 // complex_lit or rune_lit
728                 p.next()
729                 if p.tok == scanner.Char {
730                         p.next()
731                         p.expect('+')
732                         p.parseNumber()
733                         p.expect(')')
734                         // TODO: x = ...
735                         break
736                 }
737                 re := p.parseNumber()
738                 p.expect('+')
739                 im := p.parseNumber()
740                 p.expect(')')
741                 x = Const{cmplx{re.val.(*big.Rat), im.val.(*big.Rat)}}
742                 typ = Complex128.Underlying
743         case scanner.Char:
744                 // TODO: x = ...
745                 p.next()
746         case scanner.String:
747                 // string_lit
748                 x = MakeConst(token.STRING, p.lit)
749                 p.next()
750                 typ = String.Underlying
751         default:
752                 p.errorf("expected literal got %s", scanner.TokenString(p.tok))
753         }
754         if obj.Type == nil {
755                 obj.Type = typ
756         }
757         obj.Data = x
758 }
759
760 // TypeDecl = "type" ExportedName Type .
761 //
762 func (p *gcParser) parseTypeDecl() {
763         p.expectKeyword("type")
764         pkg, name := p.parseExportedName()
765         obj := p.declare(pkg.Data.(*ast.Scope), ast.Typ, name)
766
767         // The type object may have been imported before and thus already
768         // have a type associated with it. We still need to parse the type
769         // structure, but throw it away if the object already has a type.
770         // This ensures that all imports refer to the same type object for
771         // a given type declaration.
772         typ := p.parseType()
773
774         if name := obj.Type.(*Name); name.Underlying == nil {
775                 assert(Underlying(typ) == typ)
776                 name.Underlying = typ
777         }
778 }
779
780 // VarDecl = "var" ExportedName Type .
781 //
782 func (p *gcParser) parseVarDecl() {
783         p.expectKeyword("var")
784         pkg, name := p.parseExportedName()
785         obj := p.declare(pkg.Data.(*ast.Scope), ast.Var, name)
786         obj.Type = p.parseType()
787 }
788
789 // FuncBody = "{" ... "}" .
790 //
791 func (p *gcParser) parseFuncBody() {
792         p.expect('{')
793         for i := 1; i > 0; p.next() {
794                 switch p.tok {
795                 case '{':
796                         i++
797                 case '}':
798                         i--
799                 }
800         }
801 }
802
803 // FuncDecl = "func" ExportedName Signature [ FuncBody ] .
804 //
805 func (p *gcParser) parseFuncDecl() {
806         // "func" already consumed
807         pkg, name := p.parseExportedName()
808         obj := p.declare(pkg.Data.(*ast.Scope), ast.Fun, name)
809         obj.Type = p.parseSignature()
810         if p.tok == '{' {
811                 p.parseFuncBody()
812         }
813 }
814
815 // MethodDecl = "func" Receiver Name Signature .
816 // Receiver   = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" [ FuncBody ].
817 //
818 func (p *gcParser) parseMethodDecl() {
819         // "func" already consumed
820         p.expect('(')
821         p.parseParameter() // receiver
822         p.expect(')')
823         p.parseName() // unexported method names in imports are qualified with their package.
824         p.parseSignature()
825         if p.tok == '{' {
826                 p.parseFuncBody()
827         }
828 }
829
830 // Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
831 //
832 func (p *gcParser) parseDecl() {
833         switch p.lit {
834         case "import":
835                 p.parseImportDecl()
836         case "const":
837                 p.parseConstDecl()
838         case "type":
839                 p.parseTypeDecl()
840         case "var":
841                 p.parseVarDecl()
842         case "func":
843                 p.next() // look ahead
844                 if p.tok == '(' {
845                         p.parseMethodDecl()
846                 } else {
847                         p.parseFuncDecl()
848                 }
849         }
850         p.expect('\n')
851 }
852
853 // ----------------------------------------------------------------------------
854 // Export
855
856 // Export        = "PackageClause { Decl } "$$" .
857 // PackageClause = "package" identifier [ "safe" ] "\n" .
858 //
859 func (p *gcParser) parseExport() *ast.Object {
860         p.expectKeyword("package")
861         name := p.expect(scanner.Ident)
862         if p.tok != '\n' {
863                 // A package is safe if it was compiled with the -u flag,
864                 // which disables the unsafe package.
865                 // TODO(gri) remember "safe" package
866                 p.expectKeyword("safe")
867         }
868         p.expect('\n')
869
870         assert(p.imports[p.id] == nil)
871         pkg := ast.NewObj(ast.Pkg, name)
872         pkg.Data = ast.NewScope(nil)
873         p.imports[p.id] = pkg
874
875         for p.tok != '$' && p.tok != scanner.EOF {
876                 p.parseDecl()
877         }
878
879         if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
880                 // don't call next()/expect() since reading past the
881                 // export data may cause scanner errors (e.g. NUL chars)
882                 p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
883         }
884
885         if n := p.scanner.ErrorCount; n != 0 {
886                 p.errorf("expected no scanner errors, got %d", n)
887         }
888
889         return pkg
890 }