Changeset 409
- Timestamp:
- 11/02/10 18:45:48 (2 years ago)
- Files:
-
- trunk/src/core/demangle.d (modified) (38 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/core/demangle.d
r386 r409 22 22 23 23 24 /** 25 * Demangles D mangled names. If it is not a D mangled name, it returns its 26 * argument name. 27 * 28 * Params: 29 * buf = The string to demangle. 30 * dst = An optional destination buffer. 31 * 32 * Returns: 33 * The demangled name or the original string if the name is not a mangled D 34 * name. 35 */ 36 char[] demangle( const(char)[] buf, char[] dst = null ) 24 private struct Demangle 37 25 { 38 26 // NOTE: This implementation currently only works with mangled function … … 52 40 // allocation during the course of a parsing run, this is still 53 41 // faster than assembling the result piecemeal. 42 43 44 enum AddType { yes, no } 45 46 47 this( const(char)[] buf_, char[] dst_ = null ) 48 { 49 this( buf_, AddType.no, dst_ ); 50 } 51 52 53 this( const(char)[] buf_, AddType addType_, char[] dst_ = null ) 54 { 55 buf = buf_; 56 addType = addType_; 57 dst = dst_; 58 } 59 54 60 55 61 enum minBufSize = 4000; 56 62 57 size_t pos = 0; 58 size_t len = 0; 63 64 const(char)[] buf = null; 65 char[] dst = null; 66 size_t pos = 0; 67 size_t len = 0; 68 AddType addType = AddType.no; 69 59 70 60 71 static class ParseException : Exception … … 66 77 } 67 78 79 68 80 static class OverflowException : Exception 69 81 { … … 73 85 } 74 86 } 87 75 88 76 89 static void error( string msg = "Invalid symbol" ) … … 82 95 } 83 96 97 84 98 static void overflow( string msg = "Buffer overflow" ) 85 99 { … … 89 103 } 90 104 105 91 106 ////////////////////////////////////////////////////////////////////////// 92 107 // Type Testing and Conversion 93 108 ////////////////////////////////////////////////////////////////////////// 94 109 110 111 static bool isAlpha( char val ) 112 { 113 return ('a' <= val && 'z' >= val) || 114 ('A' <= val && 'Z' >= val); 115 } 116 117 95 118 static bool isDigit( char val ) 96 119 { 97 120 return '0' <= val && '9' >= val; 98 121 } 122 99 123 100 124 static bool isHexDigit( char val ) … … 105 129 } 106 130 107 static bool isAlpha( char val )108 {109 return ('a' <= val && 'z' >= val) ||110 ('A' <= val && 'Z' >= val);111 }112 131 113 132 static ubyte ascii2hex( char val ) … … 127 146 } 128 147 148 129 149 ////////////////////////////////////////////////////////////////////////// 130 150 // Data Output 131 151 ////////////////////////////////////////////////////////////////////////// 132 152 153 133 154 static bool contains( const(char)[] a, const(char)[] b ) 134 155 { … … 137 158 b.ptr + b.length <= a.ptr + a.length; 138 159 } 160 139 161 140 162 char[] shift( const(char)[] val ) … … 163 185 return null; 164 186 } 187 165 188 166 189 char[] append( const(char)[] val ) … … 185 208 } 186 209 210 187 211 char[] put( const(char)[] val ) 188 212 { … … 196 220 } 197 221 222 198 223 void pad( const(char)[] val ) 199 224 { … … 204 229 } 205 230 } 231 206 232 207 233 void silent( lazy void dg ) … … 212 238 } 213 239 240 214 241 ////////////////////////////////////////////////////////////////////////// 215 242 // Parsing Utility 216 243 ////////////////////////////////////////////////////////////////////////// 217 244 245 218 246 char tok() 219 247 { … … 223 251 } 224 252 253 225 254 void test( char val ) 226 255 { … … 229 258 } 230 259 260 231 261 void next() 232 262 { … … 235 265 } 236 266 267 237 268 void match( char val ) 238 269 { … … 241 272 } 242 273 243 void matchS( const(char)[] val ) 274 275 void match( const(char)[] val ) 244 276 { 245 277 foreach( e; val ) … … 250 282 } 251 283 284 252 285 void eat( char val ) 253 286 { … … 255 288 next(); 256 289 } 290 257 291 258 292 ////////////////////////////////////////////////////////////////////////// 259 293 // Parsing Implementation 260 294 ////////////////////////////////////////////////////////////////////////// 295 261 296 262 297 /* … … 285 320 } 286 321 322 287 323 size_t decodeNumber() 288 324 { … … 302 338 return val; 303 339 } 340 304 341 305 342 void parseReal() … … 354 391 } 355 392 393 356 394 /* 357 395 LName: … … 394 432 pos += n; 395 433 } 434 396 435 397 436 /* … … 851 890 case 'T': // TypeTypedef (T LName) 852 891 next(); 853 parse LName();892 parseQualifiedName(); 854 893 return dst[beg .. len]; 855 894 case 'D': // TypeDelegate (D TypeFunction) … … 978 1017 } 979 1018 } 1019 980 1020 981 1021 /* … … 1062 1102 } 1063 1103 put( "\"" ); 1064 if( 'a' != t ok())1104 if( 'a' != t ) 1065 1105 put( (cast(char*) &t)[0 .. 1] ); 1066 1106 return; … … 1073 1113 } 1074 1114 } 1115 1075 1116 1076 1117 /* … … 1107 1148 next(); 1108 1149 if( n ) put( ", " ); 1109 parse LName();1150 parseQualifiedName(); 1110 1151 continue; 1111 1152 default: … … 1114 1155 } 1115 1156 } 1157 1116 1158 1117 1159 /* … … 1128 1170 auto n = decodeNumber(); 1129 1171 auto beg = pos; 1130 match S( "__T" );1172 match( "__T" ); 1131 1173 parseLName(); 1132 1174 put( "!(" ); … … 1138 1180 } 1139 1181 1182 1140 1183 bool mayBeTemplateInstanceName() 1141 1184 { … … 1151 1194 pos < buf.length && 'T' == buf[pos++]; 1152 1195 } 1196 1153 1197 1154 1198 /* … … 1190 1234 } 1191 1235 1236 1192 1237 /* 1193 1238 QualifiedName: … … 1211 1256 } 1212 1257 1258 1213 1259 /* 1214 1260 MangledName: … … 1228 1274 if( 'M' == tok() ) 1229 1275 next(); // has 'this' pointer 1230 parseType( name ); 1231 } 1232 1233 while( true ) 1234 { 1235 try 1236 { 1237 debug(info) printf( "demangle(%.*s)\n", cast(int) buf.length, buf.ptr ); 1238 parseMangledName(); 1239 return dst[0 .. len]; 1240 } 1241 catch( OverflowException e ) 1242 { 1243 debug(trace) printf( "overflow... restarting\n" ); 1244 auto a = minBufSize; 1245 auto b = 2 * dst.length; 1246 auto newsz = a < b ? b : a; 1247 debug(info) printf( "growing dst to %lu bytes\n", newsz ); 1248 dst.length = newsz; 1249 pos = len = 0; 1250 continue; 1251 } 1252 catch( ParseException e ) 1253 { 1254 debug 1276 if( addType ) 1277 parseType( name ); 1278 } 1279 1280 1281 char[] opCall() 1282 { 1283 while( true ) 1284 { 1285 try 1255 1286 { 1256 auto msg = e.toString; 1257 printf( "error: %.*s\n", cast(int) msg.length, msg.ptr ); 1287 debug(info) printf( "demangle(%.*s)\n", cast(int) buf.length, buf.ptr ); 1288 parseMangledName(); 1289 return dst[0 .. len]; 1258 1290 } 1259 if( dst.length < buf.length ) 1260 dst.length = buf.length; 1261 dst[0 .. buf.length] = buf[]; 1262 return dst[0 .. buf.length]; 1263 } 1264 } 1291 catch( OverflowException e ) 1292 { 1293 debug(trace) printf( "overflow... restarting\n" ); 1294 auto a = minBufSize; 1295 auto b = 2 * dst.length; 1296 auto newsz = a < b ? b : a; 1297 debug(info) printf( "growing dst to %lu bytes\n", newsz ); 1298 dst.length = newsz; 1299 pos = len = 0; 1300 continue; 1301 } 1302 catch( ParseException e ) 1303 { 1304 debug(info) 1305 { 1306 auto msg = e.toString; 1307 printf( "error: %.*s\n", cast(int) msg.length, msg.ptr ); 1308 } 1309 if( dst.length < buf.length ) 1310 dst.length = buf.length; 1311 dst[0 .. buf.length] = buf[]; 1312 return dst[0 .. buf.length]; 1313 } 1314 } 1315 } 1316 } 1317 1318 1319 /** 1320 * Demangles D mangled names. If it is not a D mangled name, it returns its 1321 * argument name. 1322 * 1323 * Params: 1324 * buf = The string to demangle. 1325 * dst = An optional destination buffer. 1326 * 1327 * Returns: 1328 * The demangled name or the original string if the name is not a mangled D 1329 * name. 1330 */ 1331 char[] demangle( const(char)[] buf, char[] dst = null ) 1332 { 1333 //return Demangle(buf, dst)(); 1334 auto d = Demangle(buf, dst); 1335 return d(); 1265 1336 } 1266 1337 … … 1277 1348 [ "_D6object6Object8opEqualsFC6ObjectZi", "int object.Object.opEquals(class Object)" ], 1278 1349 [ "_D4test2dgDFiYd", "double delegate(int, ...) test.dg" ], 1279 //[ "_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial" ],1280 //[ "_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, cdouble 6.8+3i, char[5] \"hello\"c, void* null).factorial" ],1350 [ "_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial" ], 1351 [ "_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, cdouble 6.8+3i, char[5] \"hello\"c, void* null).factorial" ], 1281 1352 [ "_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi", "int test.bar!(wchar[3] \"abc\"w, dchar[3] \"def\"d).x" ], 1282 1353 [ "_D8demangle4testFLC6ObjectLDFLiZiZi", "int demangle.test(lazy class Object, lazy int delegate(lazy int))"], … … 1299 1370 } 1300 1371 } 1372 1373 1374 /* 1375 * 1376 */ 1377 string decodeDmdString( char[] ln, ref int p ) 1378 { 1379 string s; 1380 uint zlen, zpos; 1381 1382 // decompress symbol 1383 while( p < ln.length ) 1384 { 1385 int ch = cast(ubyte) ln[p++]; 1386 if( (ch & 0xc0) == 0xc0 ) 1387 { 1388 zlen = (ch & 0x7) + 1; 1389 zpos = ((ch >> 3) & 7) + 1; // + zlen; 1390 if( zpos > s.length ) 1391 break; 1392 s ~= s[$ - zpos .. $ - zpos + zlen]; 1393 } 1394 else if( ch >= 0x80 ) 1395 { 1396 if( p >= ln.length ) 1397 break; 1398 int ch2 = cast(ubyte) ln[p++]; 1399 zlen = (ch2 & 0x7f) | ((ch & 0x38) << 4); 1400 if( p >= ln.length ) 1401 break; 1402 int ch3 = cast(ubyte) ln[p++]; 1403 zpos = (ch3 & 0x7f) | ((ch & 7) << 7); 1404 if( zpos > s.length ) 1405 break; 1406 s ~= s[$ - zpos .. $ - zpos + zlen]; 1407 } 1408 else if( Demangle.isAlpha(cast(char)ch) || Demangle.isDigit(cast(char)ch) || ch == '_' ) 1409 s ~= cast(char) ch; 1410 else 1411 { 1412 p--; 1413 break; 1414 } 1415 } 1416 return s; 1417 }
