forked from OSchip/llvm-project
72 lines
2.3 KiB
C++
72 lines
2.3 KiB
C++
//===--- Symbol.cpp ----------------------------------------------*- C++-*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Symbol.h"
|
|
|
|
namespace clang {
|
|
namespace clangd {
|
|
|
|
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) {
|
|
if (F == Symbol::None)
|
|
return OS << "None";
|
|
std::string S;
|
|
if (F & Symbol::Deprecated)
|
|
S += "deprecated|";
|
|
if (F & Symbol::IndexedForCodeCompletion)
|
|
S += "completion|";
|
|
return OS << llvm::StringRef(S).rtrim('|');
|
|
}
|
|
|
|
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
|
|
return OS << S.Scope << S.Name;
|
|
}
|
|
|
|
float quality(const Symbol &S) {
|
|
// This avoids a sharp gradient for tail symbols, and also neatly avoids the
|
|
// question of whether 0 references means a bad symbol or missing data.
|
|
if (S.References < 3)
|
|
return 1;
|
|
return std::log(S.References);
|
|
}
|
|
|
|
SymbolSlab::const_iterator SymbolSlab::find(const SymbolID &ID) const {
|
|
auto It = llvm::partition_point(Symbols,
|
|
[&](const Symbol &S) { return S.ID < ID; });
|
|
if (It != Symbols.end() && It->ID == ID)
|
|
return It;
|
|
return Symbols.end();
|
|
}
|
|
|
|
// Copy the underlying data of the symbol into the owned arena.
|
|
static void own(Symbol &S, llvm::UniqueStringSaver &Strings) {
|
|
visitStrings(S, [&](llvm::StringRef &V) { V = Strings.save(V); });
|
|
}
|
|
|
|
void SymbolSlab::Builder::insert(const Symbol &S) {
|
|
own(Symbols[S.ID] = S, UniqueStrings);
|
|
}
|
|
|
|
SymbolSlab SymbolSlab::Builder::build() && {
|
|
// Sort symbols into vector so the slab can binary search over them.
|
|
std::vector<Symbol> SortedSymbols;
|
|
SortedSymbols.reserve(Symbols.size());
|
|
for (auto &Entry : Symbols)
|
|
SortedSymbols.push_back(std::move(Entry.second));
|
|
llvm::sort(SortedSymbols,
|
|
[](const Symbol &L, const Symbol &R) { return L.ID < R.ID; });
|
|
// We may have unused strings from overwritten symbols. Build a new arena.
|
|
llvm::BumpPtrAllocator NewArena;
|
|
llvm::UniqueStringSaver Strings(NewArena);
|
|
for (auto &S : SortedSymbols)
|
|
own(S, Strings);
|
|
return SymbolSlab(std::move(NewArena), std::move(SortedSymbols));
|
|
}
|
|
|
|
} // namespace clangd
|
|
} // namespace clang
|