1 // Copyright 2014 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <brillo/type_name_undecorate.h> 6 7 #include <cstring> 8 9 #ifdef __GNUG__ 10 #include <cstdlib> 11 #include <cxxabi.h> 12 #include <memory> 13 #endif // __GNUG__ 14 15 namespace brillo { 16 17 std::string UndecorateTypeName(const char* type_name) { 18 #ifdef __GNUG__ 19 // Under g++ use abi::__cxa_demangle() to undecorate the type name. 20 int status = 0; 21 22 std::unique_ptr<char, decltype(&std::free)> res{ 23 abi::__cxa_demangle(type_name, nullptr, nullptr, &status), 24 std::free 25 }; 26 27 return (status == 0) ? res.get() : type_name; 28 #else 29 // If not compiled with g++, do nothing... 30 // E.g. MSVC's type_info::name() already contains undecorated name. 31 return type_name; 32 #endif 33 } 34 35 std::string GetUndecoratedTypeNameForTag(const char* type_tag) { 36 #if defined(USE_RTTI_FOR_TYPE_TAGS) && \ 37 (defined(__cpp_rtti) || defined(__GXX_RTTI)) 38 return UndecorateTypeName(type_tag); 39 #else 40 // The signature of type tag for, say, 'int' would be the following: 41 // const char *brillo::GetTypeTag() [T = int] 42 // So we just need to extract the type name between '[T = ' and ']'. 43 const char* token = " = "; 44 const char* pos = std::strstr(type_tag, token); 45 if (!pos) 46 return type_tag; 47 std::string name = pos + std::strlen(token); 48 if (!name.empty() && name.back() == ']') 49 name.pop_back(); 50 return name; 51 #endif 52 } 53 54 // Implementations of the explicitly instantiated GetTypeTag<T>() for common 55 // types. 56 template const char* GetTypeTag<int8_t>(); 57 template const char* GetTypeTag<uint8_t>(); 58 template const char* GetTypeTag<int16_t>(); 59 template const char* GetTypeTag<uint16_t>(); 60 template const char* GetTypeTag<int32_t>(); 61 template const char* GetTypeTag<uint32_t>(); 62 template const char* GetTypeTag<int64_t>(); 63 template const char* GetTypeTag<uint64_t>(); 64 template const char* GetTypeTag<bool>(); 65 template const char* GetTypeTag<double>(); 66 template const char* GetTypeTag<std::string>(); 67 68 } // namespace brillo 69