[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Dec 23 07:01:45 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: None (cmtice)
<details>
<summary>Changes</summary>
Add the Data Inspection Language (DIL) implementation pieces for handling plain local and global variable names.
See https://discourse.llvm.org/t/rfc-data-inspection-language/69893 for information about DIL.
This change includes the basic AST, Lexer, Parser and Evaluator pieces, as well as some tests.
---
Patch is 63.08 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/120971.diff
20 Files Affected:
- (added) lldb/docs/dil-expr-lang.ebnf (+40)
- (added) lldb/include/lldb/ValueObject/DILAST.h (+161)
- (added) lldb/include/lldb/ValueObject/DILEval.h (+62)
- (added) lldb/include/lldb/ValueObject/DILLexer.h (+166)
- (added) lldb/include/lldb/ValueObject/DILParser.h (+105)
- (modified) lldb/source/Target/StackFrame.cpp (+45-7)
- (modified) lldb/source/ValueObject/CMakeLists.txt (+4)
- (added) lldb/source/ValueObject/DILAST.cpp (+228)
- (added) lldb/source/ValueObject/DILEval.cpp (+117)
- (added) lldb/source/ValueObject/DILLexer.cpp (+191)
- (added) lldb/source/ValueObject/DILParser.cpp (+356)
- (added) lldb/test/API/commands/frame/var-dil/basics/GlobalVariableLookup/Makefile (+3)
- (added) lldb/test/API/commands/frame/var-dil/basics/GlobalVariableLookup/TestFrameVarDILGlobalVariableLookup.py (+82)
- (added) lldb/test/API/commands/frame/var-dil/basics/GlobalVariableLookup/main.cpp (+18)
- (added) lldb/test/API/commands/frame/var-dil/basics/InstanceVariables/Makefile (+3)
- (added) lldb/test/API/commands/frame/var-dil/basics/InstanceVariables/TestFrameVarDILInstanceVariables.py (+62)
- (added) lldb/test/API/commands/frame/var-dil/basics/InstanceVariables/main.cpp (+25)
- (added) lldb/test/API/commands/frame/var-dil/basics/LocalVars/Makefile (+3)
- (added) lldb/test/API/commands/frame/var-dil/basics/LocalVars/TestFrameVarDILLocalVars.py (+65)
- (added) lldb/test/API/commands/frame/var-dil/basics/LocalVars/main.cpp (+26)
``````````diff
diff --git a/lldb/docs/dil-expr-lang.ebnf b/lldb/docs/dil-expr-lang.ebnf
new file mode 100644
index 00000000000000..64b3e7758229c2
--- /dev/null
+++ b/lldb/docs/dil-expr-lang.ebnf
@@ -0,0 +1,40 @@
+(* Data Inspection Language (DIL) definition - LLDB Debug Expressions *)
+
+(* This is currently a subset of the final DIL Language, matching the current
+ DIL implementation. *)
+
+expression = primary_expression ;
+
+primary_expression = id_expression
+ | "this"
+ | "(" expression ")";
+
+id_expression = unqualified_id
+ | qualified_id ;
+
+unqualified_id = identifier ;
+
+qualified_id = ["::"] [nested_name_specifier] unqualified_id
+ | ["::"] identifier ;
+
+identifier = ? dil::TokenKind::identifier ? ;
+
+nested_name_specifier = type_name "::"
+ | namespace_name '::'
+ | nested_name_specifier identifier "::" ;
+
+type_name = class_name
+ | enum_name
+ | typedef_name;
+
+class_name = identifier ;
+
+enum_name = identifier ;
+
+typedef_name = identifier ;
+
+namespace_name = identifier ;
+
+
+
+
diff --git a/lldb/include/lldb/ValueObject/DILAST.h b/lldb/include/lldb/ValueObject/DILAST.h
new file mode 100644
index 00000000000000..9f0a1a2221e388
--- /dev/null
+++ b/lldb/include/lldb/ValueObject/DILAST.h
@@ -0,0 +1,161 @@
+//===-- DILAST.h ------------------------------------------------*- C++ -*-===//
+//
+// 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_VALUEOBJECT_DILAST_H
+#define LLDB_VALUEOBJECT_DILAST_H
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "lldb/ValueObject/ValueObject.h"
+
+namespace lldb_private {
+
+namespace dil {
+
+/// The various types DIL AST nodes (used by the DIL parser).
+enum class NodeKind {
+ eErrorNode,
+ eIdentifierNode,
+};
+
+/// Class used to store & manipulate information about identifiers.
+class IdentifierInfo {
+public:
+ enum class Kind {
+ eValue,
+ eContextArg,
+ };
+
+ static std::unique_ptr<IdentifierInfo> FromValue(ValueObject &valobj) {
+ CompilerType type;
+ type = valobj.GetCompilerType();
+ return std::unique_ptr<IdentifierInfo>(
+ new IdentifierInfo(Kind::eValue, type, valobj.GetSP(), {}));
+ }
+
+ static std::unique_ptr<IdentifierInfo> FromContextArg(CompilerType type) {
+ lldb::ValueObjectSP empty_value;
+ return std::unique_ptr<IdentifierInfo>(
+ new IdentifierInfo(Kind::eContextArg, type, empty_value, {}));
+ }
+
+ Kind GetKind() const { return m_kind; }
+ lldb::ValueObjectSP GetValue() const { return m_value; }
+
+ CompilerType GetType() { return m_type; }
+ bool IsValid() const { return m_type.IsValid(); }
+
+ IdentifierInfo(Kind kind, CompilerType type, lldb::ValueObjectSP value,
+ std::vector<uint32_t> path)
+ : m_kind(kind), m_type(type), m_value(std::move(value)) {}
+
+private:
+ Kind m_kind;
+ CompilerType m_type;
+ lldb::ValueObjectSP m_value;
+};
+
+/// Given the name of an identifier (variable name, member name, type name,
+/// etc.), find the ValueObject for that name (if it exists) and create and
+/// return an IdentifierInfo object containing all the relevant information
+/// about that object (for DIL parsing and evaluating).
+std::unique_ptr<IdentifierInfo> LookupIdentifier(
+ const std::string &name, std::shared_ptr<ExecutionContextScope> ctx_scope,
+ lldb::DynamicValueType use_dynamic, CompilerType *scope_ptr = nullptr);
+
+/// Forward declaration, for use in DIL AST nodes. Definition is at the very
+/// end of this file.
+class Visitor;
+
+/// The rest of the classes in this file, except for the Visitor class at the
+/// very end, define all the types of AST nodes used by the DIL parser and
+/// expression evaluator. The DIL parser parses the input string and creates
+/// the AST parse tree from the AST nodes. The resulting AST node tree gets
+/// passed to the DIL expression evaluator, which evaluates the DIL AST nodes
+/// and creates/returns a ValueObjectSP containing the result.
+
+/// Base class for AST nodes used by the Data Inspection Language (DIL) parser.
+/// All of the specialized types of AST nodes inherit from this (virtual) base
+/// class.
+class DILASTNode {
+public:
+ DILASTNode(uint32_t location, NodeKind kind)
+ : m_location(location), m_kind(kind) {}
+ virtual ~DILASTNode() = default;
+
+ virtual void Accept(Visitor *v) const = 0;
+
+ uint32_t GetLocation() const { return m_location; }
+ NodeKind GetKind() const { return m_kind; }
+
+private:
+ uint32_t m_location;
+ const NodeKind m_kind;
+};
+
+using DILASTNodeUP = std::unique_ptr<DILASTNode>;
+
+class ErrorNode : public DILASTNode {
+public:
+ ErrorNode(CompilerType empty_type)
+ : DILASTNode(0, NodeKind::eErrorNode), m_empty_type(empty_type) {}
+ void Accept(Visitor *v) const override;
+
+ static bool classof(const DILASTNode *node) {
+ return node->GetKind() == NodeKind::eErrorNode;
+ }
+
+private:
+ CompilerType m_empty_type;
+};
+
+class IdentifierNode : public DILASTNode {
+public:
+ IdentifierNode(uint32_t location, std::string name,
+ lldb::DynamicValueType use_dynamic,
+ std::shared_ptr<ExecutionContextScope> exe_ctx_scope)
+ : DILASTNode(location, NodeKind::eIdentifierNode),
+ m_name(std::move(name)), m_use_dynamic(use_dynamic),
+ m_ctx_scope(exe_ctx_scope) {}
+
+ void Accept(Visitor *v) const override;
+
+ lldb::DynamicValueType use_dynamic() const { return m_use_dynamic; }
+ std::string name() const { return m_name; }
+ std::shared_ptr<ExecutionContextScope> get_exe_context() const {
+ return m_ctx_scope;
+ }
+
+ static bool classof(const DILASTNode *node) {
+ return node->GetKind() == NodeKind::eIdentifierNode;
+ }
+
+private:
+ std::string m_name;
+ lldb::DynamicValueType m_use_dynamic;
+ std::shared_ptr<ExecutionContextScope> m_ctx_scope;
+};
+
+/// This class contains one Visit method for each specialized type of
+/// DIL AST node. The Visit methods are used to dispatch a DIL AST node to
+/// the correct function in the DIL expression evaluator for evaluating that
+/// type of AST node.
+class Visitor {
+public:
+ virtual ~Visitor() = default;
+ virtual void Visit(const ErrorNode *node) = 0;
+ virtual void Visit(const IdentifierNode *node) = 0;
+};
+
+} // namespace dil
+
+} // namespace lldb_private
+
+#endif // LLDB_VALUEOBJECT_DILAST_H
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
new file mode 100644
index 00000000000000..4006bb10630f24
--- /dev/null
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -0,0 +1,62 @@
+//===-- DILEval.h -----------------------------------------------*- C++ -*-===//
+//
+// 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_VALUEOBJECT_DILEVAL_H_
+#define LLDB_VALUEOBJECT_DILEVAL_H_
+
+#include <memory>
+#include <vector>
+
+#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILParser.h"
+
+namespace lldb_private {
+
+namespace dil {
+
+class DILInterpreter : Visitor {
+public:
+ DILInterpreter(lldb::TargetSP target, std::shared_ptr<std::string> sm);
+ DILInterpreter(lldb::TargetSP target, std::shared_ptr<std::string> sm,
+ lldb::ValueObjectSP scope);
+ DILInterpreter(lldb::TargetSP target, std::shared_ptr<std::string> sm,
+ lldb::DynamicValueType use_dynamic);
+
+ lldb::ValueObjectSP DILEval(const DILASTNode *tree, lldb::TargetSP target_sp,
+ Status &error);
+
+private:
+ lldb::ValueObjectSP DILEvalNode(const DILASTNode *node);
+
+ bool Success() { return m_error.Success(); }
+
+ void SetError(ErrorCode error_code, std::string error, uint32_t loc);
+
+ void Visit(const ErrorNode *node) override;
+ void Visit(const IdentifierNode *node) override;
+
+private:
+ // Used by the interpreter to create objects, perform casts, etc.
+ lldb::TargetSP m_target;
+
+ std::shared_ptr<std::string> m_sm;
+
+ lldb::ValueObjectSP m_result;
+
+ lldb::ValueObjectSP m_scope;
+
+ lldb::DynamicValueType m_default_dynamic;
+
+ Status m_error;
+};
+
+} // namespace dil
+
+} // namespace lldb_private
+
+#endif // LLDB_VALUEOBJECT_DILEVAL_H_
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
new file mode 100644
index 00000000000000..c794fb2bfc0ed3
--- /dev/null
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -0,0 +1,166 @@
+//===-- DILLexer.h ----------------------------------------------*- C++ -*-===//
+//
+// 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_VALUEOBJECT_DILLEXER_H_
+#define LLDB_VALUEOBJECT_DILLEXER_H_
+
+#include <limits.h>
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "llvm/ADT/StringRef.h"
+
+namespace lldb_private {
+
+namespace dil {
+
+enum class TokenKind {
+ coloncolon,
+ eof,
+ identifier,
+ invalid,
+ kw_namespace,
+ kw_this,
+ l_paren,
+ none,
+ r_paren,
+ unknown,
+};
+
+/// Class defining the tokens generated by the DIL lexer and used by the
+/// DIL parser.
+class DILToken {
+public:
+ DILToken(dil::TokenKind kind, std::string spelling, uint32_t start,
+ uint32_t len)
+ : m_kind(kind), m_spelling(spelling), m_start_pos(start), m_length(len) {}
+
+ DILToken()
+ : m_kind(dil::TokenKind::none), m_spelling(""), m_start_pos(0),
+ m_length(0) {}
+
+ void setKind(dil::TokenKind kind) { m_kind = kind; }
+ dil::TokenKind getKind() const { return m_kind; }
+
+ std::string getSpelling() const { return m_spelling; }
+
+ uint32_t getLength() const { return m_length; }
+
+ bool is(dil::TokenKind kind) const { return m_kind == kind; }
+
+ bool isNot(dil::TokenKind kind) const { return m_kind != kind; }
+
+ bool isOneOf(dil::TokenKind kind1, dil::TokenKind kind2) const {
+ return is(kind1) || is(kind2);
+ }
+
+ template <typename... Ts> bool isOneOf(dil::TokenKind kind, Ts... Ks) const {
+ return is(kind) || isOneOf(Ks...);
+ }
+
+ uint32_t getLocation() const { return m_start_pos; }
+
+ void setValues(dil::TokenKind kind, std::string spelling, uint32_t start,
+ uint32_t len) {
+ m_kind = kind;
+ m_spelling = spelling;
+ m_start_pos = start;
+ m_length = len;
+ }
+
+ static const std::string getTokenName(dil::TokenKind kind);
+
+private:
+ dil::TokenKind m_kind;
+ std::string m_spelling;
+ uint32_t m_start_pos; // within entire expression string
+ uint32_t m_length;
+};
+
+/// Class for doing the simple lexing required by DIL.
+class DILLexer {
+public:
+ DILLexer(std::shared_ptr<std::string> dil_sm) : m_expr(*dil_sm) {
+ m_cur_pos = m_expr.begin();
+ // Use UINT_MAX to indicate invalid/uninitialized value.
+ m_tokens_idx = UINT_MAX;
+ }
+
+ bool Lex(DILToken &result, bool look_ahead = false);
+
+ bool Is_Word(std::string::iterator start, uint32_t &length);
+
+ uint32_t GetLocation() { return m_cur_pos - m_expr.begin(); }
+
+ /// Update 'result' with the other paremeter values, create a
+ /// duplicate token, and push the duplicate token onto the vector of
+ /// lexed tokens.
+ void UpdateLexedTokens(DILToken &result, dil::TokenKind tok_kind,
+ std::string tok_str, uint32_t tok_pos,
+ uint32_t tok_len);
+
+ /// Return the lexed token N+1 positions ahead of the 'current' token
+ /// being handled by the DIL parser.
+ const DILToken &LookAhead(uint32_t N);
+
+ const DILToken &AcceptLookAhead(uint32_t N);
+
+ /// Return the index for the 'current' token being handled by the DIL parser.
+ uint32_t GetCurrentTokenIdx() { return m_tokens_idx; }
+
+ /// Return the current token to be handled by the DIL parser.
+ DILToken &GetCurrentToken() { return m_lexed_tokens[m_tokens_idx]; }
+
+ /// Update the index for the 'current' token, to point to the next lexed
+ /// token.
+ bool IncrementTokenIdx() {
+ if (m_tokens_idx >= m_lexed_tokens.size() - 1)
+ return false;
+
+ m_tokens_idx++;
+ return true;
+ }
+
+ /// Set the index for the 'current' token (to be handled by the parser)
+ /// to a particular position. Used for either committing 'look ahead' parsing
+ /// or rolling back tentative parsing.
+ bool ResetTokenIdx(uint32_t new_value) {
+ if (new_value > m_lexed_tokens.size() - 1)
+ return false;
+
+ m_tokens_idx = new_value;
+ return true;
+ }
+
+private:
+ // The input string we are lexing & parsing.
+ std::string m_expr;
+
+ // The current position of the lexer within m_expr (the character position,
+ // within the string, of the next item to be lexed).
+ std::string::iterator m_cur_pos;
+
+ // Holds all of the tokens lexed so far.
+ std::vector<DILToken> m_lexed_tokens;
+
+ // Index into m_lexed_tokens; indicates which token the DIL parser is
+ // currently trying to parse/handle.
+ uint32_t m_tokens_idx;
+
+ // "invalid" token; to be returned by lexer when 'look ahead' fails.
+ DILToken m_invalid_token;
+};
+
+} // namespace dil
+
+} // namespace lldb_private
+
+#endif // LLDB_VALUEOBJECT_DILLEXER_H_
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
new file mode 100644
index 00000000000000..b718903b7bea49
--- /dev/null
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -0,0 +1,105 @@
+//===-- DILParser.h ---------------------------------------------*- C++ -*-===//
+//
+// 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_VALUEOBJECT_DILPARSER_H_
+#define LLDB_VALUEOBJECT_DILPARSER_H_
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/ValueObject/DILAST.h"
+#include "lldb/ValueObject/DILLexer.h"
+
+namespace lldb_private {
+
+namespace dil {
+
+enum class ErrorCode : unsigned char {
+ kOk = 0,
+ kInvalidExpressionSyntax,
+ kUndeclaredIdentifier,
+ kUnknown,
+};
+
+std::string FormatDiagnostics(std::shared_ptr<std::string> input_expr,
+ const std::string &message, uint32_t loc);
+
+/// Pure recursive descent parser for C++ like expressions.
+/// EBNF grammar for the parser is described in lldb/docs/dil-expr-lang.ebnf
+class DILParser {
+public:
+ explicit DILParser(std::shared_ptr<std::string> dil_input_expr,
+ std::shared_ptr<ExecutionContextScope> exe_ctx_scope,
+ lldb::DynamicValueType use_dynamic, bool use_synthetic,
+ bool fragile_ivar, bool check_ptr_vs_member);
+
+ DILASTNodeUP Run(Status &error);
+
+ ~DILParser() { m_ctx_scope.reset(); }
+
+ bool UseSynthetic() { return m_use_synthetic; }
+
+ lldb::DynamicValueType UseDynamic() { return m_use_dynamic; }
+
+ using PtrOperator = std::tuple<dil::TokenKind, uint32_t>;
+
+private:
+ DILASTNodeUP ParseExpression();
+ DILASTNodeUP ParsePrimaryExpression();
+
+ std::string ParseNestedNameSpecifier();
+
+ std::string ParseIdExpression();
+ std::string ParseUnqualifiedId();
+
+ void ConsumeToken();
+
+ void BailOut(ErrorCode error_code, const std::string &error, uint32_t loc);
+
+ void BailOut(Status error);
+
+ void Expect(dil::TokenKind kind);
+
+ std::string TokenDescription(const DILToken &token);
+
+ template <typename... Ts> void ExpectOneOf(dil::TokenKind k, Ts... ks);
+
+ void TentativeParsingRollback(uint32_t saved_idx) {
+ m_error.Clear();
+ m_dil_lexer.ResetTokenIdx(saved_idx);
+ m_dil_token = m_dil_lexer.GetCurrentToken();
+ }
+
+ // Parser doesn't own the evaluation context. The produced AST may depend on
+ // it (for example, for source locations), so it's expected that expression
+ // context will outlive the parser.
+ std::shared_ptr<ExecutionContextScope> m_ctx_scope;
+
+ std::shared_ptr<std::string> m_input_expr;
+ // The token lexer is stopped at (aka "current token").
+ DILToken m_dil_token;
+ // Holds an error if it occures during parsing.
+ Status m_error;
+
+ lldb::DynamicValueType m_use_dynamic;
+ bool m_use_synthetic;
+ bool m_fragile_ivar;
+ bool m_check_ptr_vs_member;
+ DILLexer m_dil_lexer;
+}; // class DILParser
+
+} // namespace dil
+
+} // namespace lldb_private
+
+#endif // LLDB_VALUEOBJECT_DILPARSER_H_
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 2633c976c13bf4..28450b1d1c1c1e 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -31,6 +31,8 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
+#include "lldb/ValueObject/DILEval.h"
+#include "lldb/ValueObject/DILParser.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "lldb/ValueObject/ValueObjectMemory.h"
#include "lldb/ValueObject/ValueObjectVariable.h"
@@ -511,22 +513,58 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
VariableSP &var_sp, Status &error) {
ExecutionContext exe_ctx;
CalculateExecutionContext(exe_ctx);
+
bool use_DIL = exe_ctx.GetTargetRef().GetUseDIL(&exe_ctx);
+
if (use_DIL)
return DILGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
var_sp, error);
-
- return LegacyGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
- var_sp, error);
+ else
+ return LegacyGetValueForVariableExpressionPath(var_expr, use_dynamic,
+ options, var_sp, error);
}
ValueObjectSP StackFrame::DILGetValueForVariableExpressionPath(
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error) {
- // This is a place-holder for the calls into the DIL parser and
- // evaluator. For now, just call the "real" frame variable implementation.
- return LegacyGetValueForVariableExpressionPath(var_expr, use_dynamic, options,
- var_sp, error);
+ ValueObjectSP ret_val;
+ std::shared_ptr<std::string> source =
+ std::make_shared<std::string>(var_expr.data());
+
+ const bool check_ptr_vs_member =
+ (options & eExpressionPathOptionCheckPtrVsMember) != 0;
+ const bool no_fragile_ivar =
+ (options & eExpressionPathOptionsNoFragileObjcIvar) != 0;
+ const bool no_synth_child =
+ (options & eExpressionPathOptionsNoSyntheticChildren) != 0;
+
+ // Parse the expression.
+ Status parse_error, eval_error;
+ dil::DILParser parser(source, shared_from_this(), use_dynamic,
+ !no_synth_child, !no_fragile_ivar, check_ptr_vs_member);
+ dil::DILASTNodeUP tree = parser.Run(parse_error);
+ if (parse_error.Fail()) {
+ error = std::move(parse_error);
+ return ValueObjectSP();
+ }
+
+ // Evaluate the parsed expression.
+ lldb::TargetSP target = this->CalculateTarget();
+ dil::DILInterpreter interpreter(target, source, use_dynamic);
+
+ ret_val = interpreter.DILEval(tree.get(), target, eval_error);
+ if (eval_error.Fail()) {
+ error = std::move(eval_error);
+ return ValueObjectSP();
+ }
+
+ if (ret_val) {
+ var_sp = ret_val->GetVariable();
+ if (!var_sp && ret_val->GetParent()) {
+ var_sp = ret_val->GetParent()->GetVariable();
+ }
+ }
+ return ret_val;
}
ValueObjectSP StackFrame::LegacyGetValueForVariableExpressionPath(
diff --git a/lldb/source/ValueObject/CMakeLists.txt b/lldb/source/...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/120971
More information about the lldb-commits
mailing list