demangle_gcc_v2.h

Go to the documentation of this file.
00001 /** @file rutz/demangle_gcc_v2.h hand-rolled demangling of
00002     std::type_info::name() from the g++ 2.x series */
00003 
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 16:58:19 2001 (as gcc_v2_demangle.h)
00011 // commit: $Id: demangle_gcc_v2.h 8249 2007-04-12 06:03:40Z rjpeters $
00012 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/demangle_gcc_v2.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 //
00033 ///////////////////////////////////////////////////////////////////////
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); // we need to also erase the '_'
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     // Check if we have namespace qualifiers...
00163     if (out[0] == 'Q')
00164       {
00165         out.erase(0, 1);
00166         int num_levels = 0;
00167         // get the number of nesting levels...
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             // Get the length of the current qualifier
00184             int length = munch_int(out, pos);
00185             // Skip over the qualifier itself
00186             pos += length;
00187             // Insert a scope resolution operator after the qualifier "::"
00188             out.insert(pos, "::");
00189             // Skip over the just-inserted "::"
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         // Read length of template base name and skip over it
00214         int base_length = munch_int(out, pos);
00215         pos += base_length;
00216 
00217         // Insert left bracket
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             // Template parameters must start with 'Z'
00227             GVX_ASSERT( out[pos] == 'Z' );
00228             out.erase(pos, 1);
00229 
00230             dbg_eval_nl(3, out.c_str());
00231 
00232             // Get the parameter name:
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                 // Read length of template parameter name and skip over it
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             // Insert a comma if this is not the last parameter
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         // Insert right bracket
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 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/demangle_gcc_v2.h $";
00270 #endif // !GROOVX_RUTZ_DEMANGLE_GCC_V2_H_UTC20050626084020_DEFINED
Generated on Sun May 8 08:42:09 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3