Example #1
0
// 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
}
Example #2
0
// 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.