Consistent Demangle on MSVC and gcc/clang

Use regex list from here:
https://github.com/RobotLocomotion/drake/blob/master/common/nice_type_name.cc
This commit is contained in:
Matthias Hochsteger 2021-09-01 16:56:01 +02:00
parent 6fa47a2a6e
commit 6a26125889

View File

@ -4,10 +4,45 @@
#ifndef WIN32 #ifndef WIN32
#include <cxxabi.h> #include <cxxabi.h>
#endif #endif
#include <array>
#include <iostream> #include <iostream>
#include <regex>
namespace ngcore namespace ngcore
{ {
namespace detail
{
// see https://github.com/RobotLocomotion/drake/blob/master/common/nice_type_name.cc
static const auto demangle_regexes =
std::array<std::pair<std::regex, std::string>, 8>{
// Remove unwanted keywords and following space. (\b is word boundary.)
std::make_pair(std::regex("\\b(class|struct|enum|union) "), ""),
// Tidy up anonymous namespace.
{std::regex("[`(]anonymous namespace[')]"), "(anonymous)"},
// Replace Microsoft __int64 with long long.
{std::regex("\\b__int64\\b"), "long long"},
// Temporarily replace spaces we want to keep with "!". (\w is
// alphanumeric or underscore.)
{std::regex("(\\w) (\\w)"), "$1!$2"},
{std::regex(" "), ""}, // Delete unwanted spaces.
// Some compilers throw in extra namespaces like "__1" or "__cxx11".
// Delete them.
{std::regex("\\b__[[:alnum:]_]+::"), ""},
{std::regex("!"), " "}, // Restore wanted spaces.
// Recognize std::string's full name and abbreviate.
{std::regex("\\bstd::basic_string<char,std::char_traits<char>,"
"std::allocator<char>>"), "std::string"}
};
std::string CleanupDemangledName( std::string s )
{
for(const auto & [r, sub] : demangle_regexes)
s = std::regex_replace (s,r,sub);
return s;
}
} // namespace detail
// parallel netgen // parallel netgen
int id = 0, ntasks = 1; int id = 0, ntasks = 1;
@ -15,12 +50,7 @@ namespace ngcore
// windows does demangling in typeid(T).name() // windows does demangling in typeid(T).name()
NGCORE_API std::string Demangle(const char* typeinfo) { NGCORE_API std::string Demangle(const char* typeinfo) {
std::string name = typeinfo; std::string name = typeinfo;
// remove "class " and "struct " at beginning of type names to be consistent with demangled names of gcc/clang return detail::CleanupDemangledName(name);
if(name.find("class ") == 0)
name.erase(0,6);
if(name.find("struct ") == 0)
name.erase(0,7);
return name;
} }
#else #else
NGCORE_API std::string Demangle(const char* typeinfo) NGCORE_API std::string Demangle(const char* typeinfo)
@ -31,13 +61,15 @@ namespace ngcore
char *s = abi::__cxa_demangle(typeinfo, nullptr, nullptr, &status); char *s = abi::__cxa_demangle(typeinfo, nullptr, nullptr, &status);
std::string result{s}; std::string result{s};
free(s); free(s);
result = detail::CleanupDemangledName(result);
return result; return result;
} }
catch( const std::exception & e ) catch( const std::exception & e )
{ {
GetLogger("utils")->warn("{}:{} cannot demangle {}, status: {}, error:{}", __FILE__, __LINE__, typeinfo, status, e.what()); GetLogger("utils")->warn("{}:{} cannot demangle {}, status: {}, error:{}", __FILE__, __LINE__, typeinfo, status, e.what());
} }
return typeinfo; std::string name = typeinfo;
return detail::CleanupDemangledName(name);
} }
#endif #endif