This doesn't do a whole lot yet other than change the print out produced
by the analysis, but it lays the groundwork for a very major change I'm
working on next: teaching the call graph to actually be a call graph,
modeling *both* the indirect reference graph and the call graph
simultaneously. More details on that in the next patch though.
Here, the biggest qustion I have for reviewers is whether they like the
core interface used by the edge abstraction. Notably, the Edge::Kind
enums end up used broadly in the API of the entire call graph. Better
names or structure for these abstractions would be very interesting.
The rest of this is essentially a bunch of over-engineering that won't be
interesting until the next patch. But this also isolates essentially all of the
churn necessary to introduce the edge abstraction from the very important
behavior change necessary in order to separately model the two graphs. So it
should make review of the subsequent patch a bit easier at the cost of making
this patch seem poorly motivated. ;]
That said, if folks would rather me merge this into the big patch that
makes having this abstraction necessary, I'm happy to do that.