mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[Demangle][Rust] Parse dyn-trait-assoc-binding
Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D103364
This commit is contained in:
parent
5534f83077
commit
1d2a2e625f
@ -57,6 +57,11 @@ enum class InType {
|
||||
Yes,
|
||||
};
|
||||
|
||||
enum class LeaveOpen {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
class Demangler {
|
||||
// Maximum recursion level. Used to avoid stack overflow.
|
||||
size_t MaxRecursionLevel;
|
||||
@ -84,7 +89,7 @@ public:
|
||||
bool demangle(StringView MangledName);
|
||||
|
||||
private:
|
||||
void demanglePath(InType InType);
|
||||
bool demanglePath(InType InType, LeaveOpen LeaveOpen = LeaveOpen::No);
|
||||
void demangleImplPath(InType InType);
|
||||
void demangleGenericArg();
|
||||
void demangleType();
|
||||
|
@ -121,7 +121,10 @@ bool Demangler::demangle(StringView Mangled) {
|
||||
return !Error;
|
||||
}
|
||||
|
||||
// Demangles a path. InType indicates whether a path is inside a type.
|
||||
// Demangles a path. InType indicates whether a path is inside a type. When
|
||||
// LeaveOpen is true, a closing `>` after generic arguments is omitted from the
|
||||
// output. Return value indicates whether generics arguments have been left
|
||||
// open.
|
||||
//
|
||||
// <path> = "C" <identifier> // crate root
|
||||
// | "M" <impl-path> <type> // <T> (inherent impl)
|
||||
@ -135,10 +138,10 @@ bool Demangler::demangle(StringView Mangled) {
|
||||
// | "S" // shim
|
||||
// | <A-Z> // other special namespaces
|
||||
// | <a-z> // internal namespaces
|
||||
void Demangler::demanglePath(InType InType) {
|
||||
bool Demangler::demanglePath(InType InType, LeaveOpen LeaveOpen) {
|
||||
if (Error || RecursionLevel >= MaxRecursionLevel) {
|
||||
Error = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
SwapAndRestore<size_t> SaveRecursionLevel(RecursionLevel, RecursionLevel + 1);
|
||||
|
||||
@ -220,7 +223,10 @@ void Demangler::demanglePath(InType InType) {
|
||||
print(", ");
|
||||
demangleGenericArg();
|
||||
}
|
||||
print(">");
|
||||
if (LeaveOpen == rust_demangle::LeaveOpen::Yes)
|
||||
return true;
|
||||
else
|
||||
print(">");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -228,6 +234,8 @@ void Demangler::demanglePath(InType InType) {
|
||||
Error = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// <impl-path> = [<disambiguator>] <path>
|
||||
@ -555,8 +563,20 @@ void Demangler::demangleDynBounds() {
|
||||
// <dyn-trait> = <path> {<dyn-trait-assoc-binding>}
|
||||
// <dyn-trait-assoc-binding> = "p" <undisambiguated-identifier> <type>
|
||||
void Demangler::demangleDynTrait() {
|
||||
demanglePath(InType::Yes);
|
||||
// FIXME demangle {<dyn-trait-assoc-binding>}
|
||||
bool IsOpen = demanglePath(InType::Yes, LeaveOpen::Yes);
|
||||
while (!Error && consumeIf('p')) {
|
||||
if (!IsOpen) {
|
||||
IsOpen = true;
|
||||
print('<');
|
||||
} else {
|
||||
print(", ");
|
||||
}
|
||||
print(parseIdentifier().Name);
|
||||
print(" = ");
|
||||
demangleType();
|
||||
}
|
||||
if (IsOpen)
|
||||
print(">");
|
||||
}
|
||||
|
||||
// Demangles optional binder and updates the number of bound lifetimes.
|
||||
|
@ -252,6 +252,15 @@ CHECK: trait::<dyn Display + Send + Sync>
|
||||
CHECK: trait::<dyn for<'a> Display>
|
||||
_RIC5traitDG_C7DisplayEL_E
|
||||
|
||||
CHECK: trait::<dyn IntoIterator<_, Item = _>>
|
||||
_RIC5traitDIC12IntoIteratorpEp4ItempEL_E
|
||||
|
||||
CHECK: trait::<dyn IntoIterator<Item = _>>
|
||||
_RIC5traitDC12IntoIteratorp4ItempEL_E
|
||||
|
||||
CHECK: trait::<dyn IntoIterator<Item = _, IntoIter = _>>
|
||||
_RIC5traitDC12IntoIteratorp4Itempp8IntoIterpEL_E
|
||||
|
||||
; Invalid trait object, missing lifetime.
|
||||
|
||||
CHECK: _RIC5traitDEE
|
||||
|
Loading…
Reference in New Issue
Block a user