LLDB mainline
Mangled.cpp
Go to the documentation of this file.
1//===-- Mangled.cpp -------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/Mangled.h"
10
18#include "lldb/Utility/Log.h"
20#include "lldb/Utility/Stream.h"
22
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/Demangle/Demangle.h"
26#include "llvm/Support/Compiler.h"
27
28#include <mutex>
29#include <string>
30#include <string_view>
31#include <utility>
32
33#include <cstdlib>
34#include <cstring>
35using namespace lldb_private;
36
37#pragma mark Mangled
38
39bool Mangled::IsMangledName(llvm::StringRef name) {
41}
42
44 if (name.empty())
46
47 if (name.starts_with("?"))
49
50 if (name.starts_with("_R"))
52
53 if (name.starts_with("_D")) {
54 // A dlang mangled name begins with `_D`, followed by a numeric length. One
55 // known exception is the symbol `_Dmain`.
56 // See `SymbolName` and `LName` in
57 // https://dlang.org/spec/abi.html#name_mangling
58 llvm::StringRef buf = name.drop_front(2);
59 if (!buf.empty() && (llvm::isDigit(buf.front()) || name == "_Dmain"))
61 }
62
63 if (name.starts_with("_Z"))
65
66 // ___Z is a clang extension of block invocations
67 if (name.starts_with("___Z"))
69
70 // Swift's older style of mangling used "_T" as a mangling prefix. This can
71 // lead to false positives with other symbols that just so happen to start
72 // with "_T". To minimize the chance of that happening, we only return true
73 // for select old-style swift mangled names. The known cases are ObjC classes
74 // and protocols. Classes are either prefixed with "_TtC" or "_TtGC".
75 // Protocols are prefixed with "_TtP".
76 if (name.starts_with("_TtC") || name.starts_with("_TtGC") ||
77 name.starts_with("_TtP"))
79
80 // Swift 4.2 used "$S" and "_$S".
81 // Swift 5 and onward uses "$s" and "_$s".
82 // Swift also uses "@__swiftmacro_" as a prefix for mangling filenames.
83 // Embedded Swift introduced "$e" and "_$e" as Swift mangling prefixes.
84 if (name.starts_with("$S") || name.starts_with("_$S") ||
85 name.starts_with("$s") || name.starts_with("_$s") ||
86 name.starts_with("$e") || name.starts_with("_$e") ||
87 name.starts_with("@__swiftmacro_"))
89
91}
92
97
98Mangled::Mangled(llvm::StringRef name) {
99 if (!name.empty())
100 SetValue(ConstString(name));
101}
102
103// Convert to bool operator. This allows code to check any Mangled objects
104// to see if they contain anything valid using code such as:
105//
106// Mangled mangled(...);
107// if (mangled)
108// { ...
109Mangled::operator bool() const { return m_mangled || m_demangled; }
110
111// Clear the mangled and demangled values.
113 m_mangled.Clear();
114 m_demangled.Clear();
115 m_demangled_info.reset();
116}
117
118// Compare the string values.
123
125 if (name) {
126 if (IsMangledName(name.GetStringRef())) {
127 m_demangled.Clear();
128 m_mangled = name;
129 m_demangled_info.reset();
130 } else {
131 m_demangled = name;
132 m_mangled.Clear();
133 m_demangled_info.reset();
134 }
135 } else {
136 m_demangled.Clear();
137 m_mangled.Clear();
138 m_demangled_info.reset();
139 }
140}
141
142// Local helpers for different demangling implementations.
143static char *GetMSVCDemangledStr(llvm::StringRef M) {
144 char *demangled_cstr = llvm::microsoftDemangle(
145 M, nullptr, nullptr,
146 llvm::MSDemangleFlags(
147 llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention |
148 llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType));
149
150 if (Log *log = GetLog(LLDBLog::Demangle)) {
151 if (demangled_cstr && demangled_cstr[0])
152 LLDB_LOGF(log, "demangled msvc: %s -> \"%s\"", M.data(), demangled_cstr);
153 else
154 LLDB_LOGF(log, "demangled msvc: %s -> error", M.data());
155 }
156
157 return demangled_cstr;
158}
159
160static std::pair<char *, DemangledNameInfo>
162 char *demangled_cstr = nullptr;
163
165 llvm::ItaniumPartialDemangler ipd;
166 bool err = ipd.partialDemangle(M);
167 if (!err) {
168 // Default buffer and size (OutputBuffer will realloc in case it's too
169 // small).
170 size_t demangled_size = 80;
171 demangled_cstr = static_cast<char *>(std::malloc(80));
172
173 TrackingOutputBuffer OB(demangled_cstr, demangled_size);
174 demangled_cstr = ipd.finishDemangle(&OB);
175 info = std::move(OB.NameInfo);
176
177 assert(demangled_cstr &&
178 "finishDemangle must always succeed if partialDemangle did");
179 assert(demangled_cstr[OB.getCurrentPosition() - 1] == '\0' &&
180 "Expected demangled_size to return length including trailing null");
181 }
182
183 if (Log *log = GetLog(LLDBLog::Demangle)) {
184 if (demangled_cstr)
185 LLDB_LOGF(log, "demangled itanium: %s -> \"%s\"", M, demangled_cstr);
186 else
187 LLDB_LOGF(log, "demangled itanium: %s -> error: failed to demangle", M);
188
189 if (!info.hasBasename())
190 LLDB_LOGF(log,
191 "demangled itanium: %s -> error: failed to retrieve name info",
192 M);
193 }
194
195 return {demangled_cstr, std::move(info)};
196}
197
198static char *GetRustV0DemangledStr(llvm::StringRef M) {
199 char *demangled_cstr = llvm::rustDemangle(M);
200
201 if (Log *log = GetLog(LLDBLog::Demangle)) {
202 if (demangled_cstr && demangled_cstr[0])
203 LLDB_LOG(log, "demangled rustv0: {0} -> \"{1}\"", M, demangled_cstr);
204 else
205 LLDB_LOG(log, "demangled rustv0: {0} -> error: failed to demangle",
206 static_cast<std::string_view>(M));
207 }
208
209 return demangled_cstr;
210}
211
212static char *GetDLangDemangledStr(llvm::StringRef M) {
213 char *demangled_cstr = llvm::dlangDemangle(M);
214
215 if (Log *log = GetLog(LLDBLog::Demangle)) {
216 if (demangled_cstr && demangled_cstr[0])
217 LLDB_LOG(log, "demangled dlang: {0} -> \"{1}\"", M, demangled_cstr);
218 else
219 LLDB_LOG(log, "demangled dlang: {0} -> error: failed to demangle",
220 static_cast<std::string_view>(M));
221 }
222
223 return demangled_cstr;
224}
225
226// Explicit demangling for scheduled requests during batch processing. This
227// makes use of ItaniumPartialDemangler's rich demangle info
229 SkipMangledNameFn *skip_mangled_name) {
230 // Others are not meant to arrive here. ObjC names or C's main() for example
231 // have their names stored in m_demangled, while m_mangled is empty.
232 assert(m_mangled);
233
234 // Check whether or not we are interested in this name at all.
235 ManglingScheme scheme = GetManglingScheme(m_mangled.GetStringRef());
236 if (skip_mangled_name && skip_mangled_name(m_mangled.GetStringRef(), scheme))
237 return false;
238
239 switch (scheme) {
241 // The current mangled_name_filter would allow llvm_unreachable here.
242 return false;
243
245 // We want the rich mangling info here, so we don't care whether or not
246 // there is a demangled string in the pool already.
247 return context.FromItaniumName(m_mangled);
248
249 case eManglingSchemeMSVC: {
250 // We have no rich mangling for MSVC-mangled names yet, so first try to
251 // demangle it if necessary.
252 if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) {
253 if (char *d = GetMSVCDemangledStr(m_mangled)) {
254 // Without the rich mangling info we have to demangle the full name.
255 // Copy it to string pool and connect the counterparts to accelerate
256 // later access in GetDemangledName().
257 m_demangled.SetStringWithMangledCounterpart(llvm::StringRef(d),
258 m_mangled);
259 ::free(d);
260 } else {
261 m_demangled.SetCString("");
262 }
263 }
264
265 if (m_demangled.IsEmpty()) {
266 // Cannot demangle it, so don't try parsing.
267 return false;
268 } else {
269 // Demangled successfully, we can try and parse it with
270 // CPlusPlusLanguage::CxxMethodName.
271 return context.FromCxxMethodName(m_demangled);
272 }
273 }
274
276 case eManglingSchemeD:
278 // Rich demangling scheme is not supported
279 return false;
280 }
281 llvm_unreachable("Fully covered switch above!");
282}
283
285 return GetDemangledNameImpl(/*force=*/false);
286}
287
289 if (!m_demangled_info)
290 GetDemangledNameImpl(/*force=*/true);
291 return m_demangled_info.get();
292}
293
294// Generate the demangled name on demand using this accessor. Code in this
295// class will need to use this accessor if it wishes to decode the demangled
296// name. The result is cached and will be kept until a new string value is
297// supplied to this object, or until the end of the object's lifetime.
299 if (!m_mangled)
300 return m_demangled;
301
302 // Re-use previously demangled names.
303 if (!force && !m_demangled.IsNull())
304 return m_demangled;
305
306 if (!force && m_mangled.GetMangledCounterpart(m_demangled) &&
307 !m_demangled.IsNull())
308 return m_demangled;
309
310 // We didn't already mangle this name, demangle it and if all goes well
311 // add it to our map.
312 char *demangled_name = nullptr;
313 switch (GetManglingScheme(m_mangled.GetStringRef())) {
315 demangled_name = GetMSVCDemangledStr(m_mangled);
316 break;
318 std::pair<char *, DemangledNameInfo> demangled =
319 GetItaniumDemangledStr(m_mangled.GetCString());
320 demangled_name = demangled.first;
322 std::make_unique<DemangledNameInfo>(std::move(demangled.second));
323 break;
324 }
326 demangled_name = GetRustV0DemangledStr(m_mangled);
327 break;
328 case eManglingSchemeD:
329 demangled_name = GetDLangDemangledStr(m_mangled);
330 break;
332 // Demangling a swift name requires the swift compiler. This is
333 // explicitly unsupported on llvm.org.
334 break;
336 // Don't bother demangling anything that isn't mangled.
337 break;
338 }
339
340 if (demangled_name) {
341 m_demangled.SetStringWithMangledCounterpart(demangled_name, m_mangled);
342 free(demangled_name);
343 }
344
345 if (m_demangled.IsNull()) {
346 // Set the demangled string to the empty string to indicate we tried to
347 // parse it once and failed.
348 m_demangled.SetCString("");
349 }
350
351 return m_demangled;
352}
353
356 return lang->GetDisplayDemangledName(*this);
357 return GetDemangledName();
358}
359
360bool Mangled::NameMatches(const RegularExpression &regex) const {
361 if (m_mangled && regex.Execute(m_mangled.GetStringRef()))
362 return true;
363
364 ConstString demangled = GetDemangledName();
365 return demangled && regex.Execute(demangled.GetStringRef());
366}
367
368// Get the demangled name if there is one, else return the mangled name.
370 if (preference == ePreferMangled && m_mangled)
371 return m_mangled;
372
373 // Call the accessor to make sure we get a demangled name in case it hasn't
374 // been demangled yet...
375 ConstString demangled = GetDemangledName();
376
377 if (preference == ePreferDemangledWithoutArguments) {
379 return lang->GetDemangledFunctionNameWithoutArguments(*this);
380 }
381 }
382 if (preference == ePreferDemangled) {
383 if (demangled)
384 return demangled;
385 return m_mangled;
386 }
387 return demangled;
388}
389
390// Dump a Mangled object to stream "s". We don't force our demangled name to be
391// computed currently (we don't use the accessor).
392void Mangled::Dump(Stream *s) const {
393 if (m_mangled) {
394 *s << ", mangled = " << m_mangled;
395 }
396 if (m_demangled)
397 s->Format(", demangled = {0}", m_demangled.GetStringRef());
398}
399
400// Dumps a debug version of this string with extra object and state information
401// to stream "s".
403 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void *) * 2),
404 static_cast<const void *>(this));
405 m_mangled.DumpDebug(s);
406 s->Printf(", demangled = ");
407 m_demangled.DumpDebug(s);
408}
409
410// We "guess" the language because we can't determine a symbol's language from
411// it's name. For example, a Pascal symbol can be mangled using the C++
412// Itanium scheme, and defined in a compilation unit within the same module as
413// other C++ units. In addition, different targets could have different ways
414// of mangling names from a given language, likewise the compilation units
415// within those targets.
418 // Ask each language plugin to check if the mangled name belongs to it.
419 Language::ForEach([this, &result](Language *l) {
420 if (l->SymbolNameFitsToLanguage(*this)) {
421 result = l->GetLanguageType();
423 }
425 });
426 return result;
427}
428
429// Dump OBJ to the supplied stream S.
430Stream &operator<<(Stream &s, const Mangled &obj) {
431 if (obj.GetMangledName())
432 s << "mangled = '" << obj.GetMangledName() << "'";
433
434 ConstString demangled = obj.GetDemangledName();
435 if (demangled)
436 s << ", demangled = '" << demangled << '\'';
437 else
438 s << ", demangled = <error>";
439 return s;
440}
441
442// When encoding Mangled objects we can get away with encoding as little
443// information as is required. The enumeration below helps us to efficiently
444// encode Mangled objects.
446 /// If the Mangled object has neither a mangled name or demangled name we can
447 /// encode the object with one zero byte using the Empty enumeration.
448 Empty = 0u,
449 /// If the Mangled object has only a demangled name and no mangled named, we
450 /// can encode only the demangled name.
452 /// If the mangle name can calculate the demangled name (it is the
453 /// mangled/demangled counterpart), then we only need to encode the mangled
454 /// name as the demangled name can be recomputed.
456 /// If we have a Mangled object with two different names that are not related
457 /// then we need to save both strings. This can happen if we have a name that
458 /// isn't a true mangled name, but we want to be able to lookup a symbol by
459 /// name and type in the symbol table. We do this for Objective C symbols like
460 /// "OBJC_CLASS_$_NSValue" where the mangled named will be set to
461 /// "OBJC_CLASS_$_NSValue" and the demangled name will be manually set to
462 /// "NSValue". If we tried to demangled the name "OBJC_CLASS_$_NSValue" it
463 /// would fail, but in these cases we want these unrelated names to be
464 /// preserved.
466};
467
468bool Mangled::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
469 const StringTableReader &strtab) {
470 m_mangled.Clear();
471 m_demangled.Clear();
472 m_demangled_info.reset();
473 MangledEncoding encoding = (MangledEncoding)data.GetU8(offset_ptr);
474 switch (encoding) {
475 case Empty:
476 return true;
477
478 case DemangledOnly:
479 m_demangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
480 return true;
481
482 case MangledOnly:
483 m_mangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
484 return true;
485
487 m_mangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
488 m_demangled.SetString(strtab.Get(data.GetU32(offset_ptr)));
489 return true;
490 }
491 return false;
492}
493/// The encoding format for the Mangled object is as follows:
494///
495/// uint8_t encoding;
496/// char str1[]; (only if DemangledOnly, MangledOnly)
497/// char str2[]; (only if MangledAndDemangled)
498///
499/// The strings are stored as NULL terminated UTF8 strings and str1 and str2
500/// are only saved if we need them based on the encoding.
501///
502/// Some mangled names have a mangled name that can be demangled by the built
503/// in demanglers. These kinds of mangled objects know when the mangled and
504/// demangled names are the counterparts for each other. This is done because
505/// demangling is very expensive and avoiding demangling the same name twice
506/// saves us a lot of compute time. For these kinds of names we only need to
507/// save the mangled name and have the encoding set to "MangledOnly".
508///
509/// If a mangled object has only a demangled name, then we save only that string
510/// and have the encoding set to "DemangledOnly".
511///
512/// Some mangled objects have both mangled and demangled names, but the
513/// demangled name can not be computed from the mangled name. This is often used
514/// for runtime named, like Objective C runtime V2 and V3 names. Both these
515/// names must be saved and the encoding is set to "MangledAndDemangled".
516///
517/// For a Mangled object with no names, we only need to set the encoding to
518/// "Empty" and not store any string values.
519void Mangled::Encode(DataEncoder &file, ConstStringTable &strtab) const {
520 MangledEncoding encoding = Empty;
521 if (m_mangled) {
522 encoding = MangledOnly;
523 if (m_demangled) {
524 // We have both mangled and demangled names. If the demangled name is the
525 // counterpart of the mangled name, then we only need to save the mangled
526 // name. If they are different, we need to save both.
527 ConstString s;
528 if (!(m_mangled.GetMangledCounterpart(s) && s == m_demangled))
529 encoding = MangledAndDemangled;
530 }
531 } else if (m_demangled) {
532 encoding = DemangledOnly;
533 }
534 file.AppendU8(encoding);
535 switch (encoding) {
536 case Empty:
537 break;
538 case DemangledOnly:
539 file.AppendU32(strtab.Add(m_demangled));
540 break;
541 case MangledOnly:
542 file.AppendU32(strtab.Add(m_mangled));
543 break;
545 file.AppendU32(strtab.Add(m_mangled));
546 file.AppendU32(strtab.Add(m_demangled));
547 break;
548 }
549}
550
552 const auto *demangled_info = GetDemangledInfo();
553 if (demangled_info == nullptr)
554 return {};
555
556 ConstString demangled_name = GetDemangledName();
557 if (!demangled_name)
558 return {};
559
560 const auto &range = demangled_info->BasenameRange;
561 return ConstString(
562 demangled_name.GetStringRef().slice(range.first, range.second));
563}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:376
#define LLDB_LOGF(log,...)
Definition Log.h:390
static char * GetDLangDemangledStr(llvm::StringRef M)
Definition Mangled.cpp:212
static char * GetRustV0DemangledStr(llvm::StringRef M)
Definition Mangled.cpp:198
static std::pair< char *, DemangledNameInfo > GetItaniumDemangledStr(const char *M)
Definition Mangled.cpp:161
MangledEncoding
Definition Mangled.cpp:445
@ MangledAndDemangled
If we have a Mangled object with two different names that are not related then we need to save both s...
Definition Mangled.cpp:465
@ DemangledOnly
If the Mangled object has only a demangled name and no mangled named, we can encode only the demangle...
Definition Mangled.cpp:451
@ Empty
If the Mangled object has neither a mangled name or demangled name we can encode the object with one ...
Definition Mangled.cpp:448
@ MangledOnly
If the mangle name can calculate the demangled name (it is the mangled/demangled counterpart),...
Definition Mangled.cpp:455
static char * GetMSVCDemangledStr(llvm::StringRef M)
Definition Mangled.cpp:143
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.
Definition ConstString.h:40
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.
Definition DataEncoder.h:42
void AppendU32(uint32_t value)
void AppendU8(uint8_t value)
Append a unsigned integer to the end of the owned data.
An data extractor class.
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
uint8_t GetU8(lldb::offset_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
static void ForEach(llvm::function_ref< IterationAction(Language *)> callback)
Definition Language.cpp:127
static Language * FindPlugin(lldb::LanguageType language)
Definition Language.cpp:84
A class that handles mangled names.
Definition Mangled.h:34
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
Definition Mangled.cpp:519
bool NameMatches(ConstString name) const
Check if "name" matches either the mangled or demangled name.
Definition Mangled.h:194
static int Compare(const Mangled &lhs, const Mangled &rhs)
Compare the mangled string values.
Definition Mangled.cpp:119
static bool IsMangledName(llvm::StringRef name)
Definition Mangled.cpp:39
@ ePreferDemangledWithoutArguments
Definition Mangled.h:39
Mangled()=default
Default constructor.
void DumpDebug(Stream *s) const
Dump a debug description of this object to a Stream s.
Definition Mangled.cpp:402
ConstString GetMangledName() const
Mangled name get accessor.
Definition Mangled.h:174
bool GetRichManglingInfo(RichManglingContext &context, SkipMangledNameFn *skip_mangled_name)
Get rich mangling information.
Definition Mangled.cpp:228
ConstString GetDemangledName() const
Demangled name get accessor.
Definition Mangled.cpp:284
ConstString GetBaseName() const
Compute the base name (without namespace/class qualifiers) from the demangled name.
Definition Mangled.cpp:551
std::unique_ptr< DemangledNameInfo > m_demangled_info
If available, holds information about where in m_demangled certain parts of the name (e....
Definition Mangled.h:323
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition Mangled.cpp:416
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const StringTableReader &strtab)
Decode a serialized version of this object from data.
Definition Mangled.cpp:468
bool(llvm::StringRef, ManglingScheme) SkipMangledNameFn
Function signature for filtering mangled names.
Definition Mangled.h:227
void SetValue(ConstString name)
Set the string value in this object.
Definition Mangled.cpp:124
const DemangledNameInfo * GetDemangledInfo() const
Retrieve DemangledNameInfo of the demangled name held by this object.
Definition Mangled.cpp:288
ConstString GetName(NamePreference preference=ePreferDemangled) const
Best name get accessor.
Definition Mangled.cpp:369
static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef name)
Try to identify the mangling scheme used.
Definition Mangled.cpp:43
ConstString GetDemangledNameImpl(bool force) const
If force is false, this function will re-use the previously demangled name (if any).
Definition Mangled.cpp:298
ConstString m_mangled
The mangled version of the name.
Definition Mangled.h:315
ConstString m_demangled
Mutable so we can get it on demand with a const version of this object.
Definition Mangled.h:319
ConstString GetDisplayDemangledName() const
Display demangled name get accessor.
Definition Mangled.cpp:354
void Dump(Stream *s) const
Dump a description of this object to a Stream s.
Definition Mangled.cpp:392
void Clear()
Clear the mangled and demangled values.
Definition Mangled.cpp:112
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...
Uniform wrapper for access to rich mangling information from different providers.
bool FromItaniumName(ConstString mangled)
Use the ItaniumPartialDemangler to obtain rich mangling information from the given mangled name.
bool FromCxxMethodName(ConstString demangled)
Use the legacy language parser implementation to obtain rich mangling information from the given dema...
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
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.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:339
Stream & operator<<(Stream &s, const Mangled &obj)
uint64_t offset_t
Definition lldb-types.h:85
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
Stores information about where certain portions of a demangled function name begin and end.
bool hasBasename() const
Returns true if this object holds a valid basename range.
An OutputBuffer which keeps a record of where certain parts of a demangled name begin/end (e....
DemangledNameInfo NameInfo
Holds information about the demangled name that is being printed into this buffer.