Introduce a new demangling function that supports symbols using Itanium mangling and Rust v0 mangling, and is expected in the near future to include support for D mangling as well. Unlike llvm::demangle, the function does not accept extra underscore decoration. The callers generally know exactly when symbols should include the extra decoration and so they should be responsible for stripping it. Functionally the only intended change is to allow demangling Rust symbols with an extra underscore decoration through llvm::demangle, which matches the existing behaviour for Itanium symbols. Reviewed By: dblaikie, jhenderson Part of https://reviews.llvm.org/D110664
58 lines
1.7 KiB
C++
58 lines
1.7 KiB
C++
//===-- Demangle.cpp - Common demangling functions ------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file This file contains definitions of common demangling functions.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Demangle/Demangle.h"
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
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'; }
|
|
|
|
std::string llvm::demangle(const std::string &MangledName) {
|
|
std::string Result;
|
|
const char *S = MangledName.c_str();
|
|
|
|
if (nonMicrosoftDemangle(S, Result))
|
|
return Result;
|
|
|
|
if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result))
|
|
return Result;
|
|
|
|
if (char *Demangled =
|
|
microsoftDemangle(S, nullptr, nullptr, nullptr, nullptr)) {
|
|
Result = Demangled;
|
|
std::free(Demangled);
|
|
return Result;
|
|
}
|
|
|
|
return MangledName;
|
|
}
|
|
|
|
bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) {
|
|
char *Demangled = nullptr;
|
|
if (isItaniumEncoding(MangledName))
|
|
Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr);
|
|
else if (isRustEncoding(MangledName))
|
|
Demangled = rustDemangle(MangledName, nullptr, nullptr, nullptr);
|
|
|
|
if (!Demangled)
|
|
return false;
|
|
|
|
Result = Demangled;
|
|
std::free(Demangled);
|
|
return true;
|
|
}
|