[Function] Factor out GetCallEdgeForReturnAddress, NFC
authorVedant Kumar <vsk@apple.com>
Tue, 10 Sep 2019 18:36:50 +0000 (18:36 +0000)
committerVedant Kumar <vsk@apple.com>
Tue, 10 Sep 2019 18:36:50 +0000 (18:36 +0000)
Finding the call edge in a function which corresponds to a particular
return address is a generic/useful operation.

llvm-svn: 371543

lldb/include/lldb/Symbol/Function.h
lldb/source/Symbol/Function.cpp
lldb/source/Target/StackFrameList.cpp

index f68a167..b0a7a0d 100644 (file)
@@ -402,6 +402,11 @@ public:
   /// return None.
   llvm::MutableArrayRef<CallEdge> GetTailCallingEdges();
 
+  /// Get the outgoing call edge from this function which has the given return
+  /// address \p return_pc, or return nullptr. Note that this will not return a
+  /// tail-calling edge.
+  CallEdge *GetCallEdgeForReturnAddress(lldb::addr_t return_pc, Target &target);
+
   /// Get accessor for the block list.
   ///
   /// \return
index 28ce4fd..9ba178f 100644 (file)
@@ -276,6 +276,20 @@ llvm::MutableArrayRef<CallEdge> Function::GetTailCallingEdges() {
   });
 }
 
+CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc,
+                                                Target &target) {
+  auto edges = GetCallEdges();
+  auto edge_it =
+      std::lower_bound(edges.begin(), edges.end(), return_pc,
+                       [&](const CallEdge &edge, addr_t pc) {
+                         return edge.GetReturnPCAddress(*this, target) < pc;
+                       });
+  if (edge_it == edges.end() ||
+      edge_it->GetReturnPCAddress(*this, target) != return_pc)
+    return nullptr;
+  return &const_cast<CallEdge &>(*edge_it);
+}
+
 Block &Function::GetBlock(bool can_create) {
   if (!m_block.BlockInfoHasBeenParsed() && can_create) {
     ModuleSP module_sp = CalculateSymbolContextModule();
index 6944562..fbced5f 100644 (file)
@@ -250,26 +250,19 @@ static void FindInterveningFrames(Function &begin, Function &end,
            begin.GetDisplayName(), end.GetDisplayName(), return_pc);
 
   // Find a non-tail calling edge with the correct return PC.
-  auto first_level_edges = begin.GetCallEdges();
   if (log)
-    for (const CallEdge &edge : first_level_edges)
+    for (const CallEdge &edge : begin.GetCallEdges())
       LLDB_LOG(log, "FindInterveningFrames: found call with retn-PC = {0:x}",
                edge.GetReturnPCAddress(begin, target));
-  auto first_edge_it = std::lower_bound(
-      first_level_edges.begin(), first_level_edges.end(), return_pc,
-      [&](const CallEdge &edge, addr_t target_pc) {
-        return edge.GetReturnPCAddress(begin, target) < target_pc;
-      });
-  if (first_edge_it == first_level_edges.end() ||
-      first_edge_it->GetReturnPCAddress(begin, target) != return_pc) {
+  CallEdge *first_edge = begin.GetCallEdgeForReturnAddress(return_pc, target);
+  if (!first_edge) {
     LLDB_LOG(log, "No call edge outgoing from {0} with retn-PC == {1:x}",
              begin.GetDisplayName(), return_pc);
     return;
   }
-  CallEdge &first_edge = const_cast<CallEdge &>(*first_edge_it);
 
   // The first callee may not be resolved, or there may be nothing to fill in.
-  Function *first_callee = first_edge.GetCallee(images);
+  Function *first_callee = first_edge->GetCallee(images);
   if (!first_callee) {
     LLDB_LOG(log, "Could not resolve callee");
     return;