This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: how do I demangle the name from typeinfo(obj).name()?


David Baraff wrote:

> [Apologies for cross-post; couldn't decide which one was really
> correct.]
> I'm trying to demangle names that come back from typeinfo, e.g.
>
>     cout << typeinfo(someObject).name() << "\n";
>
> Some of the things I get out are successfully demangled using the
> c++filt program (with
> option -edg) but some simple things are not!!  I add the required "__"
> (two underscores)
> but that doesn't always work.
>
> Here are some outputs:
>     6foobar    /* demangles after adding __ */
>     t4list2Z6foobarZt15TaggedAllocator1Z6foobar  /* demangles after
> adding __ */
>     i             /* doesn't demangle no matter what */
>     Fv_i      /* doesn't demangle no matter what */
>
> Sadly, the last two cases are, respectively, printing the signatures
> of an int, and main.
>
> Could someone PLEASE tell me how to consistently demangle these names?

The attached code works for me.
#ifndef demangle_typename_hpp__INCL
#define demangle_typename_hpp__INCL
#include <string>
  string
demangle_typename
  ( char const* mangled
	)
	//Requires:
	//  mangled = a class name, as returned by typeinfo::name
	//Ensures:
	//  output = a demangled version of mangled 
	;
#endif
#ifndef typestring_T_hpp__INCL
#define typestring_T_hpp__INCL
#include "demangle_typename.hpp"
#include <typeinfo>
template<typename T>
  string
typestring_T(void)
  {
	; return demangle_typename(typeid(T).name())
  ;}
template<typename T>
  string
typestring_T(T const& t)
  {
	; return demangle_typename(typeid(t).name())
  ;}
#endif
    extern "C"
{
#include <demangle.h>
}
#include <cstddef>
#include "demangle_typename.hpp"
//#include <iostream>
//using namespace std;
  string
demangle_typename
  ( char const* c_mangled
	)
	//Requires:
  //  c_mangled is the result of typeinfo::name()
	//  for some instance of typeinfo.
	//Ensures:
	//  <output> = the demangled c_mangled.
	//Method:
	//  prepends <name>__ to c_mangled and then passes result to
  //  cplus_demangle.  the result from cplus_demangle is
  //  <typename>::<name> where <typename> is the actual typename of
  //  the class represented by c_mangled.  The code then strips the
  //  ::<name> from the resulting string and returns the result.
	//Portability:
	//	This method probably only works for the gnu compiler.  The
	//	demangle.h include file is gnu specific.  The library where the
	//	corresponding .o file is located is also gnu specific. Also, the
  //  method assumes that the mangled version of method name is
  //  <name>__<mangled_typename>, where <mangled_typename> is the
  //  value returned from typeinfo::name().
	{
	//; cout<<"c_mangled="<<c_mangled<<"="<<endl
	; char const*const fake_memfun="fakeFun__"
  //now transform c_mangled into a string which cplus_demangle
	//can work on:
  ; string s_fake_mangled=string(fake_memfun)+string(c_mangled)
	; char const* c_fake_mangled=s_fake_mangled.c_str()
	; int const flags = 0
		//^the above value should just cause function names with no args
		// to be produced. i.e. A::f instead of, e.g. A::f(int)
	//; cout<<"cf_mangled="<<c_fake_mangled<<endl
	; char* c_fake_demangled=cplus_demangle(c_fake_mangled,flags)
	//; cout<<"cf_demangled="<<c_fake_demangled<<endl
	; assert(c_fake_demangled)
	; { 
	  ; int const len_f=strlen(fake_memfun)
		; int const len_c=strlen(c_fake_demangled)
  	; c_fake_demangled[len_c-len_f]='\0' //end string before ::fake_memfun
		;}
  ; string s_demangled=c_fake_demangled
	; delete c_fake_demangled
	; return s_demangled
	;}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]