https://github.com/medismailben updated 
https://github.com/llvm/llvm-project/pull/170191

>From 048f2c57e87ba8f18f0a49cf745452f97fec1a8f Mon Sep 17 00:00:00 2001
From: Med Ismail Bennani <[email protected]>
Date: Mon, 1 Dec 2025 21:18:37 -0800
Subject: [PATCH] [lldb/Target] Add BorrowedStackFrame and make StackFrame
 methods virtual

This change makes StackFrame methods virtual to enable subclass overrides
and introduces BorrowedStackFrame, a wrapper that presents an existing
StackFrame with a different frame index.

This enables creating synthetic frame views or renumbering frames without
copying the underlying frame data, which is useful for frame manipulation
scenarios.

This also adds a new borrowed-info format entity to show what was the
original frame index of the borrowed frame.

Signed-off-by: Med Ismail Bennani <[email protected]>
---
 lldb/include/lldb/Core/FormatEntity.h         |   1 +
 lldb/include/lldb/Target/BorrowedStackFrame.h | 146 ++++++++++++++
 lldb/include/lldb/Target/StackFrame.h         |  81 ++++----
 lldb/source/Core/FormatEntity.cpp             |  19 ++
 .../Process/scripted/ScriptedFrame.cpp        |   2 +
 .../Plugins/Process/scripted/ScriptedFrame.h  |   7 +
 lldb/source/Target/BorrowedStackFrame.cpp     | 187 ++++++++++++++++++
 lldb/source/Target/CMakeLists.txt             |   1 +
 lldb/source/Target/StackFrame.cpp             |   3 +
 9 files changed, 412 insertions(+), 35 deletions(-)
 create mode 100644 lldb/include/lldb/Target/BorrowedStackFrame.h
 create mode 100644 lldb/source/Target/BorrowedStackFrame.cpp

diff --git a/lldb/include/lldb/Core/FormatEntity.h 
b/lldb/include/lldb/Core/FormatEntity.h
index 40916dc48a70b..107c30a000979 100644
--- a/lldb/include/lldb/Core/FormatEntity.h
+++ b/lldb/include/lldb/Core/FormatEntity.h
@@ -81,6 +81,7 @@ struct Entry {
     FrameRegisterByName,
     FrameIsArtificial,
     FrameKind,
+    FrameBorrowedInfo,
     ScriptFrame,
     FunctionID,
     FunctionDidChange,
diff --git a/lldb/include/lldb/Target/BorrowedStackFrame.h 
b/lldb/include/lldb/Target/BorrowedStackFrame.h
new file mode 100644
index 0000000000000..72e7777961da7
--- /dev/null
+++ b/lldb/include/lldb/Target/BorrowedStackFrame.h
@@ -0,0 +1,146 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_TARGET_BORROWEDSTACKFRAME_H
+#define LLDB_TARGET_BORROWEDSTACKFRAME_H
+
+#include "lldb/Target/StackFrame.h"
+
+namespace lldb_private {
+
+/// \class BorrowedStackFrame BorrowedStackFrame.h
+/// "lldb/Target/BorrowedStackFrame.h"
+///
+/// A wrapper around an existing StackFrame that supersedes its frame indices.
+///
+/// This class is useful when you need to present an existing stack frame
+/// with a different index, such as when creating synthetic frame views or
+/// renumbering frames without copying all the underlying data.
+///
+/// All methods delegate to the borrowed frame except for GetFrameIndex()
+/// & GetConcreteFrameIndex() which uses the overridden indices.
+class BorrowedStackFrame : public StackFrame {
+public:
+  /// Construct a BorrowedStackFrame that wraps an existing frame.
+  ///
+  /// \param [in] borrowed_frame_sp
+  ///   The existing StackFrame to borrow from. This frame's data will be
+  ///   used for all operations except frame index queries.
+  ///
+  /// \param [in] new_frame_index
+  ///   The frame index to report instead of the borrowed frame's index.
+  ///
+  /// \param [in] new_concrete_frame_index
+  ///   Optional concrete frame index. If not provided, defaults to
+  ///   new_frame_index.
+  BorrowedStackFrame(
+      lldb::StackFrameSP borrowed_frame_sp, uint32_t new_frame_index,
+      std::optional<uint32_t> new_concrete_frame_index = std::nullopt);
+
+  ~BorrowedStackFrame() override = default;
+
+  uint32_t GetFrameIndex() const override;
+  void SetFrameIndex(uint32_t index);
+
+  /// Get the concrete frame index for this borrowed frame.
+  ///
+  /// Returns the overridden concrete frame index provided at construction,
+  /// or LLDB_INVALID_FRAME_ID if the borrowed frame represents an inlined
+  /// function, since this would require some computation if we chain inlined
+  /// borrowed stack frames.
+  ///
+  /// \return
+  ///   The concrete frame index, or LLDB_INVALID_FRAME_ID for inline frames.
+  uint32_t GetConcreteFrameIndex() override;
+
+  StackID &GetStackID() override;
+
+  const Address &GetFrameCodeAddress() override;
+
+  Address GetFrameCodeAddressForSymbolication() override;
+
+  bool ChangePC(lldb::addr_t pc) override;
+
+  const SymbolContext &
+  GetSymbolContext(lldb::SymbolContextItem resolve_scope) override;
+
+  llvm::Error GetFrameBaseValue(Scalar &value) override;
+
+  DWARFExpressionList *GetFrameBaseExpression(Status *error_ptr) override;
+
+  Block *GetFrameBlock() override;
+
+  lldb::RegisterContextSP GetRegisterContext() override;
+
+  VariableList *GetVariableList(bool get_file_globals,
+                                Status *error_ptr) override;
+
+  lldb::VariableListSP
+  GetInScopeVariableList(bool get_file_globals,
+                         bool must_have_valid_location = false) override;
+
+  lldb::ValueObjectSP GetValueForVariableExpressionPath(
+      llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
+      uint32_t options, lldb::VariableSP &var_sp, Status &error) override;
+
+  bool HasDebugInformation() override;
+
+  const char *Disassemble() override;
+
+  lldb::ValueObjectSP
+  GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp,
+                                 lldb::DynamicValueType use_dynamic) override;
+
+  bool IsInlined() override;
+
+  bool IsSynthetic() const override;
+
+  bool IsHistorical() const override;
+
+  bool IsArtificial() const override;
+
+  bool IsHidden() override;
+
+  const char *GetFunctionName() override;
+
+  const char *GetDisplayFunctionName() override;
+
+  lldb::ValueObjectSP FindVariable(ConstString name) override;
+
+  SourceLanguage GetLanguage() override;
+
+  SourceLanguage GuessLanguage() override;
+
+  lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr) override;
+
+  lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg,
+                                                     int64_t offset) override;
+
+  StructuredData::ObjectSP GetLanguageSpecificData() override;
+
+  lldb::RecognizedStackFrameSP GetRecognizedFrame() override;
+
+  /// Get the underlying borrowed frame.
+  lldb::StackFrameSP GetBorrowedFrame() const;
+
+  bool isA(const void *ClassID) const override;
+  static bool classof(const StackFrame *obj);
+
+private:
+  lldb::StackFrameSP m_borrowed_frame_sp;
+  uint32_t m_new_frame_index;
+  uint32_t m_new_concrete_frame_index;
+  static char ID;
+
+  BorrowedStackFrame(const BorrowedStackFrame &) = delete;
+  const BorrowedStackFrame &operator=(const BorrowedStackFrame &) = delete;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_BORROWEDSTACKFRAME_H
diff --git a/lldb/include/lldb/Target/StackFrame.h 
b/lldb/include/lldb/Target/StackFrame.h
index 135bd81e4e8d4..c7ebb1708d589 100644
--- a/lldb/include/lldb/Target/StackFrame.h
+++ b/lldb/include/lldb/Target/StackFrame.h
@@ -43,6 +43,13 @@ namespace lldb_private {
 class StackFrame : public ExecutionContextScope,
                    public std::enable_shared_from_this<StackFrame> {
 public:
+  /// LLVM RTTI support.
+  /// \{
+  static char ID;
+  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+  static bool classof(const StackFrame *obj) { return obj->isA(&ID); }
+  /// \}
+
   enum ExpressionPathOption {
     eExpressionPathOptionCheckPtrVsMember = (1u << 0),
     eExpressionPathOptionsNoFragileObjcIvar = (1u << 1),
@@ -127,7 +134,7 @@ class StackFrame : public ExecutionContextScope,
 
   lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); }
 
-  StackID &GetStackID();
+  virtual StackID &GetStackID();
 
   /// Get an Address for the current pc value in this StackFrame.
   ///
@@ -135,7 +142,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   The Address object set to the current PC value.
-  const Address &GetFrameCodeAddress();
+  virtual const Address &GetFrameCodeAddress();
 
   /// Get the current code Address suitable for symbolication,
   /// may not be the same as GetFrameCodeAddress().
@@ -153,7 +160,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   The Address object set to the current PC value.
-  Address GetFrameCodeAddressForSymbolication();
+  virtual Address GetFrameCodeAddressForSymbolication();
 
   /// Change the pc value for a given thread.
   ///
@@ -165,7 +172,7 @@ class StackFrame : public ExecutionContextScope,
   /// \return
   ///     true if the pc was changed.  false if this failed -- possibly
   ///     because this frame is not a live StackFrame.
-  bool ChangePC(lldb::addr_t pc);
+  virtual bool ChangePC(lldb::addr_t pc);
 
   /// Provide a SymbolContext for this StackFrame's current pc value.
   ///
@@ -181,7 +188,8 @@ class StackFrame : public ExecutionContextScope,
   /// \return
   ///   A SymbolContext reference which includes the types of information
   ///   requested by resolve_scope, if they are available.
-  const SymbolContext &GetSymbolContext(lldb::SymbolContextItem resolve_scope);
+  virtual const SymbolContext &
+  GetSymbolContext(lldb::SymbolContextItem resolve_scope);
 
   /// Return the Canonical Frame Address (DWARF term) for this frame.
   ///
@@ -199,7 +207,7 @@ class StackFrame : public ExecutionContextScope,
   /// \return
   ///   If there is an error determining the CFA address, return an error
   ///   explaining the failure. Success otherwise.
-  llvm::Error GetFrameBaseValue(Scalar &value);
+  virtual llvm::Error GetFrameBaseValue(Scalar &value);
 
   /// Get the DWARFExpressionList corresponding to the Canonical Frame Address.
   ///
@@ -211,7 +219,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   Returns the corresponding DWARF expression, or NULL.
-  DWARFExpressionList *GetFrameBaseExpression(Status *error_ptr);
+  virtual DWARFExpressionList *GetFrameBaseExpression(Status *error_ptr);
 
   /// Get the current lexical scope block for this StackFrame, if possible.
   ///
@@ -221,7 +229,7 @@ class StackFrame : public ExecutionContextScope,
   /// \return
   ///   A pointer to the current Block.  nullptr is returned if this can
   ///   not be provided.
-  Block *GetFrameBlock();
+  virtual Block *GetFrameBlock();
 
   /// Get the RegisterContext for this frame, if possible.
   ///
@@ -235,7 +243,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   The RegisterContext shared point for this frame.
-  lldb::RegisterContextSP GetRegisterContext();
+  virtual lldb::RegisterContextSP GetRegisterContext();
 
   const lldb::RegisterContextSP &GetRegisterContextSP() const {
     return m_reg_context_sp;
@@ -261,7 +269,8 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///     A pointer to a list of variables.
-  VariableList *GetVariableList(bool get_file_globals, Status *error_ptr);
+  virtual VariableList *GetVariableList(bool get_file_globals,
+                                        Status *error_ptr);
 
   /// Retrieve the list of variables that are in scope at this StackFrame's
   /// pc.
@@ -280,7 +289,7 @@ class StackFrame : public ExecutionContextScope,
   ///     StackFrame's pc.
   /// \return
   ///     A pointer to a list of variables.
-  lldb::VariableListSP
+  virtual lldb::VariableListSP
   GetInScopeVariableList(bool get_file_globals,
                          bool must_have_valid_location = false);
 
@@ -309,7 +318,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///     A shared pointer to the ValueObject described by var_expr.
-  lldb::ValueObjectSP GetValueForVariableExpressionPath(
+  virtual lldb::ValueObjectSP GetValueForVariableExpressionPath(
       llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
       uint32_t options, lldb::VariableSP &var_sp, Status &error);
 
@@ -318,14 +327,14 @@ class StackFrame : public ExecutionContextScope,
   /// \return
   ///    true if debug information is available for this frame (function,
   ///    compilation unit, block, etc.)
-  bool HasDebugInformation();
+  virtual bool HasDebugInformation();
 
   /// Return the disassembly for the instructions of this StackFrame's
   /// function as a single C string.
   ///
   /// \return
   ///    C string with the assembly instructions for this function.
-  const char *Disassemble();
+  virtual const char *Disassemble();
 
   /// Print a description of this frame using the provided frame format.
   ///
@@ -337,9 +346,9 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   \b true if and only if dumping with the given \p format worked.
-  bool DumpUsingFormat(Stream &strm,
-                       const lldb_private::FormatEntity::Entry *format,
-                       llvm::StringRef frame_marker = {});
+  virtual bool DumpUsingFormat(Stream &strm,
+                               const lldb_private::FormatEntity::Entry *format,
+                               llvm::StringRef frame_marker = {});
 
   /// Print a description for this frame using the frame-format formatter
   /// settings. If the current frame-format settings are invalid, then the
@@ -353,8 +362,8 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \param [in] frame_marker
   ///   Optional string that will be prepended to the frame output description.
-  void DumpUsingSettingsFormat(Stream *strm, bool show_unique = false,
-                               const char *frame_marker = nullptr);
+  virtual void DumpUsingSettingsFormat(Stream *strm, bool show_unique = false,
+                                       const char *frame_marker = nullptr);
 
   /// Print a description for this frame using a default format.
   ///
@@ -366,7 +375,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \param [in] show_fullpaths
   ///   Whether to print the full source paths or just the file base name.
-  void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths);
+  virtual void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths);
 
   /// Print a description of this stack frame and/or the source
   /// context/assembly for this stack frame.
@@ -389,8 +398,9 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   Returns true if successful.
-  bool GetStatus(Stream &strm, bool show_frame_info, bool show_source,
-                 bool show_unique = false, const char *frame_marker = nullptr);
+  virtual bool GetStatus(Stream &strm, bool show_frame_info, bool show_source,
+                         bool show_unique = false,
+                         const char *frame_marker = nullptr);
 
   /// Query whether this frame is a concrete frame on the call stack, or if it
   /// is an inlined frame derived from the debug information and presented by
@@ -401,10 +411,10 @@ class StackFrame : public ExecutionContextScope,
   virtual bool IsInlined();
 
   /// Query whether this frame is synthetic.
-  bool IsSynthetic() const;
+  virtual bool IsSynthetic() const;
 
   /// Query whether this frame is part of a historical backtrace.
-  bool IsHistorical() const;
+  virtual bool IsHistorical() const;
 
   /// Query whether this frame is artificial (e.g a synthesized result of
   /// inferring missing tail call frames from a backtrace). Artificial frames
@@ -419,7 +429,7 @@ class StackFrame : public ExecutionContextScope,
   /// Language plugins can use this API to report language-specific
   /// runtime information about this compile unit, such as additional
   /// language version details or feature flags.
-  StructuredData::ObjectSP GetLanguageSpecificData();
+  virtual StructuredData::ObjectSP GetLanguageSpecificData();
 
   /// Get the frame's demangled name.
   ///
@@ -439,7 +449,7 @@ class StackFrame : public ExecutionContextScope,
   /// \return
   ///   StackFrame index 0 indicates the currently-executing function.  Inline
   ///   frames are included in this frame index count.
-  uint32_t GetFrameIndex() const;
+  virtual uint32_t GetFrameIndex() const;
 
   /// Set this frame's synthetic frame index.
   void SetFrameIndex(uint32_t index) { m_frame_index = index; }
@@ -452,7 +462,7 @@ class StackFrame : public ExecutionContextScope,
   ///   frames are not included in this frame index count; their concrete
   ///   frame index will be the same as the concrete frame that they are
   ///   derived from.
-  uint32_t GetConcreteFrameIndex() const { return m_concrete_frame_index; }
+  virtual uint32_t GetConcreteFrameIndex() { return m_concrete_frame_index; }
 
   /// Create a ValueObject for a given Variable in this StackFrame.
   ///
@@ -466,7 +476,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///     A ValueObject for this variable.
-  lldb::ValueObjectSP
+  virtual lldb::ValueObjectSP
   GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp,
                                  lldb::DynamicValueType use_dynamic);
 
@@ -474,11 +484,11 @@ class StackFrame : public ExecutionContextScope,
   /// parsing expressions given the execution context.
   ///
   /// \return   The language of the frame if known.
-  SourceLanguage GetLanguage();
+  virtual SourceLanguage GetLanguage();
 
   /// Similar to GetLanguage(), but is allowed to take a potentially incorrect
   /// guess if exact information is not available.
-  SourceLanguage GuessLanguage();
+  virtual SourceLanguage GuessLanguage();
 
   /// Attempt to econstruct the ValueObject for a given raw address touched by
   /// the current instruction.  The ExpressionPath should indicate how to get
@@ -489,7 +499,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   The ValueObject if found.  If valid, it has a valid ExpressionPath.
-  lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr);
+  virtual lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr);
 
   /// Attempt to reconstruct the ValueObject for the address contained in a
   /// given register plus an offset.  The ExpressionPath should indicate how
@@ -503,8 +513,8 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   The ValueObject if found.  If valid, it has a valid ExpressionPath.
-  lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg,
-                                                     int64_t offset);
+  virtual lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg,
+                                                             int64_t offset);
 
   /// Attempt to reconstruct the ValueObject for a variable with a given \a 
name
   /// from within the current StackFrame, within the current block. The search
@@ -517,7 +527,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   The ValueObject if found.
-  lldb::ValueObjectSP FindVariable(ConstString name);
+  virtual lldb::ValueObjectSP FindVariable(ConstString name);
 
   // lldb::ExecutionContextScope pure virtual functions
   lldb::TargetSP CalculateTarget() override;
@@ -530,7 +540,7 @@ class StackFrame : public ExecutionContextScope,
 
   void CalculateExecutionContext(ExecutionContext &exe_ctx) override;
 
-  lldb::RecognizedStackFrameSP GetRecognizedFrame();
+  virtual lldb::RecognizedStackFrameSP GetRecognizedFrame();
 
   /// Get the StackFrameList that contains this frame.
   ///
@@ -546,6 +556,7 @@ class StackFrame : public ExecutionContextScope,
   }
 
 protected:
+  friend class BorrowedStackFrame;
   friend class StackFrameList;
 
   void SetSymbolContextScope(SymbolContextScope *symbol_scope);
diff --git a/lldb/source/Core/FormatEntity.cpp 
b/lldb/source/Core/FormatEntity.cpp
index 491f5c6320d97..c528a14fa76d0 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -27,6 +27,7 @@
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/BorrowedStackFrame.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/ExecutionContextScope.h"
 #include "lldb/Target/Language.h"
@@ -109,6 +110,7 @@ constexpr Definition g_frame_child_entries[] = {
                                   g_string_entry),
     Definition("is-artificial", EntryType::FrameIsArtificial),
     Definition("kind", EntryType::FrameKind),
+    Definition("borrowed-info", EntryType::FrameBorrowedInfo),
 };
 
 constexpr Definition g_function_child_entries[] = {
@@ -382,6 +384,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) {
     ENUM_TO_CSTR(FrameRegisterByName);
     ENUM_TO_CSTR(FrameIsArtificial);
     ENUM_TO_CSTR(FrameKind);
+    ENUM_TO_CSTR(FrameBorrowedInfo);
     ENUM_TO_CSTR(ScriptFrame);
     ENUM_TO_CSTR(FunctionID);
     ENUM_TO_CSTR(FunctionDidChange);
@@ -1761,6 +1764,22 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
     return false;
   }
 
+  case Entry::Type::FrameBorrowedInfo: {
+    if (exe_ctx)
+      if (StackFrame *frame = exe_ctx->GetFramePtr()) {
+        if (BorrowedStackFrame *borrowed_frame =
+                llvm::dyn_cast<BorrowedStackFrame>(frame)) {
+          if (lldb::StackFrameSP borrowed_from_sp =
+                  borrowed_frame->GetBorrowedFrame()) {
+            s.Printf(" [borrowed from frame #%u]",
+                     borrowed_from_sp->GetFrameIndex());
+            return true;
+          }
+        }
+      }
+    return false;
+  }
+
   case Entry::Type::ScriptFrame:
     if (exe_ctx) {
       StackFrame *frame = exe_ctx->GetFramePtr();
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp 
b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
index 6519df9185df0..cd22618c10fa2 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
@@ -13,6 +13,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
+char ScriptedFrame::ID;
+
 void ScriptedFrame::CheckInterpreterAndScriptObject() const {
   lldbassert(m_script_object_sp && "Invalid Script Object.");
   lldbassert(GetInterface() && "Invalid Scripted Frame Interface.");
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h 
b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
index b6b77c4a7d160..dd77ad4b62469 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedFrame.h
@@ -43,6 +43,11 @@ class ScriptedFrame : public lldb_private::StackFrame {
   const char *GetFunctionName() override;
   const char *GetDisplayFunctionName() override;
 
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || StackFrame::isA(ClassID);
+  }
+  static bool classof(const StackFrame *obj) { return obj->isA(&ID); }
+
 private:
   void CheckInterpreterAndScriptObject() const;
   lldb::ScriptedFrameInterfaceSP GetInterface() const;
@@ -55,6 +60,8 @@ class ScriptedFrame : public lldb_private::StackFrame {
   lldb::ScriptedFrameInterfaceSP m_scripted_frame_interface_sp;
   lldb_private::StructuredData::GenericSP m_script_object_sp;
   std::shared_ptr<DynamicRegisterInfo> m_register_info_sp;
+
+  static char ID;
 };
 
 } // namespace lldb_private
diff --git a/lldb/source/Target/BorrowedStackFrame.cpp 
b/lldb/source/Target/BorrowedStackFrame.cpp
new file mode 100644
index 0000000000000..5afadf21fde03
--- /dev/null
+++ b/lldb/source/Target/BorrowedStackFrame.cpp
@@ -0,0 +1,187 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/BorrowedStackFrame.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+char BorrowedStackFrame::ID;
+
+BorrowedStackFrame::BorrowedStackFrame(
+    StackFrameSP borrowed_frame_sp, uint32_t new_frame_index,
+    std::optional<uint32_t> new_concrete_frame_index)
+    : StackFrame(
+          borrowed_frame_sp->GetThread(), new_frame_index,
+          borrowed_frame_sp->GetConcreteFrameIndex(),
+          borrowed_frame_sp->GetRegisterContextSP(),
+          borrowed_frame_sp->GetStackID().GetPC(),
+          borrowed_frame_sp->GetStackID().GetCallFrameAddressWithoutMetadata(),
+          borrowed_frame_sp->m_behaves_like_zeroth_frame,
+          &borrowed_frame_sp->GetSymbolContext(eSymbolContextEverything)),
+      m_borrowed_frame_sp(borrowed_frame_sp),
+      m_new_frame_index(new_frame_index) {
+  if (new_concrete_frame_index)
+    m_new_concrete_frame_index = *new_concrete_frame_index;
+  else
+    m_new_concrete_frame_index =
+        IsInlined() ? LLDB_INVALID_FRAME_ID : new_frame_index;
+}
+
+uint32_t BorrowedStackFrame::GetFrameIndex() const { return m_new_frame_index; 
}
+
+void BorrowedStackFrame::SetFrameIndex(uint32_t index) {
+  m_new_frame_index = index;
+}
+
+uint32_t BorrowedStackFrame::GetConcreteFrameIndex() {
+  // FIXME: We need to find where the concrete frame into which this frame was
+  // inlined landed in the new stack frame list as that is the correct concrete
+  // frame index in this
+  // stack frame.
+  return m_new_concrete_frame_index;
+}
+
+StackID &BorrowedStackFrame::GetStackID() {
+  return m_borrowed_frame_sp->GetStackID();
+}
+
+const Address &BorrowedStackFrame::GetFrameCodeAddress() {
+  return m_borrowed_frame_sp->GetFrameCodeAddress();
+}
+
+Address BorrowedStackFrame::GetFrameCodeAddressForSymbolication() {
+  return m_borrowed_frame_sp->GetFrameCodeAddressForSymbolication();
+}
+
+bool BorrowedStackFrame::ChangePC(addr_t pc) {
+  return m_borrowed_frame_sp->ChangePC(pc);
+}
+
+const SymbolContext &
+BorrowedStackFrame::GetSymbolContext(SymbolContextItem resolve_scope) {
+  return m_borrowed_frame_sp->GetSymbolContext(resolve_scope);
+}
+
+llvm::Error BorrowedStackFrame::GetFrameBaseValue(Scalar &value) {
+  return m_borrowed_frame_sp->GetFrameBaseValue(value);
+}
+
+DWARFExpressionList *
+BorrowedStackFrame::GetFrameBaseExpression(Status *error_ptr) {
+  return m_borrowed_frame_sp->GetFrameBaseExpression(error_ptr);
+}
+
+Block *BorrowedStackFrame::GetFrameBlock() {
+  return m_borrowed_frame_sp->GetFrameBlock();
+}
+
+RegisterContextSP BorrowedStackFrame::GetRegisterContext() {
+  return m_borrowed_frame_sp->GetRegisterContext();
+}
+
+VariableList *BorrowedStackFrame::GetVariableList(bool get_file_globals,
+                                                  Status *error_ptr) {
+  return m_borrowed_frame_sp->GetVariableList(get_file_globals, error_ptr);
+}
+
+VariableListSP
+BorrowedStackFrame::GetInScopeVariableList(bool get_file_globals,
+                                           bool must_have_valid_location) {
+  return m_borrowed_frame_sp->GetInScopeVariableList(get_file_globals,
+                                                     must_have_valid_location);
+}
+
+ValueObjectSP BorrowedStackFrame::GetValueForVariableExpressionPath(
+    llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
+    VariableSP &var_sp, Status &error) {
+  return m_borrowed_frame_sp->GetValueForVariableExpressionPath(
+      var_expr, use_dynamic, options, var_sp, error);
+}
+
+bool BorrowedStackFrame::HasDebugInformation() {
+  return m_borrowed_frame_sp->HasDebugInformation();
+}
+
+const char *BorrowedStackFrame::Disassemble() {
+  return m_borrowed_frame_sp->Disassemble();
+}
+
+ValueObjectSP BorrowedStackFrame::GetValueObjectForFrameVariable(
+    const VariableSP &variable_sp, DynamicValueType use_dynamic) {
+  return m_borrowed_frame_sp->GetValueObjectForFrameVariable(variable_sp,
+                                                             use_dynamic);
+}
+
+bool BorrowedStackFrame::IsInlined() {
+  return m_borrowed_frame_sp->IsInlined();
+}
+
+bool BorrowedStackFrame::IsSynthetic() const {
+  return m_borrowed_frame_sp->IsSynthetic();
+}
+
+bool BorrowedStackFrame::IsHistorical() const {
+  return m_borrowed_frame_sp->IsHistorical();
+}
+
+bool BorrowedStackFrame::IsArtificial() const {
+  return m_borrowed_frame_sp->IsArtificial();
+}
+
+bool BorrowedStackFrame::IsHidden() { return m_borrowed_frame_sp->IsHidden(); }
+
+const char *BorrowedStackFrame::GetFunctionName() {
+  return m_borrowed_frame_sp->GetFunctionName();
+}
+
+const char *BorrowedStackFrame::GetDisplayFunctionName() {
+  return m_borrowed_frame_sp->GetDisplayFunctionName();
+}
+
+ValueObjectSP BorrowedStackFrame::FindVariable(ConstString name) {
+  return m_borrowed_frame_sp->FindVariable(name);
+}
+
+SourceLanguage BorrowedStackFrame::GetLanguage() {
+  return m_borrowed_frame_sp->GetLanguage();
+}
+
+SourceLanguage BorrowedStackFrame::GuessLanguage() {
+  return m_borrowed_frame_sp->GuessLanguage();
+}
+
+ValueObjectSP BorrowedStackFrame::GuessValueForAddress(addr_t addr) {
+  return m_borrowed_frame_sp->GuessValueForAddress(addr);
+}
+
+ValueObjectSP
+BorrowedStackFrame::GuessValueForRegisterAndOffset(ConstString reg,
+                                                   int64_t offset) {
+  return m_borrowed_frame_sp->GuessValueForRegisterAndOffset(reg, offset);
+}
+
+StructuredData::ObjectSP BorrowedStackFrame::GetLanguageSpecificData() {
+  return m_borrowed_frame_sp->GetLanguageSpecificData();
+}
+
+RecognizedStackFrameSP BorrowedStackFrame::GetRecognizedFrame() {
+  return m_borrowed_frame_sp->GetRecognizedFrame();
+}
+
+StackFrameSP BorrowedStackFrame::GetBorrowedFrame() const {
+  return m_borrowed_frame_sp;
+}
+
+bool BorrowedStackFrame::isA(const void *ClassID) const {
+  return ClassID == &ID || StackFrame::isA(ClassID);
+}
+
+bool BorrowedStackFrame::classof(const StackFrame *obj) {
+  return obj->isA(&ID);
+}
diff --git a/lldb/source/Target/CMakeLists.txt 
b/lldb/source/Target/CMakeLists.txt
index cff59049cdce5..df2ee03860ac0 100644
--- a/lldb/source/Target/CMakeLists.txt
+++ b/lldb/source/Target/CMakeLists.txt
@@ -41,6 +41,7 @@ add_lldb_library(lldbTarget
   SyntheticFrameProvider.cpp
   SectionLoadHistory.cpp
   SectionLoadList.cpp
+  BorrowedStackFrame.cpp
   StackFrame.cpp
   StackFrameList.cpp
   StackFrameRecognizer.cpp
diff --git a/lldb/source/Target/StackFrame.cpp 
b/lldb/source/Target/StackFrame.cpp
index 78f67d21d6600..ca3d4a1a29b59 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -45,6 +45,9 @@
 using namespace lldb;
 using namespace lldb_private;
 
+// LLVM RTTI support.
+char StackFrame::ID;
+
 // The first bits in the flags are reserved for the SymbolContext::Scope bits
 // so we know if we have tried to look up information in our internal symbol
 // context (m_sc) already.

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to