The old implementation produces several multi-inheritance edges between
two classes if there are multiple inheritance paths between them due to
multiple inheritance diamonds. The new implementation produces only one
edge in such a case.
Also, the old implementation has performance issues when there is a huge
number of inheritance paths starting at the focused class. With a
pathological multiple inheritance class structure, the number of paths
can be exponential in the number of involved classes. The new
implementation solves this issue by considering subgraphs instead of
paths.
The following is a small problematic example, which does not show the
performance problem due to its small size. However, when focusing on
X::foo, the old implementation produces 4 different multi-level
inheritance edges from X to B1 while the new implementation produces
only one multi-level inheritance edge, which is basically the union of
the edges of the old implementation:
struct B1 {
virtual void foo() = 0;
};
struct C1 : B1 {};
struct D1 : B1 {};
struct B2 : C1, D1 {};
struct C2 : B2 {};
struct D2 : B2 {};
struct B3 : C2, D2 {};
struct X : B3 {
void foo() override {};
};
int main () {
X x;
x.foo();
return 0;
}