00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00034
00035 #ifndef GROOVX_RUTZ_DEMANGLE_GCC_V2_H_UTC20050626084020_DEFINED
00036 #define GROOVX_RUTZ_DEMANGLE_GCC_V2_H_UTC20050626084020_DEFINED
00037
00038 #include <cctype>
00039 #include <cstdlib>
00040 #include <string>
00041
00042 #include "rutz/trace.h"
00043 #include "rutz/debug.h"
00044 GVX_DBG_REGISTER
00045
00046 namespace
00047 {
00048 int munch_int(std::string& str, std::string::size_type pos)
00049 {
00050 int val = 0;
00051 while ( isdigit(str[pos]) )
00052 {
00053 val *= 10;
00054 val += (str[pos] - '0');
00055 str.erase(pos, 1);
00056 }
00057 return val;
00058 }
00059
00060 void put_int(int val, std::string& str, std::string::size_type pos)
00061 {
00062 while (val != 0)
00063 {
00064 str.insert(pos, 1, '0' + (val%10));
00065 val /= 10;
00066 }
00067 }
00068
00069 std::string read_modifiers(std::string& str, std::string::size_type& pos)
00070 {
00071 std::string modifiers("");
00072 std::string array_dims("");
00073
00074 while ( isupper(str[pos]) )
00075 {
00076 switch (str[pos])
00077 {
00078 case 'A':
00079 str.erase(pos, 1);
00080 array_dims.append("[");
00081 if ( isdigit(str[pos]) )
00082 {
00083 int dim_size = munch_int(str, pos);
00084 put_int(dim_size+1,array_dims,array_dims.length());
00085 }
00086 array_dims.append("]");
00087 break;
00088 case 'C':
00089 modifiers.insert(0, " const");
00090 break;
00091 case 'P':
00092 modifiers.insert(0, "*");
00093 break;
00094 case 'R':
00095 modifiers.insert(0, "&");
00096 break;
00097 case 'U':
00098 modifiers.insert(0, " unsigned");
00099 break;
00100 default:
00101 GVX_ASSERT(0);
00102 }
00103 str.erase(pos, 1);
00104 }
00105 dbg_eval_nl(3, str.c_str());
00106
00107 modifiers.append(array_dims);
00108
00109 return modifiers;
00110 }
00111
00112 void insert_builtin_typename(std::string& str, std::string::size_type& pos)
00113 {
00114 char typecode = str[pos];
00115 str.erase(pos, 1);
00116 switch (typecode)
00117 {
00118 case 'b':
00119 str.insert(pos, "bool"); pos += 4;
00120 break;
00121 case 'c':
00122 str.insert(pos, "char"); pos += 4;
00123 break;
00124 case 'd':
00125 str.insert(pos, "double"); pos += 6;
00126 break;
00127 case 'f':
00128 str.insert(pos, "float"); pos += 5;
00129 break;
00130 case 'i':
00131 str.insert(pos, "int"); pos += 3;
00132 break;
00133 case 'l':
00134 str.insert(pos, "long"); pos += 4;
00135 break;
00136 case 's':
00137 str.insert(pos, "short"); pos += 5;
00138 break;
00139 case 'v':
00140 str.insert(pos, "void"); pos += 4;
00141 break;
00142 default:
00143 dbg_eval_nl(3, typecode);
00144 GVX_ASSERT(0);
00145 break;
00146 }
00147 }
00148
00149 std::string demangle_gcc_v2(const std::string& in)
00150 {
00151 GVX_TRACE("demangle_impl");
00152 std::string out=in;
00153
00154 dbg_eval_nl(3, out.c_str());
00155
00156 bool isTemplate = false;
00157
00158 if (out.length() == 0) return out;
00159
00160 std::string::size_type pos = 0;
00161
00162
00163 if (out[0] == 'Q')
00164 {
00165 out.erase(0, 1);
00166 int num_levels = 0;
00167
00168 if (out[0] == '_')
00169 {
00170 out.erase(0, 1);
00171 num_levels = munch_int(out, 0);
00172 dbg_eval_nl(3, num_levels);
00173 GVX_ASSERT(out[0] == '_');
00174 out.erase(0, 1);
00175 }
00176 else
00177 {
00178 num_levels = out[0] - '0';
00179 out.erase(0, 1);
00180 }
00181 while (num_levels > 1)
00182 {
00183
00184 int length = munch_int(out, pos);
00185
00186 pos += length;
00187
00188 out.insert(pos, "::");
00189
00190 pos += 2;
00191 --num_levels;
00192 }
00193 }
00194
00195 dbg_eval_nl(3, out.c_str());
00196
00197 if (out[pos] == 't')
00198 {
00199 isTemplate = true;
00200 out.erase(pos, 1);
00201 }
00202
00203 if ( !isTemplate )
00204 {
00205 while ( isdigit(out[pos]) )
00206 {
00207 out.erase(pos, 1);
00208 }
00209 dbg_eval_nl(3, out.c_str());
00210 }
00211 else
00212 {
00213
00214 int base_length = munch_int(out, pos);
00215 pos += base_length;
00216
00217
00218 out.insert(pos++, 1, '<');
00219
00220 dbg_eval_nl(3, out.c_str());
00221
00222 int num_parameters = munch_int(out, pos);;
00223
00224 for (int n = 0; n < num_parameters; ++n)
00225 {
00226
00227 GVX_ASSERT( out[pos] == 'Z' );
00228 out.erase(pos, 1);
00229
00230 dbg_eval_nl(3, out.c_str());
00231
00232
00233 std::string modifiers = read_modifiers(out, pos);
00234
00235 if ( !isdigit(out[pos]) )
00236 {
00237 insert_builtin_typename(out, pos);
00238 }
00239 else
00240 {
00241
00242 int param_length = munch_int(out, pos);
00243 pos += param_length;
00244 }
00245
00246 out.insert(pos, modifiers);
00247 pos += modifiers.length();
00248
00249
00250 if (n < (num_parameters-1))
00251 {
00252 out.insert(pos++, 1, ',');
00253 out.insert(pos++, 1, ' ');
00254 }
00255
00256 dbg_eval_nl(3, out.c_str());
00257 }
00258
00259
00260 out.insert(pos++, 1, '>');
00261 }
00262
00263 dbg_eval_nl(3, out.c_str());
00264
00265 return out;
00266 }
00267 }
00268
00269 static const char __attribute__((used)) vcid_groovx_rutz_demangle_gcc_v2_h_utc20050626084020[] = "$Id: demangle_gcc_v2.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00270 #endif // !GROOVX_RUTZ_DEMANGLE_GCC_V2_H_UTC20050626084020_DEFINED