Commits

Anonymous committed b1c86ae Draft

[release-branch.go1] cmd/cgo: make Go code order deterministic

««« backport 319a9f3330d0
cmd/cgo: make Go code order deterministic

The type declarations were being generated using
a range over a map, which meant that successive
runs produced different orders. This will make sure
successive runs produce the same files.

Fixes issue 3707.

R=golang-dev, bradfitz
CC=golang-dev
http://codereview.appspot.com/6300062

»»»

Comments (0)

Files changed (2)

src/cmd/cgo/main.go

 	"path/filepath"
 	"reflect"
 	"runtime"
+	"sort"
 	"strings"
 )
 
 	GccOptions  []string
 	CgoFlags    map[string]string // #cgo flags (CFLAGS, LDFLAGS)
 	Written     map[string]bool
-	Name        map[string]*Name    // accumulated Name from Files
-	Typedef     map[string]ast.Expr // accumulated Typedef from Files
-	ExpFunc     []*ExpFunc          // accumulated ExpFunc from Files
+	Name        map[string]*Name // accumulated Name from Files
+	ExpFunc     []*ExpFunc       // accumulated ExpFunc from Files
 	Decl        []ast.Decl
 	GoFiles     []string // list of Go files
 	GccFiles    []string // list of gcc output files
 	Ref      []*Ref              // all references to C.xxx in AST
 	ExpFunc  []*ExpFunc          // exported functions for this file
 	Name     map[string]*Name    // map from Go name to Name
-	Typedef  map[string]ast.Expr // translations of all necessary types from C
+}
+
+func nameKeys(m map[string]*Name) []string {
+	var ks []string
+	for k := range m {
+		ks = append(ks, k)
+	}
+	sort.Strings(ks)
+	return ks
 }
 
 // A Ref refers to an expression of the form C.xxx in the AST.

src/cmd/cgo/out.go

 	}
 
 	cVars := make(map[string]bool)
-	for _, n := range p.Name {
+	for _, key := range nameKeys(p.Name) {
+		n := p.Name[key]
 		if n.Kind != "var" {
 			continue
 		}
 	}
 	fmt.Fprintf(fc, "\n")
 
-	for _, n := range p.Name {
+	for _, key := range nameKeys(p.Name) {
+		n := p.Name[key]
 		if n.Const != "" {
 			fmt.Fprintf(fgo2, "const _Cconst_%s = %s\n", n.Go, n.Const)
 		}
 	}
 	fmt.Fprintf(fgo2, "\n")
 
-	for _, n := range p.Name {
+	for _, key := range nameKeys(p.Name) {
+		n := p.Name[key]
 		if n.FuncType != nil {
 			p.writeDefsFunc(fc, fgo2, n)
 		}
 	fmt.Fprintf(fgcc, "%s\n", f.Preamble)
 	fmt.Fprintf(fgcc, "%s\n", gccProlog)
 
-	for _, n := range f.Name {
+	for _, key := range nameKeys(f.Name) {
+		n := f.Name[key]
 		if n.FuncType != nil {
 			p.writeOutputFunc(fgcc, n)
 		}