20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SmallString.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringRef.h"
34struct RegisteredManglingScheme {
35 llvm::SmallVector<llvm::SmallString<16>, 12> prefixes;
42class ManglingSchemeRegistry {
56 mutable std::mutex m_mutex;
59 std::vector<RegisteredManglingScheme> m_schemes;
66 static ManglingSchemeRegistry *g_registry =
new ManglingSchemeRegistry();
77[[maybe_unused]]
static bool
79 llvm::ArrayRef<RegisteredManglingScheme> schemes) {
80 for (
const RegisteredManglingScheme &scheme : schemes) {
83 for (llvm::StringRef prefix : prefixes)
84 for (llvm::StringRef other : scheme.prefixes)
85 if (prefix.starts_with(other) || other.starts_with(prefix))
92ManglingSchemeRegistry::Register(llvm::ArrayRef<llvm::StringRef> prefixes,
95 std::lock_guard<std::mutex> guard(m_mutex);
97 llvm::find_if(m_schemes, [&](
const RegisteredManglingScheme &scheme) {
98 return scheme.language == language && scheme.matches == matches &&
99 llvm::equal(scheme.prefixes, prefixes);
101 const size_t index = std::distance(m_schemes.begin(), it);
103 if (it == m_schemes.end()) {
106 assert(!full &&
"too many mangling schemes");
110 "mangling scheme prefixes overlap");
111 RegisteredManglingScheme &scheme = m_schemes.emplace_back();
112 scheme.prefixes.assign(prefixes.begin(), prefixes.end());
113 scheme.matches = matches;
114 scheme.language = language;
116 m_schemes[index].active =
true;
125 if (index >= m_schemes.size())
131 std::lock_guard<std::mutex> guard(m_mutex);
132 if (std::optional<size_t> index = GetIndex(scheme))
133 m_schemes[*index].active =
false;
138 std::lock_guard<std::mutex> guard(m_mutex);
139 if (std::optional<size_t> index = GetIndex(scheme))
140 return m_schemes[*index].language;
145ManglingSchemeRegistry::Find(llvm::StringRef name)
const {
146 std::lock_guard<std::mutex> guard(m_mutex);
147 for (
auto [index, scheme] : llvm::enumerate(m_schemes)) {
148 if (!scheme.active ||
149 !llvm::any_of(scheme.prefixes, [&](llvm::StringRef prefix) {
150 return name.starts_with(prefix);
155 if (scheme.matches && !scheme.matches(name))
255 if (!demangled.
name.empty())
284 return lang->GetDisplayDemangledName(*
this);
307 return lang->GetDemangledFunctionNameWithoutArguments(*
this);
331 s->
Printf(
"%*p: Mangled mangled = ",
static_cast<int>(
sizeof(
void *) * 2),
332 static_cast<const void *
>(
this));
356 if (
l->SymbolNameFitsToLanguage(*
this)) {
357 result =
l->GetLanguageType();
372 s <<
", demangled = '" << demangled <<
'\'';
374 s <<
", demangled = <error>";
496 const auto &range = demangled_info->BasenameRange;
498 demangled_name.
GetStringRef().slice(range.first, range.second));
static Mangled::ManglingScheme SchemeForIndex(size_t index)
static ManglingSchemeRegistry & GetManglingSchemeRegistry()
@ MangledAndDemangled
If we have a Mangled object with two different names that are not related then we need to save both s...
@ DemangledOnly
If the Mangled object has only a demangled name and no mangled named, we can encode only the demangle...
@ Empty
If the Mangled object has neither a mangled name or demangled name we can encode the object with one ...
@ MangledOnly
If the mangle name can calculate the demangled name (it is the mangled/demangled counterpart),...
static bool OverlapsActiveScheme(llvm::ArrayRef< llvm::StringRef > prefixes, llvm::ArrayRef< RegisteredManglingScheme > schemes)
Returns true if a name could start with both one of prefixes and a prefix of one of the active scheme...
Many cache files require string tables to store data efficiently.
uint32_t Add(ConstString s)
Add a string into the string table.
A uniqued constant string class.
static int Compare(ConstString lhs, ConstString rhs, const bool case_sensitive=true)
Compare two string objects.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
An binary data encoding class.
void AppendU32(uint32_t value)
void AppendU8(uint8_t value)
Append a unsigned integer to the end of the owned data.
virtual DemangledName DemangleSymbol(ConstString mangled, Mangled::ManglingScheme scheme, const DemangleOptions &options) const
Demangle mangled, a name mangled with scheme, a scheme that this language registered with Mangled::Re...
static void ForEach(llvm::function_ref< IterationAction(Language *)> callback)
static Language * FindPlugin(lldb::LanguageType language)
static Language * FindPluginForManglingScheme(Mangled::ManglingScheme scheme)
Returns the Language that registered scheme with Mangled::RegisterManglingScheme(),...
A class that handles mangled names.
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
bool NameMatches(ConstString name) const
Check if "name" matches either the mangled or demangled name.
static int Compare(const Mangled &lhs, const Mangled &rhs)
Compare the mangled string values.
static ManglingScheme RegisterManglingScheme(llvm::ArrayRef< llvm::StringRef > prefixes, lldb::LanguageType language, ManglingSchemeMatcher matches=nullptr)
Register a mangling scheme for language.
static bool IsMangledName(llvm::StringRef name)
@ ePreferDemangledWithoutArguments
Mangled()=default
Default constructor.
void DumpDebug(Stream *s) const
Dump a debug description of this object to a Stream s.
std::optional< DemangledNameInfo > ComputeDemangledInfo() const
Compute the DemangledNameInfo of the demangled name.
ConstString GetMangledName() const
Mangled name get accessor.
ConstString GetDemangledName() const
Demangled name get accessor.
ConstString GetBaseName() const
Compute the base name (without namespace/class qualifiers) from the demangled name.
bool(*)(llvm::StringRef name) ManglingSchemeMatcher
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const StringTableReader &strtab)
Decode a serialized version of this object from data.
static constexpr size_t g_num_mangling_schemes
The number of possible mangling schemes, which sizes the tables that are indexed by ManglingScheme.
static lldb::LanguageType GetLanguageForManglingScheme(ManglingScheme scheme)
Returns the language that registered scheme, or eLanguageTypeUnknown if no language did.
void SetValue(ConstString name)
Set the string value in this object.
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef name)
Try to identify the mangling scheme used.
ConstString m_mangled
The mangled version of the name.
@ eFirstRegisteredManglingScheme
ConstString m_demangled
Mutable so we can get it on demand with a const version of this object.
ConstString GetDisplayDemangledName() const
Display demangled name get accessor.
void Dump(Stream *s) const
Dump a description of this object to a Stream s.
static void UnregisterManglingScheme(ManglingScheme scheme)
Stop recognizing the names of scheme, a scheme returned by RegisterManglingScheme().
void Clear()
Clear the mangled and demangled values.
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Many cache files require string tables to store data efficiently.
llvm::StringRef Get(uint32_t offset) const
A class that represents a running process on the host machine.
Stream & operator<<(Stream &s, const Mangled &obj)
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
How to demangle a name in DemangleSymbol().
bool want_info
Whether to compute the DemangledNameInfo too.
A demangled name and, if requested, where its parts begin and end.
std::optional< DemangledNameInfo > info
Only computed if DemangleOptions::want_info is true.
std::string name
Empty if the name couldn't be demangled.