[Lldb-commits] [lldb] 41a53c0 - [lldb/Target] Add BorrowedStackFrame and make StackFrame methods virtual (#170191)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Dec 2 10:41:08 PST 2025
Author: Med Ismail Bennani
Date: 2025-12-02T10:41:03-08:00
New Revision: 41a53c0a23ee3268c930fa67cc0a39f18c49efc4
URL: https://github.com/llvm/llvm-project/commit/41a53c0a23ee3268c930fa67cc0a39f18c49efc4
DIFF: https://github.com/llvm/llvm-project/commit/41a53c0a23ee3268c930fa67cc0a39f18c49efc4.diff
LOG: [lldb/Target] Add BorrowedStackFrame and make StackFrame methods virtual (#170191)
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 <ismail at bennani.ma>
Added:
lldb/include/lldb/Target/BorrowedStackFrame.h
lldb/source/Target/BorrowedStackFrame.cpp
Modified:
lldb/include/lldb/Core/FormatEntity.h
lldb/include/lldb/Target/StackFrame.h
lldb/source/Core/FormatEntity.cpp
lldb/source/Plugins/Process/scripted/ScriptedFrame.cpp
lldb/source/Plugins/Process/scripted/ScriptedFrame.h
lldb/source/Target/CMakeLists.txt
lldb/source/Target/StackFrame.cpp
Removed:
################################################################################
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
diff erent 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.
More information about the lldb-commits
mailing list