VitaNuo updated this revision to Diff 493886.
VitaNuo added a comment.

Address review comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142992/new/

https://reviews.llvm.org/D142992

Files:
  clang/include/clang/Tooling/Inclusions/StandardLibrary.h
  clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp

Index: clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
===================================================================
--- clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
+++ clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp
@@ -8,6 +8,8 @@
 
 #include "clang/Tooling/Inclusions/StandardLibrary.h"
 #include "clang/AST/Decl.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/LangStandard.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 
@@ -15,35 +17,54 @@
 namespace tooling {
 namespace stdlib {
 
-static llvm::StringRef *HeaderNames;
-static std::pair<llvm::StringRef, llvm::StringRef> *SymbolNames;
-static unsigned *SymbolHeaderIDs;
-static llvm::DenseMap<llvm::StringRef, unsigned> *HeaderIDs;
 // Maps symbol name -> Symbol::ID, within a namespace.
 using NSSymbolMap = llvm::DenseMap<llvm::StringRef, unsigned>;
-static llvm::DenseMap<llvm::StringRef, NSSymbolMap *> *NamespaceSymbols;
 
-static int initialize() {
+struct SymbolHeaderMapping {
+  llvm::StringRef *HeaderNames;
+  std::pair<llvm::StringRef, llvm::StringRef> *SymbolNames;
+  unsigned *SymbolHeaderIDs;
+  llvm::DenseMap<llvm::StringRef, unsigned> HeaderIDs;
+  llvm::DenseMap<llvm::StringRef, NSSymbolMap *> NamespaceSymbols;
+};
+
+static llvm::DenseMap<Lang, SymbolHeaderMapping *> LanguageMappings;
+
+static int countSymbols(Lang Language) {
   unsigned SymCount = 0;
 #define SYMBOL(Name, NS, Header) ++SymCount;
+  switch (Language) {
+  case Lang::C:
 #include "clang/Tooling/Inclusions/CSymbolMap.inc"
+    break;
+  case Lang::CXX:
 #include "clang/Tooling/Inclusions/StdSymbolMap.inc"
+    break;
+  }
 #undef SYMBOL
-  SymbolNames = new std::remove_reference_t<decltype(*SymbolNames)>[SymCount];
-  SymbolHeaderIDs =
-      new std::remove_reference_t<decltype(*SymbolHeaderIDs)>[SymCount];
-  NamespaceSymbols = new std::remove_reference_t<decltype(*NamespaceSymbols)>;
-  HeaderIDs = new std::remove_reference_t<decltype(*HeaderIDs)>;
+  return SymCount;
+}
+
+static void initialize(Lang Language) {
+  SymbolHeaderMapping *Mapping = new SymbolHeaderMapping();
+  LanguageMappings.try_emplace(Language, Mapping);
+
+  unsigned SymCount = countSymbols(Language);
+  Mapping->SymbolNames =
+      new std::remove_reference_t<decltype(*Mapping->SymbolNames)>[SymCount];
+  Mapping->SymbolHeaderIDs = new std::remove_reference_t<
+      decltype(*Mapping->SymbolHeaderIDs)>[SymCount];
 
   auto AddNS = [&](llvm::StringRef NS) -> NSSymbolMap & {
-    auto R = NamespaceSymbols->try_emplace(NS, nullptr);
+    auto R = Mapping->NamespaceSymbols.try_emplace(NS, nullptr);
     if (R.second)
       R.first->second = new NSSymbolMap();
     return *R.first->second;
   };
 
   auto AddHeader = [&](llvm::StringRef Header) -> unsigned {
-    return HeaderIDs->try_emplace(Header, HeaderIDs->size()).first->second;
+    return Mapping->HeaderIDs.try_emplace(Header, Mapping->HeaderIDs.size())
+        .first->second;
   };
 
   auto Add = [&, SymIndex(0)](llvm::StringRef Name, llvm::StringRef NS,
@@ -51,8 +72,8 @@
     if (NS == "None")
       NS = "";
 
-    SymbolNames[SymIndex] = {NS, Name};
-    SymbolHeaderIDs[SymIndex] = AddHeader(HeaderName);
+    Mapping->SymbolNames[SymIndex] = {NS, Name};
+    Mapping->SymbolHeaderIDs[SymIndex] = AddHeader(HeaderName);
 
     NSSymbolMap &NSSymbols = AddNS(NS);
     NSSymbols.try_emplace(Name, SymIndex);
@@ -60,14 +81,24 @@
     ++SymIndex;
   };
 #define SYMBOL(Name, NS, Header) Add(#Name, #NS, #Header);
+  switch (Language) {
+  case Lang::C:
 #include "clang/Tooling/Inclusions/CSymbolMap.inc"
+    break;
+  case Lang::CXX:
 #include "clang/Tooling/Inclusions/StdSymbolMap.inc"
+    break;
+  }
 #undef SYMBOL
 
-  HeaderNames = new llvm::StringRef[HeaderIDs->size()];
-  for (const auto &E : *HeaderIDs)
-    HeaderNames[E.second] = E.first;
+  Mapping->HeaderNames = new llvm::StringRef[Mapping->HeaderIDs.size()];
+  for (const auto &E : Mapping->HeaderIDs)
+    Mapping->HeaderNames[E.second] = E.first;
+}
 
+static int initialize() {
+  for (Lang Language : AllLangs)
+    initialize(Language);
   return 0;
 }
 
@@ -76,38 +107,62 @@
   (void)Dummy;
 }
 
-std::optional<Header> Header::named(llvm::StringRef Name) {
+static SymbolHeaderMapping *GetMapping(Lang Language) {
+  auto MapIt = LanguageMappings.find(Language);
+  SymbolHeaderMapping *Mapping = MapIt->getSecond();
+  return Mapping;
+}
+
+std::optional<Header> Header::named(llvm::StringRef Name, Lang Language) {
   ensureInitialized();
-  auto It = HeaderIDs->find(Name);
-  if (It == HeaderIDs->end())
+  SymbolHeaderMapping *Mapping = GetMapping(Language);
+  auto It = Mapping->HeaderIDs.find(Name);
+  if (It == Mapping->HeaderIDs.end())
     return std::nullopt;
-  return Header(It->second);
+  return Header(It->second, Language);
+}
+
+llvm::StringRef Header::name() const {
+  SymbolHeaderMapping *Mapping = GetMapping(Language);
+  return Mapping->HeaderNames[ID];
+}
+llvm::StringRef Symbol::scope() const {
+  SymbolHeaderMapping *Mapping = GetMapping(Language);
+  return Mapping->SymbolNames[ID].first;
 }
-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::optional<Symbol> Symbol::named(llvm::StringRef Scope,
-                                     llvm::StringRef Name) {
+llvm::StringRef Symbol::name() const {
+  SymbolHeaderMapping *Mapping = GetMapping(Language);
+  return Mapping->SymbolNames[ID].second;
+}
+std::optional<Symbol> Symbol::named(llvm::StringRef Scope, llvm::StringRef Name,
+                                    Lang Language) {
   ensureInitialized();
-  if (NSSymbolMap *NSSymbols = NamespaceSymbols->lookup(Scope)) {
+  SymbolHeaderMapping *Mapping = GetMapping(Language);
+  if (NSSymbolMap *NSSymbols = Mapping->NamespaceSymbols.lookup(Scope)) {
     auto It = NSSymbols->find(Name);
     if (It != NSSymbols->end())
-      return Symbol(It->second);
+      return Symbol(It->second, Language);
   }
   return std::nullopt;
 }
-Header Symbol::header() const { return Header(SymbolHeaderIDs[ID]); }
+Header Symbol::header() const {
+  SymbolHeaderMapping *Mapping = GetMapping(Language);
+  return Header(Mapping->SymbolHeaderIDs[ID], Language);
+}
 llvm::SmallVector<Header> Symbol::headers() const {
   return {header()}; // FIXME: multiple in case of ambiguity
 }
 
 Recognizer::Recognizer() { ensureInitialized(); }
 
-NSSymbolMap *Recognizer::namespaceSymbols(const NamespaceDecl *D) {
+NSSymbolMap *Recognizer::namespaceSymbols(const NamespaceDecl *D,
+                                          Lang Language) {
   auto It = NamespaceCache.find(D);
   if (It != NamespaceCache.end())
     return It->second;
 
+  SymbolHeaderMapping *Mapping = GetMapping(Language);
+
   NSSymbolMap *Result = [&]() -> NSSymbolMap * {
     if (D && D->isAnonymousNamespace())
       return nullptr;
@@ -117,13 +172,21 @@
          ND = llvm::dyn_cast_or_null<NamespaceDecl>(ND->getParent()))
       if (!ND->isInlineNamespace() && !ND->isAnonymousNamespace())
         Scope = ND->getName().str() + "::" + Scope;
-    return NamespaceSymbols->lookup(Scope);
+    return Mapping->NamespaceSymbols.lookup(Scope);
   }();
   NamespaceCache.try_emplace(D, Result);
   return Result;
 }
 
 std::optional<Symbol> Recognizer::operator()(const Decl *D) {
+  const LangOptions &LangOpts = D->getLangOpts();
+  const LangStandard &Std =
+      LangStandard::getLangStandardForKind(LangOpts.LangStd);
+  Lang RecognizerLang = Lang::C;
+  if (Std.isCPlusPlus()) {
+    RecognizerLang = Lang::CXX;
+  }
+
   // If D is std::vector::iterator, `vector` is the outer symbol to look up.
   // We keep all the candidate DCs as some may turn out to be anon enums.
   // Do this resolution lazily as we may turn out not to have a std namespace.
@@ -134,7 +197,8 @@
       IntermediateDecl.push_back(DC);
     DC = DC->getParent();
   }
-  NSSymbolMap *Symbols = namespaceSymbols(cast_or_null<NamespaceDecl>(DC));
+  NSSymbolMap *Symbols =
+      namespaceSymbols(cast_or_null<NamespaceDecl>(DC), RecognizerLang);
   if (!Symbols)
     return std::nullopt;
 
Index: clang/include/clang/Tooling/Inclusions/StandardLibrary.h
===================================================================
--- clang/include/clang/Tooling/Inclusions/StandardLibrary.h
+++ clang/include/clang/Tooling/Inclusions/StandardLibrary.h
@@ -30,6 +30,9 @@
 namespace stdlib {
 
 class Symbol;
+enum class Lang { C, CXX };
+
+constexpr std::initializer_list<Lang> AllLangs = {Lang::C, Lang::CXX};
 
 // A standard library header, such as <iostream>
 // Lightweight class, in fact just an index into a table.
@@ -38,7 +41,8 @@
 class Header {
 public:
   // Name should contain the angle brackets, e.g. "<vector>".
-  static std::optional<Header> named(llvm::StringRef Name);
+  static std::optional<Header> named(llvm::StringRef Name,
+                                     Lang Language = Lang::CXX);
 
   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Header &H) {
     return OS << H.name();
@@ -46,8 +50,10 @@
   llvm::StringRef name() const;
 
 private:
-  Header(unsigned ID) : ID(ID) {}
+  Header(unsigned ID, Lang Language = Lang::CXX) : ID(ID), Language(Language) {}
   unsigned ID;
+  Lang Language;
+
   friend Symbol;
   friend llvm::DenseMapInfo<Header>;
   friend bool operator==(const Header &L, const Header &R) {
@@ -65,8 +71,8 @@
 public:
   /// \p Scope should have the trailing "::", for example:
   /// named("std::chrono::", "system_clock")
-  static std::optional<Symbol> named(llvm::StringRef Scope,
-                                      llvm::StringRef Name);
+  static std::optional<Symbol>
+  named(llvm::StringRef Scope, llvm::StringRef Name, Lang Language = Lang::CXX);
 
   friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
     return OS << S.scope() << S.name();
@@ -79,8 +85,9 @@
   llvm::SmallVector<Header> headers() const;
 
 private:
-  Symbol(unsigned ID) : ID(ID) {}
+  Symbol(unsigned ID, Lang Language = Lang::CXX) : ID(ID), Language(Language) {}
   unsigned ID;
+  clang::tooling::stdlib::Lang Language;
   friend class Recognizer;
   friend llvm::DenseMapInfo<Symbol>;
   friend bool operator==(const Symbol &L, const Symbol &R) {
@@ -99,7 +106,8 @@
 
 private:
   using NSSymbolMap = llvm::DenseMap<llvm::StringRef, unsigned>;
-  NSSymbolMap *namespaceSymbols(const NamespaceDecl *D);
+  NSSymbolMap *namespaceSymbols(const NamespaceDecl *D,
+                                Lang Language = Lang::CXX);
   llvm::DenseMap<const DeclContext *, NSSymbolMap *> NamespaceCache;
 };
 
@@ -140,6 +148,22 @@
     return LHS == RHS;
   }
 };
+
+template <> struct DenseMapInfo<clang::tooling::stdlib::Lang> {
+  static inline clang::tooling::stdlib::Lang getEmptyKey() {
+    return clang::tooling::stdlib::Lang(-1);
+  }
+  static inline clang::tooling::stdlib::Lang getTombstoneKey() {
+    return clang::tooling::stdlib::Lang(-2);
+  }
+  static unsigned getHashValue(const clang::tooling::stdlib::Lang &S) {
+    return hash_value(S);
+  }
+  static bool isEqual(const clang::tooling::stdlib::Lang &LHS,
+                      const clang::tooling::stdlib::Lang &RHS) {
+    return LHS == RHS;
+  }
+};
 } // namespace llvm
 
 #endif // LLVM_CLANG_TOOLING_INCLUSIONS_STANDARDLIBRARY_H
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to