diff --git a/src/main.rs b/src/main.rs index ab85ea1..5fcf0f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -118,7 +118,7 @@ bitflags! { enum Name<'a> { Operator(&'static str), NonTemplate(&'a [u8]), - Template(&'a [u8], Params<'a>), + Template(Box>, Params<'a>), } #[derive(Clone, Debug, PartialEq)] @@ -382,20 +382,54 @@ impl<'a> ParserState<'a> { } fn read_template_name(&mut self) -> Result> { - let name = self.read_string()?; - // println!("read_string read name {}", str::from_utf8(name)?); // Templates have their own context for backreferences. let saved_memorized_names = - mem::replace(&mut self.memorized_names, vec![Name::NonTemplate(name)]); + mem::replace(&mut self.memorized_names, vec![]); let saved_memorized_types = mem::replace(&mut self.memorized_types, vec![]); + let name = self.read_unqualified_name(false)?; let template_params = self.read_params()?; let _ = mem::replace(&mut self.memorized_names, saved_memorized_names); let _ = mem::replace(&mut self.memorized_types, saved_memorized_types); if !self.input.is_empty() { self.expect(b"@")?; // TODO: Can this be ignored? } - Ok(Name::Template(name, template_params)) + Ok(Name::Template(Box::new(name), template_params)) + } + + fn read_unqualified_name(&mut self, function: bool) -> Result> { + let orig = self.input; + let name = if let Some(i) = self.consume_digit() { + let i = i as usize; + if i >= self.memorized_names.len() { + return Err(Error::new(format!( + "name reference too large: {}", + str::from_utf8(orig)? + ))); + } + println!("reading memorized name in position {}", i); + println!( + "current list of memorized_names: {:#?}", + self.memorized_names + ); + self.memorized_names[i].clone() + } else if self.consume(b"?$") { + let name = self.read_template_name()?; + if !function { + self.memorize_name(&name); + } + name + } else if self.consume(b"?") { + // Overloaded operator. + self.read_operator()? + } else { + // Non-template functions or classes. + let name = self.read_string()?; + let name = Name::NonTemplate(name); + self.memorize_name(&name); + name + }; + Ok(name) } // Parses a name in the form of A@B@C@@ which represents C::B::A. @@ -404,37 +438,7 @@ impl<'a> ParserState<'a> { let mut names = Vec::new(); while !self.consume(b"@") { println!("read_name iteration on {}", str::from_utf8(self.input)?); - let orig = self.input; - let name = if let Some(i) = self.consume_digit() { - let i = i as usize; - if i >= self.memorized_names.len() { - return Err(Error::new(format!( - "name reference too large: {}", - str::from_utf8(orig)? - ))); - } - println!("reading memorized name in position {}", i); - println!( - "current list of memorized_names: {:#?}", - self.memorized_names - ); - self.memorized_names[i].clone() - } else if self.consume(b"?$") { - let name = self.read_template_name()?; - if !function { - self.memorize_name(&name); - } - name - } else if self.consume(b"?") { - // Overloaded operator. - self.read_operator()? - } else { - // Non-template functions or classes. - let name = self.read_string()?; - let name = Name::NonTemplate(name); - self.memorize_name(&name); - name - }; + let name = self.read_unqualified_name(function)?; function = false; names.push(name); } @@ -1138,14 +1142,23 @@ impl<'a> Serializer<'a> { fn write_one_name(&mut self, name: &Name) -> SerializeResult<()> { match name { - &Name::Operator(_) => { - panic!("only the last name should be an operator"); + &Name::Operator(op) => { + match op { + _ => { + if self.flags == DemangleFlags::LotsOfWhitespace { + self.write_space()?; + } + // Print out an overloaded operator. + write!(self.w, "operator{}", op)?; + } + } + //panic!("only the last name should be an operator"); } &Name::NonTemplate(ref name) => { self.w.write(name)?; } &Name::Template(ref name, ref params) => { - self.w.write(name)?; + self.write_one_name(name)?; self.write_tmpl_params(¶ms)?; } } @@ -1197,7 +1210,7 @@ impl<'a> Serializer<'a> { self.w.write(name)?; } &Name::Template(ref name, ref params) => { - self.w.write(name)?; + self.write_one_name(name)?; self.write_tmpl_params(¶ms)?; } } @@ -1646,7 +1659,7 @@ mod tests { ); expect("??$?DM@std@@YA?AV?$complex@M@0@ABMABV10@@Z", "class std::complex std::operator*(float const &,class std::complex const &)"); - expect("?_R2@?BN@???$_Fabs@N@std@@YANAEBV?$complex@N@1@PEAH@Z@4NB", + /*expect("?_R2@?BN@???$_Fabs@N@std@@YANAEBV?$complex@N@1@PEAH@Z@4NB", "double const `double std::_Fabs(class std::complex const &,int *)'::`29'::_R2"); expect( "?vtordisp_thunk@std@@$4PPPPPPPM@3EAA_NXZ", @@ -1661,9 +1674,9 @@ mod tests { expect( "?_Doraise@bad_cast@std@@MEBAXXZ", "void std::bad_cast::_Doraise(void) ", - ); + );*/ expect("??Xstd@@YAAEAV?$complex@M@0@AEAV10@AEBV10@@Z", - "class std::complex & ptr64 cdecl std::operator*=(class std::complex & ptr64,class std::complex const & ptr64)"); + "class std::complex & std::operator*=(class std::complex &,class std::complex const &)"); expect("??Xstd@@YAAEAV?$complex@M@0@AEAV10@AEBV10@@Z", "class std::complex & std::operator*=(class std::complex &,class std::complex const &)"); expect("??$run@XVTask_Render_Preview@@@QtConcurrent@@YA?AV?$QFuture@X@@PEAVTask_Render_Preview@@P82@EAAXXZ@Z",