// Create returns a new SSA Program. An SSA Package is created for // each transitively error-free package of iprog. // // Code for bodies of functions is not built until Build() is called // on the result. // // mode controls diagnostics and checking during SSA construction. // func Create(iprog *loader.Program, mode BuilderMode) *Program { prog := &Program{ Fset: iprog.Fset, PackagesByPath: make(map[string]*Package), PackagesByName: make(map[string]*Package), imported: make(map[string]*Package), packages: make(map[*types.Package]*Package), thunks: make(map[selectionKey]*Function), bounds: make(map[*types.Func]*Function), mode: mode, } h := typeutil.MakeHasher() // protected by methodsMu, in effect prog.methodSets.SetHasher(h) prog.canon.SetHasher(h) for _, info := range iprog.AllPackages { // TODO(adonovan): relax this constraint if the // program contains only "soft" errors. if info.TransitivelyErrorFree { prog.CreatePackage(info) } } return prog }
// Hash functions and equivalence relation: // hashString computes the FNV hash of s. func hashString(s string) int { var h uint32 for i := 0; i < len(s); i++ { h ^= uint32(s[i]) h *= 16777619 } return int(h) } var ( mu sync.Mutex hasher = typeutil.MakeHasher() ) // hashType returns a hash for t such that // types.Identical(x, y) => hashType(x) == hashType(y). func hashType(t types.Type) int { mu.Lock() h := int(hasher.Hash(t)) mu.Unlock() return h } // usesBuiltinMap returns true if the built-in hash function and // equivalence relation for type t are consistent with those of the // interpreter's representation of type t. Such types are: all basic // types (bool, numbers, string), pointers and channels.