summaryrefslogtreecommitdiff
path: root/clang-tools-extra/include-cleaner
diff options
context:
space:
mode:
authorViktoriia Bakalova <bakalova@google.com>2023-01-09 10:49:08 +0000
committerViktoriia Bakalova <bakalova@google.com>2023-01-09 12:54:20 +0000
commitde81dc8fdf2764fb14a3c70e5e845cfd7f3b366c (patch)
tree5f127b3bee5f5918da017599949e1760c813cd64 /clang-tools-extra/include-cleaner
parentef545ef62a833152d8975ff16333b57cc41befcc (diff)
downloadllvm-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.cpp15
-rw-r--r--clang-tools-extra/include-cleaner/unittests/RecordTest.cpp23
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;