Home | History | Annotate | Download | only in brillo
      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