From 6cc6ada143236f16faf8b383d73e00e709fa6a9f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 23 Jun 2021 15:59:24 +0200 Subject: [PATCH] [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 --- llvm/include/llvm/Demangle/RustDemangle.h | 202 --------------------------- llvm/lib/Demangle/RustDemangle.cpp | 217 ++++++++++++++++++++++++++++-- 2 files changed, 205 insertions(+), 214 deletions(-) delete mode 100644 llvm/include/llvm/Demangle/RustDemangle.h diff --git a/llvm/include/llvm/Demangle/RustDemangle.h b/llvm/include/llvm/Demangle/RustDemangle.h deleted file mode 100644 index b377e61..0000000 --- a/llvm/include/llvm/Demangle/RustDemangle.h +++ /dev/null @@ -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 - -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 void demangleBackref(Callable Demangler) { - uint64_t Backref = parseBase62Number(); - if (Error || Backref >= Position) { - Error = true; - return; - } - - if (!Print) - return; - - SwapAndRestore 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::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::max() / B) { - Error = true; - return false; - } - - A *= B; - return true; - } -}; - -} // namespace rust_demangle -} // namespace llvm - -#endif diff --git a/llvm/lib/Demangle/RustDemangle.cpp b/llvm/lib/Demangle/RustDemangle.cpp index 39db8fd..f916300 100644 --- a/llvm/lib/Demangle/RustDemangle.cpp +++ b/llvm/lib/Demangle/RustDemangle.cpp @@ -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 #include +#include #include #include 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 void demangleBackref(Callable Demangler) { + uint64_t Backref = parseBase62Number(); + if (Error || Backref >= Position) { + Error = true; + return; + } + + if (!Print) + return; + + SwapAndRestore 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 SavePrint(Print, false); - demanglePath(InType::No); + demanglePath(IsInType::No); } if (Position != Input.size()) @@ -149,7 +273,7 @@ bool Demangler::demangle(StringView Mangled) { // | "S" // shim // | // other special namespaces // | // 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) { // = [] // = "s" -void Demangler::demangleImplPath(InType InType) { +void Demangler::demangleImplPath(IsInType InType) { SwapAndRestore 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() { // = {} // = "p" 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::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::max() / B) { + Error = true; + return false; + } + + A *= B; + return true; +} -- 2.7.4