mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[Demangle][Rust] Hide implementation details NFC
Move content of the "public" header into the implementation file. This also renames two enumerations that were previously used through `rust_demangle::` scope, to avoid breaking a build bot with older version of GCC that rejects uses of enumerator through `E::A` if there is a variable with the same name as enumeration `E` in the scope. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D104362
This commit is contained in:
parent
7941cb8b83
commit
5a6e96d2d0
@ -1,202 +0,0 @@
|
||||
//===--- RustDemangle.h -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_DEMANGLE_RUSTDEMANGLE_H
|
||||
#define LLVM_DEMANGLE_RUSTDEMANGLE_H
|
||||
|
||||
#include "llvm/Demangle/DemangleConfig.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
namespace rust_demangle {
|
||||
|
||||
using llvm::itanium_demangle::OutputStream;
|
||||
using llvm::itanium_demangle::StringView;
|
||||
using llvm::itanium_demangle::SwapAndRestore;
|
||||
|
||||
struct Identifier {
|
||||
StringView Name;
|
||||
bool Punycode;
|
||||
|
||||
bool empty() const { return Name.empty(); }
|
||||
};
|
||||
|
||||
enum class BasicType {
|
||||
Bool,
|
||||
Char,
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
I128,
|
||||
ISize,
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
U128,
|
||||
USize,
|
||||
F32,
|
||||
F64,
|
||||
Str,
|
||||
Placeholder,
|
||||
Unit,
|
||||
Variadic,
|
||||
Never,
|
||||
};
|
||||
|
||||
enum class InType {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
enum class LeaveOpen {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
class Demangler {
|
||||
// Maximum recursion level. Used to avoid stack overflow.
|
||||
size_t MaxRecursionLevel;
|
||||
// Current recursion level.
|
||||
size_t RecursionLevel;
|
||||
size_t BoundLifetimes;
|
||||
// Input string that is being demangled with "_R" prefix removed.
|
||||
StringView Input;
|
||||
// Position in the input string.
|
||||
size_t Position;
|
||||
|
||||
// When true, print methods append the output to the stream.
|
||||
// When false, the output is suppressed.
|
||||
bool Print;
|
||||
|
||||
// True if an error occurred.
|
||||
bool Error;
|
||||
|
||||
public:
|
||||
// Demangled output.
|
||||
OutputStream Output;
|
||||
|
||||
Demangler(size_t MaxRecursionLevel = 500);
|
||||
|
||||
bool demangle(StringView MangledName);
|
||||
|
||||
private:
|
||||
bool demanglePath(InType InType, LeaveOpen LeaveOpen = LeaveOpen::No);
|
||||
void demangleImplPath(InType InType);
|
||||
void demangleGenericArg();
|
||||
void demangleType();
|
||||
void demangleFnSig();
|
||||
void demangleDynBounds();
|
||||
void demangleDynTrait();
|
||||
void demangleOptionalBinder();
|
||||
void demangleConst();
|
||||
void demangleConstInt();
|
||||
void demangleConstBool();
|
||||
void demangleConstChar();
|
||||
|
||||
template <typename Callable> void demangleBackref(Callable Demangler) {
|
||||
uint64_t Backref = parseBase62Number();
|
||||
if (Error || Backref >= Position) {
|
||||
Error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Print)
|
||||
return;
|
||||
|
||||
SwapAndRestore<size_t> SavePosition(Position, Position);
|
||||
Position = Backref;
|
||||
Demangler();
|
||||
}
|
||||
|
||||
Identifier parseIdentifier();
|
||||
uint64_t parseOptionalBase62Number(char Tag);
|
||||
uint64_t parseBase62Number();
|
||||
uint64_t parseDecimalNumber();
|
||||
uint64_t parseHexNumber(StringView &HexDigits);
|
||||
|
||||
void print(char C) {
|
||||
if (Error || !Print)
|
||||
return;
|
||||
|
||||
Output += C;
|
||||
}
|
||||
|
||||
void print(StringView S) {
|
||||
if (Error || !Print)
|
||||
return;
|
||||
|
||||
Output += S;
|
||||
}
|
||||
|
||||
void printDecimalNumber(uint64_t N) {
|
||||
if (Error || !Print)
|
||||
return;
|
||||
|
||||
Output << N;
|
||||
}
|
||||
|
||||
void printBasicType(BasicType);
|
||||
void printLifetime(uint64_t Index);
|
||||
|
||||
char look() const {
|
||||
if (Error || Position >= Input.size())
|
||||
return 0;
|
||||
|
||||
return Input[Position];
|
||||
}
|
||||
|
||||
char consume() {
|
||||
if (Error || Position >= Input.size()) {
|
||||
Error = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Input[Position++];
|
||||
}
|
||||
|
||||
bool consumeIf(char Prefix) {
|
||||
if (Error || Position >= Input.size() || Input[Position] != Prefix)
|
||||
return false;
|
||||
|
||||
Position += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Computes A + B. When computation wraps around sets the error and returns
|
||||
/// false. Otherwise assigns the result to A and returns true.
|
||||
bool addAssign(uint64_t &A, const uint64_t B) {
|
||||
if (A > std::numeric_limits<uint64_t>::max() - B) {
|
||||
Error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
A += B;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Computes A * B. When computation wraps around sets the error and returns
|
||||
/// false. Otherwise assigns the result to A and returns true.
|
||||
bool mulAssign(uint64_t &A, const uint64_t B) {
|
||||
if (B != 0 && A > std::numeric_limits<uint64_t>::max() / B) {
|
||||
Error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
A *= B;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace rust_demangle
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
@ -11,16 +11,140 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Demangle/RustDemangle.h"
|
||||
#include "llvm/Demangle/Demangle.h"
|
||||
#include "llvm/Demangle/StringView.h"
|
||||
#include "llvm/Demangle/Utility.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace rust_demangle;
|
||||
|
||||
using llvm::itanium_demangle::OutputStream;
|
||||
using llvm::itanium_demangle::StringView;
|
||||
using llvm::itanium_demangle::SwapAndRestore;
|
||||
|
||||
namespace {
|
||||
|
||||
struct Identifier {
|
||||
StringView Name;
|
||||
bool Punycode;
|
||||
|
||||
bool empty() const { return Name.empty(); }
|
||||
};
|
||||
|
||||
enum class BasicType {
|
||||
Bool,
|
||||
Char,
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
I128,
|
||||
ISize,
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
U128,
|
||||
USize,
|
||||
F32,
|
||||
F64,
|
||||
Str,
|
||||
Placeholder,
|
||||
Unit,
|
||||
Variadic,
|
||||
Never,
|
||||
};
|
||||
|
||||
enum class IsInType {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
enum class LeaveGenericsOpen {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
class Demangler {
|
||||
// Maximum recursion level. Used to avoid stack overflow.
|
||||
size_t MaxRecursionLevel;
|
||||
// Current recursion level.
|
||||
size_t RecursionLevel;
|
||||
size_t BoundLifetimes;
|
||||
// Input string that is being demangled with "_R" prefix removed.
|
||||
StringView Input;
|
||||
// Position in the input string.
|
||||
size_t Position;
|
||||
// When true, print methods append the output to the stream.
|
||||
// When false, the output is suppressed.
|
||||
bool Print;
|
||||
// True if an error occurred.
|
||||
bool Error;
|
||||
|
||||
public:
|
||||
// Demangled output.
|
||||
OutputStream Output;
|
||||
|
||||
Demangler(size_t MaxRecursionLevel = 500);
|
||||
|
||||
bool demangle(StringView MangledName);
|
||||
|
||||
private:
|
||||
bool demanglePath(IsInType Type,
|
||||
LeaveGenericsOpen LeaveOpen = LeaveGenericsOpen::No);
|
||||
void demangleImplPath(IsInType InType);
|
||||
void demangleGenericArg();
|
||||
void demangleType();
|
||||
void demangleFnSig();
|
||||
void demangleDynBounds();
|
||||
void demangleDynTrait();
|
||||
void demangleOptionalBinder();
|
||||
void demangleConst();
|
||||
void demangleConstInt();
|
||||
void demangleConstBool();
|
||||
void demangleConstChar();
|
||||
|
||||
template <typename Callable> void demangleBackref(Callable Demangler) {
|
||||
uint64_t Backref = parseBase62Number();
|
||||
if (Error || Backref >= Position) {
|
||||
Error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Print)
|
||||
return;
|
||||
|
||||
SwapAndRestore<size_t> SavePosition(Position, Position);
|
||||
Position = Backref;
|
||||
Demangler();
|
||||
}
|
||||
|
||||
Identifier parseIdentifier();
|
||||
uint64_t parseOptionalBase62Number(char Tag);
|
||||
uint64_t parseBase62Number();
|
||||
uint64_t parseDecimalNumber();
|
||||
uint64_t parseHexNumber(StringView &HexDigits);
|
||||
|
||||
void print(char C);
|
||||
void print(StringView S);
|
||||
void printDecimalNumber(uint64_t N);
|
||||
void printBasicType(BasicType);
|
||||
void printLifetime(uint64_t Index);
|
||||
|
||||
char look() const;
|
||||
char consume();
|
||||
bool consumeIf(char Prefix);
|
||||
|
||||
bool addAssign(uint64_t &A, uint64_t B);
|
||||
bool mulAssign(uint64_t &A, uint64_t B);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
char *llvm::rustDemangle(const char *MangledName, char *Buf, size_t *N,
|
||||
int *Status) {
|
||||
@ -113,11 +237,11 @@ bool Demangler::demangle(StringView Mangled) {
|
||||
Input = Mangled.substr(0, Dot);
|
||||
StringView Suffix = Mangled.dropFront(Dot);
|
||||
|
||||
demanglePath(rust_demangle::InType::No);
|
||||
demanglePath(IsInType::No);
|
||||
|
||||
if (Position != Input.size()) {
|
||||
SwapAndRestore<bool> SavePrint(Print, false);
|
||||
demanglePath(InType::No);
|
||||
demanglePath(IsInType::No);
|
||||
}
|
||||
|
||||
if (Position != Input.size())
|
||||
@ -149,7 +273,7 @@ bool Demangler::demangle(StringView Mangled) {
|
||||
// | "S" // shim
|
||||
// | <A-Z> // other special namespaces
|
||||
// | <a-z> // internal namespaces
|
||||
bool Demangler::demanglePath(InType InType, LeaveOpen LeaveOpen) {
|
||||
bool Demangler::demanglePath(IsInType InType, LeaveGenericsOpen LeaveOpen) {
|
||||
if (Error || RecursionLevel >= MaxRecursionLevel) {
|
||||
Error = true;
|
||||
return false;
|
||||
@ -175,7 +299,7 @@ bool Demangler::demanglePath(InType InType, LeaveOpen LeaveOpen) {
|
||||
print("<");
|
||||
demangleType();
|
||||
print(" as ");
|
||||
demanglePath(rust_demangle::InType::Yes);
|
||||
demanglePath(IsInType::Yes);
|
||||
print(">");
|
||||
break;
|
||||
}
|
||||
@ -183,7 +307,7 @@ bool Demangler::demanglePath(InType InType, LeaveOpen LeaveOpen) {
|
||||
print("<");
|
||||
demangleType();
|
||||
print(" as ");
|
||||
demanglePath(rust_demangle::InType::Yes);
|
||||
demanglePath(IsInType::Yes);
|
||||
print(">");
|
||||
break;
|
||||
}
|
||||
@ -226,7 +350,7 @@ bool Demangler::demanglePath(InType InType, LeaveOpen LeaveOpen) {
|
||||
case 'I': {
|
||||
demanglePath(InType);
|
||||
// Omit "::" when in a type, where it is optional.
|
||||
if (InType == rust_demangle::InType::No)
|
||||
if (InType == IsInType::No)
|
||||
print("::");
|
||||
print("<");
|
||||
for (size_t I = 0; !Error && !consumeIf('E'); ++I) {
|
||||
@ -234,7 +358,7 @@ bool Demangler::demanglePath(InType InType, LeaveOpen LeaveOpen) {
|
||||
print(", ");
|
||||
demangleGenericArg();
|
||||
}
|
||||
if (LeaveOpen == rust_demangle::LeaveOpen::Yes)
|
||||
if (LeaveOpen == LeaveGenericsOpen::Yes)
|
||||
return true;
|
||||
else
|
||||
print(">");
|
||||
@ -255,7 +379,7 @@ bool Demangler::demanglePath(InType InType, LeaveOpen LeaveOpen) {
|
||||
|
||||
// <impl-path> = [<disambiguator>] <path>
|
||||
// <disambiguator> = "s" <base-62-number>
|
||||
void Demangler::demangleImplPath(InType InType) {
|
||||
void Demangler::demangleImplPath(IsInType InType) {
|
||||
SwapAndRestore<bool> SavePrint(Print, false);
|
||||
parseOptionalBase62Number('s');
|
||||
demanglePath(InType);
|
||||
@ -524,7 +648,7 @@ void Demangler::demangleType() {
|
||||
break;
|
||||
default:
|
||||
Position = Start;
|
||||
demanglePath(rust_demangle::InType::Yes);
|
||||
demanglePath(IsInType::Yes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -586,7 +710,7 @@ void Demangler::demangleDynBounds() {
|
||||
// <dyn-trait> = <path> {<dyn-trait-assoc-binding>}
|
||||
// <dyn-trait-assoc-binding> = "p" <undisambiguated-identifier> <type>
|
||||
void Demangler::demangleDynTrait() {
|
||||
bool IsOpen = demanglePath(InType::Yes, LeaveOpen::Yes);
|
||||
bool IsOpen = demanglePath(IsInType::Yes, LeaveGenericsOpen::Yes);
|
||||
while (!Error && consumeIf('p')) {
|
||||
if (!IsOpen) {
|
||||
IsOpen = true;
|
||||
@ -908,6 +1032,27 @@ uint64_t Demangler::parseHexNumber(StringView &HexDigits) {
|
||||
return Value;
|
||||
}
|
||||
|
||||
void Demangler::print(char C) {
|
||||
if (Error || !Print)
|
||||
return;
|
||||
|
||||
Output += C;
|
||||
}
|
||||
|
||||
void Demangler::print(StringView S) {
|
||||
if (Error || !Print)
|
||||
return;
|
||||
|
||||
Output += S;
|
||||
}
|
||||
|
||||
void Demangler::printDecimalNumber(uint64_t N) {
|
||||
if (Error || !Print)
|
||||
return;
|
||||
|
||||
Output << N;
|
||||
}
|
||||
|
||||
// Prints a lifetime. An index 0 always represents an erased lifetime. Indices
|
||||
// starting from 1, are De Bruijn indices, referring to higher-ranked lifetimes
|
||||
// bound by one of the enclosing binders.
|
||||
@ -932,3 +1077,51 @@ void Demangler::printLifetime(uint64_t Index) {
|
||||
printDecimalNumber(Depth - 26 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
char Demangler::look() const {
|
||||
if (Error || Position >= Input.size())
|
||||
return 0;
|
||||
|
||||
return Input[Position];
|
||||
}
|
||||
|
||||
char Demangler::consume() {
|
||||
if (Error || Position >= Input.size()) {
|
||||
Error = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Input[Position++];
|
||||
}
|
||||
|
||||
bool Demangler::consumeIf(char Prefix) {
|
||||
if (Error || Position >= Input.size() || Input[Position] != Prefix)
|
||||
return false;
|
||||
|
||||
Position += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Computes A + B. When computation wraps around sets the error and returns
|
||||
/// false. Otherwise assigns the result to A and returns true.
|
||||
bool Demangler::addAssign(uint64_t &A, uint64_t B) {
|
||||
if (A > std::numeric_limits<uint64_t>::max() - B) {
|
||||
Error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
A += B;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Computes A * B. When computation wraps around sets the error and returns
|
||||
/// false. Otherwise assigns the result to A and returns true.
|
||||
bool Demangler::mulAssign(uint64_t &A, uint64_t B) {
|
||||
if (B != 0 && A > std::numeric_limits<uint64_t>::max() / B) {
|
||||
Error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
A *= B;
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user