2010-03-04

gccの名前のデマングル

GCCのtype_infoのname()は、name manglingされたままの文字列を返す。読みにくいこと極まりない。

しかたがないので、Demanglingしてやることにする。

#include <cxxabi.h>

class Demangle
{
private :
    char * realname ;

public :
    Demangle( std::type_info const & ti )
    {
        int status = 0 ;
        realname = abi::__cxa_demangle( ti.name(), 0, 0, &status ) ;
    }

    Demangle( Demangle const & ) = delete ;
    Demangle & operator = ( Demangle const & ) = delete ;

    ~Demangle()
    {
        std::free( realname ) ;
    }

    operator char const * () const
    {
        return realname ;
    }

} ;

以下のように使う。

struct Foo {} ;

int f( float, int, Foo *, Foo &, Foo const volatile * (&) [10]  ) ;

template < typename ... Args >
struct Bar { } ;



int main()
{

    std::cout << Demangle(typeid(int)) << std::endl ;
    std::cout << Demangle(typeid(float)) << std::endl ;
    std::cout << Demangle(typeid(Foo)) << std::endl ;
    std::cout << Demangle(typeid(f)) << std::endl ;
    std::cout << Demangle(typeid(Bar<int, char, float, Foo, Bar<char, int, long> >)) << std::endl ;

}

出力結果

int
float
Foo
int ()(float, int, Foo*, Foo&, Foo const volatile* (&) [10])
Bar<int, char, float, Foo, Bar<char, int, long> >

Chapter 40. Demangling

とりあえず、Variadic Templatesについて、だいぶ理解した。やはり、実際に動くコンパイラで、書いて試すことができるというのは、ありがたい。

7 comments:

tiger said...

おおーっ、こりゃええですな!

江添亮 said...

せやろ、せやろ。
ていうかな、gccはんのtype_info::name()が、ハナッからdemanglingした結果を返したったらえーねん。
なんでmanglingしたまま、よこすねん。アホちゃうか。

rigarash said...

$ nm object.o | c++filt
$ objdump -t object.o | c++filt
とかのように、typeidをcoutに出した結果をc++filtにパイプしてやればよいと思います。

Anonymous said...

別のDemangle変数に代入したらメモリリークですな

江添亮 said...

>別のDemangle変数に代入したらメモリリークですな
修正

DigitalGhost said...

void operator=(Demangle const &) = delete; も追加で。

萌ゑ said...

これはいいな
知っておこう