Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
This commit is contained in:
1
vendor/rustc-demangle/.cargo-checksum.json
vendored
Normal file
1
vendor/rustc-demangle/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"f4132bc65d5e58e2f27b9f9ef197b1c286582137b65285292b75a5a230fc81c8","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"3bb7af78423e95b207beebd452cdd973d65663cf25a0fc9358c588f53783293c","src/legacy.rs":"b4d5a140ed0bf2d792431961d6fd44a21c99235489a2c9f6717d1577a42c09ce","src/lib.rs":"607fe60c1e65da3f86a0b4b8fececb7db79049a0cd4cb316492e8e6593bf39c6","src/v0-large-test-symbols/early-recursion-limit":"96861a7042db35ee0bd04802820d0f2d6a3b534ce13547912b6364001ffd1494","src/v0.rs":"4e5bd069aa61def3dc732b3a285861914895272668ddfcb6b9eef46dd5713041"},"package":"d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"}
|
49
vendor/rustc-demangle/Cargo.toml
vendored
Normal file
49
vendor/rustc-demangle/Cargo.toml
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
description = """
|
||||
Rust compiler symbol demangling.
|
||||
"""
|
||||
homepage = "https://github.com/alexcrichton/rustc-demangle"
|
||||
documentation = "https://docs.rs/rustc-demangle"
|
||||
readme = "README.md"
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/alexcrichton/rustc-demangle"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["std"]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
[dependencies.compiler_builtins]
|
||||
version = "0.1.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.core]
|
||||
version = "1.0.0"
|
||||
optional = true
|
||||
package = "rustc-std-workspace-core"
|
||||
|
||||
[features]
|
||||
rustc-dep-of-std = [
|
||||
"core",
|
||||
"compiler_builtins",
|
||||
]
|
||||
std = []
|
201
vendor/rustc-demangle/LICENSE-APACHE
vendored
Normal file
201
vendor/rustc-demangle/LICENSE-APACHE
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
25
vendor/rustc-demangle/LICENSE-MIT
vendored
Normal file
25
vendor/rustc-demangle/LICENSE-MIT
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2014 Alex Crichton
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
48
vendor/rustc-demangle/README.md
vendored
Normal file
48
vendor/rustc-demangle/README.md
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
# rustc-demangle
|
||||
|
||||
Demangling for Rust symbols, written in Rust.
|
||||
|
||||
[Documentation](https://docs.rs/rustc-demangle)
|
||||
|
||||
## Usage
|
||||
|
||||
You can add this as a dependency via your `Cargo.toml`
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
rustc-demangle = "0.1"
|
||||
```
|
||||
|
||||
and then be sure to check out the [crate
|
||||
documentation](https://docs.rs/rustc-demangle) for usage.
|
||||
|
||||
## Usage from non-Rust languages
|
||||
|
||||
You can also use this crate from other languages via the C API wrapper in the
|
||||
`crates/capi` directory. This can be build with:
|
||||
|
||||
```sh
|
||||
$ cargo build -p rustc-demangle-capi --release
|
||||
```
|
||||
|
||||
You'll then find `target/release/librustc_demangle.a` and
|
||||
`target/release/librustc_demangle.so` (or a different name depending on your
|
||||
platform). These objects implement the interface specified in
|
||||
`crates/capi/include/rustc_demangle.h`.
|
||||
|
||||
# License
|
||||
|
||||
This project is licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||
http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in rustc-demangle you, as defined in the Apache-2.0 license, shall
|
||||
be dual licensed as above, without any additional terms or conditions.
|
392
vendor/rustc-demangle/src/legacy.rs
vendored
Normal file
392
vendor/rustc-demangle/src/legacy.rs
vendored
Normal file
@ -0,0 +1,392 @@
|
||||
use core::char;
|
||||
use core::fmt;
|
||||
|
||||
/// Representation of a demangled symbol name.
|
||||
pub struct Demangle<'a> {
|
||||
inner: &'a str,
|
||||
/// The number of ::-separated elements in the original name.
|
||||
elements: usize,
|
||||
}
|
||||
|
||||
/// De-mangles a Rust symbol into a more readable version
|
||||
///
|
||||
/// All Rust symbols by default are mangled as they contain characters that
|
||||
/// cannot be represented in all object files. The mangling mechanism is similar
|
||||
/// to C++'s, but Rust has a few specifics to handle items like lifetimes in
|
||||
/// symbols.
|
||||
///
|
||||
/// This function will take a **mangled** symbol and return a value. When printed,
|
||||
/// the de-mangled version will be written. If the symbol does not look like
|
||||
/// a mangled symbol, the original value will be written instead.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use rustc_demangle::demangle;
|
||||
///
|
||||
/// assert_eq!(demangle("_ZN4testE").to_string(), "test");
|
||||
/// assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar");
|
||||
/// assert_eq!(demangle("foo").to_string(), "foo");
|
||||
/// ```
|
||||
|
||||
// All Rust symbols are in theory lists of "::"-separated identifiers. Some
|
||||
// assemblers, however, can't handle these characters in symbol names. To get
|
||||
// around this, we use C++-style mangling. The mangling method is:
|
||||
//
|
||||
// 1. Prefix the symbol with "_ZN"
|
||||
// 2. For each element of the path, emit the length plus the element
|
||||
// 3. End the path with "E"
|
||||
//
|
||||
// For example, "_ZN4testE" => "test" and "_ZN3foo3barE" => "foo::bar".
|
||||
//
|
||||
// We're the ones printing our backtraces, so we can't rely on anything else to
|
||||
// demangle our symbols. It's *much* nicer to look at demangled symbols, so
|
||||
// this function is implemented to give us nice pretty output.
|
||||
//
|
||||
// Note that this demangler isn't quite as fancy as it could be. We have lots
|
||||
// of other information in our symbols like hashes, version, type information,
|
||||
// etc. Additionally, this doesn't handle glue symbols at all.
|
||||
pub fn demangle(s: &str) -> Result<(Demangle, &str), ()> {
|
||||
// First validate the symbol. If it doesn't look like anything we're
|
||||
// expecting, we just print it literally. Note that we must handle non-Rust
|
||||
// symbols because we could have any function in the backtrace.
|
||||
let inner = if s.starts_with("_ZN") {
|
||||
&s[3..]
|
||||
} else if s.starts_with("ZN") {
|
||||
// On Windows, dbghelp strips leading underscores, so we accept "ZN...E"
|
||||
// form too.
|
||||
&s[2..]
|
||||
} else if s.starts_with("__ZN") {
|
||||
// On OSX, symbols are prefixed with an extra _
|
||||
&s[4..]
|
||||
} else {
|
||||
return Err(());
|
||||
};
|
||||
|
||||
// only work with ascii text
|
||||
if inner.bytes().any(|c| c & 0x80 != 0) {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let mut elements = 0;
|
||||
let mut chars = inner.chars();
|
||||
let mut c = chars.next().ok_or(())?;
|
||||
while c != 'E' {
|
||||
// Decode an identifier element's length.
|
||||
if !c.is_digit(10) {
|
||||
return Err(());
|
||||
}
|
||||
let mut len = 0usize;
|
||||
while let Some(d) = c.to_digit(10) {
|
||||
len = len
|
||||
.checked_mul(10)
|
||||
.and_then(|len| len.checked_add(d as usize))
|
||||
.ok_or(())?;
|
||||
c = chars.next().ok_or(())?;
|
||||
}
|
||||
|
||||
// `c` already contains the first character of this identifier, skip it and
|
||||
// all the other characters of this identifier, to reach the next element.
|
||||
for _ in 0..len {
|
||||
c = chars.next().ok_or(())?;
|
||||
}
|
||||
|
||||
elements += 1;
|
||||
}
|
||||
|
||||
Ok((Demangle { inner, elements }, chars.as_str()))
|
||||
}
|
||||
|
||||
// Rust hashes are hex digits with an `h` prepended.
|
||||
fn is_rust_hash(s: &str) -> bool {
|
||||
s.starts_with('h') && s[1..].chars().all(|c| c.is_digit(16))
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for Demangle<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Alright, let's do this.
|
||||
let mut inner = self.inner;
|
||||
for element in 0..self.elements {
|
||||
let mut rest = inner;
|
||||
while rest.chars().next().unwrap().is_digit(10) {
|
||||
rest = &rest[1..];
|
||||
}
|
||||
let i: usize = inner[..(inner.len() - rest.len())].parse().unwrap();
|
||||
inner = &rest[i..];
|
||||
rest = &rest[..i];
|
||||
// Skip printing the hash if alternate formatting
|
||||
// was requested.
|
||||
if f.alternate() && element + 1 == self.elements && is_rust_hash(&rest) {
|
||||
break;
|
||||
}
|
||||
if element != 0 {
|
||||
f.write_str("::")?;
|
||||
}
|
||||
if rest.starts_with("_$") {
|
||||
rest = &rest[1..];
|
||||
}
|
||||
loop {
|
||||
if rest.starts_with('.') {
|
||||
if let Some('.') = rest[1..].chars().next() {
|
||||
f.write_str("::")?;
|
||||
rest = &rest[2..];
|
||||
} else {
|
||||
f.write_str(".")?;
|
||||
rest = &rest[1..];
|
||||
}
|
||||
} else if rest.starts_with('$') {
|
||||
let (escape, after_escape) = if let Some(end) = rest[1..].find('$') {
|
||||
(&rest[1..=end], &rest[end + 2..])
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
|
||||
// see src/librustc_codegen_utils/symbol_names/legacy.rs for these mappings
|
||||
let unescaped = match escape {
|
||||
"SP" => "@",
|
||||
"BP" => "*",
|
||||
"RF" => "&",
|
||||
"LT" => "<",
|
||||
"GT" => ">",
|
||||
"LP" => "(",
|
||||
"RP" => ")",
|
||||
"C" => ",",
|
||||
|
||||
_ => {
|
||||
if escape.starts_with('u') {
|
||||
let digits = &escape[1..];
|
||||
let all_lower_hex = digits.chars().all(|c| match c {
|
||||
'0'..='9' | 'a'..='f' => true,
|
||||
_ => false,
|
||||
});
|
||||
let c = u32::from_str_radix(digits, 16)
|
||||
.ok()
|
||||
.and_then(char::from_u32);
|
||||
if let (true, Some(c)) = (all_lower_hex, c) {
|
||||
// FIXME(eddyb) do we need to filter out control codepoints?
|
||||
if !c.is_control() {
|
||||
c.fmt(f)?;
|
||||
rest = after_escape;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
f.write_str(unescaped)?;
|
||||
rest = after_escape;
|
||||
} else if let Some(i) = rest.find(|c| c == '$' || c == '.') {
|
||||
f.write_str(&rest[..i])?;
|
||||
rest = &rest[i..];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
f.write_str(rest)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::prelude::v1::*;
|
||||
|
||||
macro_rules! t {
|
||||
($a:expr, $b:expr) => {
|
||||
assert!(ok($a, $b))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! t_err {
|
||||
($a:expr) => {
|
||||
assert!(ok_err($a))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! t_nohash {
|
||||
($a:expr, $b:expr) => {{
|
||||
assert_eq!(format!("{:#}", ::demangle($a)), $b);
|
||||
}};
|
||||
}
|
||||
|
||||
fn ok(sym: &str, expected: &str) -> bool {
|
||||
match ::try_demangle(sym) {
|
||||
Ok(s) => {
|
||||
if s.to_string() == expected {
|
||||
true
|
||||
} else {
|
||||
println!("\n{}\n!=\n{}\n", s, expected);
|
||||
false
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
println!("error demangling");
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_err(sym: &str) -> bool {
|
||||
match ::try_demangle(sym) {
|
||||
Ok(_) => {
|
||||
println!("succeeded in demangling");
|
||||
false
|
||||
}
|
||||
Err(_) => ::demangle(sym).to_string() == sym,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle() {
|
||||
t_err!("test");
|
||||
t!("_ZN4testE", "test");
|
||||
t_err!("_ZN4test");
|
||||
t!("_ZN4test1a2bcE", "test::a::bc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_dollars() {
|
||||
t!("_ZN4$RP$E", ")");
|
||||
t!("_ZN8$RF$testE", "&test");
|
||||
t!("_ZN8$BP$test4foobE", "*test::foob");
|
||||
t!("_ZN9$u20$test4foobE", " test::foob");
|
||||
t!("_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E", "Bar<[u32; 4]>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_many_dollars() {
|
||||
t!("_ZN13test$u20$test4foobE", "test test::foob");
|
||||
t!("_ZN12test$BP$test4foobE", "test*test::foob");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_osx() {
|
||||
t!(
|
||||
"__ZN5alloc9allocator6Layout9for_value17h02a996811f781011E",
|
||||
"alloc::allocator::Layout::for_value::h02a996811f781011"
|
||||
);
|
||||
t!("__ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap18_MSG_FILE_LINE_COL17haf7cb8d5824ee659E", "<core::option::Option<T>>::unwrap::_MSG_FILE_LINE_COL::haf7cb8d5824ee659");
|
||||
t!("__ZN4core5slice89_$LT$impl$u20$core..iter..traits..IntoIterator$u20$for$u20$$RF$$u27$a$u20$$u5b$T$u5d$$GT$9into_iter17h450e234d27262170E", "core::slice::<impl core::iter::traits::IntoIterator for &'a [T]>::into_iter::h450e234d27262170");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_windows() {
|
||||
t!("ZN4testE", "test");
|
||||
t!("ZN13test$u20$test4foobE", "test test::foob");
|
||||
t!("ZN12test$RF$test4foobE", "test&test::foob");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_elements_beginning_with_underscore() {
|
||||
t!("_ZN13_$LT$test$GT$E", "<test>");
|
||||
t!("_ZN28_$u7b$$u7b$closure$u7d$$u7d$E", "{{closure}}");
|
||||
t!("_ZN15__STATIC_FMTSTRE", "__STATIC_FMTSTR");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_trait_impls() {
|
||||
t!(
|
||||
"_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3barE",
|
||||
"<Test + 'static as foo::Bar<Test>>::bar"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_without_hash() {
|
||||
let s = "_ZN3foo17h05af221e174051e9E";
|
||||
t!(s, "foo::h05af221e174051e9");
|
||||
t_nohash!(s, "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_without_hash_edgecases() {
|
||||
// One element, no hash.
|
||||
t_nohash!("_ZN3fooE", "foo");
|
||||
// Two elements, no hash.
|
||||
t_nohash!("_ZN3foo3barE", "foo::bar");
|
||||
// Longer-than-normal hash.
|
||||
t_nohash!("_ZN3foo20h05af221e174051e9abcE", "foo");
|
||||
// Shorter-than-normal hash.
|
||||
t_nohash!("_ZN3foo5h05afE", "foo");
|
||||
// Valid hash, but not at the end.
|
||||
t_nohash!("_ZN17h05af221e174051e93fooE", "h05af221e174051e9::foo");
|
||||
// Not a valid hash, missing the 'h'.
|
||||
t_nohash!("_ZN3foo16ffaf221e174051e9E", "foo::ffaf221e174051e9");
|
||||
// Not a valid hash, has a non-hex-digit.
|
||||
t_nohash!("_ZN3foo17hg5af221e174051e9E", "foo::hg5af221e174051e9");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_thinlto() {
|
||||
// One element, no hash.
|
||||
t!("_ZN3fooE.llvm.9D1C9369", "foo");
|
||||
t!("_ZN3fooE.llvm.9D1C9369@@16", "foo");
|
||||
t_nohash!(
|
||||
"_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9",
|
||||
"backtrace::foo"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_llvm_ir_branch_labels() {
|
||||
t!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice::<impl core::ops::index::IndexMut<I> for [T]>::index_mut::haf9727c2edfbc47b.exit.i.i");
|
||||
t_nohash!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice::<impl core::ops::index::IndexMut<I> for [T]>::index_mut.exit.i.i");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_ignores_suffix_that_doesnt_look_like_a_symbol() {
|
||||
t_err!("_ZN3fooE.llvm moocow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dont_panic() {
|
||||
::demangle("_ZN2222222222222222222222EE").to_string();
|
||||
::demangle("_ZN5*70527e27.ll34csaғE").to_string();
|
||||
::demangle("_ZN5*70527a54.ll34_$b.1E").to_string();
|
||||
::demangle(
|
||||
"\
|
||||
_ZN5~saäb4e\n\
|
||||
2734cOsbE\n\
|
||||
5usage20h)3\0\0\0\0\0\0\07e2734cOsbE\
|
||||
",
|
||||
)
|
||||
.to_string();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_no_chop() {
|
||||
t_err!("_ZNfooE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handle_assoc_types() {
|
||||
t!("_ZN151_$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$9call_once17h69e8f44b3723e1caE", "<alloc::boxed::Box<alloc::boxed::FnBox<A, Output=R> + 'a> as core::ops::function::FnOnce<A>>::call_once::h69e8f44b3723e1ca");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handle_bang() {
|
||||
t!(
|
||||
"_ZN88_$LT$core..result..Result$LT$$u21$$C$$u20$E$GT$$u20$as$u20$std..process..Termination$GT$6report17hfc41d0da4a40b3e8E",
|
||||
"<core::result::Result<!, E> as std::process::Termination>::report::hfc41d0da4a40b3e8"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_utf8_idents() {
|
||||
t_nohash!(
|
||||
"_ZN11utf8_idents157_$u10e1$$u10d0$$u10ed$$u10db$$u10d4$$u10da$$u10d0$$u10d3$_$u10d2$$u10d4$$u10db$$u10e0$$u10d8$$u10d4$$u10da$$u10d8$_$u10e1$$u10d0$$u10d3$$u10d8$$u10da$$u10d8$17h21634fd5714000aaE",
|
||||
"utf8_idents::საჭმელად_გემრიელი_სადილი"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_issue_60925() {
|
||||
t_nohash!(
|
||||
"_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h059a991a004536adE",
|
||||
"issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo"
|
||||
);
|
||||
}
|
||||
}
|
588
vendor/rustc-demangle/src/lib.rs
vendored
Normal file
588
vendor/rustc-demangle/src/lib.rs
vendored
Normal file
@ -0,0 +1,588 @@
|
||||
//! Demangle Rust compiler symbol names.
|
||||
//!
|
||||
//! This crate provides a `demangle` function which will return a `Demangle`
|
||||
//! sentinel value that can be used to learn about the demangled version of a
|
||||
//! symbol name. The demangled representation will be the same as the original
|
||||
//! if it doesn't look like a mangled symbol name.
|
||||
//!
|
||||
//! `Demangle` can be formatted with the `Display` trait. The alternate
|
||||
//! modifier (`#`) can be used to format the symbol name without the
|
||||
//! trailing hash value.
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! use rustc_demangle::demangle;
|
||||
//!
|
||||
//! assert_eq!(demangle("_ZN4testE").to_string(), "test");
|
||||
//! assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar");
|
||||
//! assert_eq!(demangle("foo").to_string(), "foo");
|
||||
//! // With hash
|
||||
//! assert_eq!(format!("{}", demangle("_ZN3foo17h05af221e174051e9E")), "foo::h05af221e174051e9");
|
||||
//! // Without hash
|
||||
//! assert_eq!(format!("{:#}", demangle("_ZN3foo17h05af221e174051e9E")), "foo");
|
||||
//! ```
|
||||
|
||||
#![no_std]
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
#[cfg(any(test, feature = "std"))]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
|
||||
// HACK(eddyb) helper macros for tests.
|
||||
#[cfg(test)]
|
||||
macro_rules! assert_contains {
|
||||
($s:expr, $needle:expr) => {{
|
||||
let (s, needle) = ($s, $needle);
|
||||
assert!(
|
||||
s.contains(needle),
|
||||
"{:?} should've contained {:?}",
|
||||
s,
|
||||
needle
|
||||
);
|
||||
}};
|
||||
}
|
||||
#[cfg(test)]
|
||||
macro_rules! assert_ends_with {
|
||||
($s:expr, $suffix:expr) => {{
|
||||
let (s, suffix) = ($s, $suffix);
|
||||
assert!(
|
||||
s.ends_with(suffix),
|
||||
"{:?} should've ended in {:?}",
|
||||
s,
|
||||
suffix
|
||||
);
|
||||
}};
|
||||
}
|
||||
|
||||
mod legacy;
|
||||
mod v0;
|
||||
|
||||
use core::fmt::{self, Write as _};
|
||||
|
||||
/// Representation of a demangled symbol name.
|
||||
pub struct Demangle<'a> {
|
||||
style: Option<DemangleStyle<'a>>,
|
||||
original: &'a str,
|
||||
suffix: &'a str,
|
||||
}
|
||||
|
||||
enum DemangleStyle<'a> {
|
||||
Legacy(legacy::Demangle<'a>),
|
||||
V0(v0::Demangle<'a>),
|
||||
}
|
||||
|
||||
/// De-mangles a Rust symbol into a more readable version
|
||||
///
|
||||
/// This function will take a **mangled** symbol and return a value. When printed,
|
||||
/// the de-mangled version will be written. If the symbol does not look like
|
||||
/// a mangled symbol, the original value will be written instead.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use rustc_demangle::demangle;
|
||||
///
|
||||
/// assert_eq!(demangle("_ZN4testE").to_string(), "test");
|
||||
/// assert_eq!(demangle("_ZN3foo3barE").to_string(), "foo::bar");
|
||||
/// assert_eq!(demangle("foo").to_string(), "foo");
|
||||
/// ```
|
||||
pub fn demangle(mut s: &str) -> Demangle {
|
||||
// During ThinLTO LLVM may import and rename internal symbols, so strip out
|
||||
// those endings first as they're one of the last manglings applied to symbol
|
||||
// names.
|
||||
let llvm = ".llvm.";
|
||||
if let Some(i) = s.find(llvm) {
|
||||
let candidate = &s[i + llvm.len()..];
|
||||
let all_hex = candidate.chars().all(|c| match c {
|
||||
'A'..='F' | '0'..='9' | '@' => true,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
if all_hex {
|
||||
s = &s[..i];
|
||||
}
|
||||
}
|
||||
|
||||
let mut suffix = "";
|
||||
let mut style = match legacy::demangle(s) {
|
||||
Ok((d, s)) => {
|
||||
suffix = s;
|
||||
Some(DemangleStyle::Legacy(d))
|
||||
}
|
||||
Err(()) => match v0::demangle(s) {
|
||||
Ok((d, s)) => {
|
||||
suffix = s;
|
||||
Some(DemangleStyle::V0(d))
|
||||
}
|
||||
// FIXME(eddyb) would it make sense to treat an unknown-validity
|
||||
// symbol (e.g. one that errored with `RecursedTooDeep`) as
|
||||
// v0-mangled, and have the error show up in the demangling?
|
||||
// (that error already gets past this initial check, and therefore
|
||||
// will show up in the demangling, if hidden behind a backref)
|
||||
Err(v0::ParseError::Invalid) | Err(v0::ParseError::RecursedTooDeep) => None,
|
||||
},
|
||||
};
|
||||
|
||||
// Output like LLVM IR adds extra period-delimited words. See if
|
||||
// we are in that case and save the trailing words if so.
|
||||
if !suffix.is_empty() {
|
||||
if suffix.starts_with('.') && is_symbol_like(suffix) {
|
||||
// Keep the suffix.
|
||||
} else {
|
||||
// Reset the suffix and invalidate the demangling.
|
||||
suffix = "";
|
||||
style = None;
|
||||
}
|
||||
}
|
||||
|
||||
Demangle {
|
||||
style,
|
||||
original: s,
|
||||
suffix,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn demangle_line(
|
||||
line: &str,
|
||||
output: &mut impl std::io::Write,
|
||||
include_hash: bool,
|
||||
) -> std::io::Result<()> {
|
||||
let mut head = 0;
|
||||
while head < line.len() {
|
||||
// Move to the next potential match
|
||||
let next_head = match (line[head..].find("_ZN"), line[head..].find("_R")) {
|
||||
(Some(idx), None) | (None, Some(idx)) => head + idx,
|
||||
(Some(idx1), Some(idx2)) => head + idx1.min(idx2),
|
||||
(None, None) => {
|
||||
// No more matches...
|
||||
line.len()
|
||||
}
|
||||
};
|
||||
output.write_all(line[head..next_head].as_bytes())?;
|
||||
head = next_head;
|
||||
// Find the non-matching character.
|
||||
//
|
||||
// If we do not find a character, then until the end of the line is the
|
||||
// thing to demangle.
|
||||
let match_end = line[head..]
|
||||
.find(|ch: char| !(ch == '$' || ch == '.' || ch == '_' || ch.is_ascii_alphanumeric()))
|
||||
.map(|idx| head + idx)
|
||||
.unwrap_or(line.len());
|
||||
|
||||
let mangled = &line[head..match_end];
|
||||
head = head + mangled.len();
|
||||
if let Ok(demangled) = try_demangle(mangled) {
|
||||
if include_hash {
|
||||
write!(output, "{}", demangled)?;
|
||||
} else {
|
||||
write!(output, "{:#}", demangled)?;
|
||||
}
|
||||
} else {
|
||||
output.write_all(mangled.as_bytes())?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Process a stream of data from `input` into the provided `output`, demangling any symbols found
|
||||
/// within.
|
||||
///
|
||||
/// Note that the underlying implementation will perform many relatively small writes to the
|
||||
/// output. If the output is expensive to write to (e.g., requires syscalls), consider using
|
||||
/// `std::io::BufWriter`.
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub fn demangle_stream<R: std::io::BufRead, W: std::io::Write>(
|
||||
input: &mut R,
|
||||
output: &mut W,
|
||||
include_hash: bool,
|
||||
) -> std::io::Result<()> {
|
||||
let mut buf = std::string::String::new();
|
||||
// We read in lines to reduce the memory usage at any time.
|
||||
//
|
||||
// demangle_line is also more efficient with relatively small buffers as it will copy around
|
||||
// trailing data during demangling. In the future we might directly stream to the output but at
|
||||
// least right now that seems to be less efficient.
|
||||
while input.read_line(&mut buf)? > 0 {
|
||||
demangle_line(&buf, output, include_hash)?;
|
||||
buf.clear();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Error returned from the `try_demangle` function below when demangling fails.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TryDemangleError {
|
||||
_priv: (),
|
||||
}
|
||||
|
||||
/// The same as `demangle`, except return an `Err` if the string does not appear
|
||||
/// to be a Rust symbol, rather than "demangling" the given string as a no-op.
|
||||
///
|
||||
/// ```
|
||||
/// extern crate rustc_demangle;
|
||||
///
|
||||
/// let not_a_rust_symbol = "la la la";
|
||||
///
|
||||
/// // The `try_demangle` function will reject strings which are not Rust symbols.
|
||||
/// assert!(rustc_demangle::try_demangle(not_a_rust_symbol).is_err());
|
||||
///
|
||||
/// // While `demangle` will just pass the non-symbol through as a no-op.
|
||||
/// assert_eq!(rustc_demangle::demangle(not_a_rust_symbol).as_str(), not_a_rust_symbol);
|
||||
/// ```
|
||||
pub fn try_demangle(s: &str) -> Result<Demangle, TryDemangleError> {
|
||||
let sym = demangle(s);
|
||||
if sym.style.is_some() {
|
||||
Ok(sym)
|
||||
} else {
|
||||
Err(TryDemangleError { _priv: () })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Demangle<'a> {
|
||||
/// Returns the underlying string that's being demangled.
|
||||
pub fn as_str(&self) -> &'a str {
|
||||
self.original
|
||||
}
|
||||
}
|
||||
|
||||
fn is_symbol_like(s: &str) -> bool {
|
||||
s.chars().all(|c| {
|
||||
// Once `char::is_ascii_punctuation` and `char::is_ascii_alphanumeric`
|
||||
// have been stable for long enough, use those instead for clarity
|
||||
is_ascii_alphanumeric(c) || is_ascii_punctuation(c)
|
||||
})
|
||||
}
|
||||
|
||||
// Copied from the documentation of `char::is_ascii_alphanumeric`
|
||||
fn is_ascii_alphanumeric(c: char) -> bool {
|
||||
match c {
|
||||
'\u{0041}'..='\u{005A}' | '\u{0061}'..='\u{007A}' | '\u{0030}'..='\u{0039}' => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from the documentation of `char::is_ascii_punctuation`
|
||||
fn is_ascii_punctuation(c: char) -> bool {
|
||||
match c {
|
||||
'\u{0021}'..='\u{002F}'
|
||||
| '\u{003A}'..='\u{0040}'
|
||||
| '\u{005B}'..='\u{0060}'
|
||||
| '\u{007B}'..='\u{007E}' => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for DemangleStyle<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
DemangleStyle::Legacy(ref d) => fmt::Display::fmt(d, f),
|
||||
DemangleStyle::V0(ref d) => fmt::Display::fmt(d, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maximum size of the symbol that we'll print.
|
||||
const MAX_SIZE: usize = 1_000_000;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct SizeLimitExhausted;
|
||||
|
||||
struct SizeLimitedFmtAdapter<F> {
|
||||
remaining: Result<usize, SizeLimitExhausted>,
|
||||
inner: F,
|
||||
}
|
||||
|
||||
impl<F: fmt::Write> fmt::Write for SizeLimitedFmtAdapter<F> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.remaining = self
|
||||
.remaining
|
||||
.and_then(|r| r.checked_sub(s.len()).ok_or(SizeLimitExhausted));
|
||||
|
||||
match self.remaining {
|
||||
Ok(_) => self.inner.write_str(s),
|
||||
Err(SizeLimitExhausted) => Err(fmt::Error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for Demangle<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.style {
|
||||
None => f.write_str(self.original)?,
|
||||
Some(ref d) => {
|
||||
let alternate = f.alternate();
|
||||
let mut size_limited_fmt = SizeLimitedFmtAdapter {
|
||||
remaining: Ok(MAX_SIZE),
|
||||
inner: &mut *f,
|
||||
};
|
||||
let fmt_result = if alternate {
|
||||
write!(size_limited_fmt, "{:#}", d)
|
||||
} else {
|
||||
write!(size_limited_fmt, "{}", d)
|
||||
};
|
||||
let size_limit_result = size_limited_fmt.remaining.map(|_| ());
|
||||
|
||||
// Translate a `fmt::Error` generated by `SizeLimitedFmtAdapter`
|
||||
// into an error message, instead of propagating it upwards
|
||||
// (which could cause panicking from inside e.g. `std::io::print`).
|
||||
match (fmt_result, size_limit_result) {
|
||||
(Err(_), Err(SizeLimitExhausted)) => f.write_str("{size limit reached}")?,
|
||||
|
||||
_ => {
|
||||
fmt_result?;
|
||||
size_limit_result
|
||||
.expect("`fmt::Error` from `SizeLimitedFmtAdapter` was discarded");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f.write_str(self.suffix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for Demangle<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::prelude::v1::*;
|
||||
|
||||
macro_rules! t {
|
||||
($a:expr, $b:expr) => {
|
||||
assert!(ok($a, $b))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! t_err {
|
||||
($a:expr) => {
|
||||
assert!(ok_err($a))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! t_nohash {
|
||||
($a:expr, $b:expr) => {{
|
||||
assert_eq!(format!("{:#}", super::demangle($a)), $b);
|
||||
}};
|
||||
}
|
||||
|
||||
fn ok(sym: &str, expected: &str) -> bool {
|
||||
match super::try_demangle(sym) {
|
||||
Ok(s) => {
|
||||
if s.to_string() == expected {
|
||||
true
|
||||
} else {
|
||||
println!("\n{}\n!=\n{}\n", s, expected);
|
||||
false
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
println!("error demangling");
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ok_err(sym: &str) -> bool {
|
||||
match super::try_demangle(sym) {
|
||||
Ok(_) => {
|
||||
println!("succeeded in demangling");
|
||||
false
|
||||
}
|
||||
Err(_) => super::demangle(sym).to_string() == sym,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle() {
|
||||
t_err!("test");
|
||||
t!("_ZN4testE", "test");
|
||||
t_err!("_ZN4test");
|
||||
t!("_ZN4test1a2bcE", "test::a::bc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_dollars() {
|
||||
t!("_ZN4$RP$E", ")");
|
||||
t!("_ZN8$RF$testE", "&test");
|
||||
t!("_ZN8$BP$test4foobE", "*test::foob");
|
||||
t!("_ZN9$u20$test4foobE", " test::foob");
|
||||
t!("_ZN35Bar$LT$$u5b$u32$u3b$$u20$4$u5d$$GT$E", "Bar<[u32; 4]>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_many_dollars() {
|
||||
t!("_ZN13test$u20$test4foobE", "test test::foob");
|
||||
t!("_ZN12test$BP$test4foobE", "test*test::foob");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_osx() {
|
||||
t!(
|
||||
"__ZN5alloc9allocator6Layout9for_value17h02a996811f781011E",
|
||||
"alloc::allocator::Layout::for_value::h02a996811f781011"
|
||||
);
|
||||
t!("__ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap18_MSG_FILE_LINE_COL17haf7cb8d5824ee659E", "<core::option::Option<T>>::unwrap::_MSG_FILE_LINE_COL::haf7cb8d5824ee659");
|
||||
t!("__ZN4core5slice89_$LT$impl$u20$core..iter..traits..IntoIterator$u20$for$u20$$RF$$u27$a$u20$$u5b$T$u5d$$GT$9into_iter17h450e234d27262170E", "core::slice::<impl core::iter::traits::IntoIterator for &'a [T]>::into_iter::h450e234d27262170");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_windows() {
|
||||
t!("ZN4testE", "test");
|
||||
t!("ZN13test$u20$test4foobE", "test test::foob");
|
||||
t!("ZN12test$RF$test4foobE", "test&test::foob");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_elements_beginning_with_underscore() {
|
||||
t!("_ZN13_$LT$test$GT$E", "<test>");
|
||||
t!("_ZN28_$u7b$$u7b$closure$u7d$$u7d$E", "{{closure}}");
|
||||
t!("_ZN15__STATIC_FMTSTRE", "__STATIC_FMTSTR");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_trait_impls() {
|
||||
t!(
|
||||
"_ZN71_$LT$Test$u20$$u2b$$u20$$u27$static$u20$as$u20$foo..Bar$LT$Test$GT$$GT$3barE",
|
||||
"<Test + 'static as foo::Bar<Test>>::bar"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_without_hash() {
|
||||
let s = "_ZN3foo17h05af221e174051e9E";
|
||||
t!(s, "foo::h05af221e174051e9");
|
||||
t_nohash!(s, "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_without_hash_edgecases() {
|
||||
// One element, no hash.
|
||||
t_nohash!("_ZN3fooE", "foo");
|
||||
// Two elements, no hash.
|
||||
t_nohash!("_ZN3foo3barE", "foo::bar");
|
||||
// Longer-than-normal hash.
|
||||
t_nohash!("_ZN3foo20h05af221e174051e9abcE", "foo");
|
||||
// Shorter-than-normal hash.
|
||||
t_nohash!("_ZN3foo5h05afE", "foo");
|
||||
// Valid hash, but not at the end.
|
||||
t_nohash!("_ZN17h05af221e174051e93fooE", "h05af221e174051e9::foo");
|
||||
// Not a valid hash, missing the 'h'.
|
||||
t_nohash!("_ZN3foo16ffaf221e174051e9E", "foo::ffaf221e174051e9");
|
||||
// Not a valid hash, has a non-hex-digit.
|
||||
t_nohash!("_ZN3foo17hg5af221e174051e9E", "foo::hg5af221e174051e9");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_thinlto() {
|
||||
// One element, no hash.
|
||||
t!("_ZN3fooE.llvm.9D1C9369", "foo");
|
||||
t!("_ZN3fooE.llvm.9D1C9369@@16", "foo");
|
||||
t_nohash!(
|
||||
"_ZN9backtrace3foo17hbb467fcdaea5d79bE.llvm.A5310EB9",
|
||||
"backtrace::foo"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_llvm_ir_branch_labels() {
|
||||
t!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice::<impl core::ops::index::IndexMut<I> for [T]>::index_mut::haf9727c2edfbc47b.exit.i.i");
|
||||
t_nohash!("_ZN4core5slice77_$LT$impl$u20$core..ops..index..IndexMut$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$9index_mut17haf9727c2edfbc47bE.exit.i.i", "core::slice::<impl core::ops::index::IndexMut<I> for [T]>::index_mut.exit.i.i");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn demangle_ignores_suffix_that_doesnt_look_like_a_symbol() {
|
||||
t_err!("_ZN3fooE.llvm moocow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dont_panic() {
|
||||
super::demangle("_ZN2222222222222222222222EE").to_string();
|
||||
super::demangle("_ZN5*70527e27.ll34csaғE").to_string();
|
||||
super::demangle("_ZN5*70527a54.ll34_$b.1E").to_string();
|
||||
super::demangle(
|
||||
"\
|
||||
_ZN5~saäb4e\n\
|
||||
2734cOsbE\n\
|
||||
5usage20h)3\0\0\0\0\0\0\07e2734cOsbE\
|
||||
",
|
||||
)
|
||||
.to_string();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_no_chop() {
|
||||
t_err!("_ZNfooE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handle_assoc_types() {
|
||||
t!("_ZN151_$LT$alloc..boxed..Box$LT$alloc..boxed..FnBox$LT$A$C$$u20$Output$u3d$R$GT$$u20$$u2b$$u20$$u27$a$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$9call_once17h69e8f44b3723e1caE", "<alloc::boxed::Box<alloc::boxed::FnBox<A, Output=R> + 'a> as core::ops::function::FnOnce<A>>::call_once::h69e8f44b3723e1ca");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handle_bang() {
|
||||
t!(
|
||||
"_ZN88_$LT$core..result..Result$LT$$u21$$C$$u20$E$GT$$u20$as$u20$std..process..Termination$GT$6report17hfc41d0da4a40b3e8E",
|
||||
"<core::result::Result<!, E> as std::process::Termination>::report::hfc41d0da4a40b3e8"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn limit_recursion() {
|
||||
assert_contains!(
|
||||
super::demangle("_RNvB_1a").to_string(),
|
||||
"{recursion limit reached}"
|
||||
);
|
||||
assert_contains!(
|
||||
super::demangle("_RMC0RB2_").to_string(),
|
||||
"{recursion limit reached}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn limit_output() {
|
||||
assert_ends_with!(
|
||||
super::demangle("RYFG_FGyyEvRYFF_EvRYFFEvERLB_B_B_ERLRjB_B_B_").to_string(),
|
||||
"{size limit reached}"
|
||||
);
|
||||
// NOTE(eddyb) somewhat reduced version of the above, effectively
|
||||
// `<for<...> fn()>` with a larger number of lifetimes in `...`.
|
||||
assert_ends_with!(
|
||||
super::demangle("_RMC0FGZZZ_Eu").to_string(),
|
||||
"{size limit reached}"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
fn demangle_str(input: &str) -> String {
|
||||
let mut output = Vec::new();
|
||||
super::demangle_line(input, &mut output, false);
|
||||
String::from_utf8(output).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "std")]
|
||||
fn find_multiple() {
|
||||
assert_eq!(
|
||||
demangle_str("_ZN3fooE.llvm moocow _ZN3fooE.llvm"),
|
||||
"foo.llvm moocow foo.llvm"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "std")]
|
||||
fn interleaved_new_legacy() {
|
||||
assert_eq!(
|
||||
demangle_str("_ZN3fooE.llvm moocow _RNvMNtNtNtNtCs8a2262Dv4r_3mio3sys4unix8selector5epollNtB2_8Selector6select _ZN3fooE.llvm"),
|
||||
"foo.llvm moocow <mio::sys::unix::selector::epoll::Selector>::select foo.llvm"
|
||||
);
|
||||
}
|
||||
}
|
10
vendor/rustc-demangle/src/v0-large-test-symbols/early-recursion-limit
vendored
Normal file
10
vendor/rustc-demangle/src/v0-large-test-symbols/early-recursion-limit
vendored
Normal file
File diff suppressed because one or more lines are too long
1530
vendor/rustc-demangle/src/v0.rs
vendored
Normal file
1530
vendor/rustc-demangle/src/v0.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user