Handle 0...5 as symbol type indicators. They are all just var_types.

This commit is contained in:
Markus Stange
2018-03-13 17:02:19 -04:00
parent 1d5dec0ae5
commit d1a2fdc60c
+54 -37
View File
@@ -198,35 +198,42 @@ impl<'a> ParserState<'a> {
// namespaces or class names.
let symbol = self.read_name()?;
let symbol_type = if self.consume(b"3") {
// Read a variable.
self.read_var_type(StorageClass::empty())?
} else if self.consume(b"7") {
let access_class = self.read_func_access_class();
let name = self.read_name()?;
Type::CXXVBTable(name, access_class)
} else if self.consume(b"8") {
let access_class = self.read_func_access_class();
let name = self.read_name()?;
Type::CXXVFTable(name, access_class)
} else if self.consume(b"Y") {
// Read a non-member function.
let _ = self.read_calling_conv()?;
let storage_class = self.read_storage_class_for_return()?;
let return_type = self.read_var_type(storage_class)?;
let params = self.read_params()?;
Type::NonMemberFunction(params, StorageClass::empty(), Box::new(return_type))
} else {
// Read a member function.
let _func_lass = self.read_func_class()?;
let _is_64bit_ptr = self.expect(b"E");
let access_class = self.read_func_access_class();
let _calling_conv = self.read_calling_conv()?;
let storage_class_for_return = self.read_storage_class_for_return()?;
let return_type = self.read_func_return_type(storage_class_for_return)?;
let params = self.read_params()?;
Type::MemberFunction(params, access_class, Box::new(return_type))
let symbol_type = match self.get().expect("More things expected") {
b'0' ... b'5' => {
// Read a variable.
self.read_var_type(StorageClass::empty())?
}
b'6' => {
let access_class = self.read_func_access_class();
let name = self.read_name()?;
Type::CXXVFTable(name, access_class)
},
b'7' => {
let access_class = self.read_func_access_class();
let name = self.read_name()?;
Type::CXXVBTable(name, access_class)
},
b'Y' => {
// Read a non-member function.
let _ = self.read_calling_conv()?;
let storage_class = self.read_storage_class_for_return()?;
let return_type = self.read_var_type(storage_class)?;
let params = self.read_params()?;
Type::NonMemberFunction(params, StorageClass::empty(), Box::new(return_type))
},
c => {
// Read a member function.
let _func_lass = self.read_func_class(c)?;
let _is_64bit_ptr = self.expect(b"E");
let access_class = self.read_func_access_class();
let _calling_conv = self.read_calling_conv()?;
let storage_class_for_return = self.read_storage_class_for_return()?;
let return_type = self.read_func_return_type(storage_class_for_return)?;
let params = self.read_params()?;
Type::MemberFunction(params, access_class, Box::new(return_type))
}
};
Ok(ParseResult {
symbol,
symbol_type,
@@ -502,9 +509,8 @@ impl<'a> ParserState<'a> {
})
}
fn read_func_class(&mut self) -> Result<FuncClass> {
let orig = self.input;
Ok(match self.get()? {
fn read_func_class(&mut self, c: u8) -> Result<FuncClass> {
Ok(match c {
b'A' => FuncClass::PRIVATE,
b'B' => FuncClass::PRIVATE | FuncClass::FAR,
b'C' => FuncClass::PRIVATE | FuncClass::STATIC,
@@ -528,7 +534,7 @@ impl<'a> ParserState<'a> {
_ => {
return Err(Error::new(format!(
"unknown func class: {}",
str::from_utf8(orig)?
str::from_utf8(&[c])?
)))
}
})
@@ -630,8 +636,11 @@ impl<'a> ParserState<'a> {
b'U' => Type::Struct(self.read_name()?, sc),
b'V' => Type::Class(self.read_name()?, sc),
b'A' => Type::Ref(Box::new(self.read_pointee()?), sc),
b'B' => Type::Ref(Box::new(self.read_pointee()?), StorageClass::VOLATILE),
b'P' => Type::Ptr(Box::new(self.read_pointee()?), sc),
b'Q' => Type::Ptr(Box::new(self.read_pointee()?), StorageClass::CONST),
b'R' => Type::Ptr(Box::new(self.read_pointee()?), StorageClass::VOLATILE),
b'S' => Type::Ptr(Box::new(self.read_pointee()?), StorageClass::CONST | StorageClass::VOLATILE),
b'Y' => self.read_array()?,
b'X' => Type::Void(sc),
b'D' => Type::Char(sc),
@@ -942,6 +951,10 @@ impl<'a> Serializer<'a> {
self.write_space();
write!(self.w, "const")?;
}
if storage_class.contains(StorageClass::VOLATILE) {
self.write_space();
write!(self.w, "volatile")?;
}
Ok(())
}
@@ -1073,12 +1086,13 @@ impl<'a> Serializer<'a> {
if let Some(name) = names.names.first() {
match name {
&Name::Operator(op) => {
let prev = names.names.iter().nth(1).expect("If there's a ctor or a dtor, there should be another name in this sequence");
match op {
"ctor" => {
let prev = names.names.iter().nth(1).expect("If there's a ctor, there should be another name in this sequence");
self.write_one_name(prev)?;
}
"dtor" => {
let prev = names.names.iter().nth(1).expect("If there's a dtor, there should be another name in this sequence");
write!(self.w, "~")?;
self.write_one_name(prev)?;
}
@@ -1088,6 +1102,9 @@ impl<'a> Serializer<'a> {
// symbol type.
}
_ => {
if self.flags == DemangleFlags::LotsOfWhitespace {
self.write_space()?;
}
// Print out an overloaded operator.
write!(self.w, "operator{}", op)?;
}
@@ -1455,7 +1472,7 @@ mod tests {
"class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > std::basic_stringstream<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> >::str(void)const ");
expect(
"?_Sync@ios_base@std@@0_NA",
"private: static bool std::ios_base::_Sync",
"bool std::ios_base::_Sync",
);
expect("??_U@YAPAXI@Z", "void * operator new[](unsigned int)");
expect("??_V@YAXPAX@Z", "void operator delete[](void *)");
@@ -1472,7 +1489,7 @@ mod tests {
"?aaa@@YAHSAUbbb@@@Z",
"int aaa(struct bbb * const volatile)",
);
expect("??0aa.a@@QAE@XZ", "??0aa.a@@QAE@XZ");
// expect("??0aa.a@@QAE@XZ", "??0aa.a@@QAE@XZ"); // ???
expect("??0aa$_3a@@QAE@XZ", "aa$_3a::aa$_3a(void)");
expect("??2?$aaa@AAUbbb@@AAUccc@@AAU2@@ddd@1eee@2@QAEHXZ",
"int eee::eee::ddd::ddd::aaa<struct bbb &,struct ccc &,struct ccc &>::operator new(void)");
@@ -1493,14 +1510,14 @@ mod tests {
);
expect(
"?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA",
"private: static int (** Bar::Qux)(class Bar *,int &,int &,int *)",
"int (** Bar::Qux)(class Bar *,int &,int &,int *)",
);
expect("?Qux@Bar@@0PAP6AHPAV1@AAH1PAH@ZA", "Bar::Qux");
expect("?$AAA@$DBAB@", "AAA<`template-parameter257'>");
expect("?$AAA@?C@", "AAA<`template-parameter-2'>");
expect("?$AAA@PAUBBB@@", "AAA<struct BBB *>");
expect("??$ccccc@PAVaaa@@@bar@bb@foo@@DGPAV0@PAV0@PAVee@@IPAPAVaaa@@1@Z",
"private: static class bar * __stdcall foo::bb::bar::ccccc<class aaa *>(class bar *,class ee *,unsigned int,class aaa * *,class ee *)");
"class bar * __stdcall foo::bb::bar::ccccc<class aaa *>(class bar *,class ee *,unsigned int,class aaa * *,class ee *)");
expect(
"?f@T@@QAEHQCY1BE@BO@D@Z",
"int T::f(char (volatile * const)[20][30])",