type Result … type rta … type concreteTypeInfo … type interfaceTypeInfo … // addReachable marks a function as potentially callable at run-time, // and ensures that it gets processed. func (r *rta) addReachable(f *ssa.Function, addrTaken bool) { … } // addEdge adds the specified call graph edge, and marks it reachable. // addrTaken indicates whether to mark the callee as "address-taken". // site is nil for calls made via reflection. func (r *rta) addEdge(caller *ssa.Function, site ssa.CallInstruction, callee *ssa.Function, addrTaken bool) { … } // visitAddrTakenFunc is called each time we encounter an address-taken function f. func (r *rta) visitAddrTakenFunc(f *ssa.Function) { … } // visitDynCall is called each time we encounter a dynamic "call"-mode call. func (r *rta) visitDynCall(site ssa.CallInstruction) { … } // addInvokeEdge is called for each new pair (site, C) in the matrix. func (r *rta) addInvokeEdge(site ssa.CallInstruction, C types.Type) { … } // visitInvoke is called each time the algorithm encounters an "invoke"-mode call. func (r *rta) visitInvoke(site ssa.CallInstruction) { … } // visitFunc processes function f. func (r *rta) visitFunc(f *ssa.Function) { … } // Analyze performs Rapid Type Analysis, starting at the specified root // functions. It returns nil if no roots were specified. // // The root functions must be one or more entrypoints (main and init // functions) of a complete SSA program, with function bodies for all // dependencies, constructed with the [ssa.InstantiateGenerics] mode // flag. // // If buildCallGraph is true, Result.CallGraph will contain a call // graph; otherwise, only the other fields (reachable functions) are // populated. func Analyze(roots []*ssa.Function, buildCallGraph bool) *Result { … } // interfaces(C) returns all currently known interfaces implemented by C. func (r *rta) interfaces(C types.Type) []*types.Interface { … } // implementations(I) returns all currently known concrete types that implement I. func (r *rta) implementations(I *types.Interface) []types.Type { … } // addRuntimeType is called for each concrete type that can be the // dynamic type of some interface or reflect.Value. // Adapted from needMethods in go/ssa/builder.go func (r *rta) addRuntimeType(T types.Type, skip bool) { … } // fingerprint returns a bitmask with one bit set per method id, // enabling 'implements' to quickly reject most candidates. func fingerprint(mset *types.MethodSet) uint64 { … } // implements reports whether types.Implements(cinfo.C, iinfo.I), // but more efficiently. func implements(cinfo *concreteTypeInfo, iinfo *interfaceTypeInfo) (got bool) { … }