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
