00001 /** @file rutz/demangle.cc get a demangled name from a std::type_info 00002 object */ 00003 /////////////////////////////////////////////////////////////////////// 00004 // 00005 // Copyright (c) 1999-2004 California Institute of Technology 00006 // Copyright (c) 2004-2007 University of Southern California 00007 // Rob Peters <rjpeters at usc dot edu> 00008 // 00009 // created: Wed Oct 13 10:41:19 1999 00010 // commit: $Id: demangle.cc 8249 2007-04-12 06:03:40Z rjpeters $ 00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/demangle.cc $ 00012 // 00013 // -------------------------------------------------------------------- 00014 // 00015 // This file is part of GroovX. 00016 // [http://ilab.usc.edu/rjpeters/groovx/] 00017 // 00018 // GroovX is free software; you can redistribute it and/or modify it 00019 // under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation; either version 2 of the License, or 00021 // (at your option) any later version. 00022 // 00023 // GroovX is distributed in the hope that it will be useful, but 00024 // WITHOUT ANY WARRANTY; without even the implied warranty of 00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00026 // General Public License for more details. 00027 // 00028 // You should have received a copy of the GNU General Public License 00029 // along with GroovX; if not, write to the Free Software Foundation, 00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00031 // 00032 /////////////////////////////////////////////////////////////////////// 00033 00034 #ifndef GROOVX_RUTZ_DEMANGLE_CC_UTC20050626084020_DEFINED 00035 #define GROOVX_RUTZ_DEMANGLE_CC_UTC20050626084020_DEFINED 00036 00037 #include "rutz/demangle.h" 00038 00039 #if defined(GVX_NO_TYPENAME_MANGLING) 00040 00041 namespace 00042 { 00043 const char* demangle_impl(const char* in) { return in; } 00044 } 00045 00046 # define DEMANGLE_IMPL demangle_impl 00047 00048 #else // !defined(GVX_NO_TYPENAME_MANGLING) 00049 00050 // Here we pick the appropriate system-dependent header that defines a 00051 // function for demangling mangled names with the following prototype: 00052 00053 // std::string demangle_impl(const std::string& mangled) 00054 00055 # if defined(HAVE_CXXABI_H) 00056 # include "rutz/demangle_gcc_v3.h" 00057 # define DEMANGLE_IMPL demangle_gcc_v3 00058 # elif defined(__GNUC__) && __GNUC__ < 3 00059 # include "rutz/demangle_gcc_v2.h" 00060 # define DEMANGLE_IMPL demangle_gcc_v2 00061 # elif defined(GVX_HAVE_PROG_CXXFILT) 00062 # include "rutz/demangle_cxxfilt.h" 00063 # define DEMANGLE_IMPL demangle_cxxfilt 00064 # else 00065 // use the cxxabi demangler by default 00066 # include "rutz/demangle_gcc_v3.h" 00067 # define DEMANGLE_IMPL demangle_gcc_v3 00068 # endif 00069 #endif // !defined(GVX_NO_TYPENAME_MANGLING) 00070 00071 #include "rutz/mutex.h" 00072 #include "rutz/trace.h" 00073 00074 #include <map> 00075 #include <pthread.h> 00076 #include <string> 00077 00078 namespace 00079 { 00080 // why can't we make this a map<type_info, string>? 00081 // (1) gcc libstdc++ doesn't seem to have type_info::operator<() 00082 // (2) gcc libstdc++ doesn't allow copying of type_info objects 00083 typedef std::map<std::string, std::string> cache_type; 00084 cache_type* g_name_cache = 0; 00085 pthread_once_t g_name_cache_init_once = PTHREAD_ONCE_INIT; 00086 pthread_mutex_t g_name_cache_mutex = PTHREAD_MUTEX_INITIALIZER; 00087 00088 void name_cache_init() 00089 { 00090 GVX_ASSERT(g_name_cache == 0); 00091 g_name_cache = new cache_type; 00092 } 00093 } 00094 00095 const char* rutz::demangled_name(const std::type_info& info) 00096 { 00097 GVX_TRACE("rutz::demangled_name"); 00098 00099 pthread_once(&g_name_cache_init_once, &name_cache_init); 00100 GVX_ASSERT(g_name_cache != 0); 00101 00102 const std::string mangled = info.name(); 00103 00104 GVX_MUTEX_LOCK(&g_name_cache_mutex); 00105 00106 cache_type::iterator itr = g_name_cache->find(mangled); 00107 00108 if (itr != g_name_cache->end()) 00109 { 00110 return (*itr).second.c_str(); 00111 } 00112 00113 const std::string demangled = DEMANGLE_IMPL(info.name()); 00114 00115 std::pair<cache_type::iterator, bool> result = 00116 g_name_cache->insert(cache_type::value_type(mangled, demangled)); 00117 00118 GVX_ASSERT(result.second == true); 00119 00120 return (*result.first).second.c_str(); 00121 } 00122 00123 static const char __attribute__((used)) vcid_groovx_rutz_demangle_cc_utc20050626084020[] = "$Id: demangle.cc 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/demangle.cc $"; 00124 #endif // !GROOVX_RUTZ_DEMANGLE_CC_UTC20050626084020_DEFINED