201c4b9cc4
The rust demangler has some odd buffer handling code, which will copy the demangled string into the provided buffer, if it will fit. Otherwise it uses the allocated buffer it made. But the length of the incoming buffer will have come from a previous call, which was the length of the demangled string -- not the buffer size. And of course, we're unconditionally allocating a temporary buffer in the first place. So we don't actually get buffer reuse, and we get a memcpy in somecases. However, nothing in LLVM ever passes in a non-null pointer. Neither does anything pass in a status pointer that is then made use of. The only exercise these have is in the test suite. So let's just make the rust demangler have the same API as the dlang demangler. Reviewed By: tmiasko Differential Revision: https://reviews.llvm.org/D123420
65 lines
1.9 KiB
C++
65 lines
1.9 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'; }
|
|
|
|
static bool isDLangEncoding(const std::string &MangledName) {
|
|
return MangledName.size() >= 2 && MangledName[0] == '_' &&
|
|
MangledName[1] == 'D';
|
|
}
|
|
|
|
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);
|
|
else if (isDLangEncoding(MangledName))
|
|
Demangled = dlangDemangle(MangledName);
|
|
|
|
if (!Demangled)
|
|
return false;
|
|
|
|
Result = Demangled;
|
|
std::free(Demangled);
|
|
return true;
|
|
}
|