[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,26 @@ +int +main(int argc, char **argv) +{ + int a = 1; + int b = 2; + + char c = -3; + unsigned short s = 4; + + return 0; // Set a breakpoint here +} + +/* labath wrote: ?? https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,356 @@ +//===-- DILParser.cpp -===// +// +// 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 +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILParser.h" + +#include +#include + +#include +#include +#include + +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/DILEval.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" + +namespace lldb_private { + +namespace dil { + +inline void TokenKindsJoinImpl(std::ostringstream &os, dil::TokenKind k) { + os << "'" << DILToken::getTokenName(k) << "'"; +} + +template +inline void TokenKindsJoinImpl(std::ostringstream &os, dil::TokenKind k, + Ts... ks) { + TokenKindsJoinImpl(os, k); + os << ", "; + TokenKindsJoinImpl(os, ks...); +} + +template +inline std::string TokenKindsJoin(dil::TokenKind k, Ts... ks) { + std::ostringstream os; + TokenKindsJoinImpl(os, k, ks...); + + return os.str(); +} + +std::string FormatDiagnostics(std::shared_ptr input_expr, + const std::string &message, uint32_t loc) { + // Get the source buffer and the location of the current token. + llvm::StringRef text(*input_expr); + size_t loc_offset = (size_t)loc; + + // Look for the start of the line. + size_t line_start = text.rfind('\n', loc_offset); + line_start = line_start == llvm::StringRef::npos ? 0 : line_start + 1; + + // Look for the end of the line. + size_t line_end = text.find('\n', loc_offset); + line_end = line_end == llvm::StringRef::npos ? text.size() : line_end; + + // Get a view of the current line in the source code and the position of the + // diagnostics pointer. + llvm::StringRef line = text.slice(line_start, line_end); + int32_t arrow = loc + 1; // Column offset starts at 1, not 0. + + // Calculate the padding in case we point outside of the expression (this can + // happen if the parser expected something, but got EOF).˚ + size_t expr_rpad = std::max(0, arrow - static_cast(line.size())); + size_t arrow_rpad = std::max(0, static_cast(line.size()) - arrow); + + return llvm::formatv(": {1}\n{2}\n{3}", loc, message, + llvm::fmt_pad(line, 0, expr_rpad), + llvm::fmt_pad("^", arrow - 1, arrow_rpad)); +} + +DILParser::DILParser(std::shared_ptr dil_input_expr, + std::shared_ptr exe_ctx_scope, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member) +: m_ctx_scope(exe_ctx_scope), m_input_expr(dil_input_expr), + m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic), + m_fragile_ivar(fragile_ivar), m_check_ptr_vs_member(check_ptr_vs_member), + m_dil_lexer(DILLexer(dil_input_expr)) { + // Initialize the token. + m_dil_token.setKind(dil::TokenKind::unknown); +} + +DILASTNodeUP DILParser::Run(Status &error) { + ConsumeToken(); + + DILASTNodeUP expr; + + expr = ParseExpression(); + + Expect(dil::TokenKind::eof); + + error = std::move(m_error); + m_error.Clear(); + + // Explicitly return ErrorNode if there was an error during the parsing. + // Some routines raise an error, but don't change the return value (e.g. + // Expect). + if (error.Fail()) { +CompilerType bad_type; +return std::make_unique(bad_type); + } + return expr; +} + +// Parse an expression. +// +// expression: +//primary_expression +// +DILASTNodeUP DILParser::ParseExpression() { return ParsePrimaryExpression(); } + +// Parse a primary_expression. +// +// primary_expression: +//id_expression +//"this" +//"(" expression ")" +// +DILASTNodeUP DILParser::ParsePrimaryExpression() { + CompilerType bad_type; + if (m_dil_token.isOneOf(dil::TokenKind::coloncolon, + dil::TokenKind::identifier)) { +// Save the source location for the diagnostics message. +uint32_t loc = m_dil_token.getLocation(); +auto identifier = ParseIdExpression(); + +return std::make_unique(loc, identifier, m_use_dynamic, +m_ctx_scope); + } else if (m_dil_token.is(dil::TokenKind::kw_this)) { +// Save the source location for the diagnostics message. +uint32_t loc = m_dil_token.getLocation(); +ConsumeToken(); + +// Special case for "this" pointer. As per C++ standard, it's a prvalue. +return std::make_uniqu
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,228 @@ +//===-- DILAST.cpp ===// +// +// 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/ValueObject/DILAST.h" + +#include "lldb/API/SBType.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/LanguageRuntime.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/ValueObject/ValueObjectRegister.h" +#include "lldb/ValueObject/ValueObjectVariable.h" +#include "llvm/ADT/StringRef.h" + +#include + +namespace lldb_private { + +namespace dil { + +static lldb::ValueObjectSP +LookupStaticIdentifier(lldb::TargetSP target_sp, + const llvm::StringRef &name_ref, + ConstString unqualified_name) { + // List global variable with the same "basename". There can be many matches + // from other scopes (namespaces, classes), so we do additional filtering + // later. + VariableList variable_list; + ConstString name(name_ref); + target_sp->GetImages().FindGlobalVariables(name, 1, variable_list); + if (!variable_list.Empty()) { +ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get(); +if (exe_scope == nullptr) + exe_scope = target_sp.get(); +for (const lldb::VariableSP &var_sp : variable_list) { + lldb::ValueObjectSP valobj_sp( + ValueObjectVariable::Create(exe_scope, var_sp)); + if (valobj_sp && valobj_sp->GetVariable() && + (valobj_sp->GetVariable()->NameMatches(unqualified_name) || + valobj_sp->GetVariable()->NameMatches(ConstString(name_ref +return valobj_sp; +} + } + return nullptr; +} + +static lldb::VariableSP DILFindVariable(ConstString name, +VariableList *variable_list) { + lldb::VariableSP exact_match; + std::vector possible_matches; + + typedef std::vector collection; + typedef collection::iterator iterator; + + iterator pos, end = variable_list->end(); + for (pos = variable_list->begin(); pos != end; ++pos) { +llvm::StringRef str_ref_name = pos->get()->GetName().GetStringRef(); +// Check for global vars, which might start with '::'. +str_ref_name.consume_front("::"); + +if (str_ref_name == name.GetStringRef()) + possible_matches.push_back(*pos); +else if (pos->get()->NameMatches(name)) + possible_matches.push_back(*pos); + } + + // Look for exact matches (favors local vars over global vars) + auto exact_match_it = + llvm::find_if(possible_matches, [&](lldb::VariableSP var_sp) { +return var_sp->GetName() == name; + }); + + if (exact_match_it != llvm::adl_end(possible_matches)) +exact_match = *exact_match_it; + + if (!exact_match) +// Look for a global var exact match. +for (auto var_sp : possible_matches) { + llvm::StringRef str_ref_name = var_sp->GetName().GetStringRef(); + if (str_ref_name.size() > 2 && str_ref_name[0] == ':' && + str_ref_name[1] == ':') +str_ref_name = str_ref_name.drop_front(2); + ConstString tmp_name(str_ref_name); + if (tmp_name == name) { +exact_match = var_sp; +break; + } +} + + // Take any match at this point. + if (!exact_match && possible_matches.size() > 0) +exact_match = possible_matches[0]; + + return exact_match; +} + +std::unique_ptr +LookupIdentifier(const std::string &name, + std::shared_ptr ctx_scope, + lldb::DynamicValueType use_dynamic, CompilerType *scope_ptr) { + ConstString name_str(name); + llvm::StringRef name_ref = name_str.GetStringRef(); + + // Support $rax as a special syntax for accessing registers. + // Will return an invalid value in case the requested register doesn't exist. + if (name_ref.starts_with("$")) { +lldb::ValueObjectSP value_sp; +const char *reg_name = name_ref.drop_front(1).data(); +Target *target = ctx_scope->CalculateTarget().get(); +Process *process = ctx_scope->CalculateProcess().get(); +if (target && process) { + StackFrame *stack_frame = ctx_scope->CalculateStackFrame().get(); + if (stack_frame) { +lldb::RegisterContextSP reg_ctx(stack_frame->GetRegisterContext()); +if (reg_ctx) { + if (const RegisterInfo *reg_info = + reg_ctx->GetRegisterInfoByName(reg_name)) +value_sp = +ValueObjectRegister::Create(stack_frame, reg_ctx, reg_info); +} + } +} +if (value_sp) + return IdentifierInfo::FromValue(*value_sp); +else + return nullptr; + } + + // Internally values don't have global scope qualifier in their names and + // LLDB doesn't support queries with it too. + bool global_scope = fa
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,191 @@ +//===-- DILLexer.cpp --===// +// +// 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 +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILLexer.h" + +namespace lldb_private { + +namespace dil { + +const std::string DILToken::getTokenName(dil::TokenKind kind) { + std::string retval; + switch (kind) { + case dil::TokenKind::coloncolon: +retval = "coloncolon"; +break; + case dil::TokenKind::eof: +retval = "eof"; +break; + case dil::TokenKind::identifier: +retval = "identifier"; +break; + case dil::TokenKind::kw_namespace: +retval = "namespace"; +break; + case dil::TokenKind::kw_this: +retval = "this"; +break; + case dil::TokenKind::l_paren: +retval = "l_paren"; +break; + case dil::TokenKind::r_paren: +retval = "r_paren"; +break; + case dil::TokenKind::unknown: +retval = "unknown"; +break; + default: +retval = "token_name"; +break; + } + return retval; +} + +static bool Is_Letter(char c) { + if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) +return true; + return false; +} + +static bool Is_Digit(char c) { return ('0' <= c && c <= '9'); } + +bool DILLexer::Is_Word(std::string::iterator start, uint32_t &length) { + bool done = false; + for (; m_cur_pos != m_expr.end() && !done; ++m_cur_pos) { +char c = *m_cur_pos; +if (!Is_Letter(c) && !Is_Digit(c) && c != '_') { + done = true; + break; +} else + length++; + } + if (length > 0) +return true; + else labath wrote: https://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,117 @@ +//===-- DILEval.cpp ---===// +// +// 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/ValueObject/DILEval.h" + +#include + +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/ValueObject.h" +#include "llvm/Support/FormatAdapters.h" + +namespace lldb_private { + +namespace dil { + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm) +: m_target(std::move(target)), m_sm(std::move(sm)) { + m_default_dynamic = lldb::eNoDynamicValues; +} + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm, + lldb::DynamicValueType use_dynamic) +: m_target(std::move(target)), m_sm(std::move(sm)), + m_default_dynamic(use_dynamic) {} + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm, + lldb::ValueObjectSP scope) +: m_target(std::move(target)), m_sm(std::move(sm)), + m_scope(std::move(scope)) { + m_default_dynamic = lldb::eNoDynamicValues; + // If `m_scope` is a reference, dereference it. All operations on a reference + // should be operations on the referent. + if (m_scope->GetCompilerType().IsValid() && + m_scope->GetCompilerType().IsReferenceType()) { +Status error; +m_scope = m_scope->Dereference(error); labath wrote: What if dereferencing fails (maybe because it's a null/dangling reference)? https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -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 source = + std::make_shared(var_expr.data()); labath wrote: To convert a StringRef to a string, you should use the `.str()` method. `.data()` is more expensive (calls `strlen`) and can produce bad results or even crashes because StringRefs don't need to be null-terminated. *However*, a `shared_ptr` is really unusual. What are you trying to achieve here? I don't think you are/should be modifying the string, so are you trying to avoid copies? If so, the usual way to deal with that is to std::move the string to transfer ownership and use non-owning references (i.e. a StringRef) everywhere else). In this case, I think none of the DIL classes should outlive this function (if that's not the case, I'd like to know why), so I think you should just use the StringRef you got as an argument and avoid making any copies of at all. https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -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 +#include +#include + +#include "lldb/ValueObject/ValueObject.h" labath wrote: The [llvm style](https://llvm.org/docs/CodingStandards.html#include-style) puts the more specific includes first, and doesn't use empty line separators. If you just remove the empty lines, clang-format will put this in the right order. https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,191 @@ +//===-- DILLexer.cpp --===// +// +// 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 +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILLexer.h" + +namespace lldb_private { + +namespace dil { + +const std::string DILToken::getTokenName(dil::TokenKind kind) { + std::string retval; + switch (kind) { + case dil::TokenKind::coloncolon: +retval = "coloncolon"; +break; + case dil::TokenKind::eof: +retval = "eof"; +break; labath wrote: ```suggestion llvm::StringRef DILToken::getTokenName(dil::TokenKind kind) { switch (kind) { case dil::TokenKind::coloncolon: return "coloncolon"; case dil::TokenKind::eof: return "eof"; ... ``` https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -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 + +#include +#include +#include +#include + +#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 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; labath wrote: What's the relationship of `m_length` and `m_spelling.size()`? https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -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 +#include +#include + +#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 FromValue(ValueObject &valobj) { +CompilerType type; +type = valobj.GetCompilerType(); +return std::unique_ptr( +new IdentifierInfo(Kind::eValue, type, valobj.GetSP(), {})); + } + + static std::unique_ptr FromContextArg(CompilerType type) { +lldb::ValueObjectSP empty_value; +return std::unique_ptr( +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 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 LookupIdentifier( +const std::string &name, std::shared_ptr 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; + +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; labath wrote: ?? https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
https://github.com/labath commented: This is a partial review. I ran out of steam when I reached the Lexer component. I really think that one should be a patch of its own because: - all of the lookaheads and everything are sufficiently complicated to deserve the proper attention - the implementation is really amenable to unit testing (all you need is a string as an input) I also noticed that this implementation casts a much wider web when it comes to searching for global variables (it uses `Target::FindGlobalVariables`, which searches the entire process, whereas the current implementation only uses variables from the [current compile unit](https://github.com/llvm/llvm-project/blob/cbe583b0bd8d46b4e5edda463e19e6a24c0817bc/lldb/source/Target/StackFrame.cpp#L476). I think it would be best to stick to the existing implementation for now (ideally by even reusing the `GetInScopeVariableList` function), and saving the discussion about the pros and cons of changing that to a separate patch. The reason for that is I can find at least two benefits to the current implementation (it's faster and it's guaranteed to return the same variable you would get by compiling the expression in the compiler). I think it'd be best if that was isolated from the more technical/mundane aspects of parsing an expression. https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,117 @@ +//===-- DILEval.cpp ---===// +// +// 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/ValueObject/DILEval.h" + +#include + +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/ValueObject.h" +#include "llvm/Support/FormatAdapters.h" + +namespace lldb_private { + +namespace dil { + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm) +: m_target(std::move(target)), m_sm(std::move(sm)) { + m_default_dynamic = lldb::eNoDynamicValues; +} + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm, + lldb::DynamicValueType use_dynamic) +: m_target(std::move(target)), m_sm(std::move(sm)), + m_default_dynamic(use_dynamic) {} + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm, + lldb::ValueObjectSP scope) +: m_target(std::move(target)), m_sm(std::move(sm)), + m_scope(std::move(scope)) { + m_default_dynamic = lldb::eNoDynamicValues; + // If `m_scope` is a reference, dereference it. All operations on a reference + // should be operations on the referent. + if (m_scope->GetCompilerType().IsValid() && + m_scope->GetCompilerType().IsReferenceType()) { +Status error; +m_scope = m_scope->Dereference(error); + } +} + +lldb::ValueObjectSP DILInterpreter::DILEval(const DILASTNode *tree, +lldb::TargetSP target_sp, +Status &error) { + m_error.Clear(); + // Evaluate an AST. + DILEvalNode(tree); + // Set the error. + error = std::move(m_error); + // Return the computed result. If there was an error, it will be invalid. + return m_result; +} + +lldb::ValueObjectSP DILInterpreter::DILEvalNode(const DILASTNode *node) { + + // Traverse an AST pointed by the `node`. + node->Accept(this); + + // Return the computed value for convenience. The caller is responsible for + // checking if an error occured during the evaluation. + return m_result; +} labath wrote: Is this function needed (given that it's only caller is ignoring the result)? https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -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 source = + std::make_shared(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(); + } labath wrote: How about something like this: ```suggestion auto tree_or_error = dil::DILParser::Run(source, shared_from_this(), use_dynamic, !no_synth_child, !no_fragile_ivar, check_ptr_vs_member); if (!tree_or_error) { error = Status::FromError(tree_or_error.takeError()); return ValueObjectSP(); } ``` Basically, the changes are: - to make `Run` a static function (which creates a DILParser internally). From what I undertstand the DILParser object is not needed once it has finished parsing (all of its output is encompassed by the returned tree), so we could make the existence of the object an implementation detail - use llvm::Expected result to avoid the by-value error argument I think the same could be done with the interpreter object. https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,117 @@ +//===-- DILEval.cpp ---===// +// +// 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/ValueObject/DILEval.h" + +#include + +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/ValueObject.h" +#include "llvm/Support/FormatAdapters.h" + +namespace lldb_private { + +namespace dil { + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm) +: m_target(std::move(target)), m_sm(std::move(sm)) { + m_default_dynamic = lldb::eNoDynamicValues; +} + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm, + lldb::DynamicValueType use_dynamic) +: m_target(std::move(target)), m_sm(std::move(sm)), + m_default_dynamic(use_dynamic) {} + +DILInterpreter::DILInterpreter(lldb::TargetSP target, + std::shared_ptr sm, + lldb::ValueObjectSP scope) +: m_target(std::move(target)), m_sm(std::move(sm)), + m_scope(std::move(scope)) { + m_default_dynamic = lldb::eNoDynamicValues; + // If `m_scope` is a reference, dereference it. All operations on a reference + // should be operations on the referent. + if (m_scope->GetCompilerType().IsValid() && + m_scope->GetCompilerType().IsReferenceType()) { +Status error; +m_scope = m_scope->Dereference(error); + } +} + +lldb::ValueObjectSP DILInterpreter::DILEval(const DILASTNode *tree, +lldb::TargetSP target_sp, +Status &error) { + m_error.Clear(); + // Evaluate an AST. + DILEvalNode(tree); + // Set the error. + error = std::move(m_error); + // Return the computed result. If there was an error, it will be invalid. + return m_result; +} + +lldb::ValueObjectSP DILInterpreter::DILEvalNode(const DILASTNode *node) { + + // Traverse an AST pointed by the `node`. + node->Accept(this); + + // Return the computed value for convenience. The caller is responsible for + // checking if an error occured during the evaluation. + return m_result; +} + +void DILInterpreter::SetError(ErrorCode code, std::string error, uint32_t loc) { + assert(m_error.Success() && "interpreter can error only once"); + m_error = Status((uint32_t)code, lldb::eErrorTypeGeneric, + FormatDiagnostics(m_sm, error, loc)); +} + +void DILInterpreter::Visit(const ErrorNode *node) { + // The AST is not valid. + m_result = lldb::ValueObjectSP(); +} + +void DILInterpreter::Visit(const IdentifierNode *node) { + std::shared_ptr exe_ctx_scope = + node->get_exe_context(); + lldb::DynamicValueType use_dynamic = node->use_dynamic(); + + std::unique_ptr identifier = + LookupIdentifier(node->name(), exe_ctx_scope, use_dynamic); + + if (!identifier) { +std::string errMsg; +std::string name = node->name(); +if (name == "this") labath wrote: I'd really like to avoid special handling of "this". FWICS, the old implementation does it via `SymbolContext::GetInstanceVariableName`. https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -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 +#include + +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/DILParser.h" labath wrote: The same goes for this and all of the other files. https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 1b476ec - [lldb] A few more pieces towards OpenBSD support (#121051)
Author: Brad Smith Date: 2024-12-26T08:04:44-05:00 New Revision: 1b476ecdcf4b544af1436341fc923c0b73793cbe URL: https://github.com/llvm/llvm-project/commit/1b476ecdcf4b544af1436341fc923c0b73793cbe DIFF: https://github.com/llvm/llvm-project/commit/1b476ecdcf4b544af1436341fc923c0b73793cbe.diff LOG: [lldb] A few more pieces towards OpenBSD support (#121051) Added: Modified: lldb/cmake/modules/LLDBConfig.cmake lldb/source/Initialization/CMakeLists.txt lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp lldb/source/Plugins/Process/CMakeLists.txt Removed: diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index ee4c2630d32e25..9bb37f5967d4f3 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -292,7 +292,7 @@ endif() # Figure out if lldb could use lldb-server. If so, then we'll # ensure we build lldb-server when an lldb target is being built. -if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|Windows") +if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD|OpenBSD|Windows") set(LLDB_CAN_USE_LLDB_SERVER ON) else() set(LLDB_CAN_USE_LLDB_SERVER OFF) diff --git a/lldb/source/Initialization/CMakeLists.txt b/lldb/source/Initialization/CMakeLists.txt index c1a167826f76fd..b6282e162aa102 100644 --- a/lldb/source/Initialization/CMakeLists.txt +++ b/lldb/source/Initialization/CMakeLists.txt @@ -1,4 +1,4 @@ -if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD" ) +if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD|OpenBSD" ) list(APPEND EXTRA_PLUGINS lldbPluginProcessPOSIX) endif() diff --git a/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp index ad13a4406cfdad..54028b1b3261a7 100644 --- a/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp +++ b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp @@ -95,6 +95,7 @@ ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) case llvm::Triple::OSType::Linux: case llvm::Triple::OSType::MacOSX: case llvm::Triple::OSType::NetBSD: +case llvm::Triple::OSType::OpenBSD: case llvm::Triple::OSType::Solaris: case llvm::Triple::OSType::UnknownOS: return ABISP( diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt index a51d0f7afd1759..7f4f6fee7a9ea7 100644 --- a/lldb/source/Plugins/Process/CMakeLists.txt +++ b/lldb/source/Plugins/Process/CMakeLists.txt @@ -7,6 +7,8 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") add_subdirectory(NetBSD) add_subdirectory(POSIX) +elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") + add_subdirectory(POSIX) elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(Windows/Common) elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] A few more pieces towards OpenBSD support (PR #121051)
https://github.com/brad0 closed https://github.com/llvm/llvm-project/pull/121051 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] clang-format changes for some basic #if _AIX changes (PR #120978)
https://github.com/labath approved this pull request. https://github.com/llvm/llvm-project/pull/120978 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] A few more pieces towards OpenBSD support (PR #121051)
https://github.com/labath approved this pull request. https://github.com/llvm/llvm-project/pull/121051 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][DWARFASTParserClang][NFC] Remove redundant parameter to ParseChildParameters (PR #121033)
https://github.com/labath approved this pull request. https://github.com/llvm/llvm-project/pull/121033 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Ensure the IO forwarding threads are managed by the DAP object lifecycle. (PR #120457)
https://github.com/labath approved this pull request. > I know in my other pull request we talked about linking against lldb/host for > some utilities like the use of Pipe, but is this an issue with the current > architecture? Should I avoid that Host/FileSystem API or will I run into this > with other APIs potentially? You're right. This is potential problem, one whose scope I did not fully realize when I made that suggestion. It happens because liblldb only exposes the public lldb API, which means that anything linking against it gets its own copy it. This can be a problem with classes that use singletons or some for of explicit initialization, etc. Nonetheless, I still believe reimplementing any class that we might want to use on the other side of the API is not a solution. Overall, I think you've managed to strike a good balance with this version of the patch. The filesystem class is not particularly important here as the only thing we really get from it is the (os-specific) name of /dev/null. The socket and pipe classes on the other hand, are a lot more complicated, which makes it more worthwhile to reuse them. Fortunately, they are also the ones that don't suffer from these kinds of problems. If you run into other problems with some changes like this, let me know, and I'll see what I can do about it. https://github.com/llvm/llvm-project/pull/120457 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Ensure the IO forwarding threads are managed by the DAP object lifecycle. (PR #120457)
@@ -6,34 +6,62 @@ // //===--===// -#include -#include -#include -#include - #include "DAP.h" #include "JSONUtils.h" #include "LLDBUtils.h" +#include "OutputRedirector.h" +#include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBLanguageRuntime.h" #include "lldb/API/SBListener.h" +#include "lldb/API/SBProcess.h" #include "lldb/API/SBStream.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include +#include +#include +#include +#include #if defined(_WIN32) #define NOMINMAX #include #include #include +#else +#include #endif using namespace lldb_dap; +namespace { +#ifdef _WIN32 +const char *DEV_NULL = "nul"; +#else +const char *DEV_NULL = "/dev/null"; labath wrote: ```suggestion const char DEV_NULL[] = "nul"; #else const char DEV_NULL[] = "/dev/null"; ``` (This actually makes sure it's a constant, and makes it a bit smaller. I know you copied this code.) https://github.com/llvm/llvm-project/pull/120457 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Ensure the IO forwarding threads are managed by the DAP object lifecycle. (PR #120457)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/120457 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] AIX Changes for MainLoop polling (PR #120378)
https://github.com/DhruvSrivastavaX updated https://github.com/llvm/llvm-project/pull/120378 >From cf6a863b6da6bdaf474d2abc4524960b6436f645 Mon Sep 17 00:00:00 2001 From: Dhruv-Srivastava Date: Wed, 18 Dec 2024 02:17:04 -0600 Subject: [PATCH 1/4] AIX Changes for MainLoop --- lldb/source/Host/posix/MainLoopPosix.cpp | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lldb/source/Host/posix/MainLoopPosix.cpp b/lldb/source/Host/posix/MainLoopPosix.cpp index 1715610e0f84f1..a1d697e10a04ed 100644 --- a/lldb/source/Host/posix/MainLoopPosix.cpp +++ b/lldb/source/Host/posix/MainLoopPosix.cpp @@ -170,11 +170,23 @@ Status MainLoopPosix::RunImpl::Poll() { read_fds.push_back(pfd); } +#if defined(_AIX) + sigset_t origmask; + int timeout; + + timeout = -1; + pthread_sigmask(SIG_SETMASK, nullptr, &origmask); + int ready = poll(read_fds.data(), read_fds.size(), timeout); + pthread_sigmask(SIG_SETMASK, &origmask, nullptr); + if (ready == -1 && errno != EINTR) +return Status(errno, eErrorTypePOSIX); +#else if (ppoll(read_fds.data(), read_fds.size(), ToTimeSpec(loop.GetNextWakeupTime()), /*sigmask=*/nullptr) == -1 && errno != EINTR) return Status(errno, eErrorTypePOSIX); +#endif return Status(); } @@ -226,13 +238,13 @@ MainLoopPosix::~MainLoopPosix() { #endif m_read_fds.erase(m_interrupt_pipe.GetReadFileDescriptor()); m_interrupt_pipe.Close(); - assert(m_read_fds.size() == 0); + assert(m_read_fds.size() == 0); assert(m_signals.size() == 0); } MainLoopPosix::ReadHandleUP MainLoopPosix::RegisterReadObject(const IOObjectSP &object_sp, - const Callback &callback, Status &error) { + const Callback &callback, Status &error) { if (!object_sp || !object_sp->IsValid()) { error = Status::FromErrorString("IO object is not valid."); return nullptr; >From 7dc11e353e8420858adad3e58867727ef53f715f Mon Sep 17 00:00:00 2001 From: Dhruv-Srivastava Date: Mon, 23 Dec 2024 08:11:11 -0600 Subject: [PATCH 2/4] Implemented Wrapper with HAVE_PPOLL --- lldb/source/Host/posix/MainLoopPosix.cpp | 33 +--- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lldb/source/Host/posix/MainLoopPosix.cpp b/lldb/source/Host/posix/MainLoopPosix.cpp index a1d697e10a04ed..9b904ba2aa16ba 100644 --- a/lldb/source/Host/posix/MainLoopPosix.cpp +++ b/lldb/source/Host/posix/MainLoopPosix.cpp @@ -99,6 +99,7 @@ class MainLoopPosix::RunImpl { ~RunImpl() = default; Status Poll(); + int StartPoll(std::optional point); void ProcessReadEvents(); private: @@ -159,6 +160,22 @@ MainLoopPosix::RunImpl::RunImpl(MainLoopPosix &loop) : loop(loop) { read_fds.reserve(loop.m_read_fds.size()); } +int MainLoopPosix::RunImpl::StartPoll( +std::optional point) { +#if HAVE_PPOLL + return ppoll(read_fds.data(), read_fds.size(), ToTimeSpec(point), + /*sigmask=*/nullptr); +#else + using namespace std::chrono; + int timeout = -1; + if (point) { +nanosecond dur = std::max(*point - steady_clock::now(), nanoseconds(0)); +timeout = ceil(dur).count(); + } + return poll(read_fds.data(), read_fds.size(), timeout); +#endif +} + Status MainLoopPosix::RunImpl::Poll() { read_fds.clear(); @@ -169,24 +186,10 @@ Status MainLoopPosix::RunImpl::Poll() { pfd.revents = 0; read_fds.push_back(pfd); } + int ready = StartPoll(loop.GetNextWakeupTime()); -#if defined(_AIX) - sigset_t origmask; - int timeout; - - timeout = -1; - pthread_sigmask(SIG_SETMASK, nullptr, &origmask); - int ready = poll(read_fds.data(), read_fds.size(), timeout); - pthread_sigmask(SIG_SETMASK, &origmask, nullptr); if (ready == -1 && errno != EINTR) return Status(errno, eErrorTypePOSIX); -#else - if (ppoll(read_fds.data(), read_fds.size(), -ToTimeSpec(loop.GetNextWakeupTime()), -/*sigmask=*/nullptr) == -1 && - errno != EINTR) -return Status(errno, eErrorTypePOSIX); -#endif return Status(); } >From b9ceb61abfe2d29cae7d5e4778de385653057439 Mon Sep 17 00:00:00 2001 From: Dhruv-Srivastava Date: Mon, 23 Dec 2024 08:54:19 -0600 Subject: [PATCH 3/4] blunder --- lldb/source/Host/posix/MainLoopPosix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Host/posix/MainLoopPosix.cpp b/lldb/source/Host/posix/MainLoopPosix.cpp index 9b904ba2aa16ba..d7c99dbd877ded 100644 --- a/lldb/source/Host/posix/MainLoopPosix.cpp +++ b/lldb/source/Host/posix/MainLoopPosix.cpp @@ -169,7 +169,7 @@ int MainLoopPosix::RunImpl::StartPoll( using namespace std::chrono; int timeout = -1; if (point) { -nanosecond dur = std::max(*point - steady_clock::now(), nanoseconds(0)); +nanoseconds dur = std::max(*point - steady_clock::now(), nanoseconds(0)); timeout = ceil(dur).count(); } return poll(read_fds.data(), read_fds.size(), timeout); >From b262aa320d5606
[Lldb-commits] [lldb] [lldb][AIX] AIX Changes for MainLoop polling (PR #120378)
DhruvSrivastavaX wrote: > For me personally this would look better as thin syscall wrapper -- a static > function with all arguments passed explicitly (since the arguments are > modified, it would have to be MutableArrayRef, and not ArrayRef as I > originally wrote), rather than a method, but this will work too. Okay sure. That will increase the utility of the API. Done! https://github.com/llvm/llvm-project/pull/120378 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] clang-format changes for some basic #if _AIX changes (PR #120978)
DhruvSrivastavaX wrote: Request you to merge this one too. Thanks! https://github.com/llvm/llvm-project/pull/120978 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] AIX Changes for MainLoop polling (PR #120378)
DhruvSrivastavaX wrote: Request you to merge it as well, if all is good. Thanks! https://github.com/llvm/llvm-project/pull/120378 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Make workaround for the Dynamic loader issue (PR #120166)
@@ -89,8 +89,11 @@ Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() { "Failed to fill in header and directory " "sections. Written / Expected (%" PRIx64 " / %" PRIx64 ")", new_offset, m_saved_data_size); - return error; + if (error.Fail()) +return error; labath wrote: Remove the extra return? (It would be nice to at least have a test that verifies that the lldb stream is actually written) https://github.com/llvm/llvm-project/pull/120166 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Make workaround for the Dynamic loader issue (PR #120166)
https://github.com/labath approved this pull request. https://github.com/llvm/llvm-project/pull/120166 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -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 +#include +#include + +#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 FromValue(ValueObject &valobj) { +CompilerType type; +type = valobj.GetCompilerType(); +return std::unique_ptr( +new IdentifierInfo(Kind::eValue, type, valobj.GetSP(), {})); + } + + static std::unique_ptr FromContextArg(CompilerType type) { +lldb::ValueObjectSP empty_value; +return std::unique_ptr( +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 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 LookupIdentifier( +const std::string &name, std::shared_ptr ctx_scope, +lldb::DynamicValueType use_dynamic, CompilerType *scope_ptr = nullptr); labath wrote: Should this be in DILEval given that (I think) it's no longer used in ast construction? https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] AIX Changes for MainLoop polling (PR #120378)
https://github.com/labath approved this pull request. For me personally this would look better as thin syscall wrapper -- a static function with all arguments passed explicitly (since the arguments are modified, it would have to be MutableArrayRef, and not ArrayRef as I originally wrote), rather than a method, but this will work too. https://github.com/llvm/llvm-project/pull/120378 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][telemetry] Implement LLDB Telemetry (part 1) (PR #119716)
https://github.com/oontvoo reopened https://github.com/llvm/llvm-project/pull/119716 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][telemetry] Implement LLDB Telemetry (part 1) (PR #119716)
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/119716 >From b7216d7c3edd5974d84612586fbabdef19037387 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Thu, 26 Dec 2024 20:50:40 -0500 Subject: [PATCH] Implement LLDB Telemetry (Part 1) This contains only the concrete implementation of the framework to be used but no usages yet. This is a subset of PR/98528. I plan to send a few follow-up patches: part2 : includes changes in the plugin-manager to set up the plugin stuff (ie., how to create a default vs vendor impl) part3 (all of the following can be done in parallel): * part 3_a: define DebuggerTelemetryInfo and related methods to collect data about debugger startup/exit * part 3_b: define TargetTelemetryInfo and related methods to collect data about debug target(s) * part 3_c: define CommandTelemetryInfo and related methods to collect data about debug-commands * part 3_d: define ClientTelemtryInfo and related methods to collect data about lldb-dap/any other client --- lldb/include/lldb/Core/Telemetry.h| 101 ++ lldb/include/lldb/lldb-enumerations.h | 4 +- lldb/source/Core/CMakeLists.txt | 2 + lldb/source/Core/Telemetry.cpp| 92 +++ lldb/test/CMakeLists.txt | 3 + 5 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 lldb/include/lldb/Core/Telemetry.h create mode 100644 lldb/source/Core/Telemetry.cpp diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h new file mode 100644 index 000..882511efd804d23 --- /dev/null +++ b/lldb/include/lldb/Core/Telemetry.h @@ -0,0 +1,101 @@ +//===-- Telemetry.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_CORE_TELEMETRY_H +#define LLDB_CORE_TELEMETRY_H + +#include +#include +#include +#include +#include +#include + +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" +#include "llvm/Telemetry/Telemetry.h" + +namespace lldb_private { + +using llvm::telemetry::Destination; +using llvm::telemetry::KindType; +using llvm::telemetry::Serializer; +using llvm::telemetry::TelemetryInfo; + +struct LldbEntryKind : public ::llvm::telemetry::EntryKind { + static const KindType BaseInfo = 0b11000; +}; + +/// Defines a convenient type for timestamp of various events. +/// This is used by the EventStats below. +using SteadyTimePoint = std::chrono::time_point; + +/// Various time (and possibly memory) statistics of an event. +struct EventStats { + // REQUIRED: Start time of an event + SteadyTimePoint start; + // OPTIONAL: End time of an event - may be empty if not meaningful. + std::optional end; + // TBD: could add some memory stats here too? + + EventStats() = default; + EventStats(SteadyTimePoint start) : start(start) {} + EventStats(SteadyTimePoint start, SteadyTimePoint end) + : start(start), end(end) {} +}; + +/// Describes the exit signal of an event. +struct ExitDescription { + int exit_code; + std::string description; +}; + +struct LldbBaseTelemetryInfo : public TelemetryInfo { + EventStats stats; + + std::optional exit_desc; + + Debugger *debugger; + + // For dyn_cast, isa, etc operations. + KindType getKind() const override { return LldbEntryKind::BaseInfo; } + + static bool classof(const TelemetryInfo *t) { +// Subclasses of this is also acceptable. +return (t->getKind() & LldbEntryKind::BaseInfo) == LldbEntryKind::BaseInfo; + } + + void serialize(Serializer &serializer) const override; +}; + +/// The base Telemetry manager instance in LLDB +/// This class declares additional instrumentation points +/// applicable to LLDB. +class TelemetryManager : public llvm::telemetry::Manager { +public: + TelemetryManager(std::unique_ptr config); + + llvm::Error dispatch(TelemetryInfo *entry) override; + + void addDestination(std::unique_ptr destination) override; + +private: + std::unique_ptr m_config; + const std::string m_session_uuid; + std::vector> m_destinations; +}; + +} // namespace lldb_private +#endif // LLDB_CORE_TELEMETRY_H diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 0094fcd596fdf70..f63e446b6042f62 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -257,8 +257,8 @@ enum StopReason { }; /// Command Return Status Types. -enum ReturnStatus { - eReturnStatusInvalid, +enum ReturnStatus : int { + eReturnStatusInvalid =
[Lldb-commits] [lldb] [lldb][telemetry] Implement LLDB Telemetry (part 1) (PR #119716)
oontvoo wrote: (accidentally closed the PR - reopening now) https://github.com/llvm/llvm-project/pull/119716 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][telemetry] Implement LLDB Telemetry (part 1) (PR #119716)
@@ -0,0 +1,95 @@ + +//===-- Telemetry.cpp -===// +// +// 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/Core/Telemetry.h" oontvoo wrote: done https://github.com/llvm/llvm-project/pull/119716 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][telemetry] Implement LLDB Telemetry (part 1) (PR #119716)
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/119716 >From b7216d7c3edd5974d84612586fbabdef19037387 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Thu, 26 Dec 2024 20:50:40 -0500 Subject: [PATCH 1/2] Implement LLDB Telemetry (Part 1) This contains only the concrete implementation of the framework to be used but no usages yet. This is a subset of PR/98528. I plan to send a few follow-up patches: part2 : includes changes in the plugin-manager to set up the plugin stuff (ie., how to create a default vs vendor impl) part3 (all of the following can be done in parallel): * part 3_a: define DebuggerTelemetryInfo and related methods to collect data about debugger startup/exit * part 3_b: define TargetTelemetryInfo and related methods to collect data about debug target(s) * part 3_c: define CommandTelemetryInfo and related methods to collect data about debug-commands * part 3_d: define ClientTelemtryInfo and related methods to collect data about lldb-dap/any other client --- lldb/include/lldb/Core/Telemetry.h| 101 ++ lldb/include/lldb/lldb-enumerations.h | 4 +- lldb/source/Core/CMakeLists.txt | 2 + lldb/source/Core/Telemetry.cpp| 92 +++ lldb/test/CMakeLists.txt | 3 + 5 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 lldb/include/lldb/Core/Telemetry.h create mode 100644 lldb/source/Core/Telemetry.cpp diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h new file mode 100644 index 000..882511efd804d23 --- /dev/null +++ b/lldb/include/lldb/Core/Telemetry.h @@ -0,0 +1,101 @@ +//===-- Telemetry.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_CORE_TELEMETRY_H +#define LLDB_CORE_TELEMETRY_H + +#include +#include +#include +#include +#include +#include + +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" +#include "llvm/Telemetry/Telemetry.h" + +namespace lldb_private { + +using llvm::telemetry::Destination; +using llvm::telemetry::KindType; +using llvm::telemetry::Serializer; +using llvm::telemetry::TelemetryInfo; + +struct LldbEntryKind : public ::llvm::telemetry::EntryKind { + static const KindType BaseInfo = 0b11000; +}; + +/// Defines a convenient type for timestamp of various events. +/// This is used by the EventStats below. +using SteadyTimePoint = std::chrono::time_point; + +/// Various time (and possibly memory) statistics of an event. +struct EventStats { + // REQUIRED: Start time of an event + SteadyTimePoint start; + // OPTIONAL: End time of an event - may be empty if not meaningful. + std::optional end; + // TBD: could add some memory stats here too? + + EventStats() = default; + EventStats(SteadyTimePoint start) : start(start) {} + EventStats(SteadyTimePoint start, SteadyTimePoint end) + : start(start), end(end) {} +}; + +/// Describes the exit signal of an event. +struct ExitDescription { + int exit_code; + std::string description; +}; + +struct LldbBaseTelemetryInfo : public TelemetryInfo { + EventStats stats; + + std::optional exit_desc; + + Debugger *debugger; + + // For dyn_cast, isa, etc operations. + KindType getKind() const override { return LldbEntryKind::BaseInfo; } + + static bool classof(const TelemetryInfo *t) { +// Subclasses of this is also acceptable. +return (t->getKind() & LldbEntryKind::BaseInfo) == LldbEntryKind::BaseInfo; + } + + void serialize(Serializer &serializer) const override; +}; + +/// The base Telemetry manager instance in LLDB +/// This class declares additional instrumentation points +/// applicable to LLDB. +class TelemetryManager : public llvm::telemetry::Manager { +public: + TelemetryManager(std::unique_ptr config); + + llvm::Error dispatch(TelemetryInfo *entry) override; + + void addDestination(std::unique_ptr destination) override; + +private: + std::unique_ptr m_config; + const std::string m_session_uuid; + std::vector> m_destinations; +}; + +} // namespace lldb_private +#endif // LLDB_CORE_TELEMETRY_H diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 0094fcd596fdf70..f63e446b6042f62 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -257,8 +257,8 @@ enum StopReason { }; /// Command Return Status Types. -enum ReturnStatus { - eReturnStatusInvalid, +enum ReturnStatus : int { + eReturnStatusInvali
[Lldb-commits] [lldb] [lldb] Fix address to read segment data (PR #120655)
labath wrote: > Updated the commit to address @labath's comment. Can you explain how you did that? The new implementation does something completely different (and wrong on several levels) from the one I pointed you to. [Here](https://android.googlesource.com/platform/bionic/+/android-4.2_r1/linker/linker_phdr.c#34) is a description of elf loading from a linker POV that might be helpful. https://github.com/llvm/llvm-project/pull/120655 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ResolveSourceFileCallback] Update SBModule (PR #120832)
https://github.com/labath approved this pull request. https://github.com/llvm/llvm-project/pull/120832 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits