================ @@ -376,6 +382,147 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch, } } + // Add variable location annotations to the disassembly output. + // + // For each instruction, this block attempts to resolve in-scope variables + // and determine if the current PC falls within their + // DWARF location entry. If so, it prints a simplified annotation using the + // variable name and its resolved location (e.g., "var = reg; " ). + // + // Annotations are only included if the variable has a valid DWARF location + // entry, and the location string is non-empty after filtering. Decoding + // errors and DWARF opcodes are intentionally omitted to keep the output + // concise and user-friendly. + // + // The goal is to give users helpful live variable hints alongside the + // disassembled instruction stream, similar to how debug information + // enhances source-level debugging. + + struct VarState { + std::string name; ///< Display name. + std::string last_loc; ///< Last printed location (empty means <undef>). + bool seen_this_inst = false; + }; + + // Track live variables across instructions. + llvm::DenseMap<lldb::user_id_t, VarState> live_vars; + + // Stateful annotator: updates live_vars and returns only what should be + // printed for THIS instruction. + auto annotate_static = [&](Instruction &inst, Target &target, + ModuleSP module_sp) -> std::vector<std::string> { + std::vector<std::string> events; + + // Reset per-instruction seen flags. + for (auto &kv : live_vars) + kv.second.seen_this_inst = false; + + const Address &iaddr = inst.GetAddress(); + if (!module_sp) { + // Everything previously live becomes <undef>. + for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) { + auto Cur = I++; + events.push_back( + llvm::formatv("{0} = <undef>", Cur->second.name).str()); + live_vars.erase(Cur); + } + return events; + } + + // Resolve innermost block at this *file* address. + SymbolContext sc; + const lldb::SymbolContextItem mask = + eSymbolContextFunction | eSymbolContextBlock; + if (!module_sp->ResolveSymbolContextForAddress(iaddr, mask, sc) || + !sc.function) { + // No function context: everything dies here. + for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) { + auto Cur = I++; + events.push_back( + llvm::formatv("{0} = <undef>", Cur->second.name).str()); + live_vars.erase(Cur); + } + return events; + } + + Block *B = sc.block; ///< Innermost block containing iaddr. + VariableList var_list; + if (B) { + auto filter = [](Variable *v) -> bool { return v && !v->IsArtificial(); }; + + B->AppendVariables(/*can_create*/ true, + /*get_parent_variables*/ true, + /*stop_if_block_is_inlined_function*/ false, + /*filter*/ filter, + /*variable_list*/ &var_list); + } + + const lldb::addr_t pc_file = iaddr.GetFileAddress(); + const lldb::addr_t func_file = sc.function->GetAddress().GetFileAddress(); + + // ABI from Target (pretty reg names if plugin exists). Safe to be null. + lldb::ProcessSP no_process; + lldb::ABISP abi_sp = ABI::FindPlugin(no_process, target.GetArchitecture()); + ABI *abi = abi_sp.get(); + + llvm::DIDumpOptions opts; + opts.ShowAddresses = false; + if (abi) + opts.PrintRegisterOnly = true; ---------------- JDevlieghere wrote:
```suggestion opts.PrintRegisterOnly = static_cast<bool>(abi_sp); ``` https://github.com/llvm/llvm-project/pull/152887 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits