This is an archive of the discontinued LLVM Phabricator instance.

[ASTImporter] Refactor IsStructurallyEquivalent's Decl overloads to be more consistent
ClosedPublic

Authored by teemperor on Sep 14 2020, 9:57 AM.

Details

Summary

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.

Diff Detail

Event Timeline

teemperor created this revision.Sep 14 2020, 9:57 AM
teemperor requested review of this revision.Sep 14 2020, 9:57 AM
teemperor updated this revision to Diff 291600.Sep 14 2020, 9:58 AM
  • Removed an unrelated change.

Thank you! This is a great simplification of the code and it is much cleaner this way, nice work!
I queued a CTU build, just to verify nothing will be break:
#1​71​9 at http://codechecker-buildbot.eastus.cloudapp.azure.com:8080/job/ctu_pipeline_clang-master-monorepo/

Thank you! This is a great simplification of the code and it is much cleaner this way, nice work!
I queued a CTU build, just to verify nothing will be break:
#1​71​9 at http://codechecker-buildbot.eastus.cloudapp.azure.com:8080/job/ctu_pipeline_clang-master-monorepo/

A related question: You see any problem with doing the same generated Traversal* code we do for the Stmts also for the Decls? This way we could simplify some common checks (e.g., NameDecl's name comparison could cover all subclasses that want it). It seems that for example the Records can't just reuse the name comparison because of the getTypedefNameForAnonDecl() trick, so it might not be as simple as the Stmt code.

Thank you! This is a great simplification of the code and it is much cleaner this way, nice work!
I queued a CTU build, just to verify nothing will be break:
#1​71​9 at http://codechecker-buildbot.eastus.cloudapp.azure.com:8080/job/ctu_pipeline_clang-master-monorepo/

A related question: You see any problem with doing the same generated Traversal* code we do for the Stmts also for the Decls? This way we could simplify some common checks (e.g., NameDecl's name comparison could cover all subclasses that want it). It seems that for example the Records can't just reuse the name comparison because of the getTypedefNameForAnonDecl() trick, so it might not be as simple as the Stmt code.

No, I don't see any problem with that, could be another step forward. About the difficulties with getTypedefNameForAnonDecl(), perhaps we could have an overload for TagDecls that dispatches further (?).

martong accepted this revision.Sep 16 2020, 12:25 AM

Thank you! This is a great simplification of the code and it is much cleaner this way, nice work!
I queued a CTU build, just to verify nothing will be break:
#1​71​9 at http://codechecker-buildbot.eastus.cloudapp.azure.com:8080/job/ctu_pipeline_clang-master-monorepo/

The build passed.

This revision is now accepted and ready to land.Sep 16 2020, 12:25 AM

Hello Raphael! Nice patch, thank you for this refactoring!

clang/lib/AST/ASTStructuralEquivalence.cpp
1867

What happens if D2 is an overloaded operator and D1 is not? It looks like this block doesn't handle this case.

teemperor added inline comments.Sep 16 2020, 12:37 PM
clang/lib/AST/ASTStructuralEquivalence.cpp
1867

Just to clarify: This code is just moved from the dispatch code below and not added by this patch.

But I actually noticed the same when moving the code here and it's on my list of TODO list :)

a_sidorin accepted this revision.Sep 16 2020, 12:39 PM
a_sidorin added inline comments.
clang/lib/AST/ASTStructuralEquivalence.cpp
1867

Yes, this is a perfect example of how code simplification makes it easier to spot bugs.

Herald added a project: Restricted Project. · View Herald TranscriptSep 21 2020, 7:41 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript