00001 00004 00005 // 00006 // Copyright (c) 2002-2004 California Institute of Technology 00007 // Copyright (c) 2004-2007 University of Southern California 00008 // Rob Peters <rjpeters at usc dot edu> 00009 // 00010 // created: Tue Jun 19 17:00:38 2001 (as gcc_v3_demangle.h) 00011 // commit: $Id: demangle_gcc_v3.h 10065 2007-04-12 05:54:56Z rjpeters $ 00012 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/rutz/demangle_gcc_v3.h $ 00013 // 00014 // -------------------------------------------------------------------- 00015 // 00016 // This file is part of GroovX. 00017 // [http://ilab.usc.edu/rjpeters/groovx/] 00018 // 00019 // GroovX is free software; you can redistribute it and/or modify it 00020 // under the terms of the GNU General Public License as published by 00021 // the Free Software Foundation; either version 2 of the License, or 00022 // (at your option) any later version. 00023 // 00024 // GroovX is distributed in the hope that it will be useful, but 00025 // WITHOUT ANY WARRANTY; without even the implied warranty of 00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00027 // General Public License for more details. 00028 // 00029 // You should have received a copy of the GNU General Public License 00030 // along with GroovX; if not, write to the Free Software Foundation, 00031 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00032 // 00034 00035 #ifndef GROOVX_RUTZ_DEMANGLE_GCC_V3_H_UTC20050626084020_DEFINED 00036 #define GROOVX_RUTZ_DEMANGLE_GCC_V3_H_UTC20050626084020_DEFINED 00037 00038 #include "rutz/error.h" 00039 00040 #include "rutz/demangle_cxxfilt.h" 00041 #include "rutz/sfmt.h" 00042 00043 #include <cstdlib> 00044 #include <cxxabi.h> 00045 #include <string> 00046 00047 #include "rutz/debug.h" 00048 #include "rutz/trace.h" 00049 00050 namespace 00051 { 00052 const char* get_err_reason(int status) 00053 { 00054 switch (status) 00055 { 00056 case -1: 00057 return "memory allocation error"; 00058 break; 00059 00060 case -2: 00061 return "invalid mangled name"; 00062 break; 00063 00064 case -3: 00065 return "invalid arguments (e.g. buf non-NULL " 00066 "and length NULL)"; 00067 break; 00068 } 00069 00070 // default: 00071 return "unknown error code"; 00072 } 00073 00074 std::string demangle_gcc_v3(const std::string& mangled) 00075 { 00076 GVX_TRACE("demangle_gcc_v3"); 00077 00078 int status = 0; 00079 00080 static std::size_t length = 256; 00081 static char* demangled = static_cast<char*>(malloc(length)); 00082 00083 demangled = abi::__cxa_demangle(mangled.c_str(), demangled, 00084 &length, &status); 00085 00086 if (status == 0) 00087 { 00088 GVX_ASSERT(demangled != 0); 00089 return std::string(demangled); 00090 } 00091 00092 // ok, cxa_demangle failed, but before we report that error let's 00093 // try falling back to c++filt (but if any exception occurs there, 00094 // we'll ignore it and just report the original cxa_demangle error 00095 // instead): 00096 try 00097 { 00098 return demangle_cxxfilt(mangled); 00099 } 00100 catch (std::exception& e) 00101 { 00102 const rutz::fstring msg = 00103 rutz::sfmt("during cxa_demangle of '%s': %s\n" 00104 "(c++filt also failed: %s)", 00105 mangled.c_str(), get_err_reason(status), 00106 e.what()); 00107 00108 throw rutz::error(msg, SRC_POS); 00109 } 00110 00111 GVX_ASSERT(false); 00112 return "can't happen"; // can't happen, but placate compiler 00113 } 00114 } 00115 00116 // 00117 // demangling test code 00118 // 00119 00120 // #include <iostream> 00121 // #include <exception> 00122 // #include <typeinfo> 00123 00124 // #include "src/util/demangle_gcc_v3.h" 00125 00126 // void printboth(const char* n) 00127 // { 00128 // std::cout << n << '\t' << gcc_v3_demangle(n) << std::endl; 00129 // } 00130 00131 // class Global { int x; }; 00132 00133 // namespace Nspace { struct Nested { struct Inner {int x; }; }; } 00134 00135 // template <typename T> 00136 // class Tplate { T x; }; 00137 00138 // class i {}; 00139 00140 // template <class T1, class T2> 00141 // class Tplate2 { T1 x1; T2 x2; }; 00142 00143 // template <class T1> 00144 // class Tplate3 { struct Xt {}; }; 00145 00146 // int main() 00147 // { 00148 // printboth(typeid(int).name()); 00149 // printboth(typeid(double).name()); 00150 // printboth(typeid(i).name()); 00151 // printboth(typeid(Global).name()); 00152 // printboth(typeid(std::exception).name()); 00153 // printboth(typeid(Nspace::Nested).name()); 00154 // printboth(typeid(Nspace::Nested::Inner).name()); 00155 // printboth(typeid(Tplate<int>).name()); 00156 // printboth(typeid(Tplate<double>).name()); 00157 // printboth(typeid(Tplate<Global>).name()); 00158 // printboth(typeid(Tplate<std::exception>).name()); 00159 // printboth(typeid(Tplate<Nspace::Nested::Inner>).name()); 00160 // printboth(typeid(Tplate2<int, double>).name()); 00161 // printboth(typeid(Tplate<int*>).name()); 00162 // printboth(typeid(Tplate<Global*>).name()); 00163 // printboth(typeid(Tplate<const int*>).name()); 00164 // printboth(typeid(Tplate<const Global*>).name()); 00165 // printboth(typeid(Tplate<int* const>).name()); 00166 // printboth(typeid(Tplate<Global* const>).name()); 00167 // printboth(typeid(Tplate<int const* const>).name()); 00168 // printboth(typeid(Tplate<Global const* const>).name()); 00169 // printboth(typeid(Tplate3<int>::Xt).name()); 00170 // } 00171 00172 static const char __attribute__((used)) vcid_groovx_rutz_demangle_gcc_v3_h_utc20050626084020[] = "$Id: demangle_gcc_v3.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file: 00173 #endif // !GROOVX_RUTZ_DEMANGLE_GCC_V3_H_UTC20050626084020_DEFINED