VitaNuo updated this revision to Diff 487385. VitaNuo added a comment. Address review comments.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D141271/new/ https://reviews.llvm.org/D141271 Files: clang-tools-extra/include-cleaner/lib/Record.cpp clang-tools-extra/include-cleaner/unittests/RecordTest.cpp Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp =================================================================== --- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp +++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp @@ -101,6 +101,29 @@ 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; Index: clang-tools-extra/include-cleaner/lib/Record.cpp =================================================================== --- clang-tools-extra/include-cleaner/lib/Record.cpp +++ 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 @@ 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 @@ 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);
Index: clang-tools-extra/include-cleaner/unittests/RecordTest.cpp =================================================================== --- clang-tools-extra/include-cleaner/unittests/RecordTest.cpp +++ clang-tools-extra/include-cleaner/unittests/RecordTest.cpp @@ -101,6 +101,29 @@ 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; Index: clang-tools-extra/include-cleaner/lib/Record.cpp =================================================================== --- clang-tools-extra/include-cleaner/lib/Record.cpp +++ 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 @@ 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 @@ 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);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits