https://github.com/hokein created https://github.com/llvm/llvm-project/pull/66485
In libcpp, the `std::remove(const char*)` is a using decl in std namespace `using ::remove`, which was not handled correctly in `headerForAmbiguousStdSymbol` >From ffd109a7b4273d6a1dc5810b64039a110a4147c9 Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Fri, 15 Sep 2023 11:59:06 +0200 Subject: [PATCH] [include-cleaner] Respect the UsingShadowDecl when find headers for ambiguous std symbols. In libcpp, the `std::remove(const char*)` is a using decl in std namespace `using ::remove`, which was not handled correctly in `headerForAmbiguousStdSymbol` --- .../include-cleaner/lib/FindHeaders.cpp | 3 ++ .../unittests/FindHeadersTest.cpp | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp index 06e5e1812ba7218..fd2de6a17ad4a53 100644 --- a/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp +++ b/clang-tools-extra/include-cleaner/lib/FindHeaders.cpp @@ -13,6 +13,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/FileEntry.h" #include "clang/Basic/SourceLocation.h" @@ -116,6 +117,8 @@ std::optional<tooling::stdlib::Header> headerForAmbiguousStdSymbol(const NamedDecl *ND) { if (!ND->isInStdNamespace()) return {}; + if (auto* USD = llvm::dyn_cast<UsingShadowDecl>(ND)) + ND = USD->getTargetDecl(); const auto *FD = ND->getAsFunction(); if (!FD) return std::nullopt; diff --git a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp index 4cdcde1184a0a9e..5a2a41b2d99bdd7 100644 --- a/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp @@ -11,6 +11,7 @@ #include "clang-include-cleaner/Analysis.h" #include "clang-include-cleaner/Record.h" #include "clang-include-cleaner/Types.h" +#include "clang/AST/Expr.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/FileEntry.h" #include "clang/Basic/FileManager.h" @@ -587,6 +588,36 @@ TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) { } } +TEST_F(HeadersForSymbolTest, AmbiguousStdSymbolsUsingShadow) { + Inputs.Code = R"cpp( + void remove(char*); + namespace std { using ::remove; } + + void k() { + std::remove("abc"); + } + )cpp"; + buildAST(); + + // Find the DeclRefExpr in the std::remove("abc") function call. + struct Visitor : public RecursiveASTVisitor<Visitor> { + const DeclRefExpr *Out = nullptr; + bool VisitDeclRefExpr(const DeclRefExpr *DRE) { + EXPECT_TRUE(Out == nullptr) << "Found multiple DeclRefExpr!"; + Out = DRE; + return true; + } + }; + Visitor V; + V.TraverseDecl(AST->context().getTranslationUnitDecl()); + ASSERT_TRUE(V.Out) << "Couldn't find a DeclRefExpr!"; + EXPECT_THAT(headersForSymbol(*(V.Out->getFoundDecl()), + AST->sourceManager(), &PI), + UnorderedElementsAre( + Header(*tooling::stdlib::Header::named("<cstdio>")))); +} + + TEST_F(HeadersForSymbolTest, StandardHeaders) { Inputs.Code = "void assert();"; buildAST(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits