//===-- Mangled.cpp -------------------------------------------------------===// // // 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 "lldb/Core/Mangled.h" #include "lldb/Core/DataFileCache.h" #include "lldb/Core/RichManglingContext.h" #include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataEncoder.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Support/Compiler.h" #include <mutex> #include <string> #include <string_view> #include <utility> #include <cstdlib> #include <cstring> usingnamespacelldb_private; static inline bool cstring_is_mangled(llvm::StringRef s) { … } #pragma mark Mangled Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) { … } Mangled::Mangled(ConstString s) : … { … } Mangled::Mangled(llvm::StringRef name) { … } // Convert to bool operator. This allows code to check any Mangled objects // to see if they contain anything valid using code such as: // // Mangled mangled(...); // if (mangled) // { ... operator bool() // Clear the mangled and demangled values. void Mangled::Clear() { … } // Compare the string values. int Mangled::Compare(const Mangled &a, const Mangled &b) { … } void Mangled::SetValue(ConstString name) { … } // Local helpers for different demangling implementations. static char *GetMSVCDemangledStr(llvm::StringRef M) { … } static char *GetItaniumDemangledStr(const char *M) { … } static char *GetRustV0DemangledStr(llvm::StringRef M) { … } static char *GetDLangDemangledStr(llvm::StringRef M) { … } // Explicit demangling for scheduled requests during batch processing. This // makes use of ItaniumPartialDemangler's rich demangle info bool Mangled::GetRichManglingInfo(RichManglingContext &context, SkipMangledNameFn *skip_mangled_name) { … } // Generate the demangled name on demand using this accessor. Code in this // class will need to use this accessor if it wishes to decode the demangled // name. The result is cached and will be kept until a new string value is // supplied to this object, or until the end of the object's lifetime. ConstString Mangled::GetDemangledName() const { … } ConstString Mangled::GetDisplayDemangledName() const { … } bool Mangled::NameMatches(const RegularExpression ®ex) const { … } // Get the demangled name if there is one, else return the mangled name. ConstString Mangled::GetName(Mangled::NamePreference preference) const { … } // Dump a Mangled object to stream "s". We don't force our demangled name to be // computed currently (we don't use the accessor). void Mangled::Dump(Stream *s) const { … } // Dumps a debug version of this string with extra object and state information // to stream "s". void Mangled::DumpDebug(Stream *s) const { … } // Return the size in byte that this object takes in memory. The size includes // the size of the objects it owns, and not the strings that it references // because they are shared strings. size_t Mangled::MemorySize() const { … } // We "guess" the language because we can't determine a symbol's language from // it's name. For example, a Pascal symbol can be mangled using the C++ // Itanium scheme, and defined in a compilation unit within the same module as // other C++ units. In addition, different targets could have different ways // of mangling names from a given language, likewise the compilation units // within those targets. lldb::LanguageType Mangled::GuessLanguage() const { … } // Dump OBJ to the supplied stream S. Stream &operator<<(Stream &s, const Mangled &obj) { … } // When encoding Mangled objects we can get away with encoding as little // information as is required. The enumeration below helps us to efficiently // encode Mangled objects. enum MangledEncoding { … }; bool Mangled::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const StringTableReader &strtab) { … } /// The encoding format for the Mangled object is as follows: /// /// uint8_t encoding; /// char str1[]; (only if DemangledOnly, MangledOnly) /// char str2[]; (only if MangledAndDemangled) /// /// The strings are stored as NULL terminated UTF8 strings and str1 and str2 /// are only saved if we need them based on the encoding. /// /// Some mangled names have a mangled name that can be demangled by the built /// in demanglers. These kinds of mangled objects know when the mangled and /// demangled names are the counterparts for each other. This is done because /// demangling is very expensive and avoiding demangling the same name twice /// saves us a lot of compute time. For these kinds of names we only need to /// save the mangled name and have the encoding set to "MangledOnly". /// /// If a mangled obejct has only a demangled name, then we save only that string /// and have the encoding set to "DemangledOnly". /// /// Some mangled objects have both mangled and demangled names, but the /// demangled name can not be computed from the mangled name. This is often used /// for runtime named, like Objective C runtime V2 and V3 names. Both these /// names must be saved and the encoding is set to "MangledAndDemangled". /// /// For a Mangled object with no names, we only need to set the encoding to /// "Empty" and not store any string values. void Mangled::Encode(DataEncoder &file, ConstStringTable &strtab) const { … }