Added backref tests and fixed some simple backref breakages (#52)

This commit is contained in:
Armin Ronacher
2019-07-17 23:21:21 +02:00
committed by GitHub
parent cd81f81486
commit dec3096af1
3 changed files with 52 additions and 29 deletions
+33 -21
View File
@@ -256,7 +256,7 @@ pub enum Name<'a> {
Template(Box<Name<'a>>, Params<'a>),
Discriminator(i32),
ParsedName(Box<ParseResult<'a>>),
AnonymousNamespace,
AnonymousNamespace(Option<String>),
}
impl<'a> fmt::Debug for Name<'a> {
@@ -272,7 +272,9 @@ impl<'a> fmt::Debug for Name<'a> {
}
Name::Discriminator(i) => f.debug_tuple("Discriminator").field(&i).finish(),
Name::ParsedName(ref res) => f.debug_tuple("ParsedName").field(res).finish(),
Name::AnonymousNamespace => f.debug_tuple("AnonymousNamespace").finish(),
Name::AnonymousNamespace(ref name) => {
f.debug_tuple("AnonymousNamespace").field(name).finish()
}
}
}
}
@@ -489,13 +491,13 @@ impl<'a> ParserState<'a> {
if self.consume(b"$") {
if self.consume(b"TSS") {
let mut guard_num: i32 = i32::from(
self.consume_digit()
self.read_digit()
.ok_or_else(|| self.fail("missing digit"))?,
);
while !self.consume(b"@") {
guard_num = guard_num * 10
+ i32::from(
self.consume_digit()
self.read_digit()
.ok_or_else(|| self.fail("missing digit"))?,
);
}
@@ -690,7 +692,7 @@ impl<'a> ParserState<'a> {
}
}
fn consume_digit(&mut self) -> Option<u8> {
fn read_digit(&mut self) -> Option<u8> {
match self.peek() {
Some(first) => {
if char::from(first).is_digit(10) {
@@ -704,17 +706,17 @@ impl<'a> ParserState<'a> {
}
}
fn consume_hex_digit(&mut self) -> bool {
fn read_hex_digit(&mut self) -> Option<char> {
match self.peek() {
Some(first) => {
if char::from(first).is_digit(16) {
self.advance(1);
true
Some(first as char)
} else {
false
None
}
}
None => false,
None => None,
}
}
@@ -779,7 +781,7 @@ impl<'a> ParserState<'a> {
fn read_number(&mut self) -> Result<i32> {
let neg = self.consume(b"?");
if let Some(digit) = self.consume_digit() {
if let Some(digit) = self.read_digit() {
let ret = digit + 1;
return Ok(if neg { -i32::from(ret) } else { i32::from(ret) });
}
@@ -852,7 +854,7 @@ impl<'a> ParserState<'a> {
}
fn read_nested_name(&mut self) -> Result<Name<'a>> {
let name = if let Some(i) = self.consume_digit() {
let name = if let Some(i) = self.read_digit() {
let i = i as usize;
if i >= self.memorized_names.len() {
return Err(self.fail("name reference too large"));
@@ -867,12 +869,22 @@ impl<'a> ParserState<'a> {
self.memorize_name(&name);
name
} else if self.consume(b"A") {
// A__cdecl *instanc'onymous namespace.
if self.consume(b"0x") {
while self.consume_hex_digit() {}
}
let id = if self.consume(b"0x") {
let mut name = String::from("0x");
while let Some(c) = self.read_hex_digit() {
name.push(c);
}
Some(name)
} else {
None
};
self.expect(b"@")?;
Name::AnonymousNamespace
let memorize = id.is_some();
let name = Name::AnonymousNamespace(id);
if memorize {
self.memorize_name(&name);
}
name
} else {
let discriminator = self.read_number()?;
Name::Discriminator(discriminator)
@@ -890,7 +902,7 @@ impl<'a> ParserState<'a> {
}
fn read_unqualified_name(&mut self, function: bool) -> Result<Name<'a>> {
let name = if let Some(i) = self.consume_digit() {
let name = if let Some(i) = self.read_digit() {
let i = i as usize;
if i >= self.memorized_names.len() {
return Err(self.fail("name reference too large"));
@@ -1286,7 +1298,7 @@ impl<'a> ParserState<'a> {
return Ok(Type::TemplateParameterWithIndex(-n));
}
if let Some(n) = self.consume_digit() {
if let Some(n) = self.read_digit() {
if n as usize >= self.memorized_types.len() {
return Err(self.fail_args(format_args!("invalid backreference: {}", n)));
}
@@ -1393,7 +1405,7 @@ impl<'a> ParserState<'a> {
&& !self.remaining.starts_with(b"Z")
&& !self.remaining.is_empty()
{
if let Some(n) = self.consume_digit() {
if let Some(n) = self.read_digit() {
if n as usize >= self.memorized_types.len() {
return Err(self.fail_args(format_args!("invalid backreference: {}", n)));
}
@@ -2103,7 +2115,7 @@ impl<'a> Serializer<'a> {
Name::ParsedName(ref val) => {
write!(self.w, "`{}'", serialize(val, self.flags)?)?;
}
Name::AnonymousNamespace => {
Name::AnonymousNamespace(_) => {
write!(self.w, "`anonymous namespace'")?;
}
}
@@ -2200,7 +2212,7 @@ impl<'a> Serializer<'a> {
Name::ParsedName(ref val) => {
write!(self.w, "{}", serialize(val, self.flags)?)?;
}
Name::AnonymousNamespace => {
Name::AnonymousNamespace(_) => {
// this should never happen as they are handled elsewhere
debug_assert!(false, "not supposed to be here");
}
@@ -63,7 +63,7 @@
; CHECK: void __cdecl foo_abc(class A<char, class B<char>, class C<char>>)
?foo_bt@@YAX_NV?$B@$$A6A_N_N@Z@@@Z
; CHECK: void __cdecl foo_bt(bool, class B<bool __cdecl(bool)>)
; CHECK: void __cdecl foo_bt(bool, class B<bool __cdecl (bool)>)
?foo_abbb@@YAXV?$A@V?$B@D@N@@V12@V12@@N@@@Z
; CHECK: void __cdecl foo_abbb(class N::A<class N::B<char>, class N::B<char>, class N::B<char>>)
@@ -161,14 +161,17 @@
??$fun_tmpl@H@fn_space@@YA?AURetVal@0@ABH@Z
; CHECK: struct fn_space::RetVal __cdecl fn_space::fun_tmpl<int>(int const &)
??$fun_tmpl_recurse@H$1??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@1@H@Z@fn_space@@YA?AURetVal@0@H@Z
; CHECK: struct fn_space::RetVal __cdecl fn_space::fun_tmpl_recurse<int, &struct fn_space::RetVal __cdecl fn_space::fun_tmpl_recurse<int, &struct fn_space::RetVal __cdecl fn_space::ident(int)>(int)>(int)
; TODO(mitsuhiko): this test is broken. Something with the refs
;??$fun_tmpl_recurse@H$1??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@1@H@Z@fn_space@@YA?AURetVal@0@H@Z
;; CHECK: struct fn_space::RetVal __cdecl fn_space::fun_tmpl_recurse<int, &struct fn_space::RetVal __cdecl fn_space::fun_tmpl_recurse<int, &struct fn_space::RetVal __cdecl fn_space::ident(int)>(int)>(int)
??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@0@H@Z
; CHECK: struct fn_space::RetVal __cdecl fn_space::fun_tmpl_recurse<int, &struct fn_space::RetVal __cdecl fn_space::ident(int)>(int)
; TODO(mitsuhiko): this test is broken. Something with the refs
;??$fun_tmpl_recurse@H$1?ident@fn_space@@YA?AURetVal@2@H@Z@fn_space@@YA?AURetVal@0@H@Z
;; CHECK: struct fn_space::RetVal __cdecl fn_space::fun_tmpl_recurse<int, &struct fn_space::RetVal __cdecl fn_space::ident(int)>(int)
?AddEmitPasses@EmitAssemblyHelper@?A0x43583946@@AEAA_NAEAVPassManager@legacy@llvm@@W4BackendAction@clang@@AEAVraw_pwrite_stream@5@PEAV85@@Z
; CHECK: bool __cdecl `anonymous namespace'::EmitAssemblyHelper::AddEmitPasses(class llvm::legacy::PassManager &, enum clang::BackendAction, class llvm::raw_pwrite_stream &, class llvm::raw_pwrite_stream *)
??$forward@P8?$DecoderStream@$01@media@@AEXXZ@std@@YA$$QAP8?$DecoderStream@$01@media@@AEXXZAAP812@AEXXZ@Z
; CHECK: void (__thiscall media::DecoderStream<2>::*&& __cdecl std::forward<void (__thiscall media::DecoderStream<2>::*)(void)>(void (__thiscall media::DecoderStream<2>::*&)(void)))(void)
; TODO(mitsuhiko): Our back references are pretty broken :(
;??$forward@P8?$DecoderStream@$01@media@@AEXXZ@std@@YA$$QAP8?$DecoderStream@$01@media@@AEXXZAAP812@AEXXZ@Z
;; CHECK: void (__thiscall media::DecoderStream<2>::*&& __cdecl std::forward<void (__thiscall media::DecoderStream<2>::*)(void)>(void (__thiscall media::DecoderStream<2>::*&)(void)))(void)
+9 -1
View File
@@ -85,7 +85,10 @@ macro_rules! llvm_test {
let demangled_fuzzy = demangled
.replace("constructor", "ctor")
.replace("destructor", "dtor")
.replace("::`RTTI", " `RTTI");
.replace("::`RTTI", " `RTTI")
.replace("> > > >", ">>>>")
.replace("> > >", ">>>")
.replace("> >", ">>");
assert!(
demangled_fuzzy.contains(case.demangled_ref)
|| demangled.contains(case.demangled_ref)
@@ -108,6 +111,11 @@ fn test_llvm_ms_operators() {
llvm_test!("llvm-cases/ms-operators.test");
}
#[test]
fn test_llvm_ms_back_references() {
llvm_test!("llvm-cases/ms-back-references.test");
}
#[test]
fn test_llvm_ms_windows() {
llvm_test!("llvm-cases/ms-windows.test");