There are several ::IsStructurallyEquivalent overloads for Decl subclasses that are
used for comparing declarations. There is also one overload that takes just two Decl
pointers which ends up queuing the passed Decls to be later compared in
CheckKindSpecificEquivalence.
CheckKindSpecificEquivalence implements the dispatch logic for the different Decl
subclasses. It is supposed to hand over the queued Decls to the subclass-specific
::IsStructurallyEquivalent overload that will actually compare the Decl instance.
It also seems to implement a few pieces of actual node comparison logic inbetween the
dispatch code.
This implementation causes that the different overloads of ::IsStructurallyEquivalent do
different (and sometimes no) comparisons depending on which overload of ::IsStructurallyEquivalent
ends up being called.
For example, if I want to compare two FieldDecl instances, then I could either call the
::IsStructurallyEquivalent with Decl * or with FieldDecl * parameters. The overload
that takes FieldDecls is doing a correct comparison. However, the Decl * overload just
queues the Decl pair. CheckKindSpecificEquivalence has no dispatch logic for FieldDecl,
so it always returns true and never does any actual comparison.
On the other hand, if I try to compare two FunctionDecl instances the two possible overloads
of ::IsStructurallyEquivalent have the opposite behaviour: The overload that takes FunctionDecl
pointers isn't comparing the names of the FunctionDecls while the overload taking a plain Decl
ends up comparing the function names (as the comparison logic for that is implemented in
CheckKindSpecificEquivalence).
This patch tries to make this set of functions more consistent by making CheckKindSpecificEquivalence
a pure dispatch function without any subclass-specific comparison logic. Also the
dispatch logic is now autogenerated so it can no longer miss certain subclasses.
The comparison code from CheckKindSpecificEquivalence is moved to the respective ::IsStructurallyEquivalent overload
so that the comparison result no longer depends if one calls the Decl * overload or the overload for the
specific subclass. The only difference is now that the Decl * overload is queuing the parameter while
the subclass-specific overload is directly doing the comparison.
::IsStructurallyEquivalent is an implementation detail and I don't think the behaviour
causes any bugs in the current implementation (as carefully calling the right overload for the different classes
works around the issue), so the test for this change is that I added some new code for comparing MemberExpr.
The new comparison code always calls the dispatching overload and it previously failed as the dispatch didn't support
FieldDecls.
What happens if D2 is an overloaded operator and D1 is not? It looks like this block doesn't handle this case.