diff options
author | Viktoriia Bakalova <bakalova@google.com> | 2023-01-09 10:49:08 +0000 |
---|---|---|
committer | Viktoriia Bakalova <bakalova@google.com> | 2023-01-09 12:54:20 +0000 |
commit | de81dc8fdf2764fb14a3c70e5e845cfd7f3b366c (patch) | |
tree | 5f127b3bee5f5918da017599949e1760c813cd64 /clang-tools-extra/include-cleaner | |
parent | ef545ef62a833152d8975ff16333b57cc41befcc (diff) | |
download | llvm-de81dc8fdf2764fb14a3c70e5e845cfd7f3b366c.tar.gz |
[include-cleaner] Filter template instantiations from AST roots.
Fix: https://github.com/llvm/llvm-project/issues/59825
Differential Revision: https://reviews.llvm.org/D141271
Diffstat (limited to 'clang-tools-extra/include-cleaner')
-rw-r--r-- | clang-tools-extra/include-cleaner/lib/Record.cpp | 15 | ||||
-rw-r--r-- | clang-tools-extra/include-cleaner/unittests/RecordTest.cpp | 23 |
2 files changed, 37 insertions, 1 deletions
diff --git a/clang-tools-extra/include-cleaner/lib/Record.cpp b/clang-tools-extra/include-cleaner/lib/Record.cpp index ab5a2415cbf9..4df65959011c 100644 --- a/clang-tools-extra/include-cleaner/lib/Record.cpp +++ b/clang-tools-extra/include-cleaner/lib/Record.cpp @@ -12,6 +12,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclGroup.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Specifiers.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" @@ -352,6 +353,14 @@ bool PragmaIncludes::isPrivate(const FileEntry *FE) const { return IWYUPublic.find(FE->getUniqueID()) != IWYUPublic.end(); } +namespace { +template <typename T> bool isImplicitTemplateSpecialization(const Decl *D) { + if (const auto *TD = dyn_cast<T>(D)) + return TD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation; + return false; +} +} // namespace + std::unique_ptr<ASTConsumer> RecordedAST::record() { class Recorder : public ASTConsumer { RecordedAST *Out; @@ -364,7 +373,11 @@ std::unique_ptr<ASTConsumer> RecordedAST::record() { for (Decl *D : DG) { if (!SM.isWrittenInMainFile(SM.getExpansionLoc(D->getLocation()))) continue; - // FIXME: Filter out certain Obj-C and template-related decls. + if (isImplicitTemplateSpecialization<FunctionDecl>(D) || + isImplicitTemplateSpecialization<CXXRecordDecl>(D) || + isImplicitTemplateSpecialization<VarDecl>(D)) + continue; + // FIXME: Filter out certain Obj-C as well. Out->Roots.push_back(D); } return ASTConsumer::HandleTopLevelDecl(DG); diff --git a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp index 919d6bdc0d68..cc99146c4419 100644 --- a/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/RecordTest.cpp @@ -101,6 +101,29 @@ TEST_F(RecordASTTest, Macros) { EXPECT_THAT(Recorded.Roots, testing::ElementsAre(named("x"))); } +// Decl from template instantiation is filtered out from roots. +TEST_F(RecordASTTest, ImplicitTemplates) { + Inputs.ExtraFiles["dispatch.h"] = R"cpp( + struct A { + static constexpr int value = 1; + }; + template <class Getter> + int dispatch() { + return Getter::template get<A>(); + } + )cpp"; + Inputs.Code = R"cpp( + #include "dispatch.h" + struct MyGetter { + template <class T> static int get() { return T::value; } + }; + int v = dispatch<MyGetter>(); + )cpp"; + auto AST = build(); + EXPECT_THAT(Recorded.Roots, + testing::ElementsAre(named("MyGetter"), named("v"))); +} + class RecordPPTest : public ::testing::Test { protected: TestInputs Inputs; |