Changeset c20fafd for src/SymTab/Demangle.cc
- Timestamp:
- Aug 2, 2018, 5:16:47 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- d8cb7df
- Parents:
- 7804e2a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Demangle.cc
r7804e2a rc20fafd 324 324 namespace Mangler { 325 325 namespace { 326 // strips __NAME__cfa__TYPE_N, where N is [0-9]+: returns str is a match is found, returns empty string otherwise 327 bool stripMangleName(const std::string & mangleName, std::string & name, std::string & type) { 328 PRINT( std::cerr << "====== " << mangleName.size() << " " << mangleName << std::endl; ) 329 if (mangleName.size() < 4+nameSeparator.size()) return false; 330 if (mangleName[0] != '_' || mangleName[1] != '_' || ! isdigit(mangleName.back())) return false; 331 332 // find bounds for name 333 size_t nameStart = 2; 334 size_t nameEnd = mangleName.rfind(nameSeparator); 335 PRINT( std::cerr << nameStart << " " << nameEnd << std::endl; ) 336 if (nameEnd == std::string::npos) return false; 337 338 // find bounds for type 339 size_t typeStart = nameEnd+nameSeparator.size(); 340 size_t typeEnd = mangleName.size()-1; 341 PRINT( std::cerr << typeStart << " " << typeEnd << std::endl; ) 342 PRINT( std::cerr << "["); 343 while (isdigit(mangleName[typeEnd])) { 344 PRINT(std::cerr << "."); 345 typeEnd--; 346 } 347 PRINT( std::cerr << "]" << std::endl ); 348 if (mangleName[typeEnd] != '_') return false; 349 PRINT( std::cerr << typeEnd << std::endl; ) 350 351 // trim and return 352 name = mangleName.substr(nameStart, nameEnd-nameStart); 353 type = mangleName.substr(typeStart, typeEnd-typeStart); 326 struct StringView { 327 private: 328 std::string str; 329 size_t idx = 0; 330 // typedef Type * (StringView::*parser)(Type::Qualifiers); 331 typedef std::function<Type * (Type::Qualifiers)> parser; 332 std::vector<std::pair<std::string, parser>> parsers; 333 public: 334 StringView(const std::string & str); 335 336 bool done() const { return idx >= str.size(); } 337 char cur() const { assert(! done()); return str[idx]; } 338 339 bool expect(char ch) { return str[idx++] == ch; } 340 void next(size_t inc = 1) { idx += inc; } 341 342 /// determines if `pref` is a prefix of `str` 343 bool isPrefix(const std::string & pref); 344 bool extractNumber(size_t & out); 345 bool extractName(std::string & out); 346 bool stripMangleName(std::string & name); 347 348 Type * parseFunction(Type::Qualifiers tq); 349 Type * parseTuple(Type::Qualifiers tq); 350 Type * parseVoid(Type::Qualifiers tq); 351 Type * parsePointer(Type::Qualifiers tq); 352 Type * parseStruct(Type::Qualifiers tq); 353 354 Type * parseType(); 355 bool parse(std::string & name, Type *& type); 356 }; 357 358 StringView::StringView(const std::string & str) : str(str) { 359 // basic types 360 for (size_t k = 0; k < BasicType::NUMBER_OF_BASIC_TYPES; ++k) { 361 parsers.emplace_back(Encoding::basicTypes[k], [this, k](Type::Qualifiers tq) { 362 PRINT( std::cerr << "basic type: " << k << std::endl; ) 363 return new BasicType(tq, (BasicType::Kind)k); 364 }); 365 } 366 // everything else 367 parsers.emplace_back(Encoding::void_t, [this](Type::Qualifiers tq) { return parseVoid(tq); }); 368 parsers.emplace_back(Encoding::function, [this](Type::Qualifiers tq) { return parseFunction(tq); }); 369 parsers.emplace_back(Encoding::pointer, [this](Type::Qualifiers tq) { return parsePointer(tq); }); 370 parsers.emplace_back(Encoding::tuple, [this](Type::Qualifiers tq) { return parseTuple(tq); }); 371 parsers.emplace_back(Encoding::struct_t, [this](Type::Qualifiers tq) { return parseStruct(tq); }); 372 } 373 374 bool StringView::extractNumber(size_t & out) { 375 std::stringstream numss; 376 while (isdigit(str[idx])) { 377 numss << str[idx]; 378 ++idx; 379 if (idx >= str.size()) return false; 380 } 381 if (! (numss >> out)) return false; 354 382 return true; 355 383 } 356 384 357 /// determines if `pref` is a prefix of `str` 358 static inline bool isPrefix( const std::string & str, const std::string & pref, unsigned int idx ) { 385 bool StringView::extractName(std::string & out) { 386 size_t len; 387 if (! extractNumber(len)) return false; 388 if (idx+len >= str.size()) return false; 389 out = str.substr(idx, len); 390 idx += len; 391 return true; 392 } 393 394 bool StringView::isPrefix(const std::string & pref) { 359 395 if ( pref.size() > str.size()-idx ) return false; 360 396 auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) ); 361 return its.first == pref.end(); 362 } 363 364 Type * parseType(const std::string & typeString, unsigned int & idx) { 365 if (idx >= typeString.size()) return nullptr; 397 if (its.first == pref.end()) { 398 idx += pref.size(); 399 return true; 400 } 401 return false; 402 } 403 404 // strips __NAME__cfa__TYPE_N, where N is [0-9]+: returns str is a match is found, returns empty string otherwise 405 bool StringView::stripMangleName(std::string & name) { 406 PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; ) 407 if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix 408 if (! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back())) return false; 409 410 // get name 411 if (! extractName(name)) return false; 412 413 // find bounds for type 414 PRINT( std::cerr << idx << " " << str.size() << std::endl; ) 415 PRINT( std::cerr << "["); 416 while (isdigit(str.back())) { 417 PRINT(std::cerr << "."); 418 str.pop_back(); 419 if (str.size() <= idx) return false; 420 } 421 PRINT( std::cerr << "]" << std::endl ); 422 if (str.back() != '_') return false; 423 str.pop_back(); 424 PRINT( std::cerr << str.size() << " " << name << " " << str.substr(idx) << std::endl; ) 425 return str.size() > idx; 426 } 427 428 Type * StringView::parseFunction(Type::Qualifiers tq) { 429 PRINT( std::cerr << "function..." << std::endl; ) 430 if (done()) return nullptr; 431 FunctionType * ftype = new FunctionType( tq, false ); 432 Type * retVal = parseType(); 433 if (! retVal) return nullptr; 434 PRINT( std::cerr << "with return type: " << retVal << std::endl; ) 435 ftype->returnVals.push_back(ObjectDecl::newObject("", retVal, nullptr)); 436 if (done() || ! expect('_')) return nullptr; 437 while (! done()) { 438 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 439 if (cur() == '_') return ftype; 440 Type * param = parseType(); 441 if (! param) return nullptr; 442 PRINT( std::cerr << "with parameter : " << param << std::endl; ) 443 ftype->parameters.push_back(ObjectDecl::newObject("", param, nullptr)); 444 } 445 return nullptr; 446 } 447 448 Type * StringView::parseTuple(Type::Qualifiers tq) { 449 PRINT( std::cerr << "tuple..." << std::endl; ) 450 std::list< Type * > types; 451 size_t ncomponents; 452 if (! extractNumber(ncomponents)) return nullptr; 453 for (size_t i = 0; i < ncomponents; ++i) { 454 if (done()) return nullptr; 455 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 456 Type * t = parseType(); 457 if (! t) return nullptr; 458 PRINT( std::cerr << "with type : " << t << std::endl; ) 459 types.push_back(t); 460 } 461 return new TupleType( tq, types ); 462 } 463 464 Type * StringView::parseVoid(Type::Qualifiers tq) { 465 return new VoidType( tq ); 466 } 467 468 Type * StringView::parsePointer(Type::Qualifiers tq) { 469 PRINT( std::cerr << "pointer..." << std::endl; ) 470 Type * t = parseType(); 471 if (! t) return nullptr; 472 return new PointerType( tq, t ); 473 } 474 475 Type * StringView::parseStruct(Type::Qualifiers tq) { 476 PRINT( std::cerr << "struct..." << std::endl; ) 477 std::string name; 478 if (! extractName(name)) return nullptr; 479 return new StructInstType(tq, name); 480 } 481 482 Type * StringView::parseType() { 483 if (done()) return nullptr; 366 484 367 485 // qualifiers 368 486 Type::Qualifiers tq; 369 487 while (true) { 370 auto qual = std::find_if(qualifierLetter.begin(), qualifierLetter.end(), [&idx, &typeString](decltype(qualifierLetter)::value_type val) { 371 if (isPrefix(typeString, val.second, idx)) { 372 PRINT( std::cerr << "found qualifier: " << val.second << std::endl; ) 373 idx += std::string(val.second).size(); 374 return true; 375 } 376 return false; 488 auto qual = std::find_if(Encoding::qualifiers.begin(), Encoding::qualifiers.end(), [this](decltype(Encoding::qualifiers)::value_type val) { 489 return isPrefix(val.second); 377 490 }); 378 if (qual == qualifierLetter.end()) break;491 if (qual == Encoding::qualifiers.end()) break; 379 492 tq |= qual->first; 380 493 } 381 494 382 // basic types 383 const char ** letter = std::find_if(&btLetter[0], &btLetter[numBtLetter], [&idx, &typeString](const std::string & letter) { 384 if (isPrefix(typeString, letter, idx)) { 385 idx += letter.size(); 386 return true; 387 } 388 return false; 495 // find the correct type parser and use it 496 auto iter = std::find_if(parsers.begin(), parsers.end(), [this](std::pair<std::string, parser> & p) { 497 return isPrefix(p.first); 389 498 }); 390 if (letter != &btLetter[numBtLetter]) { 391 PRINT( std::cerr << "basic type: " << (letter-btLetter) << std::endl; ) 392 BasicType::Kind k = (BasicType::Kind)(letter-btLetter); 393 return new BasicType( tq, k ); 394 } // BasicType? 395 396 // everything else 397 switch(typeString[idx++]) { 398 case 'F': { 399 PRINT( std::cerr << "function..." << std::endl; ) 400 if (idx >= typeString.size()) return nullptr; 401 FunctionType * ftype = new FunctionType( tq, false ); 402 Type * retVal = parseType(typeString, idx); 403 if (! retVal) return nullptr; 404 PRINT( std::cerr << "with return type: " << retVal << std::endl; ) 405 ftype->returnVals.push_back(ObjectDecl::newObject("", retVal, nullptr)); 406 if (idx >= typeString.size() || typeString[idx++] != '_') return nullptr; 407 while (idx < typeString.size()) { 408 PRINT( std::cerr << "got ch: " << typeString[idx] << std::endl; ) 409 if (typeString[idx] == '_') break; 410 Type * param = parseType(typeString, idx); 411 if (! param) return nullptr; 412 PRINT( std::cerr << "with parameter : " << param << std::endl; ) 413 ftype->parameters.push_back(ObjectDecl::newObject("", param, nullptr)); 414 } 415 if (idx >= typeString.size() || typeString[idx] != '_') return nullptr; 416 ++idx; 417 return ftype; 418 } 419 case 'v': 420 return new VoidType( tq ); 421 case 'T': { 422 PRINT( std::cerr << "tuple..." << std::endl; ) 423 std::list< Type * > types; 424 while (idx < typeString.size()) { 425 PRINT( std::cerr << "got ch: " << typeString[idx] << std::endl; ) 426 if (typeString[idx] == '_') break; 427 Type * t = parseType(typeString, idx); 428 if (! t) return nullptr; 429 PRINT( std::cerr << "with type : " << t << std::endl; ) 430 types.push_back(t); 431 } 432 if (idx >= typeString.size() || typeString[idx] != '_') return nullptr; 433 ++idx; 434 return new TupleType( tq, types ); 435 } 436 case 'P': { 437 PRINT( std::cerr << "pointer..." << std::endl; ) 438 Type * t = parseType(typeString, idx); 439 if (! t) return nullptr; 440 return new PointerType( tq, t ); 441 } 442 443 default: assertf(false, "Unhandled type letter: %c at index: %u", typeString[idx], idx); 444 } 445 return nullptr; 446 } 447 448 Type * parseType(const std::string & typeString) { 449 unsigned int idx = 0; 450 return parseType(typeString, idx); 499 assertf(iter != parsers.end(), "Unhandled type letter: %c at index: %zd", cur(), idx); 500 return iter->second(tq); 501 } 502 503 bool StringView::parse(std::string & name, Type *& type) { 504 if (! stripMangleName(name)) return false; 505 PRINT( std::cerr << "stripped name: " << name << std::endl; ) 506 Type * t = parseType(); 507 if (! t) return false; 508 type = t; 509 return true; 451 510 } 452 511 } // namespace … … 456 515 extern "C" { 457 516 std::string cforall_demangle(const std::string & mangleName) { 458 std::string name, type; 459 if (! SymTab::Mangler::stripMangleName(mangleName, name, type)) return mangleName; 460 PRINT( std::cerr << name << " " << type << std::endl; ) 461 Type * t = SymTab::Mangler::parseType(type); 462 if (! t) return mangleName; 463 return genDemangleType(t, name); 517 SymTab::Mangler::StringView view(mangleName); 518 std::string name; 519 Type * type = nullptr; 520 if (! view.parse(name, type)) return mangleName; 521 return genDemangleType(type, name); 464 522 } // extern "C" 465 523 }
Note: See TracChangeset
for help on using the changeset viewer.