GoPLS Viewer

Home|gopls/internal/gcimporter/bexport.go
1// Copyright 2016 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// Binary package export.
6// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go;
7// see that file for specification of the format.
8
9package gcimporter
10
11import (
12    "bytes"
13    "encoding/binary"
14    "fmt"
15    "go/constant"
16    "go/token"
17    "go/types"
18    "math"
19    "math/big"
20    "sort"
21    "strings"
22)
23
24// If debugFormat is set, each integer and string value is preceded by a marker
25// and position information in the encoding. This mechanism permits an importer
26// to recognize immediately when it is out of sync. The importer recognizes this
27// mode automatically (i.e., it can import export data produced with debugging
28// support even if debugFormat is not set at the time of import). This mode will
29// lead to massively larger export data (by a factor of 2 to 3) and should only
30// be enabled during development and debugging.
31//
32// NOTE: This flag is the first flag to enable if importing dies because of
33// (suspected) format errors, and whenever a change is made to the format.
34const debugFormat = false // default: false
35
36// Current export format version. Increase with each format change.
37//
38// Note: The latest binary (non-indexed) export format is at version 6.
39// This exporter is still at level 4, but it doesn't matter since
40// the binary importer can handle older versions just fine.
41//
42//    6: package height (CL 105038) -- NOT IMPLEMENTED HERE
43//    5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMENTED HERE
44//    4: type name objects support type aliases, uses aliasTag
45//    3: Go1.8 encoding (same as version 2, aliasTag defined but never used)
46//    2: removed unused bool in ODCL export (compiler only)
47//    1: header format change (more regular), export package for _ struct fields
48//    0: Go1.7 encoding
49const exportVersion = 4
50
51// trackAllTypes enables cycle tracking for all types, not just named
52// types. The existing compiler invariants assume that unnamed types
53// that are not completely set up are not used, or else there are spurious
54// errors.
55// If disabled, only named types are tracked, possibly leading to slightly
56// less efficient encoding in rare cases. It also prevents the export of
57// some corner-case type declarations (but those are not handled correctly
58// with with the textual export format either).
59// TODO(gri) enable and remove once issues caused by it are fixed
60const trackAllTypes = false
61
62type exporter struct {
63    fset *token.FileSet
64    out  bytes.Buffer
65
66    // object -> index maps, indexed in order of serialization
67    strIndex map[string]int
68    pkgIndex map[*types.Package]int
69    typIndex map[types.Type]int
70
71    // position encoding
72    posInfoFormat bool
73    prevFile      string
74    prevLine      int
75
76    // debugging support
77    written int // bytes written
78    indent  int // for trace
79}
80
81// internalError represents an error generated inside this package.
82type internalError string
83
84func (e internalErrorError() string { return "gcimporter: " + string(e) }
85
86func internalErrorf(format stringargs ...interface{}) error {
87    return internalError(fmt.Sprintf(formatargs...))
88}
89
90// BExportData returns binary export data for pkg.
91// If no file set is provided, position info will be missing.
92func BExportData(fset *token.FileSetpkg *types.Package) (b []byteerr error) {
93    if !debug {
94        defer func() {
95            if e := recover(); e != nil {
96                if ierrok := e.(internalError); ok {
97                    err = ierr
98                    return
99                }
100                // Not an internal error; panic again.
101                panic(e)
102            }
103        }()
104    }
105
106    p := exporter{
107        fset:          fset,
108        strIndex:      map[string]int{""0}, // empty string is mapped to 0
109        pkgIndex:      make(map[*types.Package]int),
110        typIndex:      make(map[types.Type]int),
111        posInfoFormattrue// TODO(gri) might become a flag, eventually
112    }
113
114    // write version info
115    // The version string must start with "version %d" where %d is the version
116    // number. Additional debugging information may follow after a blank; that
117    // text is ignored by the importer.
118    p.rawStringln(fmt.Sprintf("version %d"exportVersion))
119    var debug string
120    if debugFormat {
121        debug = "debug"
122    }
123    p.rawStringln(debug// cannot use p.bool since it's affected by debugFormat; also want to see this clearly
124    p.bool(trackAllTypes)
125    p.bool(p.posInfoFormat)
126
127    // --- generic export data ---
128
129    // populate type map with predeclared "known" types
130    for indextyp := range predeclared() {
131        p.typIndex[typ] = index
132    }
133    if len(p.typIndex) != len(predeclared()) {
134        return nilinternalError("duplicate entries in type map?")
135    }
136
137    // write package data
138    p.pkg(pkgtrue)
139    if trace {
140        p.tracef("\n")
141    }
142
143    // write objects
144    objcount := 0
145    scope := pkg.Scope()
146    for _name := range scope.Names() {
147        if !token.IsExported(name) {
148            continue
149        }
150        if trace {
151            p.tracef("\n")
152        }
153        p.obj(scope.Lookup(name))
154        objcount++
155    }
156
157    // indicate end of list
158    if trace {
159        p.tracef("\n")
160    }
161    p.tag(endTag)
162
163    // for self-verification only (redundant)
164    p.int(objcount)
165
166    if trace {
167        p.tracef("\n")
168    }
169
170    // --- end of export data ---
171
172    return p.out.Bytes(), nil
173}
174
175func (p *exporterpkg(pkg *types.Packageemptypath bool) {
176    if pkg == nil {
177        panic(internalError("unexpected nil pkg"))
178    }
179
180    // if we saw the package before, write its index (>= 0)
181    if iok := p.pkgIndex[pkg]; ok {
182        p.index('P'i)
183        return
184    }
185
186    // otherwise, remember the package, write the package tag (< 0) and package data
187    if trace {
188        p.tracef("P%d = { "len(p.pkgIndex))
189        defer p.tracef("} ")
190    }
191    p.pkgIndex[pkg] = len(p.pkgIndex)
192
193    p.tag(packageTag)
194    p.string(pkg.Name())
195    if emptypath {
196        p.string("")
197    } else {
198        p.string(pkg.Path())
199    }
200}
201
202func (p *exporterobj(obj types.Object) {
203    switch obj := obj.(type) {
204    case *types.Const:
205        p.tag(constTag)
206        p.pos(obj)
207        p.qualifiedName(obj)
208        p.typ(obj.Type())
209        p.value(obj.Val())
210
211    case *types.TypeName:
212        if obj.IsAlias() {
213            p.tag(aliasTag)
214            p.pos(obj)
215            p.qualifiedName(obj)
216        } else {
217            p.tag(typeTag)
218        }
219        p.typ(obj.Type())
220
221    case *types.Var:
222        p.tag(varTag)
223        p.pos(obj)
224        p.qualifiedName(obj)
225        p.typ(obj.Type())
226
227    case *types.Func:
228        p.tag(funcTag)
229        p.pos(obj)
230        p.qualifiedName(obj)
231        sig := obj.Type().(*types.Signature)
232        p.paramList(sig.Params(), sig.Variadic())
233        p.paramList(sig.Results(), false)
234
235    default:
236        panic(internalErrorf("unexpected object %v (%T)"objobj))
237    }
238}
239
240func (p *exporterpos(obj types.Object) {
241    if !p.posInfoFormat {
242        return
243    }
244
245    fileline := p.fileLine(obj)
246    if file == p.prevFile {
247        // common case: write line delta
248        // delta == 0 means different file or no line change
249        delta := line - p.prevLine
250        p.int(delta)
251        if delta == 0 {
252            p.int(-1// -1 means no file change
253        }
254    } else {
255        // different file
256        p.int(0)
257        // Encode filename as length of common prefix with previous
258        // filename, followed by (possibly empty) suffix. Filenames
259        // frequently share path prefixes, so this can save a lot
260        // of space and make export data size less dependent on file
261        // path length. The suffix is unlikely to be empty because
262        // file names tend to end in ".go".
263        n := commonPrefixLen(p.prevFilefile)
264        p.int(n)           // n >= 0
265        p.string(file[n:]) // write suffix only
266        p.prevFile = file
267        p.int(line)
268    }
269    p.prevLine = line
270}
271
272func (p *exporterfileLine(obj types.Object) (file stringline int) {
273    if p.fset != nil {
274        pos := p.fset.Position(obj.Pos())
275        file = pos.Filename
276        line = pos.Line
277    }
278    return
279}
280
281func commonPrefixLen(ab stringint {
282    if len(a) > len(b) {
283        ab = ba
284    }
285    // len(a) <= len(b)
286    i := 0
287    for i < len(a) && a[i] == b[i] {
288        i++
289    }
290    return i
291}
292
293func (p *exporterqualifiedName(obj types.Object) {
294    p.string(obj.Name())
295    p.pkg(obj.Pkg(), false)
296}
297
298func (p *exportertyp(t types.Type) {
299    if t == nil {
300        panic(internalError("nil type"))
301    }
302
303    // Possible optimization: Anonymous pointer types *T where
304    // T is a named type are common. We could canonicalize all
305    // such types *T to a single type PT = *T. This would lead
306    // to at most one *T entry in typIndex, and all future *T's
307    // would be encoded as the respective index directly. Would
308    // save 1 byte (pointerTag) per *T and reduce the typIndex
309    // size (at the cost of a canonicalization map). We can do
310    // this later, without encoding format change.
311
312    // if we saw the type before, write its index (>= 0)
313    if iok := p.typIndex[t]; ok {
314        p.index('T'i)
315        return
316    }
317
318    // otherwise, remember the type, write the type tag (< 0) and type data
319    if trackAllTypes {
320        if trace {
321            p.tracef("T%d = {>\n"len(p.typIndex))
322            defer p.tracef("<\n} ")
323        }
324        p.typIndex[t] = len(p.typIndex)
325    }
326
327    switch t := t.(type) {
328    case *types.Named:
329        if !trackAllTypes {
330            // if we don't track all types, track named types now
331            p.typIndex[t] = len(p.typIndex)
332        }
333
334        p.tag(namedTag)
335        p.pos(t.Obj())
336        p.qualifiedName(t.Obj())
337        p.typ(t.Underlying())
338        if !types.IsInterface(t) {
339            p.assocMethods(t)
340        }
341
342    case *types.Array:
343        p.tag(arrayTag)
344        p.int64(t.Len())
345        p.typ(t.Elem())
346
347    case *types.Slice:
348        p.tag(sliceTag)
349        p.typ(t.Elem())
350
351    case *dddSlice:
352        p.tag(dddTag)
353        p.typ(t.elem)
354
355    case *types.Struct:
356        p.tag(structTag)
357        p.fieldList(t)
358
359    case *types.Pointer:
360        p.tag(pointerTag)
361        p.typ(t.Elem())
362
363    case *types.Signature:
364        p.tag(signatureTag)
365        p.paramList(t.Params(), t.Variadic())
366        p.paramList(t.Results(), false)
367
368    case *types.Interface:
369        p.tag(interfaceTag)
370        p.iface(t)
371
372    case *types.Map:
373        p.tag(mapTag)
374        p.typ(t.Key())
375        p.typ(t.Elem())
376
377    case *types.Chan:
378        p.tag(chanTag)
379        p.int(int(3 - t.Dir())) // hack
380        p.typ(t.Elem())
381
382    default:
383        panic(internalErrorf("unexpected type %T: %s"tt))
384    }
385}
386
387func (p *exporterassocMethods(named *types.Named) {
388    // Sort methods (for determinism).
389    var methods []*types.Func
390    for i := 0i < named.NumMethods(); i++ {
391        methods = append(methodsnamed.Method(i))
392    }
393    sort.Sort(methodsByName(methods))
394
395    p.int(len(methods))
396
397    if trace && methods != nil {
398        p.tracef("associated methods {>\n")
399    }
400
401    for im := range methods {
402        if trace && i > 0 {
403            p.tracef("\n")
404        }
405
406        p.pos(m)
407        name := m.Name()
408        p.string(name)
409        if !exported(name) {
410            p.pkg(m.Pkg(), false)
411        }
412
413        sig := m.Type().(*types.Signature)
414        p.paramList(types.NewTuple(sig.Recv()), false)
415        p.paramList(sig.Params(), sig.Variadic())
416        p.paramList(sig.Results(), false)
417        p.int(0// dummy value for go:nointerface pragma - ignored by importer
418    }
419
420    if trace && methods != nil {
421        p.tracef("<\n} ")
422    }
423}
424
425type methodsByName []*types.Func
426
427func (x methodsByNameLen() int           { return len(x) }
428func (x methodsByNameSwap(ij int)      { x[i], x[j] = x[j], x[i] }
429func (x methodsByNameLess(ij intbool { return x[i].Name() < x[j].Name() }
430
431func (p *exporterfieldList(t *types.Struct) {
432    if trace && t.NumFields() > 0 {
433        p.tracef("fields {>\n")
434        defer p.tracef("<\n} ")
435    }
436
437    p.int(t.NumFields())
438    for i := 0i < t.NumFields(); i++ {
439        if trace && i > 0 {
440            p.tracef("\n")
441        }
442        p.field(t.Field(i))
443        p.string(t.Tag(i))
444    }
445}
446
447func (p *exporterfield(f *types.Var) {
448    if !f.IsField() {
449        panic(internalError("field expected"))
450    }
451
452    p.pos(f)
453    p.fieldName(f)
454    p.typ(f.Type())
455}
456
457func (p *exporteriface(t *types.Interface) {
458    // TODO(gri): enable importer to load embedded interfaces,
459    // then emit Embeddeds and ExplicitMethods separately here.
460    p.int(0)
461
462    n := t.NumMethods()
463    if trace && n > 0 {
464        p.tracef("methods {>\n")
465        defer p.tracef("<\n} ")
466    }
467    p.int(n)
468    for i := 0i < ni++ {
469        if trace && i > 0 {
470            p.tracef("\n")
471        }
472        p.method(t.Method(i))
473    }
474}
475
476func (p *exportermethod(m *types.Func) {
477    sig := m.Type().(*types.Signature)
478    if sig.Recv() == nil {
479        panic(internalError("method expected"))
480    }
481
482    p.pos(m)
483    p.string(m.Name())
484    if m.Name() != "_" && !token.IsExported(m.Name()) {
485        p.pkg(m.Pkg(), false)
486    }
487
488    // interface method; no need to encode receiver.
489    p.paramList(sig.Params(), sig.Variadic())
490    p.paramList(sig.Results(), false)
491}
492
493func (p *exporterfieldName(f *types.Var) {
494    name := f.Name()
495
496    if f.Anonymous() {
497        // anonymous field - we distinguish between 3 cases:
498        // 1) field name matches base type name and is exported
499        // 2) field name matches base type name and is not exported
500        // 3) field name doesn't match base type name (alias name)
501        bname := basetypeName(f.Type())
502        if name == bname {
503            if token.IsExported(name) {
504                name = "" // 1) we don't need to know the field name or package
505            } else {
506                name = "?" // 2) use unexported name "?" to force package export
507            }
508        } else {
509            // 3) indicate alias and export name as is
510            // (this requires an extra "@" but this is a rare case)
511            p.string("@")
512        }
513    }
514
515    p.string(name)
516    if name != "" && !token.IsExported(name) {
517        p.pkg(f.Pkg(), false)
518    }
519}
520
521func basetypeName(typ types.Typestring {
522    switch typ := deref(typ).(type) {
523    case *types.Basic:
524        return typ.Name()
525    case *types.Named:
526        return typ.Obj().Name()
527    default:
528        return "" // unnamed type
529    }
530}
531
532func (p *exporterparamList(params *types.Tuplevariadic bool) {
533    // use negative length to indicate unnamed parameters
534    // (look at the first parameter only since either all
535    // names are present or all are absent)
536    n := params.Len()
537    if n > 0 && params.At(0).Name() == "" {
538        n = -n
539    }
540    p.int(n)
541    for i := 0i < params.Len(); i++ {
542        q := params.At(i)
543        t := q.Type()
544        if variadic && i == params.Len()-1 {
545            t = &dddSlice{t.(*types.Slice).Elem()}
546        }
547        p.typ(t)
548        if n > 0 {
549            name := q.Name()
550            p.string(name)
551            if name != "_" {
552                p.pkg(q.Pkg(), false)
553            }
554        }
555        p.string(""// no compiler-specific info
556    }
557}
558
559func (p *exportervalue(x constant.Value) {
560    if trace {
561        p.tracef("= ")
562    }
563
564    switch x.Kind() {
565    case constant.Bool:
566        tag := falseTag
567        if constant.BoolVal(x) {
568            tag = trueTag
569        }
570        p.tag(tag)
571
572    case constant.Int:
573        if vexact := constant.Int64Val(x); exact {
574            // common case: x fits into an int64 - use compact encoding
575            p.tag(int64Tag)
576            p.int64(v)
577            return
578        }
579        // uncommon case: large x - use float encoding
580        // (powers of 2 will be encoded efficiently with exponent)
581        p.tag(floatTag)
582        p.float(constant.ToFloat(x))
583
584    case constant.Float:
585        p.tag(floatTag)
586        p.float(x)
587
588    case constant.Complex:
589        p.tag(complexTag)
590        p.float(constant.Real(x))
591        p.float(constant.Imag(x))
592
593    case constant.String:
594        p.tag(stringTag)
595        p.string(constant.StringVal(x))
596
597    case constant.Unknown:
598        // package contains type errors
599        p.tag(unknownTag)
600
601    default:
602        panic(internalErrorf("unexpected value %v (%T)"xx))
603    }
604}
605
606func (p *exporterfloat(x constant.Value) {
607    if x.Kind() != constant.Float {
608        panic(internalErrorf("unexpected constant %v, want float"x))
609    }
610    // extract sign (there is no -0)
611    sign := constant.Sign(x)
612    if sign == 0 {
613        // x == 0
614        p.int(0)
615        return
616    }
617    // x != 0
618
619    var f big.Float
620    if vexact := constant.Float64Val(x); exact {
621        // float64
622        f.SetFloat64(v)
623    } else if numdenom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
624        // TODO(gri): add big.Rat accessor to constant.Value.
625        r := valueToRat(num)
626        f.SetRat(r.Quo(rvalueToRat(denom)))
627    } else {
628        // Value too large to represent as a fraction => inaccessible.
629        // TODO(gri): add big.Float accessor to constant.Value.
630        f.SetFloat64(math.MaxFloat64// FIXME
631    }
632
633    // extract exponent such that 0.5 <= m < 1.0
634    var m big.Float
635    exp := f.MantExp(&m)
636
637    // extract mantissa as *big.Int
638    // - set exponent large enough so mant satisfies mant.IsInt()
639    // - get *big.Int from mant
640    m.SetMantExp(&mint(m.MinPrec()))
641    mantacc := m.Int(nil)
642    if acc != big.Exact {
643        panic(internalError("internal error"))
644    }
645
646    p.int(sign)
647    p.int(exp)
648    p.string(string(mant.Bytes()))
649}
650
651func valueToRat(x constant.Value) *big.Rat {
652    // Convert little-endian to big-endian.
653    // I can't believe this is necessary.
654    bytes := constant.Bytes(x)
655    for i := 0i < len(bytes)/2i++ {
656        bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
657    }
658    return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
659}
660
661func (p *exporterbool(b boolbool {
662    if trace {
663        p.tracef("[")
664        defer p.tracef("= %v] "b)
665    }
666
667    x := 0
668    if b {
669        x = 1
670    }
671    p.int(x)
672    return b
673}
674
675// ----------------------------------------------------------------------------
676// Low-level encoders
677
678func (p *exporterindex(marker byteindex int) {
679    if index < 0 {
680        panic(internalError("invalid index < 0"))
681    }
682    if debugFormat {
683        p.marker('t')
684    }
685    if trace {
686        p.tracef("%c%d "markerindex)
687    }
688    p.rawInt64(int64(index))
689}
690
691func (p *exportertag(tag int) {
692    if tag >= 0 {
693        panic(internalError("invalid tag >= 0"))
694    }
695    if debugFormat {
696        p.marker('t')
697    }
698    if trace {
699        p.tracef("%s "tagString[-tag])
700    }
701    p.rawInt64(int64(tag))
702}
703
704func (p *exporterint(x int) {
705    p.int64(int64(x))
706}
707
708func (p *exporterint64(x int64) {
709    if debugFormat {
710        p.marker('i')
711    }
712    if trace {
713        p.tracef("%d "x)
714    }
715    p.rawInt64(x)
716}
717
718func (p *exporterstring(s string) {
719    if debugFormat {
720        p.marker('s')
721    }
722    if trace {
723        p.tracef("%q "s)
724    }
725    // if we saw the string before, write its index (>= 0)
726    // (the empty string is mapped to 0)
727    if iok := p.strIndex[s]; ok {
728        p.rawInt64(int64(i))
729        return
730    }
731    // otherwise, remember string and write its negative length and bytes
732    p.strIndex[s] = len(p.strIndex)
733    p.rawInt64(-int64(len(s)))
734    for i := 0i < len(s); i++ {
735        p.rawByte(s[i])
736    }
737}
738
739// marker emits a marker byte and position information which makes
740// it easy for a reader to detect if it is "out of sync". Used for
741// debugFormat format only.
742func (p *exportermarker(m byte) {
743    p.rawByte(m)
744    // Enable this for help tracking down the location
745    // of an incorrect marker when running in debugFormat.
746    if false && trace {
747        p.tracef("#%d "p.written)
748    }
749    p.rawInt64(int64(p.written))
750}
751
752// rawInt64 should only be used by low-level encoders.
753func (p *exporterrawInt64(x int64) {
754    var tmp [binary.MaxVarintLen64]byte
755    n := binary.PutVarint(tmp[:], x)
756    for i := 0i < ni++ {
757        p.rawByte(tmp[i])
758    }
759}
760
761// rawStringln should only be used to emit the initial version string.
762func (p *exporterrawStringln(s string) {
763    for i := 0i < len(s); i++ {
764        p.rawByte(s[i])
765    }
766    p.rawByte('\n')
767}
768
769// rawByte is the bottleneck interface to write to p.out.
770// rawByte escapes b as follows (any encoding does that
771// hides '$'):
772//
773//    '$'  => '|' 'S'
774//    '|'  => '|' '|'
775//
776// Necessary so other tools can find the end of the
777// export data by searching for "$$".
778// rawByte should only be used by low-level encoders.
779func (p *exporterrawByte(b byte) {
780    switch b {
781    case '$':
782        // write '$' as '|' 'S'
783        b = 'S'
784        fallthrough
785    case '|':
786        // write '|' as '|' '|'
787        p.out.WriteByte('|')
788        p.written++
789    }
790    p.out.WriteByte(b)
791    p.written++
792}
793
794// tracef is like fmt.Printf but it rewrites the format string
795// to take care of indentation.
796func (p *exportertracef(format stringargs ...interface{}) {
797    if strings.ContainsAny(format"<>\n") {
798        var buf bytes.Buffer
799        for i := 0i < len(format); i++ {
800            // no need to deal with runes
801            ch := format[i]
802            switch ch {
803            case '>':
804                p.indent++
805                continue
806            case '<':
807                p.indent--
808                continue
809            }
810            buf.WriteByte(ch)
811            if ch == '\n' {
812                for j := p.indentj > 0j-- {
813                    buf.WriteString(".  ")
814                }
815            }
816        }
817        format = buf.String()
818    }
819    fmt.Printf(formatargs...)
820}
821
822// Debugging support.
823// (tagString is only used when tracing is enabled)
824var tagString = [...]string{
825    // Packages
826    -packageTag"package",
827
828    // Types
829    -namedTag:     "named type",
830    -arrayTag:     "array",
831    -sliceTag:     "slice",
832    -dddTag:       "ddd",
833    -structTag:    "struct",
834    -pointerTag:   "pointer",
835    -signatureTag"signature",
836    -interfaceTag"interface",
837    -mapTag:       "map",
838    -chanTag:      "chan",
839
840    // Values
841    -falseTag:    "false",
842    -trueTag:     "true",
843    -int64Tag:    "int64",
844    -floatTag:    "float",
845    -fractionTag"fraction",
846    -complexTag:  "complex",
847    -stringTag:   "string",
848    -unknownTag:  "unknown",
849
850    // Type aliases
851    -aliasTag"alias",
852}
853
MembersX
BExportData.p
methodsByName.Less.x
exporter.index.index
exporter.paramList.i
exporter.index.p
exporter.rawStringln
strings
exportVersion
exporter.posInfoFormat
exporter.fieldList.t
exporter.paramList.p
exporter.strIndex
exporter.pos.file
exporter.tracef.args
exporter.field.f
exporter.float.v
exporter.float.mant
exporter.tag.tag
exporter.rawByte
debugFormat
exporter.assocMethods.methods
exporter.fieldList
exporter.float.p
valueToRat
BExportData.BlockStmt.BlockStmt.e
exporter.obj.obj
commonPrefixLen.b
exporter.int64.p
exporter.rawStringln.i
exporter.qualifiedName.obj
methodsByName.Swap.x
methodsByName.Less
exporter.fieldName.BlockStmt.bname
exporter.marker.m
valueToRat.i
exporter.rawByte.b
exporter.written
exporter.pos
exporter.assocMethods.named
exporter.fieldName
exporter.paramList.BlockStmt.BlockStmt.name
commonPrefixLen.a
exporter.method.m
valueToRat.x
exporter.bool.b
basetypeName
exporter.rawInt64.x
exporter.fileLine
exporter.fileLine.line
exporter.qualifiedName.p
exporter.qualifiedName
methodsByName.Len
exporter.out
exporter.pkg.emptypath
exporter.paramList.BlockStmt.t
exporter.rawInt64.i
trackAllTypes
BExportData.RangeStmt_4433.typ
exporter.assocMethods.i
exporter.index
exporter.int64.x
exporter.rawInt64
internalErrorf
BExportData.err
exporter.obj
exporter.iface
exporter.method.p
exporter.string.s
exporter.marker
exporter.rawInt64.p
types
exporter.typIndex
exporter.indent
BExportData.pkg
exporter.paramList.variadic
exporter.paramList.n
exporter.tag.p
exporter.rawByte.p
exporter.fileLine.BlockStmt.pos
exporter.typ
exporter.assocMethods.RangeStmt_9993.i
exporter.fieldList.p
exporter.field.p
exporter.iface.n
exporter.float.x
exporter.tracef.format
BExportData
exporter.pkg.pkg
exporter.pos.line
exporter.fileLine.obj
exporter.assocMethods
exporter.tracef.p
exporter
exporter.fset
BExportData.debug
exporter.obj.p
exporter.bool.x
exporter.int.x
big
internalError
BExportData.objcount
exporter.pos.obj
exporter.float.num
exporter.pkg.p
commonPrefixLen
methodsByName.Swap.i
sort
internalError.Error
internalErrorf.args
BExportData.fset
BExportData.RangeStmt_4742.name
exporter.iface.i
exporter.float.denom
exporter.float.acc
valueToRat.bytes
exporter.string.p
exporter.method
exporter.paramList.BlockStmt.q
exporter.value.x
constant
exporter.prevLine
BExportData.scope
methodsByName
methodsByName.Len.x
exporter.float.BlockStmt.r
exporter.tag
exporter.marker.p
exporter.tracef
exporter.string.i
token
exporter.typ.p
exporter.value.BlockStmt.tag
exporter.float.sign
exporter.int
exporter.paramList.params
exporter.float.f
exporter.float.exact
BExportData.RangeStmt_4433.index
exporter.typ.t
exporter.fieldList.i
exporter.iface.p
exporter.fieldName.p
exporter.bool
exporter.index.marker
basetypeName.typ
exporter.value
binary
fmt
exporter.pkg
exporter.assocMethods.p
methodsByName.Less.i
exporter.assocMethods.RangeStmt_9993.BlockStmt.name
exporter.iface.t
exporter.fieldName.name
exporter.float
exporter.rawStringln.p
internalErrorf.format
exporter.pos.BlockStmt.n
exporter.tracef.BlockStmt.i
exporter.tracef.BlockStmt.BlockStmt.BlockStmt.j
methodsByName.Swap.j
exporter.int.p
exporter.value.p
exporter.int64
internalError.Error.e
exporter.pos.p
exporter.float.m
exporter.rawInt64.n
commonPrefixLen.i
exporter.assocMethods.RangeStmt_9993.m
exporter.value.BlockStmt.exact
exporter.bool.p
exporter.rawInt64.tmp
exporter.string
exporter.tracef.BlockStmt.buf
exporter.prevFile
methodsByName.Swap
methodsByName.Less.j
exporter.field
exporter.float.exp
math
BExportData.b
exporter.fileLine.p
exporter.rawStringln.s
exporter.value.BlockStmt.v
bytes
exporter.pkgIndex
exporter.fileLine.file
exporter.fieldName.f
exporter.paramList
Members
X