Skip to content

Commit d3f0720

Browse files
committed
[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]>
1 parent a941e15 commit d3f0720

File tree

10 files changed

+330
-43
lines changed

10 files changed

+330
-43
lines changed

lldb/include/lldb/Core/FormatEntity.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct Entry {
8181
FrameRegisterByName,
8282
FrameIsArtificial,
8383
FrameKind,
84+
FrameBorrowedInfo,
8485
ScriptFrame,
8586
FunctionID,
8687
FunctionDidChange,
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
//===-- BorrowedStackFrame.h ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_TARGET_BORROWEDSTACKFRAME_H
10+
#define LLDB_TARGET_BORROWEDSTACKFRAME_H
11+
12+
#include "lldb/Target/StackFrame.h"
13+
14+
namespace lldb_private {
15+
16+
/// \class BorrowedStackFrame BorrowedStackFrame.h
17+
/// "lldb/Target/BorrowedStackFrame.h"
18+
///
19+
/// A wrapper around an existing StackFrame that supersedes its frame index.
20+
///
21+
/// This class is useful when you need to present an existing stack frame
22+
/// with a different index, such as when creating synthetic frame views or
23+
/// renumbering frames without copying all the underlying data.
24+
///
25+
/// All methods delegate to the borrowed frame except for GetFrameIndex()
26+
/// which uses the overridden index.
27+
28+
class BorrowedStackFrame : public StackFrame {
29+
public:
30+
/// Construct a BorrowedStackFrame that wraps an existing frame.
31+
///
32+
/// \param [in] borrowed_frame_sp
33+
/// The existing StackFrame to borrow from. This frame's data will be
34+
/// used for all operations except frame index queries.
35+
///
36+
/// \param [in] override_frame_index
37+
/// The frame index to report instead of the borrowed frame's index.
38+
BorrowedStackFrame(const lldb::StackFrameSP &borrowed_frame_sp,
39+
uint32_t override_frame_index);
40+
41+
~BorrowedStackFrame() override = default;
42+
43+
// Override frame index methods
44+
uint32_t GetFrameIndex() const override { return m_override_frame_index; }
45+
void SetFrameIndex(uint32_t index) { m_override_frame_index = index; }
46+
47+
uint32_t GetConcreteFrameIndex() const override {
48+
return m_borrowed_frame_sp->GetConcreteFrameIndex();
49+
}
50+
51+
// Delegate all other virtual methods to the borrowed frame
52+
StackID &GetStackID() override { return m_borrowed_frame_sp->GetStackID(); }
53+
54+
const Address &GetFrameCodeAddress() override {
55+
return m_borrowed_frame_sp->GetFrameCodeAddress();
56+
}
57+
58+
Address GetFrameCodeAddressForSymbolication() override {
59+
return m_borrowed_frame_sp->GetFrameCodeAddressForSymbolication();
60+
}
61+
62+
bool ChangePC(lldb::addr_t pc) override {
63+
return m_borrowed_frame_sp->ChangePC(pc);
64+
}
65+
66+
const SymbolContext &
67+
GetSymbolContext(lldb::SymbolContextItem resolve_scope) override {
68+
return m_borrowed_frame_sp->GetSymbolContext(resolve_scope);
69+
}
70+
71+
llvm::Error GetFrameBaseValue(Scalar &value) override {
72+
return m_borrowed_frame_sp->GetFrameBaseValue(value);
73+
}
74+
75+
DWARFExpressionList *GetFrameBaseExpression(Status *error_ptr) override {
76+
return m_borrowed_frame_sp->GetFrameBaseExpression(error_ptr);
77+
}
78+
79+
Block *GetFrameBlock() override {
80+
return m_borrowed_frame_sp->GetFrameBlock();
81+
}
82+
83+
lldb::RegisterContextSP GetRegisterContext() override {
84+
return m_borrowed_frame_sp->GetRegisterContext();
85+
}
86+
87+
VariableList *GetVariableList(bool get_file_globals,
88+
Status *error_ptr) override {
89+
return m_borrowed_frame_sp->GetVariableList(get_file_globals, error_ptr);
90+
}
91+
92+
lldb::VariableListSP
93+
GetInScopeVariableList(bool get_file_globals,
94+
bool must_have_valid_location = false) override {
95+
return m_borrowed_frame_sp->GetInScopeVariableList(
96+
get_file_globals, must_have_valid_location);
97+
}
98+
99+
lldb::ValueObjectSP GetValueForVariableExpressionPath(
100+
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
101+
uint32_t options, lldb::VariableSP &var_sp, Status &error) override {
102+
return m_borrowed_frame_sp->GetValueForVariableExpressionPath(
103+
var_expr, use_dynamic, options, var_sp, error);
104+
}
105+
106+
bool HasDebugInformation() override {
107+
return m_borrowed_frame_sp->HasDebugInformation();
108+
}
109+
110+
const char *Disassemble() override {
111+
return m_borrowed_frame_sp->Disassemble();
112+
}
113+
114+
lldb::ValueObjectSP
115+
GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp,
116+
lldb::DynamicValueType use_dynamic) override {
117+
return m_borrowed_frame_sp->GetValueObjectForFrameVariable(variable_sp,
118+
use_dynamic);
119+
}
120+
121+
bool IsInlined() override { return m_borrowed_frame_sp->IsInlined(); }
122+
123+
bool IsSynthetic() const override {
124+
return m_borrowed_frame_sp->IsSynthetic();
125+
}
126+
127+
bool IsHistorical() const override {
128+
return m_borrowed_frame_sp->IsHistorical();
129+
}
130+
131+
bool IsArtificial() const override {
132+
return m_borrowed_frame_sp->IsArtificial();
133+
}
134+
135+
bool IsHidden() override { return m_borrowed_frame_sp->IsHidden(); }
136+
137+
const char *GetFunctionName() override {
138+
return m_borrowed_frame_sp->GetFunctionName();
139+
}
140+
141+
const char *GetDisplayFunctionName() override {
142+
return m_borrowed_frame_sp->GetDisplayFunctionName();
143+
}
144+
145+
lldb::ValueObjectSP FindVariable(ConstString name) override {
146+
return m_borrowed_frame_sp->FindVariable(name);
147+
}
148+
149+
SourceLanguage GetLanguage() override {
150+
return m_borrowed_frame_sp->GetLanguage();
151+
}
152+
153+
SourceLanguage GuessLanguage() override {
154+
return m_borrowed_frame_sp->GuessLanguage();
155+
}
156+
157+
lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr) override {
158+
return m_borrowed_frame_sp->GuessValueForAddress(addr);
159+
}
160+
161+
lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg,
162+
int64_t offset) override {
163+
return m_borrowed_frame_sp->GuessValueForRegisterAndOffset(reg, offset);
164+
}
165+
166+
StructuredData::ObjectSP GetLanguageSpecificData() override {
167+
return m_borrowed_frame_sp->GetLanguageSpecificData();
168+
}
169+
170+
lldb::RecognizedStackFrameSP GetRecognizedFrame() override {
171+
return m_borrowed_frame_sp->GetRecognizedFrame();
172+
}
173+
174+
/// Get the underlying borrowed frame.
175+
lldb::StackFrameSP GetBorrowedFrame() const { return m_borrowed_frame_sp; }
176+
177+
bool isA(const void *ClassID) const override {
178+
return ClassID == &ID || StackFrame::isA(ClassID);
179+
}
180+
static bool classof(const StackFrame *obj) { return obj->isA(&ID); }
181+
182+
private:
183+
lldb::StackFrameSP m_borrowed_frame_sp;
184+
uint32_t m_override_frame_index;
185+
static char ID;
186+
187+
BorrowedStackFrame(const BorrowedStackFrame &) = delete;
188+
const BorrowedStackFrame &operator=(const BorrowedStackFrame &) = delete;
189+
};
190+
191+
} // namespace lldb_private
192+
193+
#endif // LLDB_TARGET_BORROWEDSTACKFRAME_H

0 commit comments

Comments
 (0)