aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/bimport.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/bimport.go')
-rw-r--r--src/cmd/compile/internal/gc/bimport.go77
1 files changed, 47 insertions, 30 deletions
diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go
index 94c1184138..752f65be42 100644
--- a/src/cmd/compile/internal/gc/bimport.go
+++ b/src/cmd/compile/internal/gc/bimport.go
@@ -86,10 +86,10 @@ func Import(in *bufio.Reader) {
// read version specific flags - extend as necessary
switch p.version {
- // case 4:
+ // case 5:
// ...
// fallthrough
- case 3, 2, 1:
+ case 4, 3, 2, 1:
p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
p.trackAllTypes = p.bool()
p.posInfoFormat = p.bool()
@@ -317,6 +317,12 @@ func (p *importer) obj(tag int) {
val := p.value(typ)
importconst(sym, idealType(typ), nodlit(val))
+ case aliasTag:
+ p.pos()
+ sym := p.qualifiedName()
+ typ := p.typ()
+ importalias(sym, typ)
+
case typeTag:
p.typ()
@@ -356,17 +362,6 @@ func (p *importer) obj(tag int) {
}
}
- case aliasTag:
- p.pos()
- alias := importpkg.Lookup(p.string())
- orig := p.qualifiedName()
-
- // Although the protocol allows the alias to precede the original,
- // this never happens in files produced by gc.
- alias.Flags |= SymAlias
- alias.Def = orig.Def
- importsym(alias, orig.Def.Op)
-
default:
formatErrorf("unexpected object (tag = %d)", tag)
}
@@ -473,14 +468,7 @@ func (p *importer) typ() *Type {
result := p.paramList()
nointerface := p.bool()
- base := recv[0].Type
- star := false
- if base.IsPtr() {
- base = base.Elem()
- star = true
- }
-
- n := methodname0(sym, star, base.Sym)
+ n := newfuncname(methodname(sym, recv[0].Type))
n.Type = functypefield(recv[0], params, result)
checkwidth(n.Type)
addmethod(sym, n.Type, false, nointerface)
@@ -583,19 +571,22 @@ func (p *importer) fieldList() (fields []*Field) {
func (p *importer) field() *Field {
p.pos()
- sym := p.fieldName()
+ sym, alias := p.fieldName()
typ := p.typ()
note := p.string()
f := newField()
if sym.Name == "" {
- // anonymous field - typ must be T or *T and T must be a type name
+ // anonymous field: typ must be T or *T and T must be a type name
s := typ.Sym
if s == nil && typ.IsPtr() {
s = typ.Elem().Sym // deref
}
sym = sym.Pkg.Lookup(s.Name)
f.Embedded = 1
+ } else if alias {
+ // anonymous field: we have an explicit name because it's a type alias
+ f.Embedded = 1
}
f.Sym = sym
@@ -618,7 +609,7 @@ func (p *importer) methodList() (methods []*Field) {
func (p *importer) method() *Field {
p.pos()
- sym := p.fieldName()
+ sym := p.methodName()
params := p.paramList()
result := p.paramList()
@@ -629,18 +620,44 @@ func (p *importer) method() *Field {
return f
}
-func (p *importer) fieldName() *Sym {
+func (p *importer) fieldName() (*Sym, bool) {
name := p.string()
if p.version == 0 && name == "_" {
- // version 0 didn't export a package for _ fields
+ // version 0 didn't export a package for _ field names
// but used the builtin package instead
- return builtinpkg.Lookup(name)
+ return builtinpkg.Lookup(name), false
}
pkg := localpkg
- if name != "" && !exportname(name) {
- if name == "?" {
- name = ""
+ alias := false
+ switch name {
+ case "":
+ // 1) field name matches base type name and is exported: nothing to do
+ case "?":
+ // 2) field name matches base type name and is not exported: need package
+ name = ""
+ pkg = p.pkg()
+ case "@":
+ // 3) field name doesn't match base type name (alias name): need name and possibly package
+ name = p.string()
+ alias = true
+ fallthrough
+ default:
+ if !exportname(name) {
+ pkg = p.pkg()
}
+ }
+ return pkg.Lookup(name), alias
+}
+
+func (p *importer) methodName() *Sym {
+ name := p.string()
+ if p.version == 0 && name == "_" {
+ // version 0 didn't export a package for _ method names
+ // but used the builtin package instead
+ return builtinpkg.Lookup(name)
+ }
+ pkg := localpkg
+ if !exportname(name) {
pkg = p.pkg()
}
return pkg.Lookup(name)