| 239 | } |
| 240 | |
| 241 | NodeInstance* Debugger::nodeFromFrame(lldb::SBFrame frame) { |
| 242 | using namespace std::string_literals; |
| 243 | |
| 244 | // if frame isn't valid, use the default |
| 245 | if (!frame.IsValid()) { |
| 246 | auto thread = lldbProcess().GetSelectedThread(); |
| 247 | if (!thread.IsValid()) { return {}; } |
| 248 | frame = thread.GetSelectedFrame(); |
| 249 | } |
| 250 | |
| 251 | if (!frame.IsValid()) { return {}; } |
| 252 | |
| 253 | auto mangledFunctionName = frame.GetFunctionName(); |
| 254 | // demangle that |
| 255 | std::string moduleName, functionName; |
| 256 | std::tie(moduleName, functionName) = unmangleFunctionName(mangledFunctionName); |
| 257 | |
| 258 | GraphFunction* func = nullptr; |
| 259 | |
| 260 | if (mangledFunctionName == "main"s) { func = module().functionFromName("main"); } |
| 261 | |
| 262 | if (func == nullptr) { |
| 263 | auto mod = static_cast<GraphModule*>(module().context().moduleByFullName(moduleName)); |
| 264 | if (!mod) { return nullptr; } |
| 265 | func = mod->functionFromName(functionName); |
| 266 | } |
| 267 | |
| 268 | unsigned lineNo = frame.GetLineEntry().GetLine(); |
| 269 | |
| 270 | // create assoc TODO: cache these |
| 271 | auto assoc = func->module().createLineNumberAssoc(); |
| 272 | |
| 273 | auto nodeIter = assoc.left.find(lineNo); |
| 274 | if (nodeIter == assoc.left.end()) { return nullptr; } |
| 275 | |
| 276 | return nodeIter->second; |
| 277 | } |
| 278 | |
| 279 | unsigned lineNumberFromNode(NodeInstance& inst) { |
| 280 | // TODO: cache these, they're kinda expensive to make |
no test coverage detected