1
0
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:
Tomasz Miąsko 2021-06-23 15:59:24 +02:00
parent 7941cb8b83
commit 5a6e96d2d0
2 changed files with 205 additions and 214 deletions

View File

@ -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

View File

@ -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;
}