diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp --- a/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp +++ b/clang/lib/Tooling/Inclusions/Stdlib/StandardLibrary.cpp @@ -8,6 +8,7 @@ #include "clang/Tooling/Inclusions/StandardLibrary.h" #include "clang/AST/Decl.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" @@ -17,7 +18,7 @@ static llvm::StringRef *HeaderNames; static std::pair *SymbolNames; -static unsigned *SymbolHeaderIDs; +static llvm::SmallVector *SymbolHeaderIDs; static llvm::DenseMap *HeaderIDs; // Maps symbol name -> Symbol::ID, within a namespace. using NSSymbolMap = llvm::DenseMap; @@ -29,6 +30,8 @@ #include "clang/Tooling/Inclusions/CSymbolMap.inc" #include "clang/Tooling/Inclusions/StdSymbolMap.inc" #undef SYMBOL + // Allocates more space than necessary since multiple SYMBOLs might correspond + // to the same qualified name. SymbolNames = new std::remove_reference_t[SymCount]; SymbolHeaderIDs = new std::remove_reference_t[SymCount]; @@ -46,18 +49,26 @@ return HeaderIDs->try_emplace(Header, HeaderIDs->size()).first->second; }; - auto Add = [&, SymIndex(0)](llvm::StringRef Name, llvm::StringRef NS, - llvm::StringRef HeaderName) mutable { + auto Add = [&, SymIndex(-1)](llvm::StringRef Name, llvm::StringRef NS, + llvm::StringRef HeaderName) mutable { if (NS == "None") NS = ""; + // Determine whether the symbol is new. This relies on symbols being + // ordered alpahbetically in the map. + if (SymIndex >= 0 && SymbolNames[SymIndex].first == NS && + SymbolNames[SymIndex].second == Name) { + // Not a new symbol, use the same index. + } else { + // First symbol or new symbol, increment next available index. + ++SymIndex; + } + SymbolNames[SymIndex] = {NS, Name}; - SymbolHeaderIDs[SymIndex] = AddHeader(HeaderName); + SymbolHeaderIDs[SymIndex].emplace_back(AddHeader(HeaderName)); NSSymbolMap &NSSymbols = AddNS(NS); NSSymbols.try_emplace(Name, SymIndex); - - ++SymIndex; }; #define SYMBOL(Name, NS, Header) Add(#Name, #NS, #Header); #include "clang/Tooling/Inclusions/CSymbolMap.inc" @@ -87,7 +98,7 @@ llvm::StringRef Symbol::scope() const { return SymbolNames[ID].first; } llvm::StringRef Symbol::name() const { return SymbolNames[ID].second; } std::optional Symbol::named(llvm::StringRef Scope, - llvm::StringRef Name) { + llvm::StringRef Name) { ensureInitialized(); if (NSSymbolMap *NSSymbols = NamespaceSymbols->lookup(Scope)) { auto It = NSSymbols->find(Name); @@ -96,9 +107,14 @@ } return std::nullopt; } -Header Symbol::header() const { return Header(SymbolHeaderIDs[ID]); } + +Header Symbol::header() const { return Header(SymbolHeaderIDs[ID][0]); } llvm::SmallVector
Symbol::headers() const { - return {header()}; // FIXME: multiple in case of ambiguity + llvm::SmallVector
result; + for (auto HeaderID : SymbolHeaderIDs[ID]) { + result.emplace_back(Header(HeaderID)); + } + return result; } Recognizer::Recognizer() { ensureInitialized(); } diff --git a/clang/tools/include-mapping/test.py b/clang/tools/include-mapping/test.py --- a/clang/tools/include-mapping/test.py +++ b/clang/tools/include-mapping/test.py @@ -53,7 +53,7 @@ """ - self.assertEqual(_ParseSymbolPage(html, 'foo'), set([''])) + self.assertEqual(_ParseSymbolPage(html, 'foo', ""), set([''])) def testParseSymbolPage_MulHeaders(self): @@ -94,7 +94,7 @@ """ - self.assertEqual(_ParseSymbolPage(html, "foo"), + self.assertEqual(_ParseSymbolPage(html, "foo", ""), set(['', ''])) @@ -121,7 +121,7 @@ """ - self.assertEqual(_ParseSymbolPage(html, "foo"), + self.assertEqual(_ParseSymbolPage(html, "foo", ""), set(['', ''])) def testParseSymbolPage_MulSymbolsInSameTd(self): @@ -145,9 +145,9 @@ """ - self.assertEqual(_ParseSymbolPage(html, "int8_t"), + self.assertEqual(_ParseSymbolPage(html, "int8_t", ""), set([''])) - self.assertEqual(_ParseSymbolPage(html, "int16_t"), + self.assertEqual(_ParseSymbolPage(html, "int16_t", ""), set(['']))