hokein created this revision.
hokein added a reviewer: kadircet.
Herald added a project: All.
hokein requested review of this revision.
Herald added a project: clang-tools-extra.
By special-casing them at the moment. The tooling stdlib lib doesn't
support these symbols (most important one is std::move).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D143906
Files:
clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
Index: clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
===================================================================
--- clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
+++ clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
@@ -278,25 +278,31 @@
class HeadersForSymbolTest : public FindHeadersTest {
protected:
- llvm::SmallVector<Header> headersForFoo() {
+ llvm::SmallVector<Header> headersFor(llvm::StringRef Name) {
struct Visitor : public RecursiveASTVisitor<Visitor> {
const NamedDecl *Out = nullptr;
+ llvm::StringRef Name;
+ Visitor(llvm::StringRef Name) : Name(Name) {}
bool VisitNamedDecl(const NamedDecl *ND) {
- if (ND->getName() == "foo") {
+ if (auto *TD = ND->getDescribedTemplate())
+ ND = TD;
+
+ if (ND->getName() == Name) {
EXPECT_TRUE(Out == nullptr || Out == ND->getCanonicalDecl())
- << "Found multiple matches for foo.";
+ << "Found multiple matches for " << Name << ".";
Out = cast<NamedDecl>(ND->getCanonicalDecl());
}
return true;
}
};
- Visitor V;
+ Visitor V(Name);
V.TraverseDecl(AST->context().getTranslationUnitDecl());
if (!V.Out)
- ADD_FAILURE() << "Couldn't find any decls named foo.";
+ ADD_FAILURE() << "Couldn't find any decls named " << Name << ".";
assert(V.Out);
return headersForSymbol(*V.Out, AST->sourceManager(), &PI);
}
+ llvm::SmallVector<Header> headersForFoo() { return headersFor("foo"); }
};
TEST_F(HeadersForSymbolTest, Deduplicates) {
@@ -430,5 +436,54 @@
EXPECT_THAT(headersForFoo(), ElementsAre(Header(StringRef("\"public.h\"")),
physicalHeader("foo.h")));
}
+
+TEST_F(HeadersForSymbolTest, AmbiguousStdSymbols) {
+ struct {
+ llvm::StringRef Code;
+ llvm::StringRef Name;
+
+ llvm::StringRef ExpectedHeader;
+ } TestCases[] = {
+ {
+ R"cpp(
+ namespace std {
+ template <typename InputIt, typename OutputIt>
+ constexpr OutputIt move(InputIt first, InputIt last, OutputIt dest);
+ })cpp",
+ "move",
+ "<algorithm>",
+ },
+ {
+ R"cpp(
+ namespace std {
+ template<typename T> constexpr T move(T&& t) noexcept;
+ })cpp",
+ "move",
+ "<utility>",
+ },
+ {
+ R"cpp(
+ namespace std {
+ template<class ForwardIt, class T>
+ ForwardIt remove(ForwardIt first, ForwardIt last, const T& value);
+ })cpp",
+ "remove",
+ "<algorithm>",
+ },
+ {
+ "namespace std { int remove(const char*); }",
+ "remove",
+ "<cstdio>",
+ },
+ };
+
+ for (const auto &T : TestCases) {
+ Inputs.Code = T.Code;
+ buildAST();
+ EXPECT_THAT(headersFor(T.Name),
+ UnorderedElementsAre(Header(T.ExpectedHeader)));
+ }
+}
+
} // namespace
} // namespace clang::include_cleaner
Index: clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
===================================================================
--- clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
+++ clang-tools-extra/include-cleaner/lib/FindHeaders.cpp
@@ -82,6 +82,36 @@
llvm_unreachable("unhandled Symbol kind!");
}
+// Special-case the ambiguous standard library symbols (e.g. std::move) which
+// are not supported by the tooling stdlib lib.
+llvm::SmallVector<Header> specialStandardSymbols(const Symbol &S) {
+ if (S.kind() != Symbol::Declaration || !S.declaration().isInStdNamespace())
+ return {};
+
+ const auto *FD = S.declaration().getAsFunction();
+ if (!FD)
+ return {};
+
+ llvm::StringRef FName = FD->getName();
+ if (FName == "move") {
+ if (FD->getNumParams() == 1)
+ // move(T&& t)
+ return {Header("<utility>")};
+ if (FD->getNumParams() == 3)
+ // move(InputIt first, InputIt last, OutputIt dest);
+ return {Header("<algorithm>")};
+ }
+ if (FName == "remove") {
+ if (FD->getNumParams() == 1)
+ // remove(const char*);
+ return {Header("<cstdio>")};
+ if (FD->getNumParams() == 3)
+ // remove(ForwardIt first, ForwardIt last, const T& value);
+ return {Header("<algorithm>")};
+ }
+ return {};
+}
+
} // namespace
llvm::SmallVector<Hinted<Header>> findHeaders(const SymbolLocation &Loc,
@@ -141,6 +171,9 @@
llvm::SmallVector<Header> headersForSymbol(const Symbol &S,
const SourceManager &SM,
const PragmaIncludes *PI) {
+ if (auto Headers = specialStandardSymbols(S); !Headers.empty())
+ return Headers;
+
// Get headers for all the locations providing Symbol. Same header can be
// reached through different traversals, deduplicate those into a single
// Header by merging their hints.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits