aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Demangle
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Demangle')
-rw-r--r--llvm/lib/Demangle/DLangDemangle.cpp379
-rw-r--r--llvm/lib/Demangle/Demangle.cpp44
-rw-r--r--llvm/lib/Demangle/ItaniumDemangle.cpp39
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp570
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangleNodes.cpp4
-rw-r--r--llvm/lib/Demangle/RustDemangle.cpp59
6 files changed, 585 insertions, 510 deletions
diff --git a/llvm/lib/Demangle/DLangDemangle.cpp b/llvm/lib/Demangle/DLangDemangle.cpp
index b747b0f9cc67..8856302be6dd 100644
--- a/llvm/lib/Demangle/DLangDemangle.cpp
+++ b/llvm/lib/Demangle/DLangDemangle.cpp
@@ -14,16 +14,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/Demangle/Demangle.h"
-#include "llvm/Demangle/StringView.h"
+#include "llvm/Demangle/StringViewExtras.h"
#include "llvm/Demangle/Utility.h"
#include <cctype>
#include <cstring>
#include <limits>
+#include <string_view>
using namespace llvm;
using llvm::itanium_demangle::OutputBuffer;
-using llvm::itanium_demangle::StringView;
+using llvm::itanium_demangle::starts_with;
namespace {
@@ -32,7 +33,7 @@ struct Demangler {
/// Initialize the information structure we use to pass around information.
///
/// \param Mangled String to demangle.
- Demangler(const char *Mangled);
+ Demangler(std::string_view Mangled);
/// Extract and demangle the mangled symbol and append it to the output
/// string.
@@ -52,46 +53,42 @@ private:
/// \param Demangled output buffer to write the demangled name.
/// \param Mangled mangled symbol to be demangled.
///
- /// \return The remaining string on success or nullptr on failure.
- ///
/// \see https://dlang.org/spec/abi.html#name_mangling .
/// \see https://dlang.org/spec/abi.html#MangledName .
- const char *parseMangle(OutputBuffer *Demangled, const char *Mangled);
+ void parseMangle(OutputBuffer *Demangled, std::string_view &Mangled);
/// Extract the number from a given string.
///
/// \param Mangled string to extract the number.
/// \param Ret assigned result value.
///
- /// \return The remaining string on success or nullptr on failure.
- ///
- /// \note A result larger than UINT_MAX is considered a failure.
+ /// \note Ret larger than UINT_MAX is considered a failure.
///
/// \see https://dlang.org/spec/abi.html#Number .
- const char *decodeNumber(const char *Mangled, unsigned long &Ret);
+ void decodeNumber(std::string_view &Mangled, unsigned long &Ret);
/// Extract the back reference position from a given string.
///
/// \param Mangled string to extract the back reference position.
/// \param Ret assigned result value.
///
- /// \return the remaining string on success or nullptr on failure.
+ /// \return true on success, false on error.
///
/// \note Ret is always >= 0 on success, and unspecified on failure
///
/// \see https://dlang.org/spec/abi.html#back_ref .
/// \see https://dlang.org/spec/abi.html#NumberBackRef .
- const char *decodeBackrefPos(const char *Mangled, long &Ret);
+ bool decodeBackrefPos(std::string_view &Mangled, long &Ret);
/// Extract the symbol pointed by the back reference form a given string.
///
/// \param Mangled string to extract the back reference position.
/// \param Ret assigned result value.
///
- /// \return the remaining string on success or nullptr on failure.
+ /// \return true on success, false on error.
///
/// \see https://dlang.org/spec/abi.html#back_ref .
- const char *decodeBackref(const char *Mangled, const char *&Ret);
+ bool decodeBackref(std::string_view &Mangled, std::string_view &Ret);
/// Extract and demangle backreferenced symbol from a given mangled symbol
/// and append it to the output string.
@@ -99,22 +96,18 @@ private:
/// \param Demangled output buffer to write the demangled name.
/// \param Mangled mangled symbol to be demangled.
///
- /// \return the remaining string on success or nullptr on failure.
- ///
/// \see https://dlang.org/spec/abi.html#back_ref .
/// \see https://dlang.org/spec/abi.html#IdentifierBackRef .
- const char *parseSymbolBackref(OutputBuffer *Demangled, const char *Mangled);
+ void parseSymbolBackref(OutputBuffer *Demangled, std::string_view &Mangled);
/// Extract and demangle backreferenced type from a given mangled symbol
/// and append it to the output string.
///
/// \param Mangled mangled symbol to be demangled.
///
- /// \return the remaining string on success or nullptr on failure.
- ///
/// \see https://dlang.org/spec/abi.html#back_ref .
/// \see https://dlang.org/spec/abi.html#TypeBackRef .
- const char *parseTypeBackref(const char *Mangled);
+ void parseTypeBackref(std::string_view &Mangled);
/// Check whether it is the beginning of a symbol name.
///
@@ -123,7 +116,7 @@ private:
/// \return true on success, false otherwise.
///
/// \see https://dlang.org/spec/abi.html#SymbolName .
- bool isSymbolName(const char *Mangled);
+ bool isSymbolName(std::string_view Mangled);
/// Extract and demangle an identifier from a given mangled symbol append it
/// to the output string.
@@ -131,10 +124,8 @@ private:
/// \param Demangled Output buffer to write the demangled name.
/// \param Mangled Mangled symbol to be demangled.
///
- /// \return The remaining string on success or nullptr on failure.
- ///
/// \see https://dlang.org/spec/abi.html#SymbolName .
- const char *parseIdentifier(OutputBuffer *Demangled, const char *Mangled);
+ void parseIdentifier(OutputBuffer *Demangled, std::string_view &Mangled);
/// Extract and demangle the plain identifier from a given mangled symbol and
/// prepend/append it to the output string, with a special treatment for some
@@ -144,11 +135,9 @@ private:
/// \param Mangled Mangled symbol to be demangled.
/// \param Len Length of the mangled symbol name.
///
- /// \return The remaining string on success or nullptr on failure.
- ///
/// \see https://dlang.org/spec/abi.html#LName .
- const char *parseLName(OutputBuffer *Demangled, const char *Mangled,
- unsigned long Len);
+ void parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
+ unsigned long Len);
/// Extract and demangle the qualified symbol from a given mangled symbol
/// append it to the output string.
@@ -156,33 +145,38 @@ private:
/// \param Demangled Output buffer to write the demangled name.
/// \param Mangled Mangled symbol to be demangled.
///
- /// \return The remaining string on success or nullptr on failure.
- ///
/// \see https://dlang.org/spec/abi.html#QualifiedName .
- const char *parseQualified(OutputBuffer *Demangled, const char *Mangled);
+ void parseQualified(OutputBuffer *Demangled, std::string_view &Mangled);
/// Extract and demangle a type from a given mangled symbol append it to
/// the output string.
///
/// \param Mangled mangled symbol to be demangled.
///
- /// \return the remaining string on success or nullptr on failure.
+ /// \return true on success, false on error.
///
/// \see https://dlang.org/spec/abi.html#Type .
- const char *parseType(const char *Mangled);
+ bool parseType(std::string_view &Mangled);
- /// The string we are demangling.
- const char *Str;
+ /// An immutable view of the string we are demangling.
+ const std::string_view Str;
/// The index of the last back reference.
int LastBackref;
};
} // namespace
-const char *Demangler::decodeNumber(const char *Mangled, unsigned long &Ret) {
- // Return nullptr if trying to extract something that isn't a digit.
- if (Mangled == nullptr || !std::isdigit(*Mangled))
- return nullptr;
+void Demangler::decodeNumber(std::string_view &Mangled, unsigned long &Ret) {
+ // Clear Mangled if trying to extract something that isn't a digit.
+ if (Mangled.empty()) {
+ Mangled = {};
+ return;
+ }
+
+ if (!std::isdigit(Mangled.front())) {
+ Mangled = {};
+ return;
+ }
unsigned long Val = 0;
@@ -190,25 +184,29 @@ const char *Demangler::decodeNumber(const char *Mangled, unsigned long &Ret) {
unsigned long Digit = Mangled[0] - '0';
// Check for overflow.
- if (Val > (std::numeric_limits<unsigned int>::max() - Digit) / 10)
- return nullptr;
+ if (Val > (std::numeric_limits<unsigned int>::max() - Digit) / 10) {
+ Mangled = {};
+ return;
+ }
Val = Val * 10 + Digit;
- ++Mangled;
- } while (std::isdigit(*Mangled));
+ Mangled.remove_prefix(1);
+ } while (!Mangled.empty() && std::isdigit(Mangled.front()));
- if (*Mangled == '\0')
- return nullptr;
+ if (Mangled.empty()) {
+ Mangled = {};
+ return;
+ }
Ret = Val;
- return Mangled;
}
-const char *Demangler::decodeBackrefPos(const char *Mangled, long &Ret) {
+bool Demangler::decodeBackrefPos(std::string_view &Mangled, long &Ret) {
// Return nullptr if trying to extract something that isn't a digit
- if (Mangled == nullptr || !std::isalpha(*Mangled))
- return nullptr;
-
+ if (Mangled.empty()) {
+ Mangled = {};
+ return false;
+ }
// Any identifier or non-basic type that has been emitted to the mangled
// symbol before will not be emitted again, but is referenced by a special
// sequence encoding the relative position of the original occurrence in the
@@ -221,7 +219,7 @@ const char *Demangler::decodeBackrefPos(const char *Mangled, long &Ret) {
// ^
unsigned long Val = 0;
- while (std::isalpha(*Mangled)) {
+ while (!Mangled.empty() && std::isalpha(Mangled.front())) {
// Check for overflow
if (Val > (std::numeric_limits<unsigned long>::max() - 25) / 26)
break;
@@ -233,116 +231,133 @@ const char *Demangler::decodeBackrefPos(const char *Mangled, long &Ret) {
if ((long)Val <= 0)
break;
Ret = Val;
- return Mangled + 1;
+ Mangled.remove_prefix(1);
+ return true;
}
Val += Mangled[0] - 'A';
- ++Mangled;
+ Mangled.remove_prefix(1);
}
- return nullptr;
+ Mangled = {};
+ return false;
}
-const char *Demangler::decodeBackref(const char *Mangled, const char *&Ret) {
- assert(Mangled != nullptr && *Mangled == 'Q' && "Invalid back reference!");
- Ret = nullptr;
+bool Demangler::decodeBackref(std::string_view &Mangled,
+ std::string_view &Ret) {
+ assert(!Mangled.empty() && Mangled.front() == 'Q' &&
+ "Invalid back reference!");
+ Ret = {};
// Position of 'Q'
- const char *Qpos = Mangled;
+ const char *Qpos = Mangled.data();
long RefPos;
- ++Mangled;
+ Mangled.remove_prefix(1);
- Mangled = decodeBackrefPos(Mangled, RefPos);
- if (Mangled == nullptr)
- return nullptr;
+ if (!decodeBackrefPos(Mangled, RefPos)) {
+ Mangled = {};
+ return false;
+ }
- if (RefPos > Qpos - Str)
- return nullptr;
+ if (RefPos > Qpos - Str.data()) {
+ Mangled = {};
+ return false;
+ }
// Set the position of the back reference.
Ret = Qpos - RefPos;
- return Mangled;
+ return true;
}
-const char *Demangler::parseSymbolBackref(OutputBuffer *Demangled,
- const char *Mangled) {
+void Demangler::parseSymbolBackref(OutputBuffer *Demangled,
+ std::string_view &Mangled) {
// An identifier back reference always points to a digit 0 to 9.
// IdentifierBackRef:
// Q NumberBackRef
// ^
- const char *Backref;
unsigned long Len;
// Get position of the back reference
- Mangled = decodeBackref(Mangled, Backref);
+ std::string_view Backref;
+ if (!decodeBackref(Mangled, Backref)) {
+ Mangled = {};
+ return;
+ }
// Must point to a simple identifier
- Backref = decodeNumber(Backref, Len);
- if (Backref == nullptr || strlen(Backref) < Len)
- return nullptr;
-
- Backref = parseLName(Demangled, Backref, Len);
- if (Backref == nullptr)
- return nullptr;
+ decodeNumber(Backref, Len);
+ if (Backref.empty() || Backref.length() < Len) {
+ Mangled = {};
+ return;
+ }
- return Mangled;
+ parseLName(Demangled, Backref, Len);
+ if (Backref.empty())
+ Mangled = {};
}
-const char *Demangler::parseTypeBackref(const char *Mangled) {
+void Demangler::parseTypeBackref(std::string_view &Mangled) {
// A type back reference always points to a letter.
// TypeBackRef:
// Q NumberBackRef
// ^
- const char *Backref;
// If we appear to be moving backwards through the mangle string, then
// bail as this may be a recursive back reference.
- if (Mangled - Str >= LastBackref)
- return nullptr;
+ if (Mangled.data() - Str.data() >= LastBackref) {
+ Mangled = {};
+ return;
+ }
int SaveRefPos = LastBackref;
- LastBackref = Mangled - Str;
+ LastBackref = Mangled.data() - Str.data();
// Get position of the back reference.
- Mangled = decodeBackref(Mangled, Backref);
+ std::string_view Backref;
+ if (!decodeBackref(Mangled, Backref)) {
+ Mangled = {};
+ return;
+ }
// Can't decode back reference.
- if (Backref == nullptr)
- return nullptr;
+ if (Backref.empty()) {
+ Mangled = {};
+ return;
+ }
// TODO: Add support for function type back references.
- Backref = parseType(Backref);
+ if (!parseType(Backref))
+ Mangled = {};
LastBackref = SaveRefPos;
- if (Backref == nullptr)
- return nullptr;
-
- return Mangled;
+ if (Backref.empty())
+ Mangled = {};
}
-bool Demangler::isSymbolName(const char *Mangled) {
+bool Demangler::isSymbolName(std::string_view Mangled) {
long Ret;
- const char *Qref = Mangled;
+ const char *Qref = Mangled.data();
- if (std::isdigit(*Mangled))
+ if (std::isdigit(Mangled.front()))
return true;
// TODO: Handle template instances.
- if (*Mangled != 'Q')
+ if (Mangled.front() != 'Q')
return false;
- Mangled = decodeBackrefPos(Mangled + 1, Ret);
- if (Mangled == nullptr || Ret > Qref - Str)
+ Mangled.remove_prefix(1);
+ bool Valid = decodeBackrefPos(Mangled, Ret);
+ if (!Valid || Ret > Qref - Str.data())
return false;
return std::isdigit(Qref[-Ret]);
}
-const char *Demangler::parseMangle(OutputBuffer *Demangled,
- const char *Mangled) {
+void Demangler::parseMangle(OutputBuffer *Demangled,
+ std::string_view &Mangled) {
// A D mangled symbol is comprised of both scope and type information.
// MangleName:
// _D QualifiedName Type
@@ -352,24 +367,24 @@ const char *Demangler::parseMangle(OutputBuffer *Demangled,
// above location.
// Note that type is never a function type, but only the return type of
// a function or the type of a variable.
- Mangled += 2;
+ Mangled.remove_prefix(2);
- Mangled = parseQualified(Demangled, Mangled);
+ parseQualified(Demangled, Mangled);
- if (Mangled != nullptr) {
- // Artificial symbols end with 'Z' and have no type.
- if (*Mangled == 'Z')
- ++Mangled;
- else {
- Mangled = parseType(Mangled);
- }
+ if (Mangled.empty()) {
+ Mangled = {};
+ return;
}
- return Mangled;
+ // Artificial symbols end with 'Z' and have no type.
+ if (Mangled.front() == 'Z') {
+ Mangled.remove_prefix(1);
+ } else if (!parseType(Mangled))
+ Mangled = {};
}
-const char *Demangler::parseQualified(OutputBuffer *Demangled,
- const char *Mangled) {
+void Demangler::parseQualified(OutputBuffer *Demangled,
+ std::string_view &Mangled) {
// Qualified names are identifiers separated by their encoded length.
// Nested functions also encode their argument types without specifying
// what they return.
@@ -388,10 +403,10 @@ const char *Demangler::parseQualified(OutputBuffer *Demangled,
size_t NotFirst = false;
do {
// Skip over anonymous symbols.
- if (*Mangled == '0') {
+ if (!Mangled.empty() && Mangled.front() == '0') {
do
- ++Mangled;
- while (*Mangled == '0');
+ Mangled.remove_prefix(1);
+ while (!Mangled.empty() && Mangled.front() == '0');
continue;
}
@@ -400,62 +415,63 @@ const char *Demangler::parseQualified(OutputBuffer *Demangled,
*Demangled << '.';
NotFirst = true;
- Mangled = parseIdentifier(Demangled, Mangled);
-
- } while (Mangled && isSymbolName(Mangled));
-
- return Mangled;
+ parseIdentifier(Demangled, Mangled);
+ } while (!Mangled.empty() && isSymbolName(Mangled));
}
-const char *Demangler::parseIdentifier(OutputBuffer *Demangled,
- const char *Mangled) {
- unsigned long Len;
-
- if (Mangled == nullptr || *Mangled == '\0')
- return nullptr;
+void Demangler::parseIdentifier(OutputBuffer *Demangled,
+ std::string_view &Mangled) {
+ if (Mangled.empty()) {
+ Mangled = {};
+ return;
+ }
- if (*Mangled == 'Q')
+ if (Mangled.front() == 'Q')
return parseSymbolBackref(Demangled, Mangled);
// TODO: Parse lengthless template instances.
- const char *Endptr = decodeNumber(Mangled, Len);
-
- if (Endptr == nullptr || Len == 0)
- return nullptr;
-
- if (strlen(Endptr) < Len)
- return nullptr;
+ unsigned long Len;
+ decodeNumber(Mangled, Len);
- Mangled = Endptr;
+ if (Mangled.empty()) {
+ Mangled = {};
+ return;
+ }
+ if (!Len || Mangled.length() < Len) {
+ Mangled = {};
+ return;
+ }
// TODO: Parse template instances with a length prefix.
// There can be multiple different declarations in the same function that
// have the same mangled name. To make the mangled names unique, a fake
// parent in the form `__Sddd' is added to the symbol.
- if (Len >= 4 && Mangled[0] == '_' && Mangled[1] == '_' && Mangled[2] == 'S') {
- const char *NumPtr = Mangled + 3;
- while (NumPtr < (Mangled + Len) && std::isdigit(*NumPtr))
- ++NumPtr;
-
- if (Mangled + Len == NumPtr) {
+ if (Len >= 4 && starts_with(Mangled, "__S")) {
+ const size_t SuffixLen = Mangled.length() - Len;
+ std::string_view P = Mangled.substr(3);
+ while (P.length() > SuffixLen && std::isdigit(P.front()))
+ P.remove_prefix(1);
+ if (P.length() == SuffixLen) {
// Skip over the fake parent.
- Mangled += Len;
+ Mangled.remove_prefix(Len);
return parseIdentifier(Demangled, Mangled);
}
// Else demangle it as a plain identifier.
}
- return parseLName(Demangled, Mangled, Len);
+ parseLName(Demangled, Mangled, Len);
}
-const char *Demangler::parseType(const char *Mangled) {
- if (*Mangled == '\0')
- return nullptr;
+bool Demangler::parseType(std::string_view &Mangled) {
+ if (Mangled.empty()) {
+ Mangled = {};
+ return false;
+ }
- switch (*Mangled) {
+ switch (Mangled.front()) {
// TODO: Parse type qualifiers.
// TODO: Parse function types.
// TODO: Parse compound types.
@@ -464,99 +480,102 @@ const char *Demangler::parseType(const char *Mangled) {
// Basic types.
case 'i':
- ++Mangled;
+ Mangled.remove_prefix(1);
// TODO: Add type name dumping
- return Mangled;
+ return true;
// TODO: Add support for the rest of the basic types.
// Back referenced type.
- case 'Q':
- return parseTypeBackref(Mangled);
+ case 'Q': {
+ parseTypeBackref(Mangled);
+ return true;
+ }
default: // unhandled.
- return nullptr;
+ Mangled = {};
+ return false;
}
}
-const char *Demangler::parseLName(OutputBuffer *Demangled, const char *Mangled,
- unsigned long Len) {
+void Demangler::parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
+ unsigned long Len) {
switch (Len) {
case 6:
- if (strncmp(Mangled, "__initZ", Len + 1) == 0) {
+ if (starts_with(Mangled, "__initZ")) {
// The static initializer for a given symbol.
Demangled->prepend("initializer for ");
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
- Mangled += Len;
- return Mangled;
+ Mangled.remove_prefix(Len);
+ return;
}
- if (strncmp(Mangled, "__vtblZ", Len + 1) == 0) {
+ if (starts_with(Mangled, "__vtblZ")) {
// The vtable symbol for a given class.
Demangled->prepend("vtable for ");
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
- Mangled += Len;
- return Mangled;
+ Mangled.remove_prefix(Len);
+ return;
}
break;
case 7:
- if (strncmp(Mangled, "__ClassZ", Len + 1) == 0) {
+ if (starts_with(Mangled, "__ClassZ")) {
// The classinfo symbol for a given class.
Demangled->prepend("ClassInfo for ");
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
- Mangled += Len;
- return Mangled;
+ Mangled.remove_prefix(Len);
+ return;
}
break;
case 11:
- if (strncmp(Mangled, "__InterfaceZ", Len + 1) == 0) {
+ if (starts_with(Mangled, "__InterfaceZ")) {
// The interface symbol for a given class.
Demangled->prepend("Interface for ");
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
- Mangled += Len;
- return Mangled;
+ Mangled.remove_prefix(Len);
+ return;
}
break;
case 12:
- if (strncmp(Mangled, "__ModuleInfoZ", Len + 1) == 0) {
+ if (starts_with(Mangled, "__ModuleInfoZ")) {
// The ModuleInfo symbol for a given module.
Demangled->prepend("ModuleInfo for ");
Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
- Mangled += Len;
- return Mangled;
+ Mangled.remove_prefix(Len);
+ return;
}
break;
}
- *Demangled << StringView(Mangled, Len);
- Mangled += Len;
-
- return Mangled;
+ *Demangled << Mangled.substr(0, Len);
+ Mangled.remove_prefix(Len);
}
-Demangler::Demangler(const char *Mangled)
- : Str(Mangled), LastBackref(strlen(Mangled)) {}
+Demangler::Demangler(std::string_view Mangled)
+ : Str(Mangled), LastBackref(Mangled.length()) {}
const char *Demangler::parseMangle(OutputBuffer *Demangled) {
- return parseMangle(Demangled, this->Str);
+ std::string_view M(this->Str);
+ parseMangle(Demangled, M);
+ return M.data();
}
-char *llvm::dlangDemangle(const char *MangledName) {
- if (MangledName == nullptr || strncmp(MangledName, "_D", 2) != 0)
+char *llvm::dlangDemangle(std::string_view MangledName) {
+ if (MangledName.empty() || !starts_with(MangledName, "_D"))
return nullptr;
OutputBuffer Demangled;
- if (strcmp(MangledName, "_Dmain") == 0) {
+ if (MangledName == "_Dmain") {
Demangled << "D main";
} else {
- Demangler D = Demangler(MangledName);
- MangledName = D.parseMangle(&Demangled);
+ Demangler D(MangledName);
+ const char *M = D.parseMangle(&Demangled);
// Check that the entire symbol was successfully demangled.
- if (MangledName == nullptr || *MangledName != '\0') {
+ if (M == nullptr || *M != '\0') {
std::free(Demangled.getBuffer());
return nullptr;
}
diff --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp
index 9d128424cabf..f2aa571d685f 100644
--- a/llvm/lib/Demangle/Demangle.cpp
+++ b/llvm/lib/Demangle/Demangle.cpp
@@ -11,45 +11,45 @@
//===----------------------------------------------------------------------===//
#include "llvm/Demangle/Demangle.h"
+#include "llvm/Demangle/StringViewExtras.h"
#include <cstdlib>
-#include <cstring>
+#include <string_view>
-static bool isItaniumEncoding(const char *S) {
- // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'.
- return std::strncmp(S, "_Z", 2) == 0 || std::strncmp(S, "___Z", 4) == 0;
-}
-
-static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; }
-
-static bool isDLangEncoding(const std::string &MangledName) {
- return MangledName.size() >= 2 && MangledName[0] == '_' &&
- MangledName[1] == 'D';
-}
+using llvm::itanium_demangle::starts_with;
-std::string llvm::demangle(const std::string &MangledName) {
+std::string llvm::demangle(std::string_view MangledName) {
std::string Result;
- const char *S = MangledName.c_str();
- if (nonMicrosoftDemangle(S, Result))
+ if (nonMicrosoftDemangle(MangledName, Result))
return Result;
- if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result))
+ if (starts_with(MangledName, '_') &&
+ nonMicrosoftDemangle(MangledName.substr(1), Result))
return Result;
- if (char *Demangled =
- microsoftDemangle(S, nullptr, nullptr, nullptr, nullptr)) {
+ if (char *Demangled = microsoftDemangle(MangledName, nullptr, nullptr)) {
Result = Demangled;
std::free(Demangled);
- return Result;
+ } else {
+ Result = MangledName;
}
+ return Result;
+}
- return MangledName;
+static bool isItaniumEncoding(std::string_view S) {
+ // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'.
+ return starts_with(S, "_Z") || starts_with(S, "___Z");
}
-bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) {
+static bool isRustEncoding(std::string_view S) { return starts_with(S, "_R"); }
+
+static bool isDLangEncoding(std::string_view S) { return starts_with(S, "_D"); }
+
+bool llvm::nonMicrosoftDemangle(std::string_view MangledName,
+ std::string &Result) {
char *Demangled = nullptr;
if (isItaniumEncoding(MangledName))
- Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr);
+ Demangled = itaniumDemangle(MangledName);
else if (isRustEncoding(MangledName))
Demangled = rustDemangle(MangledName);
else if (isDLangEncoding(MangledName))
diff --git a/llvm/lib/Demangle/ItaniumDemangle.cpp b/llvm/lib/Demangle/ItaniumDemangle.cpp
index 9b646ea800aa..e3f208f0adf8 100644
--- a/llvm/lib/Demangle/ItaniumDemangle.cpp
+++ b/llvm/lib/Demangle/ItaniumDemangle.cpp
@@ -18,6 +18,7 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <exception>
#include <functional>
#include <utility>
@@ -78,8 +79,8 @@ struct DumpVisitor {
}
void printStr(const char *S) { fprintf(stderr, "%s", S); }
- void print(StringView SV) {
- fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
+ void print(std::string_view SV) {
+ fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.data());
}
void print(const Node *N) {
if (N)
@@ -365,33 +366,21 @@ public:
using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
-char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
- size_t *N, int *Status) {
- if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
- if (Status)
- *Status = demangle_invalid_args;
+char *llvm::itaniumDemangle(std::string_view MangledName) {
+ if (MangledName.empty())
return nullptr;
- }
- int InternalStatus = demangle_success;
- Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
+ Demangler Parser(MangledName.data(),
+ MangledName.data() + MangledName.length());
Node *AST = Parser.parse();
+ if (!AST)
+ return nullptr;
- if (AST == nullptr)
- InternalStatus = demangle_invalid_mangled_name;
- else {
- OutputBuffer OB(Buf, N);
- assert(Parser.ForwardTemplateRefs.empty());
- AST->print(OB);
- OB += '\0';
- if (N != nullptr)
- *N = OB.getCurrentPosition();
- Buf = OB.getBuffer();
- }
-
- if (Status)
- *Status = InternalStatus;
- return InternalStatus == demangle_success ? Buf : nullptr;
+ OutputBuffer OB;
+ assert(Parser.ForwardTemplateRefs.empty());
+ AST->print(OB);
+ OB += '\0';
+ return OB.getBuffer();
}
ItaniumPartialDemangler::ItaniumPartialDemangler()
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index c21b0a30105e..cd7ff40d63a4 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -14,34 +14,50 @@
//===----------------------------------------------------------------------===//
#include "llvm/Demangle/MicrosoftDemangle.h"
-#include "llvm/Demangle/Demangle.h"
-#include "llvm/Demangle/MicrosoftDemangleNodes.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/DemangleConfig.h"
-#include "llvm/Demangle/StringView.h"
+#include "llvm/Demangle/MicrosoftDemangleNodes.h"
+#include "llvm/Demangle/StringViewExtras.h"
#include "llvm/Demangle/Utility.h"
#include <array>
#include <cctype>
#include <cstdio>
+#include <string_view>
#include <tuple>
using namespace llvm;
using namespace ms_demangle;
-static bool startsWithDigit(StringView S) {
+static bool startsWithDigit(std::string_view S) {
return !S.empty() && std::isdigit(S.front());
}
-
struct NodeList {
Node *N = nullptr;
NodeList *Next = nullptr;
};
-static bool isMemberPointer(StringView MangledName, bool &Error) {
+static bool consumeFront(std::string_view &S, char C) {
+ if (!llvm::itanium_demangle::starts_with(S, C))
+ return false;
+ S.remove_prefix(1);
+ return true;
+}
+
+static bool consumeFront(std::string_view &S, std::string_view C) {
+ if (!llvm::itanium_demangle::starts_with(S, C))
+ return false;
+ S.remove_prefix(C.size());
+ return true;
+}
+
+static bool isMemberPointer(std::string_view MangledName, bool &Error) {
Error = false;
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case '$':
// This is probably an rvalue reference (e.g. $$Q), and you cannot have an
// rvalue reference to a member.
@@ -75,9 +91,9 @@ static bool isMemberPointer(StringView MangledName, bool &Error) {
// Remove ext qualifiers since those can appear on either type and are
// therefore not indicative.
- MangledName.consumeFront('E'); // 64-bit
- MangledName.consumeFront('I'); // restrict
- MangledName.consumeFront('F'); // unaligned
+ consumeFront(MangledName, 'E'); // 64-bit
+ consumeFront(MangledName, 'I'); // restrict
+ consumeFront(MangledName, 'F'); // unaligned
if (MangledName.empty()) {
Error = true;
@@ -103,50 +119,50 @@ static bool isMemberPointer(StringView MangledName, bool &Error) {
}
static SpecialIntrinsicKind
-consumeSpecialIntrinsicKind(StringView &MangledName) {
- if (MangledName.consumeFront("?_7"))
+consumeSpecialIntrinsicKind(std::string_view &MangledName) {
+ if (consumeFront(MangledName, "?_7"))
return SpecialIntrinsicKind::Vftable;
- if (MangledName.consumeFront("?_8"))
+ if (consumeFront(MangledName, "?_8"))
return SpecialIntrinsicKind::Vbtable;
- if (MangledName.consumeFront("?_9"))
+ if (consumeFront(MangledName, "?_9"))
return SpecialIntrinsicKind::VcallThunk;
- if (MangledName.consumeFront("?_A"))
+ if (consumeFront(MangledName, "?_A"))
return SpecialIntrinsicKind::Typeof;
- if (MangledName.consumeFront("?_B"))
+ if (consumeFront(MangledName, "?_B"))
return SpecialIntrinsicKind::LocalStaticGuard;
- if (MangledName.consumeFront("?_C"))
+ if (consumeFront(MangledName, "?_C"))
return SpecialIntrinsicKind::StringLiteralSymbol;
- if (MangledName.consumeFront("?_P"))
+ if (consumeFront(MangledName, "?_P"))
return SpecialIntrinsicKind::UdtReturning;
- if (MangledName.consumeFront("?_R0"))
+ if (consumeFront(MangledName, "?_R0"))
return SpecialIntrinsicKind::RttiTypeDescriptor;
- if (MangledName.consumeFront("?_R1"))
+ if (consumeFront(MangledName, "?_R1"))
return SpecialIntrinsicKind::RttiBaseClassDescriptor;
- if (MangledName.consumeFront("?_R2"))
+ if (consumeFront(MangledName, "?_R2"))
return SpecialIntrinsicKind::RttiBaseClassArray;
- if (MangledName.consumeFront("?_R3"))
+ if (consumeFront(MangledName, "?_R3"))
return SpecialIntrinsicKind::RttiClassHierarchyDescriptor;
- if (MangledName.consumeFront("?_R4"))
+ if (consumeFront(MangledName, "?_R4"))
return SpecialIntrinsicKind::RttiCompleteObjLocator;
- if (MangledName.consumeFront("?_S"))
+ if (consumeFront(MangledName, "?_S"))
return SpecialIntrinsicKind::LocalVftable;
- if (MangledName.consumeFront("?__E"))
+ if (consumeFront(MangledName, "?__E"))
return SpecialIntrinsicKind::DynamicInitializer;
- if (MangledName.consumeFront("?__F"))
+ if (consumeFront(MangledName, "?__F"))
return SpecialIntrinsicKind::DynamicAtexitDestructor;
- if (MangledName.consumeFront("?__J"))
+ if (consumeFront(MangledName, "?__J"))
return SpecialIntrinsicKind::LocalStaticThreadGuard;
return SpecialIntrinsicKind::None;
}
-static bool startsWithLocalScopePattern(StringView S) {
- if (!S.consumeFront('?'))
+static bool startsWithLocalScopePattern(std::string_view S) {
+ if (!consumeFront(S, '?'))
return false;
size_t End = S.find('?');
- if (End == StringView::npos)
+ if (End == std::string_view::npos)
return false;
- StringView Candidate = S.substr(0, End);
+ std::string_view Candidate = S.substr(0, End);
if (Candidate.empty())
return false;
@@ -158,7 +174,7 @@ static bool startsWithLocalScopePattern(StringView S) {
// If it's not 0-9, then it's an encoded number terminated with an @
if (Candidate.back() != '@')
return false;
- Candidate = Candidate.dropBack();
+ Candidate.remove_suffix(1);
// An encoded number starts with B-P and all subsequent digits are in A-P.
// Note that the reason the first digit cannot be A is two fold. First, it
@@ -168,17 +184,17 @@ static bool startsWithLocalScopePattern(StringView S) {
// ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
if (Candidate[0] < 'B' || Candidate[0] > 'P')
return false;
- Candidate = Candidate.dropFront();
+ Candidate.remove_prefix(1);
while (!Candidate.empty()) {
if (Candidate[0] < 'A' || Candidate[0] > 'P')
return false;
- Candidate = Candidate.dropFront();
+ Candidate.remove_prefix(1);
}
return true;
}
-static bool isTagType(StringView S) {
+static bool isTagType(std::string_view S) {
switch (S.front()) {
case 'T': // union
case 'U': // struct
@@ -189,10 +205,10 @@ static bool isTagType(StringView S) {
return false;
}
-static bool isCustomType(StringView S) { return S[0] == '?'; }
+static bool isCustomType(std::string_view S) { return S[0] == '?'; }
-static bool isPointerType(StringView S) {
- if (S.startsWith("$$Q")) // foo &&
+static bool isPointerType(std::string_view S) {
+ if (llvm::itanium_demangle::starts_with(S, "$$Q")) // foo &&
return true;
switch (S.front()) {
@@ -206,27 +222,30 @@ static bool isPointerType(StringView S) {
return false;
}
-static bool isArrayType(StringView S) { return S[0] == 'Y'; }
+static bool isArrayType(std::string_view S) { return S[0] == 'Y'; }
-static bool isFunctionType(StringView S) {
- return S.startsWith("$$A8@@") || S.startsWith("$$A6");
+static bool isFunctionType(std::string_view S) {
+ return llvm::itanium_demangle::starts_with(S, "$$A8@@") ||
+ llvm::itanium_demangle::starts_with(S, "$$A6");
}
static FunctionRefQualifier
-demangleFunctionRefQualifier(StringView &MangledName) {
- if (MangledName.consumeFront('G'))
+demangleFunctionRefQualifier(std::string_view &MangledName) {
+ if (consumeFront(MangledName, 'G'))
return FunctionRefQualifier::Reference;
- else if (MangledName.consumeFront('H'))
+ else if (consumeFront(MangledName, 'H'))
return FunctionRefQualifier::RValueReference;
return FunctionRefQualifier::None;
}
static std::pair<Qualifiers, PointerAffinity>
-demanglePointerCVQualifiers(StringView &MangledName) {
- if (MangledName.consumeFront("$$Q"))
+demanglePointerCVQualifiers(std::string_view &MangledName) {
+ if (consumeFront(MangledName, "$$Q"))
return std::make_pair(Q_None, PointerAffinity::RValueReference);
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case 'A':
return std::make_pair(Q_None, PointerAffinity::Reference);
case 'P':
@@ -244,18 +263,18 @@ demanglePointerCVQualifiers(StringView &MangledName) {
DEMANGLE_UNREACHABLE;
}
-StringView Demangler::copyString(StringView Borrowed) {
+std::string_view Demangler::copyString(std::string_view Borrowed) {
char *Stable = Arena.allocUnalignedBuffer(Borrowed.size());
// This is not a micro-optimization, it avoids UB, should Borrowed be an null
// buffer.
if (Borrowed.size())
- std::memcpy(Stable, Borrowed.begin(), Borrowed.size());
+ std::memcpy(Stable, Borrowed.data(), Borrowed.size());
return {Stable, Borrowed.size()};
}
SpecialTableSymbolNode *
-Demangler::demangleSpecialTableSymbolNode(StringView &MangledName,
+Demangler::demangleSpecialTableSymbolNode(std::string_view &MangledName,
SpecialIntrinsicKind K) {
NamedIdentifierNode *NI = Arena.alloc<NamedIdentifierNode>();
switch (K) {
@@ -282,20 +301,22 @@ Demangler::demangleSpecialTableSymbolNode(StringView &MangledName,
Error = true;
return nullptr;
}
- char Front = MangledName.popFront();
+ char Front = MangledName.front();
+ MangledName.remove_prefix(1);
if (Front != '6' && Front != '7') {
Error = true;
return nullptr;
}
std::tie(STSN->Quals, IsMember) = demangleQualifiers(MangledName);
- if (!MangledName.consumeFront('@'))
+ if (!consumeFront(MangledName, '@'))
STSN->TargetName = demangleFullyQualifiedTypeName(MangledName);
return STSN;
}
LocalStaticGuardVariableNode *
-Demangler::demangleLocalStaticGuard(StringView &MangledName, bool IsThread) {
+Demangler::demangleLocalStaticGuard(std::string_view &MangledName,
+ bool IsThread) {
LocalStaticGuardIdentifierNode *LSGI =
Arena.alloc<LocalStaticGuardIdentifierNode>();
LSGI->IsThread = IsThread;
@@ -304,9 +325,9 @@ Demangler::demangleLocalStaticGuard(StringView &MangledName, bool IsThread) {
Arena.alloc<LocalStaticGuardVariableNode>();
LSGVN->Name = QN;
- if (MangledName.consumeFront("4IA"))
+ if (consumeFront(MangledName, "4IA"))
LSGVN->IsVisible = false;
- else if (MangledName.consumeFront("5"))
+ else if (consumeFront(MangledName, "5"))
LSGVN->IsVisible = true;
else {
Error = true;
@@ -319,7 +340,7 @@ Demangler::demangleLocalStaticGuard(StringView &MangledName, bool IsThread) {
}
static NamedIdentifierNode *synthesizeNamedIdentifier(ArenaAllocator &Arena,
- StringView Name) {
+ std::string_view Name) {
NamedIdentifierNode *Id = Arena.alloc<NamedIdentifierNode>();
Id->Name = Name;
return Id;
@@ -336,27 +357,29 @@ static QualifiedNameNode *synthesizeQualifiedName(ArenaAllocator &Arena,
}
static QualifiedNameNode *synthesizeQualifiedName(ArenaAllocator &Arena,
- StringView Name) {
+ std::string_view Name) {
NamedIdentifierNode *Id = synthesizeNamedIdentifier(Arena, Name);
return synthesizeQualifiedName(Arena, Id);
}
static VariableSymbolNode *synthesizeVariable(ArenaAllocator &Arena,
TypeNode *Type,
- StringView VariableName) {
+ std::string_view VariableName) {
VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();
VSN->Type = Type;
VSN->Name = synthesizeQualifiedName(Arena, VariableName);
return VSN;
}
-VariableSymbolNode *Demangler::demangleUntypedVariable(
- ArenaAllocator &Arena, StringView &MangledName, StringView VariableName) {
+VariableSymbolNode *
+Demangler::demangleUntypedVariable(ArenaAllocator &Arena,
+ std::string_view &MangledName,
+ std::string_view VariableName) {
NamedIdentifierNode *NI = synthesizeNamedIdentifier(Arena, VariableName);
QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();
VSN->Name = QN;
- if (MangledName.consumeFront("8"))
+ if (consumeFront(MangledName, "8"))
return VSN;
Error = true;
@@ -365,7 +388,7 @@ VariableSymbolNode *Demangler::demangleUntypedVariable(
VariableSymbolNode *
Demangler::demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
- StringView &MangledName) {
+ std::string_view &MangledName) {
RttiBaseClassDescriptorNode *RBCDN =
Arena.alloc<RttiBaseClassDescriptorNode>();
RBCDN->NVOffset = demangleUnsigned(MangledName);
@@ -377,18 +400,19 @@ Demangler::demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();
VSN->Name = demangleNameScopeChain(MangledName, RBCDN);
- MangledName.consumeFront('8');
+ consumeFront(MangledName, '8');
return VSN;
}
-FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
- bool IsDestructor) {
+FunctionSymbolNode *
+Demangler::demangleInitFiniStub(std::string_view &MangledName,
+ bool IsDestructor) {
DynamicStructorIdentifierNode *DSIN =
Arena.alloc<DynamicStructorIdentifierNode>();
DSIN->IsDestructor = IsDestructor;
bool IsKnownStaticDataMember = false;
- if (MangledName.consumeFront('?'))
+ if (consumeFront(MangledName, '?'))
IsKnownStaticDataMember = true;
SymbolNode *Symbol = demangleDeclarator(MangledName);
@@ -406,7 +430,7 @@ FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
// both cases.
int AtCount = IsKnownStaticDataMember ? 2 : 1;
for (int I = 0; I < AtCount; ++I) {
- if (MangledName.consumeFront('@'))
+ if (consumeFront(MangledName, '@'))
continue;
Error = true;
return nullptr;
@@ -430,7 +454,7 @@ FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
return FSN;
}
-SymbolNode *Demangler::demangleSpecialIntrinsic(StringView &MangledName) {
+SymbolNode *Demangler::demangleSpecialIntrinsic(std::string_view &MangledName) {
SpecialIntrinsicKind SIK = consumeSpecialIntrinsicKind(MangledName);
switch (SIK) {
@@ -453,7 +477,7 @@ SymbolNode *Demangler::demangleSpecialIntrinsic(StringView &MangledName) {
TypeNode *T = demangleType(MangledName, QualifierMangleMode::Result);
if (Error)
break;
- if (!MangledName.consumeFront("@8"))
+ if (!consumeFront(MangledName, "@8"))
break;
if (!MangledName.empty())
break;
@@ -484,18 +508,18 @@ SymbolNode *Demangler::demangleSpecialIntrinsic(StringView &MangledName) {
}
IdentifierNode *
-Demangler::demangleFunctionIdentifierCode(StringView &MangledName) {
- assert(MangledName.startsWith('?'));
- MangledName = MangledName.dropFront();
+Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName) {
+ assert(llvm::itanium_demangle::starts_with(MangledName, '?'));
+ MangledName.remove_prefix(1);
if (MangledName.empty()) {
Error = true;
return nullptr;
}
- if (MangledName.consumeFront("__"))
+ if (consumeFront(MangledName, "__"))
return demangleFunctionIdentifierCode(
MangledName, FunctionIdentifierCodeGroup::DoubleUnder);
- if (MangledName.consumeFront("_"))
+ if (consumeFront(MangledName, "_"))
return demangleFunctionIdentifierCode(MangledName,
FunctionIdentifierCodeGroup::Under);
return demangleFunctionIdentifierCode(MangledName,
@@ -503,7 +527,7 @@ Demangler::demangleFunctionIdentifierCode(StringView &MangledName) {
}
StructorIdentifierNode *
-Demangler::demangleStructorIdentifier(StringView &MangledName,
+Demangler::demangleStructorIdentifier(std::string_view &MangledName,
bool IsDestructor) {
StructorIdentifierNode *N = Arena.alloc<StructorIdentifierNode>();
N->IsDestructor = IsDestructor;
@@ -511,14 +535,14 @@ Demangler::demangleStructorIdentifier(StringView &MangledName,
}
ConversionOperatorIdentifierNode *
-Demangler::demangleConversionOperatorIdentifier(StringView &MangledName) {
+Demangler::demangleConversionOperatorIdentifier(std::string_view &MangledName) {
ConversionOperatorIdentifierNode *N =
Arena.alloc<ConversionOperatorIdentifierNode>();
return N;
}
LiteralOperatorIdentifierNode *
-Demangler::demangleLiteralOperatorIdentifier(StringView &MangledName) {
+Demangler::demangleLiteralOperatorIdentifier(std::string_view &MangledName) {
LiteralOperatorIdentifierNode *N =
Arena.alloc<LiteralOperatorIdentifierNode>();
N->Name = demangleSimpleString(MangledName, /*Memorize=*/false);
@@ -666,15 +690,17 @@ Demangler::translateIntrinsicFunctionCode(char CH,
}
IdentifierNode *
-Demangler::demangleFunctionIdentifierCode(StringView &MangledName,
+Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName,
FunctionIdentifierCodeGroup Group) {
if (MangledName.empty()) {
Error = true;
return nullptr;
}
+ const char CH = MangledName.front();
switch (Group) {
case FunctionIdentifierCodeGroup::Basic:
- switch (char CH = MangledName.popFront()) {
+ MangledName.remove_prefix(1);
+ switch (CH) {
case '0':
case '1':
return demangleStructorIdentifier(MangledName, CH == '1');
@@ -685,10 +711,12 @@ Demangler::demangleFunctionIdentifierCode(StringView &MangledName,
translateIntrinsicFunctionCode(CH, Group));
}
case FunctionIdentifierCodeGroup::Under:
+ MangledName.remove_prefix(1);
return Arena.alloc<IntrinsicFunctionIdentifierNode>(
- translateIntrinsicFunctionCode(MangledName.popFront(), Group));
+ translateIntrinsicFunctionCode(CH, Group));
case FunctionIdentifierCodeGroup::DoubleUnder:
- switch (char CH = MangledName.popFront()) {
+ MangledName.remove_prefix(1);
+ switch (CH) {
case 'K':
return demangleLiteralOperatorIdentifier(MangledName);
default:
@@ -700,7 +728,7 @@ Demangler::demangleFunctionIdentifierCode(StringView &MangledName,
DEMANGLE_UNREACHABLE;
}
-SymbolNode *Demangler::demangleEncodedSymbol(StringView &MangledName,
+SymbolNode *Demangler::demangleEncodedSymbol(std::string_view &MangledName,
QualifiedNameNode *Name) {
if (MangledName.empty()) {
Error = true;
@@ -730,7 +758,7 @@ SymbolNode *Demangler::demangleEncodedSymbol(StringView &MangledName,
return FSN;
}
-SymbolNode *Demangler::demangleDeclarator(StringView &MangledName) {
+SymbolNode *Demangler::demangleDeclarator(std::string_view &MangledName) {
// What follows is a main symbol name. This may include namespaces or class
// back references.
QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
@@ -754,18 +782,19 @@ SymbolNode *Demangler::demangleDeclarator(StringView &MangledName) {
return Symbol;
}
-SymbolNode *Demangler::demangleMD5Name(StringView &MangledName) {
- assert(MangledName.startsWith("??@"));
+SymbolNode *Demangler::demangleMD5Name(std::string_view &MangledName) {
+ assert(llvm::itanium_demangle::starts_with(MangledName, "??@"));
// This is an MD5 mangled name. We can't demangle it, just return the
// mangled name.
// An MD5 mangled name is ??@ followed by 32 characters and a terminating @.
size_t MD5Last = MangledName.find('@', strlen("??@"));
- if (MD5Last == StringView::npos) {
+ if (MD5Last == std::string_view::npos) {
Error = true;
return nullptr;
}
- const char *Start = MangledName.begin();
- MangledName = MangledName.dropFront(MD5Last + 1);
+ const char *Start = MangledName.data();
+ const size_t StartSize = MangledName.size();
+ MangledName.remove_prefix(MD5Last + 1);
// There are two additional special cases for MD5 names:
// 1. For complete object locators where the object name is long enough
@@ -777,18 +806,20 @@ SymbolNode *Demangler::demangleMD5Name(StringView &MangledName) {
// instead of_CT??@...@8 with just one MD5 name. Since we don't yet
// demangle catchable types anywhere, this isn't handled for MD5 names
// either.
- MangledName.consumeFront("??_R4@");
+ consumeFront(MangledName, "??_R4@");
- StringView MD5(Start, MangledName.begin());
+ assert(MangledName.size() < StartSize);
+ const size_t Count = StartSize - MangledName.size();
+ std::string_view MD5(Start, Count);
SymbolNode *S = Arena.alloc<SymbolNode>(NodeKind::Md5Symbol);
S->Name = synthesizeQualifiedName(Arena, MD5);
return S;
}
-SymbolNode *Demangler::demangleTypeinfoName(StringView &MangledName) {
- assert(MangledName.startsWith('.'));
- MangledName.consumeFront('.');
+SymbolNode *Demangler::demangleTypeinfoName(std::string_view &MangledName) {
+ assert(llvm::itanium_demangle::starts_with(MangledName, '.'));
+ consumeFront(MangledName, '.');
TypeNode *T = demangleType(MangledName, QualifierMangleMode::Result);
if (Error || !MangledName.empty()) {
@@ -799,23 +830,23 @@ SymbolNode *Demangler::demangleTypeinfoName(StringView &MangledName) {
}
// Parser entry point.
-SymbolNode *Demangler::parse(StringView &MangledName) {
+SymbolNode *Demangler::parse(std::string_view &MangledName) {
// Typeinfo names are strings stored in RTTI data. They're not symbol names.
// It's still useful to demangle them. They're the only demangled entity
// that doesn't start with a "?" but a ".".
- if (MangledName.startsWith('.'))
+ if (llvm::itanium_demangle::starts_with(MangledName, '.'))
return demangleTypeinfoName(MangledName);
- if (MangledName.startsWith("??@"))
+ if (llvm::itanium_demangle::starts_with(MangledName, "??@"))
return demangleMD5Name(MangledName);
// MSVC-style mangled symbols must start with '?'.
- if (!MangledName.startsWith('?')) {
+ if (!llvm::itanium_demangle::starts_with(MangledName, '?')) {
Error = true;
return nullptr;
}
- MangledName.consumeFront('?');
+ consumeFront(MangledName, '?');
// ?$ is a template instantiation, but all other names that start with ? are
// operators / special names.
@@ -825,12 +856,12 @@ SymbolNode *Demangler::parse(StringView &MangledName) {
return demangleDeclarator(MangledName);
}
-TagTypeNode *Demangler::parseTagUniqueName(StringView &MangledName) {
- if (!MangledName.consumeFront(".?A")) {
+TagTypeNode *Demangler::parseTagUniqueName(std::string_view &MangledName) {
+ if (!consumeFront(MangledName, ".?A")) {
Error = true;
return nullptr;
}
- MangledName.consumeFront(".?A");
+ consumeFront(MangledName, ".?A");
if (MangledName.empty()) {
Error = true;
return nullptr;
@@ -846,8 +877,9 @@ TagTypeNode *Demangler::parseTagUniqueName(StringView &MangledName) {
// ::= 3 # global
// ::= 4 # static local
-VariableSymbolNode *Demangler::demangleVariableEncoding(StringView &MangledName,
- StorageClass SC) {
+VariableSymbolNode *
+Demangler::demangleVariableEncoding(std::string_view &MangledName,
+ StorageClass SC) {
VariableSymbolNode *VSN = Arena.alloc<VariableSymbolNode>();
VSN->Type = demangleType(MangledName, QualifierMangleMode::Drop);
@@ -897,12 +929,13 @@ VariableSymbolNode *Demangler::demangleVariableEncoding(StringView &MangledName,
// ::= <hex digit>+ @ # when Number == 0 or >= 10
//
// <hex-digit> ::= [A-P] # A = 0, B = 1, ...
-std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
- bool IsNegative = MangledName.consumeFront('?');
+std::pair<uint64_t, bool>
+Demangler::demangleNumber(std::string_view &MangledName) {
+ bool IsNegative = consumeFront(MangledName, '?');
if (startsWithDigit(MangledName)) {
uint64_t Ret = MangledName[0] - '0' + 1;
- MangledName = MangledName.dropFront(1);
+ MangledName.remove_prefix(1);
return {Ret, IsNegative};
}
@@ -910,7 +943,7 @@ std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
for (size_t i = 0; i < MangledName.size(); ++i) {
char C = MangledName[i];
if (C == '@') {
- MangledName = MangledName.dropFront(i + 1);
+ MangledName.remove_prefix(i + 1);
return {Ret, IsNegative};
}
if ('A' <= C && C <= 'P') {
@@ -924,7 +957,7 @@ std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
return {0ULL, false};
}
-uint64_t Demangler::demangleUnsigned(StringView &MangledName) {
+uint64_t Demangler::demangleUnsigned(std::string_view &MangledName) {
bool IsNegative = false;
uint64_t Number = 0;
std::tie(Number, IsNegative) = demangleNumber(MangledName);
@@ -933,7 +966,7 @@ uint64_t Demangler::demangleUnsigned(StringView &MangledName) {
return Number;
}
-int64_t Demangler::demangleSigned(StringView &MangledName) {
+int64_t Demangler::demangleSigned(std::string_view &MangledName) {
bool IsNegative = false;
uint64_t Number = 0;
std::tie(Number, IsNegative) = demangleNumber(MangledName);
@@ -945,7 +978,7 @@ int64_t Demangler::demangleSigned(StringView &MangledName) {
// First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
// Memorize it.
-void Demangler::memorizeString(StringView S) {
+void Demangler::memorizeString(std::string_view S) {
if (Backrefs.NamesCount >= BackrefContext::Max)
return;
for (size_t i = 0; i < Backrefs.NamesCount; ++i)
@@ -956,7 +989,8 @@ void Demangler::memorizeString(StringView S) {
Backrefs.Names[Backrefs.NamesCount++] = N;
}
-NamedIdentifierNode *Demangler::demangleBackRefName(StringView &MangledName) {
+NamedIdentifierNode *
+Demangler::demangleBackRefName(std::string_view &MangledName) {
assert(startsWithDigit(MangledName));
size_t I = MangledName[0] - '0';
@@ -965,7 +999,7 @@ NamedIdentifierNode *Demangler::demangleBackRefName(StringView &MangledName) {
return nullptr;
}
- MangledName = MangledName.dropFront();
+ MangledName.remove_prefix(1);
return Backrefs.Names[I];
}
@@ -974,16 +1008,16 @@ void Demangler::memorizeIdentifier(IdentifierNode *Identifier) {
// memorize it for the purpose of back-referencing.
OutputBuffer OB;
Identifier->output(OB, OF_Default);
- StringView Owned = copyString(OB);
+ std::string_view Owned = copyString(OB);
memorizeString(Owned);
std::free(OB.getBuffer());
}
IdentifierNode *
-Demangler::demangleTemplateInstantiationName(StringView &MangledName,
+Demangler::demangleTemplateInstantiationName(std::string_view &MangledName,
NameBackrefBehavior NBB) {
- assert(MangledName.startsWith("?$"));
- MangledName.consumeFront("?$");
+ assert(llvm::itanium_demangle::starts_with(MangledName, "?$"));
+ consumeFront(MangledName, "?$");
BackrefContext OuterContext;
std::swap(OuterContext, Backrefs);
@@ -1013,9 +1047,9 @@ Demangler::demangleTemplateInstantiationName(StringView &MangledName,
return Identifier;
}
-NamedIdentifierNode *Demangler::demangleSimpleName(StringView &MangledName,
- bool Memorize) {
- StringView S = demangleSimpleString(MangledName, Memorize);
+NamedIdentifierNode *
+Demangler::demangleSimpleName(std::string_view &MangledName, bool Memorize) {
+ std::string_view S = demangleSimpleString(MangledName, Memorize);
if (Error)
return nullptr;
@@ -1031,33 +1065,36 @@ static uint8_t rebasedHexDigitToNumber(char C) {
return (C <= 'J') ? (C - 'A') : (10 + C - 'K');
}
-uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
+uint8_t Demangler::demangleCharLiteral(std::string_view &MangledName) {
assert(!MangledName.empty());
- if (!MangledName.startsWith('?'))
- return MangledName.popFront();
+ if (!llvm::itanium_demangle::starts_with(MangledName, '?')) {
+ const uint8_t F = MangledName.front();
+ MangledName.remove_prefix(1);
+ return F;
+ }
- MangledName = MangledName.dropFront();
+ MangledName.remove_prefix(1);
if (MangledName.empty())
goto CharLiteralError;
- if (MangledName.consumeFront('$')) {
+ if (consumeFront(MangledName, '$')) {
// Two hex digits
if (MangledName.size() < 2)
goto CharLiteralError;
- StringView Nibbles = MangledName.substr(0, 2);
+ std::string_view Nibbles = MangledName.substr(0, 2);
if (!isRebasedHexDigit(Nibbles[0]) || !isRebasedHexDigit(Nibbles[1]))
goto CharLiteralError;
// Don't append the null terminator.
uint8_t C1 = rebasedHexDigitToNumber(Nibbles[0]);
uint8_t C2 = rebasedHexDigitToNumber(Nibbles[1]);
- MangledName = MangledName.dropFront(2);
+ MangledName.remove_prefix(2);
return (C1 << 4) | C2;
}
if (startsWithDigit(MangledName)) {
const char *Lookup = ",/\\:. \n\t'-";
char C = Lookup[MangledName[0] - '0'];
- MangledName = MangledName.dropFront();
+ MangledName.remove_prefix(1);
return C;
}
@@ -1067,7 +1104,7 @@ uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
'\xEF', '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5',
'\xF6', '\xF7', '\xF8', '\xF9', '\xFA'};
char C = Lookup[MangledName[0] - 'a'];
- MangledName = MangledName.dropFront();
+ MangledName.remove_prefix(1);
return C;
}
@@ -1077,7 +1114,7 @@ uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
'\xCF', '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5',
'\xD6', '\xD7', '\xD8', '\xD9', '\xDA'};
char C = Lookup[MangledName[0] - 'A'];
- MangledName = MangledName.dropFront();
+ MangledName.remove_prefix(1);
return C;
}
@@ -1086,7 +1123,7 @@ CharLiteralError:
return '\0';
}
-wchar_t Demangler::demangleWcharLiteral(StringView &MangledName) {
+wchar_t Demangler::demangleWcharLiteral(std::string_view &MangledName) {
uint8_t C1, C2;
C1 = demangleCharLiteral(MangledName);
@@ -1131,7 +1168,7 @@ static void outputHex(OutputBuffer &OB, unsigned C) {
TempBuffer[Pos--] = 'x';
assert(Pos >= 0);
TempBuffer[Pos--] = '\\';
- OB << StringView(&TempBuffer[Pos + 1]);
+ OB << std::string_view(&TempBuffer[Pos + 1]);
}
static void outputEscapedChar(OutputBuffer &OB, unsigned C) {
@@ -1253,7 +1290,8 @@ static unsigned decodeMultiByteChar(const uint8_t *StringBytes,
return Result;
}
-FunctionSymbolNode *Demangler::demangleVcallThunkNode(StringView &MangledName) {
+FunctionSymbolNode *
+Demangler::demangleVcallThunkNode(std::string_view &MangledName) {
FunctionSymbolNode *FSN = Arena.alloc<FunctionSymbolNode>();
VcallThunkIdentifierNode *VTIN = Arena.alloc<VcallThunkIdentifierNode>();
FSN->Signature = Arena.alloc<ThunkSignatureNode>();
@@ -1261,36 +1299,39 @@ FunctionSymbolNode *Demangler::demangleVcallThunkNode(StringView &MangledName) {
FSN->Name = demangleNameScopeChain(MangledName, VTIN);
if (!Error)
- Error = !MangledName.consumeFront("$B");
+ Error = !consumeFront(MangledName, "$B");
if (!Error)
VTIN->OffsetInVTable = demangleUnsigned(MangledName);
if (!Error)
- Error = !MangledName.consumeFront('A');
+ Error = !consumeFront(MangledName, 'A');
if (!Error)
FSN->Signature->CallConvention = demangleCallingConvention(MangledName);
return (Error) ? nullptr : FSN;
}
EncodedStringLiteralNode *
-Demangler::demangleStringLiteral(StringView &MangledName) {
+Demangler::demangleStringLiteral(std::string_view &MangledName) {
// This function uses goto, so declare all variables up front.
OutputBuffer OB;
- StringView CRC;
+ std::string_view CRC;
uint64_t StringByteSize;
bool IsWcharT = false;
bool IsNegative = false;
size_t CrcEndPos = 0;
+ char F;
EncodedStringLiteralNode *Result = Arena.alloc<EncodedStringLiteralNode>();
// Prefix indicating the beginning of a string literal
- if (!MangledName.consumeFront("@_"))
+ if (!consumeFront(MangledName, "@_"))
goto StringLiteralError;
if (MangledName.empty())
goto StringLiteralError;
// Char Type (regular or wchar_t)
- switch (MangledName.popFront()) {
+ F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case '1':
IsWcharT = true;
DEMANGLE_FALLTHROUGH;
@@ -1307,10 +1348,10 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
// CRC 32 (always 8 characters plus a terminator)
CrcEndPos = MangledName.find('@');
- if (CrcEndPos == StringView::npos)
+ if (CrcEndPos == std::string_view::npos)
goto StringLiteralError;
CRC = MangledName.substr(0, CrcEndPos);
- MangledName = MangledName.dropFront(CrcEndPos + 1);
+ MangledName.remove_prefix(CrcEndPos + 1);
if (MangledName.empty())
goto StringLiteralError;
@@ -1319,7 +1360,7 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
if (StringByteSize > 64)
Result->IsTruncated = true;
- while (!MangledName.consumeFront('@')) {
+ while (!consumeFront(MangledName, '@')) {
if (MangledName.size() < 2)
goto StringLiteralError;
wchar_t W = demangleWcharLiteral(MangledName);
@@ -1336,7 +1377,7 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
uint8_t StringBytes[MaxStringByteLength];
unsigned BytesDecoded = 0;
- while (!MangledName.consumeFront('@')) {
+ while (!consumeFront(MangledName, '@')) {
if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength)
goto StringLiteralError;
StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
@@ -1382,16 +1423,16 @@ StringLiteralError:
// Returns MangledName's prefix before the first '@', or an error if
// MangledName contains no '@' or the prefix has length 0.
-StringView Demangler::demangleSimpleString(StringView &MangledName,
- bool Memorize) {
- StringView S;
+std::string_view Demangler::demangleSimpleString(std::string_view &MangledName,
+ bool Memorize) {
+ std::string_view S;
for (size_t i = 0; i < MangledName.size(); ++i) {
if (MangledName[i] != '@')
continue;
if (i == 0)
break;
S = MangledName.substr(0, i);
- MangledName = MangledName.dropFront(i + 1);
+ MangledName.remove_prefix(i + 1);
if (Memorize)
memorizeString(S);
@@ -1403,36 +1444,36 @@ StringView Demangler::demangleSimpleString(StringView &MangledName,
}
NamedIdentifierNode *
-Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
- assert(MangledName.startsWith("?A"));
- MangledName.consumeFront("?A");
+Demangler::demangleAnonymousNamespaceName(std::string_view &MangledName) {
+ assert(llvm::itanium_demangle::starts_with(MangledName, "?A"));
+ consumeFront(MangledName, "?A");
NamedIdentifierNode *Node = Arena.alloc<NamedIdentifierNode>();
Node->Name = "`anonymous namespace'";
size_t EndPos = MangledName.find('@');
- if (EndPos == StringView::npos) {
+ if (EndPos == std::string_view::npos) {
Error = true;
return nullptr;
}
- StringView NamespaceKey = MangledName.substr(0, EndPos);
+ std::string_view NamespaceKey = MangledName.substr(0, EndPos);
memorizeString(NamespaceKey);
MangledName = MangledName.substr(EndPos + 1);
return Node;
}
NamedIdentifierNode *
-Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
+Demangler::demangleLocallyScopedNamePiece(std::string_view &MangledName) {
assert(startsWithLocalScopePattern(MangledName));
NamedIdentifierNode *Identifier = Arena.alloc<NamedIdentifierNode>();
- MangledName.consumeFront('?');
+ consumeFront(MangledName, '?');
uint64_t Number = 0;
bool IsNegative = false;
std::tie(Number, IsNegative) = demangleNumber(MangledName);
assert(!IsNegative);
// One ? to terminate the number
- MangledName.consumeFront('?');
+ consumeFront(MangledName, '?');
assert(!Error);
Node *Scope = parse(MangledName);
@@ -1453,7 +1494,7 @@ Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
// Parses a type name in the form of A@B@C@@ which represents C::B::A.
QualifiedNameNode *
-Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
+Demangler::demangleFullyQualifiedTypeName(std::string_view &MangledName) {
IdentifierNode *Identifier =
demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true);
if (Error)
@@ -1471,7 +1512,7 @@ Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
// Symbol names have slightly different rules regarding what can appear
// so we separate out the implementations for flexibility.
QualifiedNameNode *
-Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
+Demangler::demangleFullyQualifiedSymbolName(std::string_view &MangledName) {
// This is the final component of a symbol name (i.e. the leftmost component
// of a mangled name. Since the only possible template instantiation that
// can appear in this context is a function template, and since those are
@@ -1500,8 +1541,9 @@ Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
return QN;
}
-IdentifierNode *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
- bool Memorize) {
+IdentifierNode *
+Demangler::demangleUnqualifiedTypeName(std::string_view &MangledName,
+ bool Memorize) {
// An inner-most name can be a back-reference, because a fully-qualified name
// (e.g. Scope + Inner) can contain other fully qualified names inside of
// them (for example template parameters), and these nested parameters can
@@ -1509,32 +1551,33 @@ IdentifierNode *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
if (startsWithDigit(MangledName))
return demangleBackRefName(MangledName);
- if (MangledName.startsWith("?$"))
+ if (llvm::itanium_demangle::starts_with(MangledName, "?$"))
return demangleTemplateInstantiationName(MangledName, NBB_Template);
return demangleSimpleName(MangledName, Memorize);
}
IdentifierNode *
-Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
+Demangler::demangleUnqualifiedSymbolName(std::string_view &MangledName,
NameBackrefBehavior NBB) {
if (startsWithDigit(MangledName))
return demangleBackRefName(MangledName);
- if (MangledName.startsWith("?$"))
+ if (llvm::itanium_demangle::starts_with(MangledName, "?$"))
return demangleTemplateInstantiationName(MangledName, NBB);
- if (MangledName.startsWith('?'))
+ if (llvm::itanium_demangle::starts_with(MangledName, '?'))
return demangleFunctionIdentifierCode(MangledName);
return demangleSimpleName(MangledName, /*Memorize=*/(NBB & NBB_Simple) != 0);
}
-IdentifierNode *Demangler::demangleNameScopePiece(StringView &MangledName) {
+IdentifierNode *
+Demangler::demangleNameScopePiece(std::string_view &MangledName) {
if (startsWithDigit(MangledName))
return demangleBackRefName(MangledName);
- if (MangledName.startsWith("?$"))
+ if (llvm::itanium_demangle::starts_with(MangledName, "?$"))
return demangleTemplateInstantiationName(MangledName, NBB_Template);
- if (MangledName.startsWith("?A"))
+ if (llvm::itanium_demangle::starts_with(MangledName, "?A"))
return demangleAnonymousNamespaceName(MangledName);
if (startsWithLocalScopePattern(MangledName))
@@ -1556,14 +1599,14 @@ static NodeArrayNode *nodeListToNodeArray(ArenaAllocator &Arena, NodeList *Head,
}
QualifiedNameNode *
-Demangler::demangleNameScopeChain(StringView &MangledName,
+Demangler::demangleNameScopeChain(std::string_view &MangledName,
IdentifierNode *UnqualifiedName) {
NodeList *Head = Arena.alloc<NodeList>();
Head->N = UnqualifiedName;
size_t Count = 1;
- while (!MangledName.consumeFront("@")) {
+ while (!consumeFront(MangledName, "@")) {
++Count;
NodeList *NewHead = Arena.alloc<NodeList>();
NewHead->Next = Head;
@@ -1587,8 +1630,10 @@ Demangler::demangleNameScopeChain(StringView &MangledName,
return QN;
}
-FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
- switch (MangledName.popFront()) {
+FuncClass Demangler::demangleFunctionClass(std::string_view &MangledName) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case '9':
return FuncClass(FC_ExternC | FC_NoParameterList);
case 'A':
@@ -1645,11 +1690,13 @@ FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
return FuncClass(FC_Global | FC_Far);
case '$': {
FuncClass VFlag = FC_VirtualThisAdjust;
- if (MangledName.consumeFront('R'))
+ if (consumeFront(MangledName, 'R'))
VFlag = FuncClass(VFlag | FC_VirtualThisAdjustEx);
if (MangledName.empty())
break;
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case '0':
return FuncClass(FC_Private | FC_Virtual | VFlag);
case '1':
@@ -1670,13 +1717,16 @@ FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
return FC_Public;
}
-CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
+CallingConv
+Demangler::demangleCallingConvention(std::string_view &MangledName) {
if (MangledName.empty()) {
Error = true;
return CallingConv::None;
}
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case 'A':
case 'B':
return CallingConv::Cdecl;
@@ -1709,10 +1759,13 @@ CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
return CallingConv::None;
}
-StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
+StorageClass
+Demangler::demangleVariableStorageClass(std::string_view &MangledName) {
assert(MangledName.front() >= '0' && MangledName.front() <= '4');
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case '0':
return StorageClass::PrivateStatic;
case '1':
@@ -1728,13 +1781,15 @@ StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
}
std::pair<Qualifiers, bool>
-Demangler::demangleQualifiers(StringView &MangledName) {
+Demangler::demangleQualifiers(std::string_view &MangledName) {
if (MangledName.empty()) {
Error = true;
return std::make_pair(Q_None, false);
}
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
// Member qualifiers
case 'Q':
return std::make_pair(Q_None, true);
@@ -1760,14 +1815,14 @@ Demangler::demangleQualifiers(StringView &MangledName) {
// <variable-type> ::= <type> <cvr-qualifiers>
// ::= <type> <pointee-cvr-qualifiers> # pointers, references
-TypeNode *Demangler::demangleType(StringView &MangledName,
+TypeNode *Demangler::demangleType(std::string_view &MangledName,
QualifierMangleMode QMM) {
Qualifiers Quals = Q_None;
bool IsMember = false;
if (QMM == QualifierMangleMode::Mangle) {
std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
} else if (QMM == QualifierMangleMode::Result) {
- if (MangledName.consumeFront('?'))
+ if (consumeFront(MangledName, '?'))
std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
}
@@ -1789,11 +1844,11 @@ TypeNode *Demangler::demangleType(StringView &MangledName,
} else if (isArrayType(MangledName))
Ty = demangleArrayType(MangledName);
else if (isFunctionType(MangledName)) {
- if (MangledName.consumeFront("$$A8@@"))
+ if (consumeFront(MangledName, "$$A8@@"))
Ty = demangleFunctionType(MangledName, true);
else {
- assert(MangledName.startsWith("$$A6"));
- MangledName.consumeFront("$$A6");
+ assert(llvm::itanium_demangle::starts_with(MangledName, "$$A6"));
+ consumeFront(MangledName, "$$A6");
Ty = demangleFunctionType(MangledName, false);
}
} else if (isCustomType(MangledName)) {
@@ -1808,18 +1863,19 @@ TypeNode *Demangler::demangleType(StringView &MangledName,
return Ty;
}
-bool Demangler::demangleThrowSpecification(StringView &MangledName) {
- if (MangledName.consumeFront("_E"))
+bool Demangler::demangleThrowSpecification(std::string_view &MangledName) {
+ if (consumeFront(MangledName, "_E"))
return true;
- if (MangledName.consumeFront('Z'))
+ if (consumeFront(MangledName, 'Z'))
return false;
Error = true;
return false;
}
-FunctionSignatureNode *Demangler::demangleFunctionType(StringView &MangledName,
- bool HasThisQuals) {
+FunctionSignatureNode *
+Demangler::demangleFunctionType(std::string_view &MangledName,
+ bool HasThisQuals) {
FunctionSignatureNode *FTy = Arena.alloc<FunctionSignatureNode>();
if (HasThisQuals) {
@@ -1833,7 +1889,7 @@ FunctionSignatureNode *Demangler::demangleFunctionType(StringView &MangledName,
// <return-type> ::= <type>
// ::= @ # structors (they have no declared return type)
- bool IsStructor = MangledName.consumeFront('@');
+ bool IsStructor = consumeFront(MangledName, '@');
if (!IsStructor)
FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
@@ -1845,9 +1901,9 @@ FunctionSignatureNode *Demangler::demangleFunctionType(StringView &MangledName,
}
FunctionSymbolNode *
-Demangler::demangleFunctionEncoding(StringView &MangledName) {
+Demangler::demangleFunctionEncoding(std::string_view &MangledName) {
FuncClass ExtraFlags = FC_None;
- if (MangledName.consumeFront("$$J0"))
+ if (consumeFront(MangledName, "$$J0"))
ExtraFlags = FC_ExternC;
if (MangledName.empty()) {
@@ -1897,13 +1953,13 @@ Demangler::demangleFunctionEncoding(StringView &MangledName) {
return Symbol;
}
-CustomTypeNode *Demangler::demangleCustomType(StringView &MangledName) {
- assert(MangledName.startsWith('?'));
- MangledName.popFront();
+CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
+ assert(llvm::itanium_demangle::starts_with(MangledName, '?'));
+ MangledName.remove_prefix(1);
CustomTypeNode *CTN = Arena.alloc<CustomTypeNode>();
CTN->Identifier = demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true);
- if (!MangledName.consumeFront('@'))
+ if (!consumeFront(MangledName, '@'))
Error = true;
if (Error)
return nullptr;
@@ -1911,11 +1967,14 @@ CustomTypeNode *Demangler::demangleCustomType(StringView &MangledName) {
}
// Reads a primitive type.
-PrimitiveTypeNode *Demangler::demanglePrimitiveType(StringView &MangledName) {
- if (MangledName.consumeFront("$$T"))
+PrimitiveTypeNode *
+Demangler::demanglePrimitiveType(std::string_view &MangledName) {
+ if (consumeFront(MangledName, "$$T"))
return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Nullptr);
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case 'X':
return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Void);
case 'D':
@@ -1947,7 +2006,9 @@ PrimitiveTypeNode *Demangler::demanglePrimitiveType(StringView &MangledName) {
Error = true;
return nullptr;
}
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case 'N':
return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Bool);
case 'J':
@@ -1970,10 +2031,12 @@ PrimitiveTypeNode *Demangler::demanglePrimitiveType(StringView &MangledName) {
return nullptr;
}
-TagTypeNode *Demangler::demangleClassType(StringView &MangledName) {
+TagTypeNode *Demangler::demangleClassType(std::string_view &MangledName) {
TagTypeNode *TT = nullptr;
- switch (MangledName.popFront()) {
+ const char F = MangledName.front();
+ MangledName.remove_prefix(1);
+ switch (F) {
case 'T':
TT = Arena.alloc<TagTypeNode>(TagKind::Union);
break;
@@ -1984,7 +2047,7 @@ TagTypeNode *Demangler::demangleClassType(StringView &MangledName) {
TT = Arena.alloc<TagTypeNode>(TagKind::Class);
break;
case 'W':
- if (!MangledName.consumeFront('4')) {
+ if (!consumeFront(MangledName, '4')) {
Error = true;
return nullptr;
}
@@ -2000,13 +2063,13 @@ TagTypeNode *Demangler::demangleClassType(StringView &MangledName) {
// <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
// # the E is required for 64-bit non-static pointers
-PointerTypeNode *Demangler::demanglePointerType(StringView &MangledName) {
+PointerTypeNode *Demangler::demanglePointerType(std::string_view &MangledName) {
PointerTypeNode *Pointer = Arena.alloc<PointerTypeNode>();
std::tie(Pointer->Quals, Pointer->Affinity) =
demanglePointerCVQualifiers(MangledName);
- if (MangledName.consumeFront("6")) {
+ if (consumeFront(MangledName, "6")) {
Pointer->Pointee = demangleFunctionType(MangledName, false);
return Pointer;
}
@@ -2018,7 +2081,8 @@ PointerTypeNode *Demangler::demanglePointerType(StringView &MangledName) {
return Pointer;
}
-PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
+PointerTypeNode *
+Demangler::demangleMemberPointerType(std::string_view &MangledName) {
PointerTypeNode *Pointer = Arena.alloc<PointerTypeNode>();
std::tie(Pointer->Quals, Pointer->Affinity) =
@@ -2030,7 +2094,7 @@ PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
// isMemberPointer() only returns true if there is at least one character
// after the qualifiers.
- if (MangledName.consumeFront("8")) {
+ if (consumeFront(MangledName, "8")) {
Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
Pointer->Pointee = demangleFunctionType(MangledName, true);
} else {
@@ -2048,21 +2112,22 @@ PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
return Pointer;
}
-Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
+Qualifiers
+Demangler::demanglePointerExtQualifiers(std::string_view &MangledName) {
Qualifiers Quals = Q_None;
- if (MangledName.consumeFront('E'))
+ if (consumeFront(MangledName, 'E'))
Quals = Qualifiers(Quals | Q_Pointer64);
- if (MangledName.consumeFront('I'))
+ if (consumeFront(MangledName, 'I'))
Quals = Qualifiers(Quals | Q_Restrict);
- if (MangledName.consumeFront('F'))
+ if (consumeFront(MangledName, 'F'))
Quals = Qualifiers(Quals | Q_Unaligned);
return Quals;
}
-ArrayTypeNode *Demangler::demangleArrayType(StringView &MangledName) {
+ArrayTypeNode *Demangler::demangleArrayType(std::string_view &MangledName) {
assert(MangledName.front() == 'Y');
- MangledName.popFront();
+ MangledName.remove_prefix(1);
uint64_t Rank = 0;
bool IsNegative = false;
@@ -2091,7 +2156,7 @@ ArrayTypeNode *Demangler::demangleArrayType(StringView &MangledName) {
}
ATy->Dimensions = nodeListToNodeArray(Arena, Head, Rank);
- if (MangledName.consumeFront("$$C")) {
+ if (consumeFront(MangledName, "$$C")) {
bool IsMember = false;
std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
if (IsMember) {
@@ -2105,17 +2170,18 @@ ArrayTypeNode *Demangler::demangleArrayType(StringView &MangledName) {
}
// Reads a function's parameters.
-NodeArrayNode *Demangler::demangleFunctionParameterList(StringView &MangledName,
- bool &IsVariadic) {
+NodeArrayNode *
+Demangler::demangleFunctionParameterList(std::string_view &MangledName,
+ bool &IsVariadic) {
// Empty parameter list.
- if (MangledName.consumeFront('X'))
+ if (consumeFront(MangledName, 'X'))
return nullptr;
NodeList *Head = Arena.alloc<NodeList>();
NodeList **Current = &Head;
size_t Count = 0;
- while (!Error && !MangledName.startsWith('@') &&
- !MangledName.startsWith('Z')) {
+ while (!Error && !llvm::itanium_demangle::starts_with(MangledName, '@') &&
+ !llvm::itanium_demangle::starts_with(MangledName, 'Z')) {
++Count;
if (startsWithDigit(MangledName)) {
@@ -2124,7 +2190,7 @@ NodeArrayNode *Demangler::demangleFunctionParameterList(StringView &MangledName,
Error = true;
return nullptr;
}
- MangledName = MangledName.dropFront();
+ MangledName.remove_prefix(1);
*Current = Arena.alloc<NodeList>();
(*Current)->N = Backrefs.FunctionParams[N];
@@ -2159,10 +2225,10 @@ NodeArrayNode *Demangler::demangleFunctionParameterList(StringView &MangledName,
// A non-empty parameter list is terminated by either 'Z' (variadic) parameter
// list or '@' (non variadic). Careful not to consume "@Z", as in that case
// the following Z could be a throw specifier.
- if (MangledName.consumeFront('@'))
+ if (consumeFront(MangledName, '@'))
return NA;
- if (MangledName.consumeFront('Z')) {
+ if (consumeFront(MangledName, 'Z')) {
IsVariadic = true;
return NA;
}
@@ -2171,14 +2237,14 @@ NodeArrayNode *Demangler::demangleFunctionParameterList(StringView &MangledName,
}
NodeArrayNode *
-Demangler::demangleTemplateParameterList(StringView &MangledName) {
+Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
NodeList *Head = nullptr;
NodeList **Current = &Head;
size_t Count = 0;
- while (!MangledName.startsWith('@')) {
- if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
- MangledName.consumeFront("$$$V") || MangledName.consumeFront("$$Z")) {
+ while (!llvm::itanium_demangle::starts_with(MangledName, '@')) {
+ if (consumeFront(MangledName, "$S") || consumeFront(MangledName, "$$V") ||
+ consumeFront(MangledName, "$$$V") || consumeFront(MangledName, "$$Z")) {
// parameter pack separator
continue;
}
@@ -2191,29 +2257,32 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
NodeList &TP = **Current;
TemplateParameterReferenceNode *TPRN = nullptr;
- if (MangledName.consumeFront("$$Y")) {
+ if (consumeFront(MangledName, "$$Y")) {
// Template alias
TP.N = demangleFullyQualifiedTypeName(MangledName);
- } else if (MangledName.consumeFront("$$B")) {
+ } else if (consumeFront(MangledName, "$$B")) {
// Array
TP.N = demangleType(MangledName, QualifierMangleMode::Drop);
- } else if (MangledName.consumeFront("$$C")) {
+ } else if (consumeFront(MangledName, "$$C")) {
// Type has qualifiers.
TP.N = demangleType(MangledName, QualifierMangleMode::Mangle);
- } else if (MangledName.startsWith("$1") || MangledName.startsWith("$H") ||
- MangledName.startsWith("$I") || MangledName.startsWith("$J")) {
+ } else if (llvm::itanium_demangle::starts_with(MangledName, "$1") ||
+ llvm::itanium_demangle::starts_with(MangledName, "$H") ||
+ llvm::itanium_demangle::starts_with(MangledName, "$I") ||
+ llvm::itanium_demangle::starts_with(MangledName, "$J")) {
// Pointer to member
TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
TPRN->IsMemberPointer = true;
- MangledName = MangledName.dropFront();
+ MangledName.remove_prefix(1);
// 1 - single inheritance <name>
// H - multiple inheritance <name> <number>
// I - virtual inheritance <name> <number> <number>
// J - unspecified inheritance <name> <number> <number> <number>
- char InheritanceSpecifier = MangledName.popFront();
+ char InheritanceSpecifier = MangledName.front();
+ MangledName.remove_prefix(1);
SymbolNode *S = nullptr;
- if (MangledName.startsWith('?')) {
+ if (llvm::itanium_demangle::starts_with(MangledName, '?')) {
S = parse(MangledName);
if (Error || !S->Name) {
Error = true;
@@ -2242,18 +2311,20 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
}
TPRN->Affinity = PointerAffinity::Pointer;
TPRN->Symbol = S;
- } else if (MangledName.startsWith("$E?")) {
- MangledName.consumeFront("$E");
+ } else if (llvm::itanium_demangle::starts_with(MangledName, "$E?")) {
+ consumeFront(MangledName, "$E");
// Reference to symbol
TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
TPRN->Symbol = parse(MangledName);
TPRN->Affinity = PointerAffinity::Reference;
- } else if (MangledName.startsWith("$F") || MangledName.startsWith("$G")) {
+ } else if (llvm::itanium_demangle::starts_with(MangledName, "$F") ||
+ llvm::itanium_demangle::starts_with(MangledName, "$G")) {
TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
// Data member pointer.
- MangledName = MangledName.dropFront();
- char InheritanceSpecifier = MangledName.popFront();
+ MangledName.remove_prefix(1);
+ char InheritanceSpecifier = MangledName.front();
+ MangledName.remove_prefix(1);
switch (InheritanceSpecifier) {
case 'G':
@@ -2271,7 +2342,7 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
}
TPRN->IsMemberPointer = true;
- } else if (MangledName.consumeFront("$0")) {
+ } else if (consumeFront(MangledName, "$0")) {
// Integral non-type template parameter
bool IsNegative = false;
uint64_t Value = 0;
@@ -2292,8 +2363,9 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
// Template parameter lists cannot be variadic, so it can only be terminated
// by @ (as opposed to 'Z' in the function parameter case).
- assert(MangledName.startsWith('@')); // The above loop exits only on '@'.
- MangledName.consumeFront('@');
+ assert(llvm::itanium_demangle::starts_with(
+ MangledName, '@')); // The above loop exits only on '@'.
+ consumeFront(MangledName, '@');
return nodeListToNodeArray(Arena, Head, Count);
}
@@ -2309,8 +2381,8 @@ void Demangler::dumpBackReferences() {
TypeNode *T = Backrefs.FunctionParams[I];
T->output(OB, OF_Default);
- StringView B = OB;
- std::printf(" [%d] - %.*s\n", (int)I, (int)B.size(), B.begin());
+ std::string_view B = OB;
+ std::printf(" [%d] - %.*s\n", (int)I, (int)B.size(), B.data());
}
std::free(OB.getBuffer());
@@ -2319,21 +2391,20 @@ void Demangler::dumpBackReferences() {
std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I]->Name.size(),
- Backrefs.Names[I]->Name.begin());
+ Backrefs.Names[I]->Name.data());
}
if (Backrefs.NamesCount > 0)
std::printf("\n");
}
-char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled,
- char *Buf, size_t *N,
+char *llvm::microsoftDemangle(std::string_view MangledName, size_t *NMangled,
int *Status, MSDemangleFlags Flags) {
Demangler D;
- StringView Name{MangledName};
+ std::string_view Name{MangledName};
SymbolNode *AST = D.parse(Name);
if (!D.Error && NMangled)
- *NMangled = Name.begin() - MangledName;
+ *NMangled = MangledName.size() - Name.size();
if (Flags & MSDF_DumpBackrefs)
D.dumpBackReferences();
@@ -2351,14 +2422,13 @@ char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled,
OF = OutputFlags(OF | OF_NoVariableType);
int InternalStatus = demangle_success;
+ char *Buf;
if (D.Error)
InternalStatus = demangle_invalid_mangled_name;
else {
- OutputBuffer OB(Buf, N);
+ OutputBuffer OB;
AST->output(OB, OF);
OB += '\0';
- if (N != nullptr)
- *N = OB.getCurrentPosition();
Buf = OB.getBuffer();
}
diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
index 975649f28ad2..9a9c34ec6d34 100644
--- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
@@ -120,7 +120,7 @@ static void outputCallingConvention(OutputBuffer &OB, CallingConv CC) {
std::string Node::toString(OutputFlags Flags) const {
OutputBuffer OB;
this->output(OB, Flags);
- StringView SV = OB;
+ std::string_view SV = OB;
std::string Owned(SV.begin(), SV.end());
std::free(OB.getBuffer());
return Owned;
@@ -158,7 +158,7 @@ void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags) const {
}
void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags,
- StringView Separator) const {
+ std::string_view Separator) const {
if (Count == 0)
return;
if (Nodes[0])
diff --git a/llvm/lib/Demangle/RustDemangle.cpp b/llvm/lib/Demangle/RustDemangle.cpp
index 8c01155127d8..f0d70de3abb5 100644
--- a/llvm/lib/Demangle/RustDemangle.cpp
+++ b/llvm/lib/Demangle/RustDemangle.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Demangle/Demangle.h"
-#include "llvm/Demangle/StringView.h"
+#include "llvm/Demangle/StringViewExtras.h"
#include "llvm/Demangle/Utility.h"
#include <algorithm>
@@ -20,17 +20,18 @@
#include <cstdint>
#include <cstring>
#include <limits>
+#include <string_view>
using namespace llvm;
using llvm::itanium_demangle::OutputBuffer;
using llvm::itanium_demangle::ScopedOverride;
-using llvm::itanium_demangle::StringView;
+using llvm::itanium_demangle::starts_with;
namespace {
struct Identifier {
- StringView Name;
+ std::string_view Name;
bool Punycode;
bool empty() const { return Name.empty(); }
@@ -77,7 +78,7 @@ class Demangler {
size_t RecursionLevel;
size_t BoundLifetimes;
// Input string that is being demangled with "_R" prefix removed.
- StringView Input;
+ std::string_view Input;
// Position in the input string.
size_t Position;
// When true, print methods append the output to the stream.
@@ -92,7 +93,7 @@ public:
Demangler(size_t MaxRecursionLevel = 500);
- bool demangle(StringView MangledName);
+ bool demangle(std::string_view MangledName);
private:
bool demanglePath(IsInType Type,
@@ -128,10 +129,10 @@ private:
uint64_t parseOptionalBase62Number(char Tag);
uint64_t parseBase62Number();
uint64_t parseDecimalNumber();
- uint64_t parseHexNumber(StringView &HexDigits);
+ uint64_t parseHexNumber(std::string_view &HexDigits);
void print(char C);
- void print(StringView S);
+ void print(std::string_view S);
void printDecimalNumber(uint64_t N);
void printBasicType(BasicType);
void printLifetime(uint64_t Index);
@@ -147,17 +148,13 @@ private:
} // namespace
-char *llvm::rustDemangle(const char *MangledName) {
- if (MangledName == nullptr)
- return nullptr;
-
+char *llvm::rustDemangle(std::string_view MangledName) {
// Return early if mangled name doesn't look like a Rust symbol.
- StringView Mangled(MangledName);
- if (!Mangled.startsWith("_R"))
+ if (MangledName.empty() || !starts_with(MangledName, "_R"))
return nullptr;
Demangler D;
- if (!D.demangle(Mangled)) {
+ if (!D.demangle(MangledName)) {
std::free(D.Output.getBuffer());
return nullptr;
}
@@ -190,20 +187,20 @@ static inline bool isValid(const char C) {
// responsibility of the caller to free the memory behind the output stream.
//
// <symbol-name> = "_R" <path> [<instantiating-crate>]
-bool Demangler::demangle(StringView Mangled) {
+bool Demangler::demangle(std::string_view Mangled) {
Position = 0;
Error = false;
Print = true;
RecursionLevel = 0;
BoundLifetimes = 0;
- if (!Mangled.consumeFront("_R")) {
+ if (!starts_with(Mangled, "_R")) {
Error = true;
return false;
}
+ Mangled.remove_prefix(2);
size_t Dot = Mangled.find('.');
- Input = Mangled.substr(0, Dot);
- StringView Suffix = Mangled.dropFront(Dot);
+ Input = Dot == std::string_view::npos ? Mangled : Mangled.substr(0, Dot);
demanglePath(IsInType::No);
@@ -215,9 +212,9 @@ bool Demangler::demangle(StringView Mangled) {
if (Position != Input.size())
Error = true;
- if (!Suffix.empty()) {
+ if (Dot != std::string_view::npos) {
print(" (");
- print(Suffix);
+ print(Mangled.substr(Dot));
print(")");
}
@@ -775,7 +772,7 @@ void Demangler::demangleConstInt() {
if (consumeIf('n'))
print('-');
- StringView HexDigits;
+ std::string_view HexDigits;
uint64_t Value = parseHexNumber(HexDigits);
if (HexDigits.size() <= 16) {
printDecimalNumber(Value);
@@ -788,7 +785,7 @@ void Demangler::demangleConstInt() {
// <const-data> = "0_" // false
// | "1_" // true
void Demangler::demangleConstBool() {
- StringView HexDigits;
+ std::string_view HexDigits;
parseHexNumber(HexDigits);
if (HexDigits == "0")
print("false");
@@ -805,7 +802,7 @@ static bool isAsciiPrintable(uint64_t CodePoint) {
// <const-data> = <hex-number>
void Demangler::demangleConstChar() {
- StringView HexDigits;
+ std::string_view HexDigits;
uint64_t CodePoint = parseHexNumber(HexDigits);
if (Error || HexDigits.size() > 6) {
Error = true;
@@ -859,7 +856,7 @@ Identifier Demangler::parseIdentifier() {
Error = true;
return {};
}
- StringView S = Input.substr(Position, Bytes);
+ std::string_view S = Input.substr(Position, Bytes);
Position += Bytes;
if (!std::all_of(S.begin(), S.end(), isValid)) {
@@ -967,7 +964,7 @@ uint64_t Demangler::parseDecimalNumber() {
//
// <hex-number> = "0_"
// | <1-9a-f> {<0-9a-f>} "_"
-uint64_t Demangler::parseHexNumber(StringView &HexDigits) {
+uint64_t Demangler::parseHexNumber(std::string_view &HexDigits) {
size_t Start = Position;
uint64_t Value = 0;
@@ -991,7 +988,7 @@ uint64_t Demangler::parseHexNumber(StringView &HexDigits) {
}
if (Error) {
- HexDigits = StringView();
+ HexDigits = std::string_view();
return 0;
}
@@ -1008,7 +1005,7 @@ void Demangler::print(char C) {
Output += C;
}
-void Demangler::print(StringView S) {
+void Demangler::print(std::string_view S) {
if (Error || !Print)
return;
@@ -1105,17 +1102,17 @@ static inline bool encodeUTF8(size_t CodePoint, char *Output) {
// Decodes string encoded using punycode and appends results to Output.
// Returns true if decoding was successful.
-static bool decodePunycode(StringView Input, OutputBuffer &Output) {
+static bool decodePunycode(std::string_view Input, OutputBuffer &Output) {
size_t OutputSize = Output.getCurrentPosition();
size_t InputIdx = 0;
// Rust uses an underscore as a delimiter.
- size_t DelimiterPos = StringView::npos;
+ size_t DelimiterPos = std::string_view::npos;
for (size_t I = 0; I != Input.size(); ++I)
if (Input[I] == '_')
DelimiterPos = I;
- if (DelimiterPos != StringView::npos) {
+ if (DelimiterPos != std::string_view::npos) {
// Copy basic code points before the last delimiter to the output.
for (; InputIdx != DelimiterPos; ++InputIdx) {
char C = Input[InputIdx];
@@ -1123,7 +1120,7 @@ static bool decodePunycode(StringView Input, OutputBuffer &Output) {
return false;
// Code points are padded with zeros while decoding is in progress.
char UTF8[4] = {C};
- Output += StringView(UTF8, UTF8 + 4);
+ Output += std::string_view(UTF8, 4);
}
// Skip over the delimiter.
++InputIdx;