OSDN Git Service

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