Compute garbled function name of C ++ template function

Say I have a C ++ template function.

template <class T>
int foo(T& t) {
...
}

How can I programmatically calculate (without using nm) the distorted function name?

Notice I'm not interested in dismantling. I am already familiar with the cxxabi header file that demangling does.

+4
source share
2 answers

This can be done with typeid; the trick is to encode a function pointer into a type name by creating a type with a template parameter of a non-type type whose value is a function pointer. For instance:

template <class T> int foo(T&);
template <class U, U> struct IntegralConstant {};
std::cout << typeid(IntegralConstant<decltype(&foo<int>), &foo<int>>).name() << '\n';

16IntegralConstantIPFiRiEXadL_Z3fooIiEiRT_EEE, c++filt -t IntegralConstant<int (*)(int&), &(int foo<int>(int&))>. , _Z3fooIiEiRT_ (demangling to int foo<int>(int&)) ; , , nullptr :

template <class U, U> struct IntegralConstant {};
template <class U, U* u> std::string mangledSymbolName() {
    std::string null = typeid(IntegralConstant<U*, nullptr>).name();
    std::string symbol = typeid(IntegralConstant<U*, u>).name();
    return symbol.substr(null.size() - 3, symbol.size() - null.size() + 0);
}

: http://melpon.org/wandbox/permlink/6b46CBOv0ZwIMukk

3 0 ++ ABI nullptr, ; , IntegralConstant .

+1

:

#include <iostream>
#include <string>
#include <regex>

#include <execinfo.h>

std::string GetMangledSymbol(const std::string& str)
{
    static const std::regex regex(R"((\([a-zA-Z0-9_+]*\)))");

    std::smatch matches;
    std::regex_search( str, matches, regex );

    if( ! matches.empty() )
    {
        auto symbolName = matches[1].str().substr(1);
        auto pos = symbolName.find_first_of('+');

        if( pos == std::string::npos)
            return symbolName;

        symbolName.erase( pos );

        return symbolName;
    }

    return {};
}

void printCurrentFunction()
{
    void* array[50] = { nullptr };
    char** strings = nullptr;

    size_t size = backtrace(array, 50);
    strings = backtrace_symbols(array, size);

    std::cout << GetMangledSymbol(strings[1]) << std::endl;

    free(strings);
}

template <class T>
int foo(T&) {
    printCurrentFunction();

    return 0;
}

int main()
{
    int i = 2;
    foo(i);

    std::string k;
    foo(k);
}

linux gcc ( - ).

Live

-1

All Articles