This is an archive of the discontinued LLVM Phabricator instance.

[IncludeCleaner] Add public API
ClosedPublic

Authored by kadircet on Oct 19 2022, 2:26 PM.

Details

Summary

Introduces walkUsed, a very simple version of the public API to enable
incremental development on rest of the pieces.

Diff Detail

Event Timeline

kadircet created this revision.Oct 19 2022, 2:26 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 19 2022, 2:26 PM
kadircet requested review of this revision.Oct 19 2022, 2:26 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 19 2022, 2:26 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
sammccall accepted this revision.Oct 19 2022, 4:43 PM

Thanks! Looks good, feel free to address/disregard design comments as you see fit.

clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
15

This is awful but: as mentioned on another patch, we can't actually use variant. AFAIK all C++17 *language* features are available, but LLVM supports apple clang 9.3, which doesn't provide <variant> at all.

There's an IntrusiveVariant in review somewhere but seems stalled (and honestly the Intrusive part makes it pretty ugly to use).

I think for now our best option is a Kind enum and some kind of uintptr_t storage :-(

33

nit: that's providing -> that provides, includeable -> includable

A bit unclear "what might not be includeable" means, say why?

35

a short comment for each case is pretty easy-to-read way to doc sum types, and these are important enough concepts it might be justified here. Up to you though.

48

this is so the caller can filter the references and rank the results, right?

I think it's worth saying so, mostly because that's an important design decision, and I keep forgetting to write them down

clang-tools-extra/include-cleaner/lib/WalkAST.cpp
45

IMO this function really deserves its own impl file I think (at least Analysis.cpp) - I think it + walkAST are going to be the two biggest bundles of complexity in the library. (if so, same with the tests)

51

nit: remove debug

52

(I think the patch is fine, but could use some extra docs/fixmes depending on what the choices are here).

In general we want a forward declaration in the main file to suppress any include insertion.
Two obvious ways to achieve that:
A) walkUsed doesn't report refs of symbols that have a decl in the main file
B) walkUsed reports the refs, the header list includes the main file, the caller recognizes it when checking if the ref is satisfied

A) feels more ad-hoc, but seems to work and *does* naturally achieve the nice effect that #include "foo.h" is marked as unused if the only used symbols are also forward-declared locally. In this case, maybe add a FIXME for this filtering? Also A seems surprising enough to be worth documenting.

B) falls more naturally out of the implementation. It looks like we have a bug here: by bailing out early, we'll omit any forward declarations from the main file. For symbols in namespace std we're arguably within our rights as such decls are UB. However such forward decls are legal in C, so maybe we should care after all? In any case, this subtlety deserves some sort of comment.

57

FIXME: handle locations from macros

clang-tools-extra/include-cleaner/unittests/CMakeLists.txt
22

needed in the main lib too?

clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
121

signal-to-noise in this test is a bit low, and there'll be a bunch more tests as the features get extended.

I think adding a TEST_F fixture and splitting the stdlib out into its own test, trying to maximize the shared code, may lead to cleaner tests.

Feel free to defer this, just watch out for incremental inertia giving you a 1000 line monster before you know it!

This revision is now accepted and ready to land.Oct 19 2022, 4:43 PM
hokein accepted this revision.Oct 20 2022, 5:44 AM
hokein added inline comments.
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
8

would be nice to have some high-level descriptions in the file comment.

30

I see we use Decl* here and elsewhere (WalkAST etc), is there any reason of not using const Decl*?

49

nit: rename the Visitor to CB? Visitor reminds me too much of ASTVisitor...

clang-tools-extra/include-cleaner/lib/WalkAST.cpp
45

+1

56

nit: remove.

kadircet marked 13 inline comments as done.Oct 24 2022, 3:24 AM
kadircet added inline comments.
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
15

right, i've seen that comment as well and wanted to pile up there. there are already uses of <variant> in LLVM today, TableGen, DenseMap, CodeGen, flang, pseudo, MLIR and lldb are some examples of big components. I don't see what they're doing to compile those today.

clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
121

yup, that's definitely something i've in pending patches.

kadircet marked 2 inline comments as done.Oct 24 2022, 3:29 AM
kadircet added inline comments.
clang-tools-extra/include-cleaner/lib/WalkAST.cpp
52

thanks, i think the conclusion is B) here, but definitely didn't notice the implications of early bailout here. adding some comments.

kadircet updated this revision to Diff 470106.Oct 24 2022, 3:29 AM
kadircet marked an inline comment as done.
  • Address comments
kadircet marked an inline comment as done.Oct 24 2022, 8:01 AM
kadircet added inline comments.
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
15

as mentioned in https://discourse.llvm.org/t/rfc-bump-minimal-requirements-apple-clang-9-3-10-0-0-before-4th-tue-in-january/66156/7?u=kadircet, LLVM is already enforcing apple clang 10.0.0 effectively (and hopefully documentation will also change soon).

hence i am moving forward with this change. in the unlikely event of community taking a different approach (like downgrading the minimum requirements), i am more than happy to get rid of the std::variant usage here.

This revision was automatically updated to reflect the committed changes.
sammccall added inline comments.Oct 25 2022, 2:15 PM
clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h
27

Doh, I was skimming and missed that you removed the Location concept and folded stdlib handling into Symbol.

tooling::stdlib::Symbol only captures top-level symbols, so we've thrown away the identity of the actual symbol being accessed. This is not a complete disaster, but I think it causes problems, and I think we should be very deliberate and consistent about what information we preserve vs throw away.

Some examples of how this might bite us:

  • distinguishing between macros/decls is non-uniform (need to check separately for decl vs macro vs stdlib-decl vs stdlib-macro)
  • can't treat different types of symbols e.g. constructors vs classes differently (you suggested elsewhere we could check the kind of targetdecl to implement external policies)
  • can't treat nested classes differently (i.e. must treat std::vector and decltype(myvec)::iterator the same).
  • can't print the name, e.g. the fixit hint for auto x = TimePoint<>::min() becomes include header <chrono> for 'std::chrono::time_point' instead of include header <chrono> for 'std::chrono::time_point<...>::min()'
  • can't insert forward declarations with a code action (legal for c symbols)
  • harder to understand/debug (is this an implicit reference to a copy constructor, move constructor, conversion operator, or the type itself? where *are* all the redecls? is this misclassified user code, such as a trait specialization)?