[demangler] Fix new/delete demangling
authorNathan Sidwell <nathan@acm.org>
Fri, 28 Jan 2022 15:09:38 +0000 (07:09 -0800)
committerNathan Sidwell <nathan@acm.org>
Thu, 10 Feb 2022 12:33:02 +0000 (04:33 -0800)
commit9d283634f7be35f229e1ebe5f908c59352fe88c2
tree70746f79ee20dbc3bef4a9708281510b1cd6b3e8
parent80eea38d8dfa02d9f1312faa1f922f14cd3e4da0
[demangler] Fix new/delete demangling

I discovered some demangler problems:

a) parsing of new expressions was broken, ignoring any 'gs' prefix
b) (when #a is fixed) badly formatted global new expressions
c) formatting of new and delete failed to correctly add whitespace

(a) happens as parseExpr swallows the 'gs' prefix but doesn't pass it
 to 'parseNewExpr'.  It seems simpler to me to just code the new
 expression parsing directly in parseExpr, as is done for delete
 expressions.

(b) global new should be rendered something like '::new T' not
 '::operator new T'

(c) is resolved by being a bit more careful with whitespace.

Best shown with some examples (don't worry that these symbols are for
impossible instantiations, that's not the point):

Old behaviour:
build/bin/llvm-cxxfilt _ZN2FnIXgsnw_iEEXna_ipiLi4EEEEEvv _ZN2FnIXnwLj4E_iEEXgsnaLj4E_ipiLi4EEEEEvv _ZN2FnIXgsdlLi4EEXdaLi4EEEEvv _ZN2FnIXdlLj4EEXgsdaLj4EEEEvv
void Fn<new int, new[] int(4)>()   // No ::new
void Fn<new (4u)int, new[] (4u)int(4)>() // No ::new, poor whitespace
void Fn<::delete4, delete[] 4>()  // missing necessary space
void Fn<delete4u, ::delete[] 4u>() // missing necessary space

New behaviour:
build/bin/llvm-cxxfilt _ZN2FnIXgsnw_iEEXna_ipiLi4EEEEEvv _ZN2FnIXnwLj4E_iEEXgsnaLj4E_ipiLi4EEEEEvv _ZN2FnIXgsdlLi4EEXdaLi4EEEEvv _ZN2FnIXdlLj4EEXgsdaLj4EEEEvv
void Fn<::new int, new[] int(4)>()
void Fn<new(4u) int, ::new[](4u) int(4)>()
void Fn<::delete 4, delete[] 4>()
void Fn<delete 4u, ::delete[] 4u>()

Binutils' behaviour:
c++filt _ZN2FnIXgsnw_iEEXna_ipiLi4EEEEEvv _ZN2FnIXnwLj4E_iEEXgsnaLj4E_ipiLi4EEEEEvv _ZN2FnIXgsdlLi4EEXdaLi4EEEEvv _ZN2FnIXdlLj4EEXgsdaLj4EEEEvv
void Fn<::new int, new int(4)>()
void Fn<new (4u) int, ::new (4u) int(4)>()
void Fn<::delete (4), delete[] (4)>()
void Fn<delete (4u), ::delete[] (4u)>()

The new and binutils demanglings are the same modulo some whitespace and optional parens.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D118476
libcxxabi/src/demangle/ItaniumDemangle.h
libcxxabi/test/test_demangle.pass.cpp
llvm/include/llvm/Demangle/ItaniumDemangle.h