[Lldb-commits] [lldb] [LLDB] Add assignment to DIL. (PR #190223)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 2 10:49:23 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: cmtice
<details>
<summary>Changes</summary>
Add the ability for DIL to recognize and process assignment, updating program variables. Recognizes '=', '+=' and '-=' operators. Increment and decrement ('++' and '--') will be added in a separate (future) PR. "*=" and "/=" need to wait until DIL handles multiply and divide operators.
---
Patch is 23.31 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/190223.diff
15 Files Affected:
- (modified) lldb/docs/dil-expr-lang.ebnf (+9-2)
- (modified) lldb/include/lldb/ValueObject/DILAST.h (+6-3)
- (modified) lldb/include/lldb/ValueObject/DILEval.h (+17-2)
- (modified) lldb/include/lldb/ValueObject/DILLexer.h (+3)
- (modified) lldb/include/lldb/ValueObject/DILParser.h (+1)
- (modified) lldb/source/ValueObject/DILAST.cpp (+8-2)
- (modified) lldb/source/ValueObject/DILEval.cpp (+62)
- (modified) lldb/source/ValueObject/DILLexer.cpp (+17-4)
- (modified) lldb/source/ValueObject/DILParser.cpp (+30-4)
- (modified) lldb/source/ValueObject/ValueObject.cpp (+17-7)
- (added) lldb/test/API/commands/frame/var-dil/expr/Assignment/Makefile (+3)
- (added) lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAddAssign.py (+31)
- (added) lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAssign.py (+110)
- (added) lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILSubAssign.py (+31)
- (added) lldb/test/API/commands/frame/var-dil/expr/Assignment/main.cpp (+17)
``````````diff
diff --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
index cdf85d75fd8e2..a1f1e5adff672 100644
--- a/lldb/docs/dil-expr-lang.ebnf
+++ b/lldb/docs/dil-expr-lang.ebnf
@@ -3,10 +3,17 @@
(* This is currently a subset of the final DIL Language, matching the current
DIL implementation. *)
-expression = additive_expression ;
+expression = assignment_expression;
+
+assignment_expression = additive_expression
+ | additive_expression assignment_operator assignment_expression ;
+
+assignment_operator = "="
+ | "+="
+ | "-=" ;
additive_expression = cast_expression {"+" cast_expression}
- cast_expression {"-" cast_expression} ;
+ | cast_expression {"-" cast_expression} ;
cast_expression = unary_expression
| "(" type_id ")" cast_expression;
diff --git a/lldb/include/lldb/ValueObject/DILAST.h b/lldb/include/lldb/ValueObject/DILAST.h
index 350722fa6f22d..a50f0e6829527 100644
--- a/lldb/include/lldb/ValueObject/DILAST.h
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -42,14 +42,17 @@ enum class UnaryOpKind {
/// The binary operators recognized by DIL.
enum class BinaryOpKind {
- Add, // "+"
- Sub, // "-"
+ Add, // "+"
+ AddAssign, // "+="
+ Assign, // "="
+ Sub, // "-"
+ SubAssign, // "-="
};
/// Translates DIL tokens to BinaryOpKind.
BinaryOpKind GetBinaryOpKindFromToken(Token::Kind token_kind);
-/// The type casts allowed by DIL.
+//// The type casts allowed by DIL.
enum class CastKind {
eArithmetic, ///< Casting to a scalar.
eEnumeration, ///< Casting from a scalar to an enumeration type
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index 323ac5eace2ba..c43ac87b2b0e9 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -88,6 +88,7 @@ class Interpreter : Visitor {
llvm::Expected<CompilerType> ArithmeticConversion(lldb::ValueObjectSP &lhs,
lldb::ValueObjectSP &rhs,
uint32_t location);
+
/// Add or subtract the offset to the pointer according to the pointee type
/// byte size.
/// \returns A new `ValueObject` with a new pointer value.
@@ -95,6 +96,7 @@ class Interpreter : Visitor {
lldb::ValueObjectSP offset,
BinaryOpKind operation,
uint32_t location);
+
llvm::Expected<lldb::ValueObjectSP> EvaluateScalarOp(BinaryOpKind kind,
lldb::ValueObjectSP lhs,
lldb::ValueObjectSP rhs,
@@ -103,9 +105,23 @@ class Interpreter : Visitor {
llvm::Expected<lldb::ValueObjectSP>
EvaluateBinaryAddition(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs,
uint32_t location);
+
llvm::Expected<lldb::ValueObjectSP>
EvaluateBinarySubtraction(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs,
uint32_t location);
+
+ llvm::Expected<lldb::ValueObjectSP>
+ EvaluateAssignment(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs,
+ uint32_t location);
+
+ llvm::Expected<lldb::ValueObjectSP>
+ EvaluateBinaryAddAssign(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs,
+ uint32_t location);
+
+ llvm::Expected<lldb::ValueObjectSP>
+ EvaluateBinarySubAssign(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs,
+ uint32_t location);
+
llvm::Expected<CompilerType>
PickIntegerType(lldb::TypeSystemSP type_system,
std::shared_ptr<ExecutionContextScope> ctx,
@@ -136,8 +152,7 @@ class Interpreter : Visitor {
bool m_use_synthetic;
bool m_fragile_ivar;
bool m_check_ptr_vs_member;
- // TODO: Remove 'maybe_unused' when next PR, using this, gets submitted.
- [[maybe_unused]] bool m_allow_var_updates;
+ bool m_allow_var_updates;
};
} // namespace lldb_private::dil
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index a927aa236377e..97ebbd713673f 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -30,6 +30,7 @@ class Token {
colon,
coloncolon,
eof,
+ equal,
float_constant,
identifier,
integer_constant,
@@ -38,8 +39,10 @@ class Token {
l_paren,
l_square,
minus,
+ minusequal,
period,
plus,
+ plusequal,
r_paren,
r_square,
star,
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index 4afedb735af86..edafbe7b2c181 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -93,6 +93,7 @@ class DILParser {
ASTNodeUP Run();
ASTNodeUP ParseExpression();
+ ASTNodeUP ParseAssignmentExpression();
ASTNodeUP ParseAdditiveExpression();
ASTNodeUP ParseUnaryExpression();
ASTNodeUP ParsePostfixExpression();
diff --git a/lldb/source/ValueObject/DILAST.cpp b/lldb/source/ValueObject/DILAST.cpp
index dadd4cd365c7e..121430036eefc 100644
--- a/lldb/source/ValueObject/DILAST.cpp
+++ b/lldb/source/ValueObject/DILAST.cpp
@@ -13,10 +13,16 @@ namespace lldb_private::dil {
BinaryOpKind GetBinaryOpKindFromToken(Token::Kind token_kind) {
switch (token_kind) {
- case Token::plus:
- return BinaryOpKind::Add;
+ case Token::equal:
+ return BinaryOpKind::Assign;
case Token::minus:
return BinaryOpKind::Sub;
+ case Token::minusequal:
+ return BinaryOpKind::SubAssign;
+ case Token::plus:
+ return BinaryOpKind::Add;
+ case Token::plusequal:
+ return BinaryOpKind::AddAssign;
default:
break;
}
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index 80b31be8e7c23..479be4e09feff 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -609,6 +609,8 @@ Interpreter::EvaluateScalarOp(BinaryOpKind kind, lldb::ValueObjectSP lhs,
return value_object(l + r);
case BinaryOpKind::Sub:
return value_object(l - r);
+ default:
+ break;
}
return llvm::make_error<DILDiagnosticError>(
m_expr, "invalid arithmetic operation", location);
@@ -729,6 +731,60 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
location);
}
+llvm::Expected<lldb::ValueObjectSP>
+Interpreter::EvaluateAssignment(lldb::ValueObjectSP lhs,
+ lldb::ValueObjectSP rhs, uint32_t location) {
+
+ Status status;
+ lhs->SetValueFromInteger(rhs, status, m_allow_var_updates);
+ if (status.Success())
+ return lhs;
+
+ std::string errMsg = std::string(status.AsCString());
+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
+ location);
+}
+
+llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryAddAssign(
+ lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
+ lldb::ValueObjectSP ret;
+
+ auto ret_or_err = EvaluateBinaryAddition(lhs, rhs, location);
+ if (!ret_or_err)
+ return ret_or_err;
+
+ ret = *ret_or_err;
+
+ Status status;
+ lhs->SetValueFromInteger(ret, status, m_allow_var_updates);
+ if (status.Success())
+ return lhs;
+
+ std::string errMsg = std::string(status.AsCString());
+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
+ location);
+}
+
+llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubAssign(
+ lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
+ lldb::ValueObjectSP ret;
+
+ auto ret_or_err = EvaluateBinarySubtraction(lhs, rhs, location);
+ if (!ret_or_err)
+ return ret_or_err;
+
+ ret = *ret_or_err;
+
+ Status status;
+ lhs->SetValueFromInteger(ret, status, m_allow_var_updates);
+ if (status.Success())
+ return lhs;
+
+ std::string errMsg = std::string(status.AsCString());
+ return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
+ location);
+}
+
llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const BinaryOpNode &node) {
auto lhs_or_err = EvaluateAndDereference(node.GetLHS());
@@ -753,8 +809,14 @@ Interpreter::Visit(const BinaryOpNode &node) {
switch (node.GetKind()) {
case BinaryOpKind::Add:
return EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
+ case BinaryOpKind::AddAssign:
+ return EvaluateBinaryAddAssign(lhs, rhs, node.GetLocation());
+ case BinaryOpKind::Assign:
+ return EvaluateAssignment(lhs, rhs, node.GetLocation());
case BinaryOpKind::Sub:
return EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
+ case BinaryOpKind::SubAssign:
+ return EvaluateBinarySubAssign(lhs, rhs, node.GetLocation());
}
return llvm::make_error<DILDiagnosticError>(
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index c1ad354502438..d92186ea26a12 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -28,6 +28,8 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "colon";
case Kind::coloncolon:
return "coloncolon";
+ case Kind::equal:
+ return "equal";
case Kind::eof:
return "eof";
case Kind::float_constant:
@@ -46,10 +48,14 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "l_square";
case Kind::minus:
return "minus";
+ case Kind::minusequal:
+ return "minusequal";
case Kind::period:
return "period";
case Kind::plus:
return "plus";
+ case Kind::plusequal:
+ return "plusequal";
case Kind::r_paren:
return "r_paren";
case Kind::r_square:
@@ -180,11 +186,18 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
return Token(kind, word.str(), position);
}
+ // IMPORTANT: If two or more tokens share the same prefix, the tokens need to
+ // be ordered longest-to-shortest in the list below. E.g. '::' must come
+ // before ':', and '+=' must come before '+'.
constexpr std::pair<Token::Kind, const char *> operators[] = {
- {Token::amp, "&"}, {Token::arrow, "->"}, {Token::coloncolon, "::"},
- {Token::colon, ":"}, {Token::l_paren, "("}, {Token::l_square, "["},
- {Token::minus, "-"}, {Token::period, "."}, {Token::plus, "+"},
- {Token::r_paren, ")"}, {Token::r_square, "]"}, {Token::star, "*"},
+ {Token::amp, "&"}, {Token::arrow, "->"},
+ {Token::coloncolon, "::"}, {Token::colon, ":"},
+ {Token::equal, "="}, {Token::l_paren, "("},
+ {Token::l_square, "["}, {Token::minusequal, "-="},
+ {Token::minus, "-"}, {Token::period, "."},
+ {Token::plusequal, "+="}, {Token::plus, "+"},
+ {Token::r_paren, ")"}, {Token::r_square, "]"},
+ {Token::star, "*"},
};
for (auto [kind, str] : operators) {
if (remainder.consume_front(str))
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index 919acd4645f71..7a162277baef0 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -89,7 +89,6 @@ CompilerType ResolveTypeByName(const std::string &name,
llvm::Expected<ASTNodeUP> DILParser::Parse(llvm::StringRef dil_input_expr,
DILLexer lexer,
std::shared_ptr<StackFrame> frame_sp,
-
lldb::DynamicValueType use_dynamic,
uint32_t options) {
const bool check_ptr_vs_member =
@@ -103,7 +102,6 @@ llvm::Expected<ASTNodeUP> DILParser::Parse(llvm::StringRef dil_input_expr,
DILParser parser(dil_input_expr, lexer, frame_sp, use_dynamic,
!no_synth_child, !no_fragile_ivar, check_ptr_vs_member,
error);
-
ASTNodeUP node_up = parser.Run();
assert(node_up && "ASTNodeUP must not contain a nullptr");
@@ -134,9 +132,37 @@ ASTNodeUP DILParser::Run() {
// Parse an expression.
//
// expression:
-// cast_expression
+// assignment_expression
+//
+ASTNodeUP DILParser::ParseExpression() { return ParseAssignmentExpression(); }
+
+// Parse an assignment_expression
//
-ASTNodeUP DILParser::ParseExpression() { return ParseAdditiveExpression(); }
+// assignment_expression
+// additive_expression
+// additive_expression assignment_operator assignment_expression
+//
+// assignment_operator:
+// "="
+// "+="
+// "-="
+//
+ASTNodeUP DILParser::ParseAssignmentExpression() {
+ auto lhs = ParseAdditiveExpression();
+ assert(lhs && "ASTNodeUP must not contain a nullptr");
+
+ // Check if it's an assignment expression.
+ if (CurToken().IsOneOf({Token::equal, Token::plusequal, Token::minusequal})) {
+ // That's an assignment!
+ Token token = CurToken();
+ m_dil_lexer.Advance();
+ auto rhs = ParseAssignmentExpression();
+ lhs = std::make_unique<BinaryOpNode>(
+ token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
+ std::move(lhs), std::move(rhs));
+ }
+ return lhs;
+}
// Parse an additive_expression.
//
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index edad5aa4d490d..b821d26070850 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -1223,16 +1223,26 @@ void ValueObject::SetValueFromInteger(const llvm::APInt &value, Status &error,
return;
}
+ // Make sure we're not trying to assign to a constant.
+ if (GetIsConstant()) {
+ error =
+ Status::FromErrorString("current value is not assignable (a constant)");
+ return;
+ }
+
// Verify the proposed new value is the right size.
lldb::TargetSP target = GetTargetSP();
uint64_t byte_size = 0;
- if (auto temp =
- llvm::expectedToOptional(GetCompilerType().GetByteSize(target.get())))
- byte_size = temp.value();
- if (value.getBitWidth() != byte_size * CHAR_BIT) {
- error = Status::FromErrorString(
- "illegal argument: new value should be of the same size");
- return;
+ // Exclude size check when assigning an integer 1 or 0 to a boolean.
+ if (!val_type.IsBoolean() || (!value.isOne() && !value.isZero())) {
+ if (auto temp = llvm::expectedToOptional(
+ GetCompilerType().GetByteSize(target.get())))
+ byte_size = temp.value();
+ if (value.getBitWidth() != byte_size * CHAR_BIT) {
+ error = Status::FromErrorString(
+ "illegal argument: new value should be of the same size");
+ return;
+ }
}
lldb::DataExtractorSP data_sp = std::make_shared<DataExtractor>(
diff --git a/lldb/test/API/commands/frame/var-dil/expr/Assignment/Makefile b/lldb/test/API/commands/frame/var-dil/expr/Assignment/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/Assignment/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAddAssign.py b/lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAddAssign.py
new file mode 100644
index 0000000000000..8559f35b7011e
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAddAssign.py
@@ -0,0 +1,31 @@
+"""
+Test DIL basic assignment.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+
+class TestFrameVarDILAssignment(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_assignment(self):
+ self.build()
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+
+ self.expect("frame variable 'i += 1'", substrs=["2"])
+ self.expect("frame variable 'i += 2'", substrs=["4"])
+ self.expect("frame variable 'i += -4'", substrs=["0"])
+ self.expect("frame variable 'i += eOne'", substrs=["0"])
+ self.expect("frame variable 'i += eTwo'", substrs=["1"])
+
+ self.expect("frame variable 'f += 1'", substrs=["2.5"])
+ self.expect("frame variable 'f += -2.0f'", substrs=["0.5"])
+ self.expect("frame variable 'f += 2.5f'", substrs=["3"])
+ self.expect("frame variable 'f += eTwo'", substrs=["4"])
diff --git a/lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAssign.py b/lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAssign.py
new file mode 100644
index 0000000000000..8d3aa825abca5
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/expr/Assignment/TestFrameVarDILAssign.py
@@ -0,0 +1,110 @@
+"""
+Test DIL basic assignment.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+#from lldbsuite.test import lldbutil
+from lldbsuite.test import *
+
+
+class TestFrameVarDILAssignment(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_assignment(self):
+ self.build()
+ (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+
+ Is32Bit = False
+ if self.target().GetAddressByteSize() == 4:
+ Is32Bit = True
+
+ self.expect(
+ "frame variable '1 = 1'",
+ error=True,
+ substrs=["current value is not assignable (a constant)"]
+ )
+
+ # Assigning to an int var
+ self.expect_var_path("i", value="1")
+ self.expect("frame variable 'i = 5'", substrs=["i = 5"])
+ self.expect_var_path("i", value="5")
+ self.expect_var_path("j", value="-4")
+ self.expect("frame variable 'i = j'", substrs=["i = -4"])
+ self.expect_var_path("i", value="-4")
+ self.expect("frame variable 'i = 2'", substrs=["i = 2"])
+ self.expect_var_path("i", value="2")
+ self.expect("frame variable 'i = -2'", substrs=["i = -2"])
+ self.expect_var_path("i", value="-2")
+ self.expect("frame variable 'i = (int)eOne'", substrs=["i = 0"])
+ self.expect_var_path("i", value="0")
+ self.expect("frame variable 'i = (int)eTwo'", substrs=["i = 1"])
+ self.expect_var_path("i", value="1")
+
+ # Assigning to a float var
+ self.expect_var_path("f", value="1.5")
+ self.expect("frame variable 'f = 17.823f'", substrs=["f = 17.823"])
+ self.expect_var_path("f", value="17.823")
+ self.expect_var_path("pi", value="3.14159012")
+ self.expect("frame variable 'f = pi'", substrs=["f = 3.14159012"])
+ self.expect_var_path("f", value="3.14159012")
+ self.expect("frame variable 'f = 2.5f'", substrs=["f = 2.5"])
+ self.expect_var_path("f", value="2.5")
+ self.expect("frame variable 'f = 3.5f'", substrs=["f = 3.5"])
+ self.expect_var_path("f", value="3.5")
+
+
+ # Assigning to an enum
+ self.expect(
+ "frame variable 'i = eOne'",
+ error=True,
+ substrs=["illegal argument: new value should be of the same size"]
+ )
+
+ self.expect("frame variable 'eOne = 1'", substrs=["eOne = TWO"])
+
+ # Assigning to a pointer
+ self.expect(
+ "frame variable 'p = 1'",
+ error=True,
+ substrs=["illegal argument: new value should be of the same size"]
+ )
+
+ if Is32Bit:
+ self.expect("frame variable 'p = (int*)12'", substrs=["p = 0x0000000c"])
+ self.expect_var_path("p", value="0x0000000c")
+ self.expect("frame variable 'p = 0'", substrs=["p = 0x00000000"])
+ else:
+ self.expect("frame variable 'p = (int*)12'", substrs=["p = 0x000000000000000c"])
+ self.expect_var_path("p", value="0x000000000000000c")
+ self.expect("fram...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/190223
More information about the lldb-commits
mailing list