[clang] e1aaa31 - [Tooling] Add stdlib::Symbol::all() and stdlib::Symbol::qualified_name()

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 3 04:22:33 PST 2023


Author: Sam McCall
Date: 2023-02-03T13:22:26+01:00
New Revision: e1aaa314a46cd303019da117bfd330611d5b7a84

URL: https://github.com/llvm/llvm-project/commit/e1aaa314a46cd303019da117bfd330611d5b7a84
DIFF: https://github.com/llvm/llvm-project/commit/e1aaa314a46cd303019da117bfd330611d5b7a84.diff

LOG: [Tooling] Add stdlib::Symbol::all() and stdlib::Symbol::qualified_name()

These address some remaining reasons to #include StdSymbolMap.inc directly.

Differential Revision: https://reviews.llvm.org/D142467

Added: 
    

Modified: 
    clang/include/clang/Tooling/Inclusions/StandardLibrary.h
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
    clang/test/AST/dump.cpp
    clang/unittests/Tooling/StandardLibraryTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
index beb2f496f51f4..6dc8d6d09390b 100644
--- a/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
+++ b/clang/include/clang/Tooling/Inclusions/StandardLibrary.h
@@ -37,6 +37,7 @@ class Symbol;
 // "<cstdio>" and "<stdio.h>" (and their symbols) are treated 
diff erently.
 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,16 +64,18 @@ class Header {
 // 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,
                                       llvm::StringRef Name);
 
   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
-    return OS << S.scope() << S.name();
+    return OS << S.qualified_name();
   }
   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.

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index b2bece4d9db08..c1af566f76bc5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -17203,6 +17203,10 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
                   SkipBody->Previous = Def;
                   return Def;
                 } else {
+                  llvm::errs() << "got here\n";
+                  Def->dump();
+                  Hidden->dump();
+                  NameLoc.dump(getSourceManager());
                   SkipBody->ShouldSkip = true;
                   SkipBody->Previous = Def;
                   makeMergedDefinitionVisible(Hidden);

diff  --git a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
index 9e5e421fdebcd..cc084c4d56894 100644
--- a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
+++ b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
@@ -15,23 +15,34 @@ namespace clang {
 namespace tooling {
 namespace stdlib {
 
+// Header::ID => header name
 static llvm::StringRef *HeaderNames;
-static std::pair<llvm::StringRef, llvm::StringRef> *SymbolNames;
-static unsigned *SymbolHeaderIDs;
+// Header name => Header::ID
 static llvm::DenseMap<llvm::StringRef, unsigned> *HeaderIDs;
-// Maps symbol name -> Symbol::ID, within a namespace.
+
+static unsigned SymbolCount = 0;
+// Symbol::ID => symbol qualified_name/name/scope
+static struct SymbolName {
+  const char *Data;  // std::vector
+  unsigned ScopeLen; // ~~~~~
+  unsigned NameLen;  //      ~~~~~~
+} *SymbolNames;
+// Symbol name -> Symbol::ID, within a namespace.
 using NSSymbolMap = llvm::DenseMap<llvm::StringRef, unsigned>;
 static llvm::DenseMap<llvm::StringRef, NSSymbolMap *> *NamespaceSymbols;
+// Symbol::ID => Header::ID
+static unsigned *SymbolHeaderIDs;
 
 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 +57,25 @@ static int initialize() {
     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 +92,13 @@ static void ensureInitialized() {
   (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 +107,26 @@ std::optional<Header> Header::named(llvm::StringRef Name) {
   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(SymbolCount);
+  for (unsigned I = 0, E = SymbolCount; 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.ScopeLen, S.NameLen);
+}
+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();

diff  --git a/clang/test/AST/dump.cpp b/clang/test/AST/dump.cpp
index bbd388cbf0957..651a594986f74 100644
--- a/clang/test/AST/dump.cpp
+++ b/clang/test/AST/dump.cpp
@@ -30,7 +30,7 @@ int ga, gb;
 // CHECK-NEXT: | `-VarDecl {{.+}} <col:40> col:40 implicit used omp_out 'char'
 // CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <line:[[@LINE-17]]:37> col:37 fun 'float' combiner 0x{{.+}} initializer 0x{{.+}}
 // CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float'
-// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float'
+// CHECK-NEXT: | | |-BOOM{{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float'
 // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:56> 'float' <LValueToRValue>
 // CHECK-NEXT: | |   `-DeclRefExpr {{.+}} <col:56> 'float' lvalue Var {{.+}} 'omp_in' 'float'
 // CHECK-NEXT: | |-BinaryOperator {{.+}} <col:87, col:98> 'float' '+'

diff  --git a/clang/unittests/Tooling/StandardLibraryTest.cpp b/clang/unittests/Tooling/StandardLibraryTest.cpp
index 01dc58c9ba481..f8d9b6a5437d2 100644
--- a/clang/unittests/Tooling/StandardLibraryTest.cpp
+++ b/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 @@ const NamedDecl &lookup(TestAST &AST, llvm::StringRef Name) {
 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) {


        


More information about the cfe-commits mailing list