| 590 | |
| 591 | |
| 592 | void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLevelILTokenEmitter& tokens, |
| 593 | DisassemblySettings* settings, BNOperatorPrecedence precedence, ExpressionType exprType, |
| 594 | std::optional<bool> signedHint) |
| 595 | { |
| 596 | // The lambdas in this function are here to reduce stack frame size of this function. Without them, |
| 597 | // complex expression can cause the process to crash from a stack overflow. |
| 598 | auto exprGuard = tokens.SetCurrentExpr(instr); |
| 599 | |
| 600 | if (settings && settings->IsOptionSet(ShowILTypes) && instr.GetType()) |
| 601 | { |
| 602 | tokens.AppendOpenParen(); |
| 603 | tokens.AppendOpenParen(); |
| 604 | RustTypePrinter printer; |
| 605 | auto typeTokens = printer.GetTypeTokens( |
| 606 | instr.GetType(), |
| 607 | GetArchitecture()->GetStandalonePlatform(), |
| 608 | QualifiedName() |
| 609 | ); |
| 610 | for (auto& token: typeTokens) |
| 611 | { |
| 612 | tokens.Append(token); |
| 613 | } |
| 614 | tokens.AppendCloseParen(); |
| 615 | tokens.Append(TextToken, " "); |
| 616 | } |
| 617 | if (settings && settings->IsOptionSet(ShowILOpcodes)) |
| 618 | { |
| 619 | tokens.Append(OperationToken, "/*"); |
| 620 | tokens.Append(OperationToken, fmt::format("{}", instr.operation)); |
| 621 | tokens.Append(OperationToken, "*/"); |
| 622 | tokens.Append(TextToken, " "); |
| 623 | } |
| 624 | |
| 625 | auto function = m_highLevelIL->GetFunction(); |
| 626 | if (instr.ast) |
| 627 | tokens.PrependCollapseIndicator(function, instr); |
| 628 | if (instr.operation != HLIL_BLOCK) |
| 629 | tokens.InitLine(); |
| 630 | switch (instr.operation) |
| 631 | { |
| 632 | case HLIL_BLOCK: |
| 633 | [&]() { |
| 634 | const auto exprs = instr.GetBlockExprs<HLIL_BLOCK>(); |
| 635 | bool needSeparator = false; |
| 636 | for (auto i = exprs.begin(); i != exprs.end(); ++i) |
| 637 | { |
| 638 | // Don't show void returns at the very end of the function when printing |
| 639 | // the root of an AST, as it is implicit and almost always omitted in |
| 640 | // normal source code. |
| 641 | auto next = i; |
| 642 | ++next; |
| 643 | if (instr.ast && (instr.exprIndex == GetHighLevelILFunction()->GetRootExpr().exprIndex) |
| 644 | && (exprs.size() > 1) && (next == exprs.end()) && ((*i).operation == HLIL_RET) |
| 645 | && ((*i).GetSourceExprs<HLIL_RET>().size() == 0)) |
| 646 | continue; |
| 647 | |
| 648 | // If the statement is one that contains additional blocks of code, insert a scope separator |
| 649 | // to visually separate the logic. |
nothing calls this directly
no test coverage detected