sammccall created this revision.
sammccall added a reviewer: VitaNuo.
Herald added a project: All.
sammccall requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
These address some remaining reasons to #include StdSymbolMap.inc directly.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D142467
Files:
clang/include/clang/Tooling/Inclusions/StandardLibrary.h
clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
clang/unittests/Tooling/StandardLibraryTest.cpp
Index: clang/unittests/Tooling/StandardLibraryTest.cpp
===================================================================
--- clang/unittests/Tooling/StandardLibraryTest.cpp
+++ clang/unittests/Tooling/StandardLibraryTest.cpp
@@ -18,6 +18,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+using ::testing::Contains;
using ::testing::ElementsAre;
namespace clang {
@@ -35,17 +36,24 @@
TEST(StdlibTest, All) {
auto VectorH = stdlib::Header::named("<vector>");
EXPECT_TRUE(VectorH);
+ EXPECT_EQ(VectorH->name(), "<vector>");
EXPECT_EQ(llvm::to_string(*VectorH), "<vector>");
EXPECT_FALSE(stdlib::Header::named("HeadersTests.cpp"));
auto Vector = stdlib::Symbol::named("std::", "vector");
EXPECT_TRUE(Vector);
+ EXPECT_EQ(Vector->scope(), "std::");
+ EXPECT_EQ(Vector->name(), "vector");
+ EXPECT_EQ(Vector->qualified_name(), "std::vector");
EXPECT_EQ(llvm::to_string(*Vector), "std::vector");
EXPECT_FALSE(stdlib::Symbol::named("std::", "dongle"));
EXPECT_FALSE(stdlib::Symbol::named("clang::", "ASTContext"));
EXPECT_EQ(Vector->header(), *VectorH);
EXPECT_THAT(Vector->headers(), ElementsAre(*VectorH));
+
+ EXPECT_THAT(stdlib::Header::all(), Contains(VectorH));
+ EXPECT_THAT(stdlib::Symbol::all(), Contains(Vector));
}
TEST(StdlibTest, Recognizer) {
Index: clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
===================================================================
--- clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
+++ clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
@@ -16,7 +16,12 @@
namespace stdlib {
static llvm::StringRef *HeaderNames;
-static std::pair<llvm::StringRef, llvm::StringRef> *SymbolNames;
+static struct SymbolName {
+ const char *Data; // std::vector
+ unsigned ScopeLen; // ~~~~~
+ unsigned NameLen; // ~~~~~~
+} *SymbolNames;
+static unsigned SymbolCount = 0;
static unsigned *SymbolHeaderIDs;
static llvm::DenseMap<llvm::StringRef, unsigned> *HeaderIDs;
// Maps symbol name -> Symbol::ID, within a namespace.
@@ -24,14 +29,15 @@
static llvm::DenseMap<llvm::StringRef, NSSymbolMap *> *NamespaceSymbols;
static int initialize() {
- unsigned SymCount = 0;
-#define SYMBOL(Name, NS, Header) ++SymCount;
+ SymbolCount = 0;
+#define SYMBOL(Name, NS, Header) ++SymbolCount;
#include "clang/Tooling/Inclusions/CSymbolMap.inc"
#include "clang/Tooling/Inclusions/StdSymbolMap.inc"
#undef SYMBOL
- SymbolNames = new std::remove_reference_t<decltype(*SymbolNames)>[SymCount];
+ SymbolNames =
+ new std::remove_reference_t<decltype(*SymbolNames)>[SymbolCount];
SymbolHeaderIDs =
- new std::remove_reference_t<decltype(*SymbolHeaderIDs)>[SymCount];
+ new std::remove_reference_t<decltype(*SymbolHeaderIDs)>[SymbolCount];
NamespaceSymbols = new std::remove_reference_t<decltype(*NamespaceSymbols)>;
HeaderIDs = new std::remove_reference_t<decltype(*HeaderIDs)>;
@@ -46,20 +52,25 @@
return HeaderIDs->try_emplace(Header, HeaderIDs->size()).first->second;
};
- auto Add = [&, SymIndex(0)](llvm::StringRef Name, llvm::StringRef NS,
+ auto Add = [&, SymIndex(0)](llvm::StringRef QName, unsigned NSLen,
llvm::StringRef HeaderName) mutable {
- if (NS == "None")
- NS = "";
+ // Correct "Nonefoo" => foo.
+ // FIXME: get rid of "None" from the generated mapping files.
+ if (QName.take_front(NSLen) == "None") {
+ QName = QName.drop_front(NSLen);
+ NSLen = 0;
+ }
- SymbolNames[SymIndex] = {NS, Name};
+ SymbolNames[SymIndex] = {QName.data(), NSLen,
+ static_cast<unsigned int>(QName.size() - NSLen)};
SymbolHeaderIDs[SymIndex] = AddHeader(HeaderName);
- NSSymbolMap &NSSymbols = AddNS(NS);
- NSSymbols.try_emplace(Name, SymIndex);
+ NSSymbolMap &NSSymbols = AddNS(QName.take_front(NSLen));
+ NSSymbols.try_emplace(QName.drop_front(NSLen), SymIndex);
++SymIndex;
};
-#define SYMBOL(Name, NS, Header) Add(#Name, #NS, #Header);
+#define SYMBOL(Name, NS, Header) Add(#NS #Name, strlen(#NS), #Header);
#include "clang/Tooling/Inclusions/CSymbolMap.inc"
#include "clang/Tooling/Inclusions/StdSymbolMap.inc"
#undef SYMBOL
@@ -76,6 +87,13 @@
(void)Dummy;
}
+std::vector<Header> Header::all() {
+ std::vector<Header> Result;
+ Result.reserve(HeaderIDs->size());
+ for (unsigned I = 0, E = HeaderIDs->size(); I < E; ++I)
+ Result.push_back(Header(I));
+ return Result;
+}
std::optional<Header> Header::named(llvm::StringRef Name) {
ensureInitialized();
auto It = HeaderIDs->find(Name);
@@ -84,8 +102,26 @@
return Header(It->second);
}
llvm::StringRef Header::name() const { return HeaderNames[ID]; }
-llvm::StringRef Symbol::scope() const { return SymbolNames[ID].first; }
-llvm::StringRef Symbol::name() const { return SymbolNames[ID].second; }
+
+std::vector<Symbol> Symbol::all() {
+ std::vector<Symbol> Result;
+ Result.reserve(HeaderIDs->size());
+ for (unsigned I = 0, E = HeaderIDs->size(); I < E; ++I)
+ Result.push_back(Symbol(I));
+ return Result;
+}
+llvm::StringRef Symbol::scope() const {
+ SymbolName &S = SymbolNames[ID];
+ return StringRef(S.Data, S.ScopeLen);
+}
+llvm::StringRef Symbol::name() const {
+ SymbolName &S = SymbolNames[ID];
+ return StringRef(S.Data + S.NameLen, S.ScopeLen);
+}
+llvm::StringRef Symbol::qualified_name() const {
+ SymbolName &S = SymbolNames[ID];
+ return StringRef(S.Data, S.ScopeLen + S.NameLen);
+}
std::optional<Symbol> Symbol::named(llvm::StringRef Scope,
llvm::StringRef Name) {
ensureInitialized();
Index: clang/include/clang/Tooling/Inclusions/StandardLibrary.h
===================================================================
--- clang/include/clang/Tooling/Inclusions/StandardLibrary.h
+++ clang/include/clang/Tooling/Inclusions/StandardLibrary.h
@@ -37,6 +37,7 @@
// "<cstdio>" and "<stdio.h>" (and their symbols) are treated differently.
class Header {
public:
+ static std::vector<Header> all();
// Name should contain the angle brackets, e.g. "<vector>".
static std::optional<Header> named(llvm::StringRef Name);
@@ -63,6 +64,7 @@
// for them.
class Symbol {
public:
+ static std::vector<Symbol> all();
/// \p Scope should have the trailing "::", for example:
/// named("std::chrono::", "system_clock")
static std::optional<Symbol> named(llvm::StringRef Scope,
@@ -73,6 +75,7 @@
}
llvm::StringRef scope() const;
llvm::StringRef name() const;
+ llvm::StringRef qualified_name() const;
// The preferred header for this symbol (e.g. the suggested insertion).
Header header() const;
// Some symbols may be provided by multiple headers.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits