aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/typecheck/iexport.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/typecheck/iexport.go')
-rw-r--r--src/cmd/compile/internal/typecheck/iexport.go68
1 files changed, 59 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go
index f001017a86..489306e1e6 100644
--- a/src/cmd/compile/internal/typecheck/iexport.go
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -63,8 +63,9 @@
// }
//
// type Func struct {
-// Tag byte // 'F'
+// Tag byte // 'F' or 'G'
// Pos Pos
+// TypeParams []typeOff // only present if Tag == 'G'
// Signature Signature
// }
//
@@ -75,8 +76,9 @@
// }
//
// type Type struct {
-// Tag byte // 'T'
+// Tag byte // 'T' or 'U'
// Pos Pos
+// TypeParams []typeOff // only present if Tag == 'U'
// Underlying typeOff
//
// Methods []struct{ // omitted if Underlying is an interface type
@@ -93,6 +95,12 @@
// Type typeOff
// }
//
+// // "Automatic" declaration of each typeparam
+// type TypeParam struct {
+// Tag byte // 'P'
+// Pos Pos
+// Bound typeOff
+// }
//
// typeOff means a uvarint that either indicates a predeclared type,
// or an offset into the Data section. If the uvarint is less than
@@ -104,7 +112,7 @@
// (*exportWriter).value for details.
//
//
-// There are nine kinds of type descriptors, distinguished by an itag:
+// There are twelve kinds of type descriptors, distinguished by an itag:
//
// type DefinedType struct {
// Tag itag // definedType
@@ -172,8 +180,30 @@
// }
// }
//
+// // Reference to a type param declaration
+// type TypeParamType struct {
+// Tag itag // typeParamType
+// Name stringOff
+// PkgPath stringOff
+// }
+//
+// // Instantiation of a generic type (like List[T2] or List[int])
+// type InstanceType struct {
+// Tag itag // instanceType
+// Pos pos
+// TypeArgs []typeOff
+// BaseType typeOff
+// }
+//
+// type UnionType struct {
+// Tag itag // interfaceType
+// Terms []struct {
+// tilde bool
+// Type typeOff
+// }
+// }
+//
//
-// TODO(danscales): fill in doc for 'type TypeParamType' and 'type InstType'
//
// type Signature struct {
// Params []Param
@@ -255,7 +285,7 @@ const (
structType
interfaceType
typeParamType
- instType
+ instanceType // Instantiation of a generic type
unionType
)
@@ -893,7 +923,7 @@ func (w *exportWriter) doTyp(t *types.Type) {
if strings.Index(s.Name, "[") < 0 {
base.Fatalf("incorrect name for instantiated type")
}
- w.startType(instType)
+ w.startType(instanceType)
w.pos(t.Pos())
// Export the type arguments for the instantiated type. The
// instantiated type could be in a method header (e.g. "func (v
@@ -1456,10 +1486,23 @@ func (w *exportWriter) node(n ir.Node) {
}
}
-// Caution: stmt will emit more than one node for statement nodes n that have a non-empty
-// n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
+func isNonEmptyAssign(n ir.Node) bool {
+ switch n.Op() {
+ case ir.OAS:
+ if n.(*ir.AssignStmt).Y != nil {
+ return true
+ }
+ case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+ return true
+ }
+ return false
+}
+
+// Caution: stmt will emit more than one node for statement nodes n that have a
+// non-empty n.Ninit and where n is not a non-empty assignment or a node with a natural init
+// section (such as in "if", "for", etc.).
func (w *exportWriter) stmt(n ir.Node) {
- if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) {
+ if len(n.Init()) > 0 && !ir.StmtWithInit(n.Op()) && !isNonEmptyAssign(n) && n.Op() != ir.ORANGE {
// can't use stmtList here since we don't want the final OEND
for _, n := range n.Init() {
w.stmt(n)
@@ -1495,8 +1538,10 @@ func (w *exportWriter) stmt(n ir.Node) {
if n.Y != nil {
w.op(ir.OAS)
w.pos(n.Pos())
+ w.stmtList(n.Init())
w.expr(n.X)
w.expr(n.Y)
+ w.bool(n.Def)
}
case ir.OASOP:
@@ -1517,8 +1562,10 @@ func (w *exportWriter) stmt(n ir.Node) {
w.op(ir.OAS2)
}
w.pos(n.Pos())
+ w.stmtList(n.Init())
w.exprList(n.Lhs)
w.exprList(n.Rhs)
+ w.bool(n.Def)
case ir.ORETURN:
n := n.(*ir.ReturnStmt)
@@ -1556,6 +1603,7 @@ func (w *exportWriter) stmt(n ir.Node) {
n := n.(*ir.RangeStmt)
w.op(ir.ORANGE)
w.pos(n.Pos())
+ w.stmtList(n.Init())
w.exprsOrNil(n.Key, n.Value)
w.expr(n.X)
w.stmtList(n.Body)
@@ -2065,8 +2113,10 @@ func (w *exportWriter) expr(n ir.Node) {
n := n.(*ir.AssignListStmt)
w.op(ir.OSELRECV2)
w.pos(n.Pos())
+ w.stmtList(n.Init())
w.exprList(n.Lhs)
w.exprList(n.Rhs)
+ w.bool(n.Def)
default:
base.Fatalf("cannot export %v (%d) node\n"+