[Lldb-commits] [lldb] [LLDB] Add Lexer (with tests) for DIL (Data Inspection Language). (PR #123521)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 4 09:54:55 PST 2025
https://github.com/cmtice updated https://github.com/llvm/llvm-project/pull/123521
>From 468f73f8539dcb8addf8ed9618d9eb797dabbb01 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Sun, 19 Jan 2025 09:15:34 -0800
Subject: [PATCH 1/8] [LLDB] Add Lexer (with tests) for DIL (Data Inspection
Language).
This adds the basic lexer, with unittests, for the Data Inspection
Language (DIL) -- see
https://discourse.llvm.org/t/rfc-data-inspection-language/69893
This version of the lexer only handles local variables and namespaces,
and is designed to work with
https://github.com/llvm/llvm-project/pull/120971.
---
lldb/include/lldb/ValueObject/DILLexer.h | 156 ++++++++++++++
lldb/source/ValueObject/DILLexer.cpp | 205 +++++++++++++++++++
lldb/unittests/ValueObject/CMakeLists.txt | 1 +
lldb/unittests/ValueObject/DILLexerTests.cpp | 193 +++++++++++++++++
4 files changed, 555 insertions(+)
create mode 100644 lldb/include/lldb/ValueObject/DILLexer.h
create mode 100644 lldb/source/ValueObject/DILLexer.cpp
create mode 100644 lldb/unittests/ValueObject/DILLexerTests.cpp
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
new file mode 100644
index 000000000000000..45c506b2f4106dc
--- /dev/null
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -0,0 +1,156 @@
+//===-- 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 "llvm/ADT/StringRef.h"
+#include <cstdint>
+#include <limits.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace lldb_private {
+
+namespace dil {
+
+enum class TokenKind {
+ coloncolon,
+ eof,
+ identifier,
+ invalid,
+ kw_namespace,
+ 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)
+ : m_kind(kind), m_spelling(spelling), m_start_pos(start) {}
+
+ DILToken() : m_kind(dil::TokenKind::none), m_spelling(""), m_start_pos(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_spelling.size(); }
+
+ 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) {
+ m_kind = kind;
+ m_spelling = spelling;
+ m_start_pos = start;
+ }
+
+ 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
+};
+
+/// Class for doing the simple lexing required by DIL.
+class DILLexer {
+public:
+ DILLexer(llvm::StringRef dil_expr) : m_expr(dil_expr.str()) {
+ 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);
+
+ /// 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/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
new file mode 100644
index 000000000000000..4c2b0b1813bb96a
--- /dev/null
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -0,0 +1,205 @@
+//===-- 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"
+#include "llvm/ADT/StringMap.h"
+
+namespace lldb_private {
+
+namespace dil {
+
+// For fast keyword lookup. More keywords will be added later.
+const llvm::StringMap<dil::TokenKind> Keywords = {
+ {"namespace", dil::TokenKind::kw_namespace},
+};
+
+const std::string DILToken::getTokenName(dil::TokenKind kind) {
+ switch (kind) {
+ case dil::TokenKind::coloncolon:
+ return "coloncolon";
+ case dil::TokenKind::eof:
+ return "eof";
+ case dil::TokenKind::identifier:
+ return "identifier";
+ case dil::TokenKind::kw_namespace:
+ return "namespace";
+ case dil::TokenKind::l_paren:
+ return "l_paren";
+ case dil::TokenKind::r_paren:
+ return "r_paren";
+ case dil::TokenKind::unknown:
+ return "unknown";
+ default:
+ return "token_name";
+ }
+}
+
+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'); }
+
+// A word starts with a letter, underscore, or dollar sign, followed by
+// letters ('a'..'z','A'..'Z'), digits ('0'..'9'), and/or underscores.
+bool DILLexer::Is_Word(std::string::iterator start, uint32_t &length) {
+ bool done = false;
+ bool dollar_start = false;
+
+ // Must not start with a digit.
+ if (m_cur_pos == m_expr.end() || Is_Digit(*m_cur_pos))
+ return false;
+
+ // First character *may* be a '$', for a register name or convenience
+ // variable.
+ if (*m_cur_pos == '$') {
+ dollar_start = true;
+ ++m_cur_pos;
+ length++;
+ }
+
+ // Contains only letters, digits or underscores
+ 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 (dollar_start && length > 1) // Must have something besides just '$'
+ return true;
+
+ if (!dollar_start && length > 0)
+ return true;
+
+ // Not a valid word, so re-set the lexing position.
+ m_cur_pos = start;
+ return false;
+}
+
+void DILLexer::UpdateLexedTokens(DILToken &result, dil::TokenKind tok_kind,
+ std::string tok_str, uint32_t tok_pos) {
+ DILToken new_token;
+ result.setValues(tok_kind, tok_str, tok_pos);
+ new_token = result;
+ m_lexed_tokens.push_back(std::move(new_token));
+}
+
+bool DILLexer::Lex(DILToken &result, bool look_ahead) {
+ bool retval = true;
+
+ if (!look_ahead) {
+ // We're being asked for the 'next' token, and not a part of a LookAhead.
+ // Check to see if we've already lexed it and pushed it onto our tokens
+ // vector; if so, return the next token from the vector, rather than doing
+ // more lexing.
+ if ((m_tokens_idx != UINT_MAX) &&
+ (m_tokens_idx < m_lexed_tokens.size() - 1)) {
+ result = m_lexed_tokens[m_tokens_idx + 1];
+ return retval;
+ }
+ }
+
+ // Skip over whitespace (spaces).
+ while (m_cur_pos != m_expr.end() && *m_cur_pos == ' ')
+ m_cur_pos++;
+
+ // Check to see if we've reached the end of our input string.
+ if (m_cur_pos == m_expr.end()) {
+ UpdateLexedTokens(result, dil::TokenKind::eof, "", m_expr.length());
+ return retval;
+ }
+
+ uint32_t position = m_cur_pos - m_expr.begin();
+ ;
+ std::string::iterator start = m_cur_pos;
+ uint32_t length = 0;
+ if (Is_Word(start, length)) {
+ dil::TokenKind kind;
+ std::string word = m_expr.substr(position, length);
+ auto iter = Keywords.find(word);
+ if (iter != Keywords.end())
+ kind = iter->second;
+ else
+ kind = dil::TokenKind::identifier;
+
+ UpdateLexedTokens(result, kind, word, position);
+ return true;
+ }
+
+ switch (*m_cur_pos) {
+ case '(':
+ m_cur_pos++;
+ UpdateLexedTokens(result, dil::TokenKind::l_paren, "(", position);
+ return true;
+ case ')':
+ m_cur_pos++;
+ UpdateLexedTokens(result, dil::TokenKind::r_paren, ")", position);
+ return true;
+ case ':':
+ if (position + 1 < m_expr.size() && m_expr[position + 1] == ':') {
+ m_cur_pos += 2;
+ UpdateLexedTokens(result, dil::TokenKind::coloncolon, "::", position);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ // Empty Token
+ result.setValues(dil::TokenKind::none, "", m_expr.length());
+ return false;
+}
+
+const DILToken &DILLexer::LookAhead(uint32_t N) {
+ uint32_t extra_lexed_tokens = m_lexed_tokens.size() - m_tokens_idx - 1;
+
+ if (N + 1 < extra_lexed_tokens)
+ return m_lexed_tokens[m_tokens_idx + N + 1];
+
+ uint32_t remaining_tokens =
+ (m_tokens_idx + N + 1) - m_lexed_tokens.size() + 1;
+
+ bool done = false;
+ bool look_ahead = true;
+ while (!done && remaining_tokens > 0) {
+ DILToken tok;
+ Lex(tok, look_ahead);
+ if (tok.getKind() == dil::TokenKind::eof)
+ done = true;
+ remaining_tokens--;
+ };
+
+ if (remaining_tokens > 0) {
+ m_invalid_token.setValues(dil::TokenKind::invalid, "", 0);
+ return m_invalid_token;
+ }
+
+ return m_lexed_tokens[m_tokens_idx + N + 1];
+}
+
+const DILToken &DILLexer::AcceptLookAhead(uint32_t N) {
+ if (m_tokens_idx + N + 1 > m_lexed_tokens.size())
+ return m_invalid_token;
+
+ m_tokens_idx += N + 1;
+ return m_lexed_tokens[m_tokens_idx];
+}
+
+} // namespace dil
+
+} // namespace lldb_private
diff --git a/lldb/unittests/ValueObject/CMakeLists.txt b/lldb/unittests/ValueObject/CMakeLists.txt
index 8fcc8d62a799797..952f5411a980577 100644
--- a/lldb/unittests/ValueObject/CMakeLists.txt
+++ b/lldb/unittests/ValueObject/CMakeLists.txt
@@ -1,5 +1,6 @@
add_lldb_unittest(LLDBValueObjectTests
DumpValueObjectOptionsTests.cpp
+ DILLexerTests.cpp
LINK_LIBS
lldbValueObject
diff --git a/lldb/unittests/ValueObject/DILLexerTests.cpp b/lldb/unittests/ValueObject/DILLexerTests.cpp
new file mode 100644
index 000000000000000..ec6ff86b64d36ba
--- /dev/null
+++ b/lldb/unittests/ValueObject/DILLexerTests.cpp
@@ -0,0 +1,193 @@
+//===-- DILLexerTests.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/DILLexer.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include <string>
+
+using llvm::StringRef;
+
+TEST(DILLexerTests, SimpleTest) {
+ StringRef dil_input_expr("simple_var");
+ uint32_t tok_len = 10;
+ lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
+ lldb_private::dil::DILToken dil_token;
+ dil_token.setKind(lldb_private::dil::TokenKind::unknown);
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::unknown);
+ dil_lexer.Lex(dil_token);
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ EXPECT_EQ(dil_token.getSpelling(), "simple_var");
+ EXPECT_EQ(dil_token.getLength(), tok_len);
+ dil_lexer.Lex(dil_token);
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::eof);
+}
+
+TEST(DILLexerTests, TokenKindTest) {
+ StringRef dil_input_expr("namespace");
+ lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
+ lldb_private::dil::DILToken dil_token;
+ dil_token.setKind(lldb_private::dil::TokenKind::unknown);
+
+ dil_lexer.Lex(dil_token);
+ EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), UINT_MAX);
+ dil_lexer.ResetTokenIdx(0);
+
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::kw_namespace);
+ EXPECT_TRUE(dil_token.isNot(lldb_private::dil::TokenKind::identifier));
+ EXPECT_FALSE(dil_token.is(lldb_private::dil::TokenKind::l_paren));
+ EXPECT_TRUE(dil_token.isOneOf(lldb_private::dil::TokenKind::eof,
+ lldb_private::dil::TokenKind::kw_namespace));
+ EXPECT_FALSE(dil_token.isOneOf(lldb_private::dil::TokenKind::l_paren,
+ lldb_private::dil::TokenKind::r_paren,
+ lldb_private::dil::TokenKind::coloncolon,
+ lldb_private::dil::TokenKind::eof));
+
+ dil_token.setKind(lldb_private::dil::TokenKind::identifier);
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+}
+
+TEST(DILLexerTests, LookAheadTest) {
+ StringRef dil_input_expr("(anonymous namespace)::some_var");
+ lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
+ lldb_private::dil::DILToken dil_token;
+ dil_token.setKind(lldb_private::dil::TokenKind::unknown);
+ uint32_t expect_loc = 23;
+
+ dil_lexer.Lex(dil_token);
+ EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), UINT_MAX);
+ dil_lexer.ResetTokenIdx(0);
+
+ // Current token is '('; check the next 4 tokens, to make
+ // sure they are the identifier 'anonymous', the namespace keyword,
+ // ')' and '::', in that order.
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::l_paren);
+ EXPECT_EQ(dil_lexer.LookAhead(0).getKind(),
+ lldb_private::dil::TokenKind::identifier);
+ EXPECT_EQ(dil_lexer.LookAhead(0).getSpelling(), "anonymous");
+ EXPECT_EQ(dil_lexer.LookAhead(1).getKind(),
+ lldb_private::dil::TokenKind::kw_namespace);
+ EXPECT_EQ(dil_lexer.LookAhead(2).getKind(),
+ lldb_private::dil::TokenKind::r_paren);
+ EXPECT_EQ(dil_lexer.LookAhead(3).getKind(),
+ lldb_private::dil::TokenKind::coloncolon);
+ // Verify we've advanced our position counter (lexing location) in the
+ // input 23 characters (the length of '(anonymous namespace)::'.
+ EXPECT_EQ(dil_lexer.GetLocation(), expect_loc);
+
+ // Our current index should still be 0, as we only looked ahead; we are still
+ // officially on the '('.
+ EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), 0);
+
+ // Accept the 'lookahead', so our current token is '::', which has the index
+ // 4 in our vector of tokens (which starts at zero).
+ dil_token = dil_lexer.AcceptLookAhead(3);
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::coloncolon);
+ EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), 4);
+
+ // Lex the final variable name in the input string
+ dil_lexer.Lex(dil_token);
+ dil_lexer.IncrementTokenIdx();
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ EXPECT_EQ(dil_token.getSpelling(), "some_var");
+ EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), 5);
+
+ dil_lexer.Lex(dil_token);
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::eof);
+}
+
+TEST(DILLexerTests, MultiTokenLexTest) {
+ StringRef dil_input_expr("This string has several identifiers");
+ lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
+ lldb_private::dil::DILToken dil_token;
+ dil_token.setKind(lldb_private::dil::TokenKind::unknown);
+
+ dil_lexer.Lex(dil_token);
+ EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), UINT_MAX);
+ dil_lexer.ResetTokenIdx(0);
+
+ EXPECT_EQ(dil_token.getSpelling(), "This");
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ dil_lexer.Lex(dil_token);
+ dil_lexer.IncrementTokenIdx();
+
+ EXPECT_EQ(dil_token.getSpelling(), "string");
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ dil_lexer.Lex(dil_token);
+ dil_lexer.IncrementTokenIdx();
+
+ EXPECT_EQ(dil_token.getSpelling(), "has");
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ dil_lexer.Lex(dil_token);
+ dil_lexer.IncrementTokenIdx();
+
+ EXPECT_EQ(dil_token.getSpelling(), "several");
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ dil_lexer.Lex(dil_token);
+ dil_lexer.IncrementTokenIdx();
+
+ EXPECT_EQ(dil_token.getSpelling(), "identifiers");
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ dil_lexer.Lex(dil_token);
+ dil_lexer.IncrementTokenIdx();
+
+ EXPECT_EQ(dil_token.getSpelling(), "");
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::eof);
+}
+
+TEST(DILLexerTests, IdentifiersTest) {
+ std::vector<std::string> valid_identifiers = {
+ "$My_name1",
+ "$pc",
+ "abcd",
+ "ab cd",
+ "_",
+ "_a",
+ "_a_",
+ "a_b",
+ "this",
+ "self",
+ "a",
+ "MyName"
+ };
+ std::vector<std::string> invalid_identifiers = {
+ "234",
+ "2a",
+ "2",
+ "$",
+ "1MyName",
+ "",
+ "namespace"
+ };
+
+ // Verify that all of the valid identifiers come out as identifier tokens.
+ for (auto str : valid_identifiers) {
+ StringRef dil_input_expr(str);
+ lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
+ lldb_private::dil::DILToken dil_token;
+ dil_token.setKind(lldb_private::dil::TokenKind::unknown);
+
+ dil_lexer.Lex(dil_token);
+ EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ }
+
+ // Verify that none of the invalid identifiers come out as identifier tokens.
+ for (auto str : invalid_identifiers) {
+ StringRef dil_input_expr(str);
+ lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
+ lldb_private::dil::DILToken dil_token;
+ dil_token.setKind(lldb_private::dil::TokenKind::unknown);
+
+ dil_lexer.Lex(dil_token);
+ EXPECT_TRUE(dil_token.isNot(lldb_private::dil::TokenKind::identifier));
+ EXPECT_TRUE(dil_token.isOneOf(lldb_private::dil::TokenKind::unknown,
+ lldb_private::dil::TokenKind::none,
+ lldb_private::dil::TokenKind::eof,
+ lldb_private::dil::TokenKind::kw_namespace));
+ }
+}
>From 61a2607a70d90688d395321e846a3be58ccbebcb Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Sun, 19 Jan 2025 09:22:51 -0800
Subject: [PATCH 2/8] [LLDB] Add Lexer (with tests) for DIL (Data Inspection
Language)
Update CMakeLists.txt to build DILLexer.cpp.
---
lldb/source/ValueObject/CMakeLists.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/lldb/source/ValueObject/CMakeLists.txt b/lldb/source/ValueObject/CMakeLists.txt
index 70cb3d6d53f0717..30c34472289e7b5 100644
--- a/lldb/source/ValueObject/CMakeLists.txt
+++ b/lldb/source/ValueObject/CMakeLists.txt
@@ -1,4 +1,5 @@
add_lldb_library(lldbValueObject
+ DILLexer.cpp
ValueObject.cpp
ValueObjectCast.cpp
ValueObjectChild.cpp
>From 5e2ee55f800726910ad6e56a192554375f61bfb8 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Sat, 25 Jan 2025 16:56:30 -0800
Subject: [PATCH 3/8] Many changes, to address all the review comments:
- Remove "DIL" prefix from DILTokenKind and DILToken.
- Change the token kind from an enum class to an enum inside the Token
class.
- Use CamelCase for all the method names.
- Replace Token::SetValues method with assignments.
- Use a StringRef, not std::string, to hold the input string in the lexer.
- Update the lexer to lex all the tokens at one time. Added two new methods
for this: LexAll and GetNextToken.
- Made some of the Lexer methods private.
- Replaces StringMap with StringSwitch for fast keyword lookups.
- Updated GetTokenName to directly return StringRefs; removed default case from
switch statement.
- Cleaned up code format in IsLetter & IsDigit.
- Updated IsWord too return an iterator range containing the word (if any).
- Updated Lex function (now called by LexAll) to return an llvm::Expected
token; removed look_ahead checks; changed the operator lexing to use
a vector of operators (as suggested).
- Cleaned up LookAhead method, now that we know all tokens have already been
lexed.
- Added helper function to unittests, to help check a sequence of tokens.
- Generally cleaned up the tests to deal with all the code changes.
---
lldb/include/lldb/ValueObject/DILLexer.h | 110 ++++----
lldb/source/ValueObject/DILLexer.cpp | 214 +++++++--------
lldb/unittests/ValueObject/DILLexerTests.cpp | 269 ++++++++++---------
3 files changed, 302 insertions(+), 291 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 45c506b2f4106dc..61e5fe622e51e65 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -10,6 +10,8 @@
#define LLDB_VALUEOBJECT_DILLEXER_H_
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Error.h"
#include <cstdint>
#include <limits.h>
#include <memory>
@@ -20,58 +22,51 @@ namespace lldb_private {
namespace dil {
-enum class TokenKind {
- coloncolon,
- eof,
- identifier,
- invalid,
- kw_namespace,
- l_paren,
- none,
- r_paren,
- unknown,
-};
-
/// Class defining the tokens generated by the DIL lexer and used by the
/// DIL parser.
-class DILToken {
+class Token {
public:
- DILToken(dil::TokenKind kind, std::string spelling, uint32_t start)
+ enum Kind {
+ coloncolon,
+ eof,
+ identifier,
+ invalid,
+ kw_namespace,
+ l_paren,
+ none,
+ r_paren,
+ unknown,
+ };
+
+ Token(Kind kind, std::string spelling, uint32_t start)
: m_kind(kind), m_spelling(spelling), m_start_pos(start) {}
- DILToken() : m_kind(dil::TokenKind::none), m_spelling(""), m_start_pos(0) {}
+ Token() : m_kind(Kind::none), m_spelling(""), m_start_pos(0) {}
- void setKind(dil::TokenKind kind) { m_kind = kind; }
- dil::TokenKind getKind() const { return m_kind; }
+ void SetKind(Kind kind) { m_kind = kind; }
- std::string getSpelling() const { return m_spelling; }
+ Kind GetKind() const { return m_kind; }
- uint32_t getLength() const { return m_spelling.size(); }
+ std::string GetSpelling() const { return m_spelling; }
- bool is(dil::TokenKind kind) const { return m_kind == kind; }
+ uint32_t GetLength() const { return m_spelling.size(); }
- bool isNot(dil::TokenKind kind) const { return m_kind != kind; }
+ bool Is(Kind kind) const { return m_kind == kind; }
- bool isOneOf(dil::TokenKind kind1, dil::TokenKind kind2) const {
- return is(kind1) || is(kind2);
- }
+ bool IsNot(Kind kind) const { return m_kind != kind; }
- template <typename... Ts> bool isOneOf(dil::TokenKind kind, Ts... Ks) const {
- return is(kind) || isOneOf(Ks...);
- }
+ bool IsOneOf(Kind kind1, Kind kind2) const { return Is(kind1) || Is(kind2); }
- uint32_t getLocation() const { return m_start_pos; }
-
- void setValues(dil::TokenKind kind, std::string spelling, uint32_t start) {
- m_kind = kind;
- m_spelling = spelling;
- m_start_pos = start;
+ template <typename... Ts> bool IsOneOf(Kind kind, Ts... Ks) const {
+ return Is(kind) || IsOneOf(Ks...);
}
- static const std::string getTokenName(dil::TokenKind kind);
+ uint32_t GetLocation() const { return m_start_pos; }
+
+ static llvm::StringRef GetTokenName(Kind kind);
private:
- dil::TokenKind m_kind;
+ Kind m_kind;
std::string m_spelling;
uint32_t m_start_pos; // within entire expression string
};
@@ -79,35 +74,30 @@ class DILToken {
/// Class for doing the simple lexing required by DIL.
class DILLexer {
public:
- DILLexer(llvm::StringRef dil_expr) : m_expr(dil_expr.str()) {
+ DILLexer(llvm::StringRef dil_expr) : m_expr(dil_expr) {
m_cur_pos = m_expr.begin();
// Use UINT_MAX to indicate invalid/uninitialized value.
m_tokens_idx = UINT_MAX;
+ m_invalid_token = Token(Token::invalid, "", 0);
}
- 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);
+ llvm::Expected<bool> LexAll();
/// 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 Token &LookAhead(uint32_t N);
+
+ const Token &AcceptLookAhead(uint32_t N);
- const DILToken &AcceptLookAhead(uint32_t N);
+ const Token &GetNextToken();
/// 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]; }
+ const Token &GetCurrentToken() { return m_lexed_tokens[m_tokens_idx]; }
+
+ uint32_t NumLexedTokens() { return m_lexed_tokens.size(); }
/// Update the index for the 'current' token, to point to the next lexed
/// token.
@@ -130,23 +120,35 @@ class DILLexer {
return true;
}
+ uint32_t GetLocation() { return m_cur_pos - m_expr.begin(); }
+
private:
+ llvm::Expected<Token> Lex();
+
+ llvm::iterator_range<llvm::StringRef::iterator> IsWord();
+
+ /// Update 'result' with the other paremeter values, create a
+ /// duplicate token, and push the duplicate token onto the vector of
+ /// lexed tokens.
+ void UpdateLexedTokens(Token &result, Token::Kind tok_kind,
+ std::string tok_str, uint32_t tok_pos);
+
// The input string we are lexing & parsing.
- std::string m_expr;
+ llvm::StringRef 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;
+ llvm::StringRef::iterator m_cur_pos;
// Holds all of the tokens lexed so far.
- std::vector<DILToken> m_lexed_tokens;
+ std::vector<Token> 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;
+ Token m_invalid_token;
};
} // namespace dil
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index 4c2b0b1813bb96a..30e4bcb04e65055 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -12,107 +12,99 @@
//===----------------------------------------------------------------------===//
#include "lldb/ValueObject/DILLexer.h"
-#include "llvm/ADT/StringMap.h"
+#include "lldb/Utility/Status.h"
+#include "llvm/ADT/StringSwitch.h"
namespace lldb_private {
namespace dil {
-// For fast keyword lookup. More keywords will be added later.
-const llvm::StringMap<dil::TokenKind> Keywords = {
- {"namespace", dil::TokenKind::kw_namespace},
-};
-
-const std::string DILToken::getTokenName(dil::TokenKind kind) {
+llvm::StringRef Token::GetTokenName(Kind kind) {
switch (kind) {
- case dil::TokenKind::coloncolon:
+ case Kind::coloncolon:
return "coloncolon";
- case dil::TokenKind::eof:
+ case Kind::eof:
return "eof";
- case dil::TokenKind::identifier:
+ case Kind::identifier:
return "identifier";
- case dil::TokenKind::kw_namespace:
+ case Kind::invalid:
+ return "invalid";
+ case Kind::kw_namespace:
return "namespace";
- case dil::TokenKind::l_paren:
+ case Kind::l_paren:
return "l_paren";
- case dil::TokenKind::r_paren:
+ case Kind::none:
+ return "none";
+ case Kind::r_paren:
return "r_paren";
- case dil::TokenKind::unknown:
+ case Kind::unknown:
return "unknown";
- default:
- return "token_name";
}
}
-static bool Is_Letter(char c) {
- if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
- return true;
- return false;
+static bool IsLetter(char c) {
+ return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}
-static bool Is_Digit(char c) { return ('0' <= c && c <= '9'); }
+static bool IsDigit(char c) { return '0' <= c && c <= '9'; }
// A word starts with a letter, underscore, or dollar sign, followed by
// letters ('a'..'z','A'..'Z'), digits ('0'..'9'), and/or underscores.
-bool DILLexer::Is_Word(std::string::iterator start, uint32_t &length) {
- bool done = false;
+llvm::iterator_range<llvm::StringRef::iterator> DILLexer::IsWord() {
+ llvm::StringRef::iterator start = m_cur_pos;
bool dollar_start = false;
// Must not start with a digit.
- if (m_cur_pos == m_expr.end() || Is_Digit(*m_cur_pos))
- return false;
+ if (m_cur_pos == m_expr.end() || IsDigit(*m_cur_pos))
+ return llvm::make_range(m_cur_pos, m_cur_pos);
// First character *may* be a '$', for a register name or convenience
// variable.
if (*m_cur_pos == '$') {
dollar_start = true;
++m_cur_pos;
- length++;
}
// Contains only letters, digits or underscores
- for (; m_cur_pos != m_expr.end() && !done; ++m_cur_pos) {
+ for (; m_cur_pos != m_expr.end(); ++m_cur_pos) {
char c = *m_cur_pos;
- if (!Is_Letter(c) && !Is_Digit(c) && c != '_') {
- done = true;
+ if (!IsLetter(c) && !IsDigit(c) && c != '_')
break;
- } else
- length++;
}
- if (dollar_start && length > 1) // Must have something besides just '$'
- return true;
-
- if (!dollar_start && length > 0)
- return true;
+ // If first char is '$', make sure there's at least one mare char, or it's
+ // invalid.
+ if (dollar_start && (m_cur_pos - start <= 1)) {
+ m_cur_pos = start;
+ return llvm::make_range(start, start); // Empty range
+ }
- // Not a valid word, so re-set the lexing position.
- m_cur_pos = start;
- return false;
+ return llvm::make_range(start, m_cur_pos);
}
-void DILLexer::UpdateLexedTokens(DILToken &result, dil::TokenKind tok_kind,
+void DILLexer::UpdateLexedTokens(Token &result, Token::Kind tok_kind,
std::string tok_str, uint32_t tok_pos) {
- DILToken new_token;
- result.setValues(tok_kind, tok_str, tok_pos);
- new_token = result;
+ Token new_token(tok_kind, tok_str, tok_pos);
+ result = new_token;
m_lexed_tokens.push_back(std::move(new_token));
}
-bool DILLexer::Lex(DILToken &result, bool look_ahead) {
- bool retval = true;
-
- if (!look_ahead) {
- // We're being asked for the 'next' token, and not a part of a LookAhead.
- // Check to see if we've already lexed it and pushed it onto our tokens
- // vector; if so, return the next token from the vector, rather than doing
- // more lexing.
- if ((m_tokens_idx != UINT_MAX) &&
- (m_tokens_idx < m_lexed_tokens.size() - 1)) {
- result = m_lexed_tokens[m_tokens_idx + 1];
- return retval;
+llvm::Expected<bool> DILLexer::LexAll() {
+ bool done = false;
+ while (!done) {
+ auto tok_or_err = Lex();
+ if (!tok_or_err)
+ return tok_or_err.takeError();
+ Token token = *tok_or_err;
+ if (token.GetKind() == Token::eof) {
+ done = true;
}
}
+ return true;
+}
+
+llvm::Expected<Token> DILLexer::Lex() {
+ Token result;
// Skip over whitespace (spaces).
while (m_cur_pos != m_expr.end() && *m_cur_pos == ' ')
@@ -120,79 +112,52 @@ bool DILLexer::Lex(DILToken &result, bool look_ahead) {
// Check to see if we've reached the end of our input string.
if (m_cur_pos == m_expr.end()) {
- UpdateLexedTokens(result, dil::TokenKind::eof, "", m_expr.length());
- return retval;
+ UpdateLexedTokens(result, Token::eof, "", (uint32_t)m_expr.size());
+ return result;
}
uint32_t position = m_cur_pos - m_expr.begin();
- ;
- std::string::iterator start = m_cur_pos;
- uint32_t length = 0;
- if (Is_Word(start, length)) {
- dil::TokenKind kind;
- std::string word = m_expr.substr(position, length);
- auto iter = Keywords.find(word);
- if (iter != Keywords.end())
- kind = iter->second;
- else
- kind = dil::TokenKind::identifier;
-
- UpdateLexedTokens(result, kind, word, position);
- return true;
+ llvm::StringRef::iterator start = m_cur_pos;
+ llvm::iterator_range<llvm::StringRef::iterator> word_range = IsWord();
+ if (!word_range.empty()) {
+ uint32_t length = word_range.end() - word_range.begin();
+ llvm::StringRef word(m_expr.substr(position, length));
+ // We will be adding more keywords here in the future...
+ Token::Kind kind = llvm::StringSwitch<Token::Kind>(word)
+ .Case("namespace", Token::kw_namespace)
+ .Default(Token::identifier);
+ UpdateLexedTokens(result, kind, word.str(), position);
+ return result;
}
- switch (*m_cur_pos) {
- case '(':
- m_cur_pos++;
- UpdateLexedTokens(result, dil::TokenKind::l_paren, "(", position);
- return true;
- case ')':
- m_cur_pos++;
- UpdateLexedTokens(result, dil::TokenKind::r_paren, ")", position);
- return true;
- case ':':
- if (position + 1 < m_expr.size() && m_expr[position + 1] == ':') {
- m_cur_pos += 2;
- UpdateLexedTokens(result, dil::TokenKind::coloncolon, "::", position);
- return true;
+ m_cur_pos = start;
+ llvm::StringRef remainder(m_expr.substr(position, m_expr.end() - m_cur_pos));
+ std::vector<std::pair<Token::Kind, const char *>> operators = {
+ {Token::l_paren, "("},
+ {Token::r_paren, ")"},
+ {Token::coloncolon, "::"},
+ };
+ for (auto [kind, str] : operators) {
+ if (remainder.consume_front(str)) {
+ m_cur_pos += strlen(str);
+ UpdateLexedTokens(result, kind, str, position);
+ return result;
}
- break;
- default:
- break;
}
- // Empty Token
- result.setValues(dil::TokenKind::none, "", m_expr.length());
- return false;
-}
-const DILToken &DILLexer::LookAhead(uint32_t N) {
- uint32_t extra_lexed_tokens = m_lexed_tokens.size() - m_tokens_idx - 1;
+ // Unrecognized character(s) in string; unable to lex it.
+ Status error("Unable to lex input string");
+ return error.ToError();
+}
- if (N + 1 < extra_lexed_tokens)
+const Token &DILLexer::LookAhead(uint32_t N) {
+ if (m_tokens_idx + N + 1 < m_lexed_tokens.size())
return m_lexed_tokens[m_tokens_idx + N + 1];
- uint32_t remaining_tokens =
- (m_tokens_idx + N + 1) - m_lexed_tokens.size() + 1;
-
- bool done = false;
- bool look_ahead = true;
- while (!done && remaining_tokens > 0) {
- DILToken tok;
- Lex(tok, look_ahead);
- if (tok.getKind() == dil::TokenKind::eof)
- done = true;
- remaining_tokens--;
- };
-
- if (remaining_tokens > 0) {
- m_invalid_token.setValues(dil::TokenKind::invalid, "", 0);
- return m_invalid_token;
- }
-
- return m_lexed_tokens[m_tokens_idx + N + 1];
+ return m_invalid_token;
}
-const DILToken &DILLexer::AcceptLookAhead(uint32_t N) {
+const Token &DILLexer::AcceptLookAhead(uint32_t N) {
if (m_tokens_idx + N + 1 > m_lexed_tokens.size())
return m_invalid_token;
@@ -200,6 +165,25 @@ const DILToken &DILLexer::AcceptLookAhead(uint32_t N) {
return m_lexed_tokens[m_tokens_idx];
}
+const Token &DILLexer::GetNextToken() {
+ if (m_tokens_idx == UINT_MAX)
+ m_tokens_idx = 0;
+ else
+ m_tokens_idx++;
+
+ // Return the next token in the vector of lexed tokens.
+ if (m_tokens_idx < m_lexed_tokens.size())
+ return m_lexed_tokens[m_tokens_idx];
+
+ // We're already at/beyond the end of our lexed tokens. If the last token
+ // is an eof token, return it.
+ if (m_lexed_tokens[m_lexed_tokens.size() - 1].GetKind() == Token::eof)
+ return m_lexed_tokens[m_lexed_tokens.size() - 1];
+
+ // Return the invalid token.
+ return m_invalid_token;
+}
+
} // namespace dil
} // namespace lldb_private
diff --git a/lldb/unittests/ValueObject/DILLexerTests.cpp b/lldb/unittests/ValueObject/DILLexerTests.cpp
index ec6ff86b64d36ba..137013e40d6adfc 100644
--- a/lldb/unittests/ValueObject/DILLexerTests.cpp
+++ b/lldb/unittests/ValueObject/DILLexerTests.cpp
@@ -13,131 +13,145 @@
using llvm::StringRef;
+bool VerifyExpectedTokens(
+ lldb_private::dil::DILLexer &lexer,
+ std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>>
+ exp_tokens,
+ uint32_t start_pos) {
+ if (lexer.NumLexedTokens() - start_pos < exp_tokens.size())
+ return false;
+
+ if (start_pos > 0)
+ lexer.ResetTokenIdx(start_pos -
+ 1); // GetNextToken increments the idx first.
+ for (const auto &pair : exp_tokens) {
+ lldb_private::dil::Token token = lexer.GetNextToken();
+ if (token.GetKind() != pair.first || token.GetSpelling() != pair.second)
+ return false;
+ }
+
+ return true;
+}
+
TEST(DILLexerTests, SimpleTest) {
- StringRef dil_input_expr("simple_var");
+ StringRef input_expr("simple_var");
uint32_t tok_len = 10;
- lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
- lldb_private::dil::DILToken dil_token;
- dil_token.setKind(lldb_private::dil::TokenKind::unknown);
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::unknown);
- dil_lexer.Lex(dil_token);
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
- EXPECT_EQ(dil_token.getSpelling(), "simple_var");
- EXPECT_EQ(dil_token.getLength(), tok_len);
- dil_lexer.Lex(dil_token);
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::eof);
+ lldb_private::dil::DILLexer lexer(input_expr);
+ lldb_private::dil::Token token;
+ token.SetKind(lldb_private::dil::Token::unknown);
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::unknown);
+ auto success = lexer.LexAll();
+
+ if (!success) {
+ EXPECT_TRUE(false);
+ }
+ token = lexer.GetNextToken();
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(token.GetSpelling(), "simple_var");
+ EXPECT_EQ(token.GetLength(), tok_len);
+ token = lexer.GetNextToken();
+ ;
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
}
TEST(DILLexerTests, TokenKindTest) {
- StringRef dil_input_expr("namespace");
- lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
- lldb_private::dil::DILToken dil_token;
- dil_token.setKind(lldb_private::dil::TokenKind::unknown);
-
- dil_lexer.Lex(dil_token);
- EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), UINT_MAX);
- dil_lexer.ResetTokenIdx(0);
-
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::kw_namespace);
- EXPECT_TRUE(dil_token.isNot(lldb_private::dil::TokenKind::identifier));
- EXPECT_FALSE(dil_token.is(lldb_private::dil::TokenKind::l_paren));
- EXPECT_TRUE(dil_token.isOneOf(lldb_private::dil::TokenKind::eof,
- lldb_private::dil::TokenKind::kw_namespace));
- EXPECT_FALSE(dil_token.isOneOf(lldb_private::dil::TokenKind::l_paren,
- lldb_private::dil::TokenKind::r_paren,
- lldb_private::dil::TokenKind::coloncolon,
- lldb_private::dil::TokenKind::eof));
-
- dil_token.setKind(lldb_private::dil::TokenKind::identifier);
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ StringRef input_expr("namespace");
+ lldb_private::dil::DILLexer lexer(input_expr);
+ lldb_private::dil::Token token;
+ token.SetKind(lldb_private::dil::Token::unknown);
+
+ auto success = lexer.LexAll();
+ if (!success) {
+ EXPECT_TRUE(false);
+ }
+ token = lexer.GetNextToken();
+
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::kw_namespace);
+ EXPECT_TRUE(token.IsNot(lldb_private::dil::Token::identifier));
+ EXPECT_FALSE(token.Is(lldb_private::dil::Token::l_paren));
+ EXPECT_TRUE(token.IsOneOf(lldb_private::dil::Token::eof,
+ lldb_private::dil::Token::kw_namespace));
+ EXPECT_FALSE(token.IsOneOf(
+ lldb_private::dil::Token::l_paren, lldb_private::dil::Token::r_paren,
+ lldb_private::dil::Token::coloncolon, lldb_private::dil::Token::eof));
+
+ token.SetKind(lldb_private::dil::Token::identifier);
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
}
TEST(DILLexerTests, LookAheadTest) {
- StringRef dil_input_expr("(anonymous namespace)::some_var");
- lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
- lldb_private::dil::DILToken dil_token;
- dil_token.setKind(lldb_private::dil::TokenKind::unknown);
+ StringRef input_expr("(anonymous namespace)::some_var");
+ lldb_private::dil::DILLexer lexer(input_expr);
+ lldb_private::dil::Token token;
+ token.SetKind(lldb_private::dil::Token::unknown);
uint32_t expect_loc = 23;
- dil_lexer.Lex(dil_token);
- EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), UINT_MAX);
- dil_lexer.ResetTokenIdx(0);
+ auto success = lexer.LexAll();
+ if (!success) {
+ EXPECT_TRUE(false);
+ }
+ token = lexer.GetNextToken();
// Current token is '('; check the next 4 tokens, to make
// sure they are the identifier 'anonymous', the namespace keyword,
// ')' and '::', in that order.
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::l_paren);
- EXPECT_EQ(dil_lexer.LookAhead(0).getKind(),
- lldb_private::dil::TokenKind::identifier);
- EXPECT_EQ(dil_lexer.LookAhead(0).getSpelling(), "anonymous");
- EXPECT_EQ(dil_lexer.LookAhead(1).getKind(),
- lldb_private::dil::TokenKind::kw_namespace);
- EXPECT_EQ(dil_lexer.LookAhead(2).getKind(),
- lldb_private::dil::TokenKind::r_paren);
- EXPECT_EQ(dil_lexer.LookAhead(3).getKind(),
- lldb_private::dil::TokenKind::coloncolon);
- // Verify we've advanced our position counter (lexing location) in the
- // input 23 characters (the length of '(anonymous namespace)::'.
- EXPECT_EQ(dil_lexer.GetLocation(), expect_loc);
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::l_paren);
+ EXPECT_EQ(lexer.LookAhead(0).GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(lexer.LookAhead(0).GetSpelling(), "anonymous");
+ EXPECT_EQ(lexer.LookAhead(1).GetKind(),
+ lldb_private::dil::Token::kw_namespace);
+ EXPECT_EQ(lexer.LookAhead(2).GetKind(), lldb_private::dil::Token::r_paren);
+ EXPECT_EQ(lexer.LookAhead(3).GetKind(), lldb_private::dil::Token::coloncolon);
// Our current index should still be 0, as we only looked ahead; we are still
// officially on the '('.
- EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), 0);
+ EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)0);
// Accept the 'lookahead', so our current token is '::', which has the index
// 4 in our vector of tokens (which starts at zero).
- dil_token = dil_lexer.AcceptLookAhead(3);
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::coloncolon);
- EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), 4);
-
- // Lex the final variable name in the input string
- dil_lexer.Lex(dil_token);
- dil_lexer.IncrementTokenIdx();
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
- EXPECT_EQ(dil_token.getSpelling(), "some_var");
- EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), 5);
-
- dil_lexer.Lex(dil_token);
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::eof);
+ token = lexer.AcceptLookAhead(3);
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::coloncolon);
+ EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)4);
+
+ token = lexer.GetNextToken();
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(token.GetSpelling(), "some_var");
+ EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)5);
+ // Verify we've advanced our position counter (lexing location) in the
+ // input 23 characters (the length of '(anonymous namespace)::'.
+ EXPECT_EQ(token.GetLocation(), expect_loc);
+ token = lexer.GetNextToken();
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
}
TEST(DILLexerTests, MultiTokenLexTest) {
- StringRef dil_input_expr("This string has several identifiers");
- lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
- lldb_private::dil::DILToken dil_token;
- dil_token.setKind(lldb_private::dil::TokenKind::unknown);
-
- dil_lexer.Lex(dil_token);
- EXPECT_EQ(dil_lexer.GetCurrentTokenIdx(), UINT_MAX);
- dil_lexer.ResetTokenIdx(0);
-
- EXPECT_EQ(dil_token.getSpelling(), "This");
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
- dil_lexer.Lex(dil_token);
- dil_lexer.IncrementTokenIdx();
-
- EXPECT_EQ(dil_token.getSpelling(), "string");
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
- dil_lexer.Lex(dil_token);
- dil_lexer.IncrementTokenIdx();
-
- EXPECT_EQ(dil_token.getSpelling(), "has");
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
- dil_lexer.Lex(dil_token);
- dil_lexer.IncrementTokenIdx();
-
- EXPECT_EQ(dil_token.getSpelling(), "several");
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
- dil_lexer.Lex(dil_token);
- dil_lexer.IncrementTokenIdx();
-
- EXPECT_EQ(dil_token.getSpelling(), "identifiers");
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
- dil_lexer.Lex(dil_token);
- dil_lexer.IncrementTokenIdx();
-
- EXPECT_EQ(dil_token.getSpelling(), "");
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::eof);
+ StringRef input_expr("This string has (several ) ::identifiers");
+ lldb_private::dil::DILLexer lexer(input_expr);
+ lldb_private::dil::Token token;
+ token.SetKind(lldb_private::dil::Token::unknown);
+
+ auto success = lexer.LexAll();
+ if (!success) {
+ EXPECT_TRUE(false);
+ }
+
+ std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>>
+ expected_tokens = {
+ {lldb_private::dil::Token::identifier, "This"},
+ {lldb_private::dil::Token::identifier, "string"},
+ {lldb_private::dil::Token::identifier, "has"},
+ {lldb_private::dil::Token::l_paren, "("},
+ {lldb_private::dil::Token::identifier, "several"},
+ {lldb_private::dil::Token::r_paren, ")"},
+ {lldb_private::dil::Token::coloncolon, "::"},
+ {lldb_private::dil::Token::identifier, "identifiers"},
+ };
+
+ EXPECT_TRUE(VerifyExpectedTokens(lexer, expected_tokens, 0));
+
+ token = lexer.GetNextToken();
+ EXPECT_EQ(token.GetSpelling(), "");
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
}
TEST(DILLexerTests, IdentifiersTest) {
@@ -166,28 +180,39 @@ TEST(DILLexerTests, IdentifiersTest) {
};
// Verify that all of the valid identifiers come out as identifier tokens.
- for (auto str : valid_identifiers) {
- StringRef dil_input_expr(str);
- lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
- lldb_private::dil::DILToken dil_token;
- dil_token.setKind(lldb_private::dil::TokenKind::unknown);
-
- dil_lexer.Lex(dil_token);
- EXPECT_EQ(dil_token.getKind(), lldb_private::dil::TokenKind::identifier);
+ for (auto &str : valid_identifiers) {
+ SCOPED_TRACE(str);
+ lldb_private::dil::DILLexer lexer(str);
+ lldb_private::dil::Token token;
+ token.SetKind(lldb_private::dil::Token::unknown);
+
+ auto success = lexer.LexAll();
+ if (!success) {
+ EXPECT_TRUE(false);
+ }
+ token = lexer.GetNextToken();
+ EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
}
// Verify that none of the invalid identifiers come out as identifier tokens.
- for (auto str : invalid_identifiers) {
- StringRef dil_input_expr(str);
- lldb_private::dil::DILLexer dil_lexer(dil_input_expr);
- lldb_private::dil::DILToken dil_token;
- dil_token.setKind(lldb_private::dil::TokenKind::unknown);
-
- dil_lexer.Lex(dil_token);
- EXPECT_TRUE(dil_token.isNot(lldb_private::dil::TokenKind::identifier));
- EXPECT_TRUE(dil_token.isOneOf(lldb_private::dil::TokenKind::unknown,
- lldb_private::dil::TokenKind::none,
- lldb_private::dil::TokenKind::eof,
- lldb_private::dil::TokenKind::kw_namespace));
+ for (auto &str : invalid_identifiers) {
+ SCOPED_TRACE(str);
+ lldb_private::dil::DILLexer lexer(str);
+ lldb_private::dil::Token token;
+ token.SetKind(lldb_private::dil::Token::unknown);
+
+ auto success = lexer.LexAll();
+ // In this case, it's ok for Lex() to return an error.
+ if (!success) {
+ llvm::consumeError(success.takeError());
+ } else {
+ // We didn't get an error; make sure we did not get an identifier token.
+ token = lexer.GetNextToken();
+ EXPECT_TRUE(token.IsNot(lldb_private::dil::Token::identifier));
+ EXPECT_TRUE(token.IsOneOf(lldb_private::dil::Token::unknown,
+ lldb_private::dil::Token::none,
+ lldb_private::dil::Token::eof,
+ lldb_private::dil::Token::kw_namespace));
+ }
}
}
>From ccf5203595ec22d2e58d774ecbe58cdccfc2f106 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Thu, 30 Jan 2025 15:07:33 -0800
Subject: [PATCH 4/8] Address latest review comments:
- Remove 'namespace' as a keyword (make it a normal identifier)
- Remove 'invalid' and 'none' token types.
- Remove unnecessary SetKind and GetLength methods from Tokens.
- Re-arrange Lexer:
- Give it a static Create method, which pre-lexes all the tokens
- Make Lex method static
- Pull IsWord method out of Lexer class
- Make the Lexer constructor private.
- Remove LexAll, GetLocation, UpdateLexedTokens, AcceptLookAhead, GetNextToken,
and IncrementTokenIdx methods from Lexer class.
- Add new 'Advance' method (to help replace some of the removed methods).
- Update indexing in LookAhead (LookAead(0) now means the 'current' token).
- Remove m_cur_pos data member from Lexer class.
- Replace m_invalid_token with m_eof_token.
- Use 'remainder' StringRef to help with lexing.
- Update the unit tests to handle all the code changes in the Lexer.
- Update the unit tests to use ASSERT_THAT_EXPECTED to check llvm::Expected
return values.
- Update the unit tests to use "testing::ElementsAre(testing::Pair ..." to
verify all the lexed tokens; also added helper function ExtractTokenData, and
deleted function VerifyExpectedTokens.
---
lldb/include/lldb/ValueObject/DILLexer.h | 97 +++-----
lldb/source/ValueObject/DILLexer.cpp | 153 ++++--------
lldb/unittests/ValueObject/CMakeLists.txt | 1 +
lldb/unittests/ValueObject/DILLexerTests.cpp | 232 ++++++++-----------
4 files changed, 187 insertions(+), 296 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 61e5fe622e51e65..9e6cec18a686720 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -18,9 +18,7 @@
#include <string>
#include <vector>
-namespace lldb_private {
-
-namespace dil {
+namespace lldb_private::dil {
/// Class defining the tokens generated by the DIL lexer and used by the
/// DIL parser.
@@ -30,10 +28,7 @@ class Token {
coloncolon,
eof,
identifier,
- invalid,
- kw_namespace,
l_paren,
- none,
r_paren,
unknown,
};
@@ -41,16 +36,10 @@ class Token {
Token(Kind kind, std::string spelling, uint32_t start)
: m_kind(kind), m_spelling(spelling), m_start_pos(start) {}
- Token() : m_kind(Kind::none), m_spelling(""), m_start_pos(0) {}
-
- void SetKind(Kind kind) { m_kind = kind; }
-
Kind GetKind() const { return m_kind; }
std::string GetSpelling() const { return m_spelling; }
- uint32_t GetLength() const { return m_spelling.size(); }
-
bool Is(Kind kind) const { return m_kind == kind; }
bool IsNot(Kind kind) const { return m_kind != kind; }
@@ -74,72 +63,58 @@ class Token {
/// Class for doing the simple lexing required by DIL.
class DILLexer {
public:
- DILLexer(llvm::StringRef dil_expr) : m_expr(dil_expr) {
- m_cur_pos = m_expr.begin();
- // Use UINT_MAX to indicate invalid/uninitialized value.
- m_tokens_idx = UINT_MAX;
- m_invalid_token = Token(Token::invalid, "", 0);
- }
-
- llvm::Expected<bool> LexAll();
-
- /// Return the lexed token N+1 positions ahead of the 'current' token
- /// being handled by the DIL parser.
- const Token &LookAhead(uint32_t N);
-
- const Token &AcceptLookAhead(uint32_t N);
-
- const Token &GetNextToken();
-
- /// Return the index for the 'current' token being handled by the DIL parser.
- uint32_t GetCurrentTokenIdx() { return m_tokens_idx; }
+ /// Lexes all the tokens in expr and calls the private constructor
+ /// with the lexed tokens.
+ static llvm::Expected<DILLexer> Create(llvm::StringRef expr);
/// Return the current token to be handled by the DIL parser.
const Token &GetCurrentToken() { return m_lexed_tokens[m_tokens_idx]; }
- uint32_t NumLexedTokens() { return m_lexed_tokens.size(); }
+ /// Advance the current token position by N.
+ void Advance(uint32_t N = 1) {
+ // UINT_MAX means uninitialized, no "current" position, so move to start.
+ if (m_tokens_idx == UINT_MAX)
+ m_tokens_idx = 0;
+ else if (m_tokens_idx + N >= m_lexed_tokens.size())
+ // N is too large; advance to the end of the lexed tokens.
+ m_tokens_idx = m_lexed_tokens.size() - 1;
+ else
+ m_tokens_idx += N;
+ }
- /// 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;
+ /// Return the lexed token N positions ahead of the 'current' token
+ /// being handled by the DIL parser.
+ const Token &LookAhead(uint32_t N) {
+ if (m_tokens_idx + N < m_lexed_tokens.size())
+ return m_lexed_tokens[m_tokens_idx + N];
- m_tokens_idx++;
- return true;
+ return m_eof_token;
}
+ /// Return the index for the 'current' token being handled by the DIL parser.
+ uint32_t GetCurrentTokenIdx() { return m_tokens_idx; }
+
/// 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;
-
+ void ResetTokenIdx(uint32_t new_value) {
+ assert(new_value == UINT_MAX || new_value < m_lexed_tokens.size());
m_tokens_idx = new_value;
- return true;
}
- uint32_t GetLocation() { return m_cur_pos - m_expr.begin(); }
+ uint32_t NumLexedTokens() { return m_lexed_tokens.size(); }
private:
- llvm::Expected<Token> Lex();
+ DILLexer(llvm::StringRef dil_expr, std::vector<Token> lexed_tokens)
+ : m_expr(dil_expr), m_lexed_tokens(lexed_tokens), m_tokens_idx(UINT_MAX),
+ m_eof_token(Token(Token::eof, "", 0)) {}
- llvm::iterator_range<llvm::StringRef::iterator> IsWord();
-
- /// Update 'result' with the other paremeter values, create a
- /// duplicate token, and push the duplicate token onto the vector of
- /// lexed tokens.
- void UpdateLexedTokens(Token &result, Token::Kind tok_kind,
- std::string tok_str, uint32_t tok_pos);
+ static llvm::Expected<Token> Lex(llvm::StringRef expr,
+ llvm::StringRef &remainder);
// The input string we are lexing & parsing.
llvm::StringRef m_expr;
- // The current position of the lexer within m_expr (the character position,
- // within the string, of the next item to be lexed).
- llvm::StringRef::iterator m_cur_pos;
-
// Holds all of the tokens lexed so far.
std::vector<Token> m_lexed_tokens;
@@ -147,12 +122,10 @@ class DILLexer {
// currently trying to parse/handle.
uint32_t m_tokens_idx;
- // "invalid" token; to be returned by lexer when 'look ahead' fails.
- Token m_invalid_token;
+ // "eof" token; to be returned by lexer when 'look ahead' fails.
+ Token m_eof_token;
};
-} // namespace dil
-
-} // namespace lldb_private
+} // namespace lldb_private::dil
#endif // LLDB_VALUEOBJECT_DILLEXER_H_
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index 30e4bcb04e65055..b92bb86c8219c6f 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -15,9 +15,7 @@
#include "lldb/Utility/Status.h"
#include "llvm/ADT/StringSwitch.h"
-namespace lldb_private {
-
-namespace dil {
+namespace lldb_private::dil {
llvm::StringRef Token::GetTokenName(Kind kind) {
switch (kind) {
@@ -27,14 +25,8 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "eof";
case Kind::identifier:
return "identifier";
- case Kind::invalid:
- return "invalid";
- case Kind::kw_namespace:
- return "namespace";
case Kind::l_paren:
return "l_paren";
- case Kind::none:
- return "none";
case Kind::r_paren:
return "r_paren";
case Kind::unknown:
@@ -50,140 +42,91 @@ static bool IsDigit(char c) { return '0' <= c && c <= '9'; }
// A word starts with a letter, underscore, or dollar sign, followed by
// letters ('a'..'z','A'..'Z'), digits ('0'..'9'), and/or underscores.
-llvm::iterator_range<llvm::StringRef::iterator> DILLexer::IsWord() {
- llvm::StringRef::iterator start = m_cur_pos;
+static std::optional<llvm::StringRef> IsWord(llvm::StringRef expr,
+ llvm::StringRef &remainder) {
+ llvm::StringRef::iterator cur_pos = expr.end() - remainder.size();
+ llvm::StringRef::iterator start = cur_pos;
bool dollar_start = false;
// Must not start with a digit.
- if (m_cur_pos == m_expr.end() || IsDigit(*m_cur_pos))
- return llvm::make_range(m_cur_pos, m_cur_pos);
+ if (cur_pos == expr.end() || IsDigit(*cur_pos))
+ return std::nullopt;
// First character *may* be a '$', for a register name or convenience
// variable.
- if (*m_cur_pos == '$') {
+ if (*cur_pos == '$') {
dollar_start = true;
- ++m_cur_pos;
+ ++cur_pos;
}
// Contains only letters, digits or underscores
- for (; m_cur_pos != m_expr.end(); ++m_cur_pos) {
- char c = *m_cur_pos;
+ for (; cur_pos != expr.end(); ++cur_pos) {
+ char c = *cur_pos;
if (!IsLetter(c) && !IsDigit(c) && c != '_')
break;
}
// If first char is '$', make sure there's at least one mare char, or it's
// invalid.
- if (dollar_start && (m_cur_pos - start <= 1)) {
- m_cur_pos = start;
- return llvm::make_range(start, start); // Empty range
+ if (dollar_start && (cur_pos - start <= 1)) {
+ cur_pos = start;
+ return std::nullopt;
}
- return llvm::make_range(start, m_cur_pos);
-}
+ if (cur_pos == start)
+ return std::nullopt;
+
+ llvm::StringRef word = expr.substr(start - expr.begin(), cur_pos - start);
+ if (remainder.consume_front(word))
+ return word;
-void DILLexer::UpdateLexedTokens(Token &result, Token::Kind tok_kind,
- std::string tok_str, uint32_t tok_pos) {
- Token new_token(tok_kind, tok_str, tok_pos);
- result = new_token;
- m_lexed_tokens.push_back(std::move(new_token));
+ return std::nullopt;
}
-llvm::Expected<bool> DILLexer::LexAll() {
- bool done = false;
- while (!done) {
- auto tok_or_err = Lex();
- if (!tok_or_err)
- return tok_or_err.takeError();
- Token token = *tok_or_err;
- if (token.GetKind() == Token::eof) {
- done = true;
+llvm::Expected<DILLexer> DILLexer::Create(llvm::StringRef expr) {
+ std::vector<Token> tokens;
+ llvm::StringRef remainder = expr;
+ do {
+ if (llvm::Expected<Token> t = Lex(expr, remainder)) {
+ tokens.push_back(std::move(*t));
+ } else {
+ return t.takeError();
}
- }
- return true;
+ } while (tokens.back().GetKind() != Token::eof);
+ return DILLexer(expr, std::move(tokens));
}
-llvm::Expected<Token> DILLexer::Lex() {
- Token result;
-
+llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
+ llvm::StringRef &remainder) {
// Skip over whitespace (spaces).
- while (m_cur_pos != m_expr.end() && *m_cur_pos == ' ')
- m_cur_pos++;
+ remainder = remainder.ltrim();
+ llvm::StringRef::iterator cur_pos = expr.end() - remainder.size();
// Check to see if we've reached the end of our input string.
- if (m_cur_pos == m_expr.end()) {
- UpdateLexedTokens(result, Token::eof, "", (uint32_t)m_expr.size());
- return result;
+ if (remainder.empty() || cur_pos == expr.end())
+ return Token(Token::eof, "", (uint32_t)expr.size());
+
+ uint32_t position = cur_pos - expr.begin();
+ std::optional<llvm::StringRef> maybe_word = IsWord(expr, remainder);
+ if (maybe_word) {
+ llvm::StringRef word = *maybe_word;
+ return Token(Token::identifier, word.str(), position);
}
- uint32_t position = m_cur_pos - m_expr.begin();
- llvm::StringRef::iterator start = m_cur_pos;
- llvm::iterator_range<llvm::StringRef::iterator> word_range = IsWord();
- if (!word_range.empty()) {
- uint32_t length = word_range.end() - word_range.begin();
- llvm::StringRef word(m_expr.substr(position, length));
- // We will be adding more keywords here in the future...
- Token::Kind kind = llvm::StringSwitch<Token::Kind>(word)
- .Case("namespace", Token::kw_namespace)
- .Default(Token::identifier);
- UpdateLexedTokens(result, kind, word.str(), position);
- return result;
- }
-
- m_cur_pos = start;
- llvm::StringRef remainder(m_expr.substr(position, m_expr.end() - m_cur_pos));
- std::vector<std::pair<Token::Kind, const char *>> operators = {
+ constexpr std::pair<Token::Kind, const char *> operators[] = {
{Token::l_paren, "("},
{Token::r_paren, ")"},
{Token::coloncolon, "::"},
};
for (auto [kind, str] : operators) {
if (remainder.consume_front(str)) {
- m_cur_pos += strlen(str);
- UpdateLexedTokens(result, kind, str, position);
- return result;
+ cur_pos += strlen(str);
+ return Token(kind, str, position);
}
}
// Unrecognized character(s) in string; unable to lex it.
- Status error("Unable to lex input string");
- return error.ToError();
-}
-
-const Token &DILLexer::LookAhead(uint32_t N) {
- if (m_tokens_idx + N + 1 < m_lexed_tokens.size())
- return m_lexed_tokens[m_tokens_idx + N + 1];
-
- return m_invalid_token;
+ return llvm::createStringError("Unable to lex input string");
}
-const Token &DILLexer::AcceptLookAhead(uint32_t N) {
- if (m_tokens_idx + N + 1 > m_lexed_tokens.size())
- return m_invalid_token;
-
- m_tokens_idx += N + 1;
- return m_lexed_tokens[m_tokens_idx];
-}
-
-const Token &DILLexer::GetNextToken() {
- if (m_tokens_idx == UINT_MAX)
- m_tokens_idx = 0;
- else
- m_tokens_idx++;
-
- // Return the next token in the vector of lexed tokens.
- if (m_tokens_idx < m_lexed_tokens.size())
- return m_lexed_tokens[m_tokens_idx];
-
- // We're already at/beyond the end of our lexed tokens. If the last token
- // is an eof token, return it.
- if (m_lexed_tokens[m_lexed_tokens.size() - 1].GetKind() == Token::eof)
- return m_lexed_tokens[m_lexed_tokens.size() - 1];
-
- // Return the invalid token.
- return m_invalid_token;
-}
-
-} // namespace dil
-
-} // namespace lldb_private
+} // namespace lldb_private::dil
diff --git a/lldb/unittests/ValueObject/CMakeLists.txt b/lldb/unittests/ValueObject/CMakeLists.txt
index 952f5411a980577..14808aa2f213a55 100644
--- a/lldb/unittests/ValueObject/CMakeLists.txt
+++ b/lldb/unittests/ValueObject/CMakeLists.txt
@@ -6,6 +6,7 @@ add_lldb_unittest(LLDBValueObjectTests
lldbValueObject
lldbPluginPlatformLinux
lldbPluginScriptInterpreterNone
+ LLVMTestingSupport
LINK_COMPONENTS
Support
diff --git a/lldb/unittests/ValueObject/DILLexerTests.cpp b/lldb/unittests/ValueObject/DILLexerTests.cpp
index 137013e40d6adfc..f5523d3c5c40684 100644
--- a/lldb/unittests/ValueObject/DILLexerTests.cpp
+++ b/lldb/unittests/ValueObject/DILLexerTests.cpp
@@ -8,100 +8,90 @@
#include "lldb/ValueObject/DILLexer.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
#include <string>
using llvm::StringRef;
-bool VerifyExpectedTokens(
- lldb_private::dil::DILLexer &lexer,
- std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>>
- exp_tokens,
- uint32_t start_pos) {
- if (lexer.NumLexedTokens() - start_pos < exp_tokens.size())
- return false;
-
- if (start_pos > 0)
- lexer.ResetTokenIdx(start_pos -
- 1); // GetNextToken increments the idx first.
- for (const auto &pair : exp_tokens) {
- lldb_private::dil::Token token = lexer.GetNextToken();
- if (token.GetKind() != pair.first || token.GetSpelling() != pair.second)
- return false;
- }
-
- return true;
+std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>>
+ExtractTokenData(lldb_private::dil::DILLexer &lexer) {
+ std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>> data;
+ if (lexer.NumLexedTokens() == 0)
+ return data;
+
+ lexer.ResetTokenIdx(UINT_MAX);
+ do {
+ lexer.Advance();
+ lldb_private::dil::Token tok = lexer.GetCurrentToken();
+ data.push_back(std::make_pair(tok.GetKind(), tok.GetSpelling()));
+ } while (data.back().first != lldb_private::dil::Token::eof);
+ return data;
}
TEST(DILLexerTests, SimpleTest) {
StringRef input_expr("simple_var");
uint32_t tok_len = 10;
- lldb_private::dil::DILLexer lexer(input_expr);
- lldb_private::dil::Token token;
- token.SetKind(lldb_private::dil::Token::unknown);
+ llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
+ lldb_private::dil::DILLexer::Create(input_expr);
+ ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
+ lldb_private::dil::DILLexer lexer(*maybe_lexer);
+ lldb_private::dil::Token token =
+ lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::unknown);
- auto success = lexer.LexAll();
- if (!success) {
- EXPECT_TRUE(false);
- }
- token = lexer.GetNextToken();
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
EXPECT_EQ(token.GetSpelling(), "simple_var");
- EXPECT_EQ(token.GetLength(), tok_len);
- token = lexer.GetNextToken();
- ;
+ EXPECT_EQ(token.GetSpelling().size(), tok_len);
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
}
TEST(DILLexerTests, TokenKindTest) {
StringRef input_expr("namespace");
- lldb_private::dil::DILLexer lexer(input_expr);
- lldb_private::dil::Token token;
- token.SetKind(lldb_private::dil::Token::unknown);
-
- auto success = lexer.LexAll();
- if (!success) {
- EXPECT_TRUE(false);
- }
- token = lexer.GetNextToken();
-
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::kw_namespace);
- EXPECT_TRUE(token.IsNot(lldb_private::dil::Token::identifier));
+ llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
+ lldb_private::dil::DILLexer::Create(input_expr);
+ ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
+ lldb_private::dil::DILLexer lexer(*maybe_lexer);
+ lldb_private::dil::Token token =
+ lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
+
+ EXPECT_TRUE(token.Is(lldb_private::dil::Token::identifier));
EXPECT_FALSE(token.Is(lldb_private::dil::Token::l_paren));
EXPECT_TRUE(token.IsOneOf(lldb_private::dil::Token::eof,
- lldb_private::dil::Token::kw_namespace));
+ lldb_private::dil::Token::identifier));
EXPECT_FALSE(token.IsOneOf(
lldb_private::dil::Token::l_paren, lldb_private::dil::Token::r_paren,
lldb_private::dil::Token::coloncolon, lldb_private::dil::Token::eof));
-
- token.SetKind(lldb_private::dil::Token::identifier);
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
}
TEST(DILLexerTests, LookAheadTest) {
StringRef input_expr("(anonymous namespace)::some_var");
- lldb_private::dil::DILLexer lexer(input_expr);
- lldb_private::dil::Token token;
- token.SetKind(lldb_private::dil::Token::unknown);
+ llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
+ lldb_private::dil::DILLexer::Create(input_expr);
+ ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
+ lldb_private::dil::DILLexer lexer(*maybe_lexer);
+ lldb_private::dil::Token token =
+ lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
uint32_t expect_loc = 23;
-
- auto success = lexer.LexAll();
- if (!success) {
- EXPECT_TRUE(false);
- }
- token = lexer.GetNextToken();
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
// Current token is '('; check the next 4 tokens, to make
- // sure they are the identifier 'anonymous', the namespace keyword,
+ // sure they are the identifier 'anonymous', the identifier 'namespace'
// ')' and '::', in that order.
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::l_paren);
- EXPECT_EQ(lexer.LookAhead(0).GetKind(), lldb_private::dil::Token::identifier);
- EXPECT_EQ(lexer.LookAhead(0).GetSpelling(), "anonymous");
- EXPECT_EQ(lexer.LookAhead(1).GetKind(),
- lldb_private::dil::Token::kw_namespace);
- EXPECT_EQ(lexer.LookAhead(2).GetKind(), lldb_private::dil::Token::r_paren);
- EXPECT_EQ(lexer.LookAhead(3).GetKind(), lldb_private::dil::Token::coloncolon);
+ EXPECT_EQ(lexer.LookAhead(1).GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(lexer.LookAhead(1).GetSpelling(), "anonymous");
+ EXPECT_EQ(lexer.LookAhead(2).GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(lexer.LookAhead(2).GetSpelling(), "namespace");
+ EXPECT_EQ(lexer.LookAhead(3).GetKind(), lldb_private::dil::Token::r_paren);
+ EXPECT_EQ(lexer.LookAhead(4).GetKind(), lldb_private::dil::Token::coloncolon);
// Our current index should still be 0, as we only looked ahead; we are still
// officially on the '('.
@@ -109,110 +99,94 @@ TEST(DILLexerTests, LookAheadTest) {
// Accept the 'lookahead', so our current token is '::', which has the index
// 4 in our vector of tokens (which starts at zero).
- token = lexer.AcceptLookAhead(3);
+ lexer.Advance(4);
+ token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::coloncolon);
EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)4);
- token = lexer.GetNextToken();
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
EXPECT_EQ(token.GetSpelling(), "some_var");
EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)5);
// Verify we've advanced our position counter (lexing location) in the
// input 23 characters (the length of '(anonymous namespace)::'.
EXPECT_EQ(token.GetLocation(), expect_loc);
- token = lexer.GetNextToken();
+
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
}
TEST(DILLexerTests, MultiTokenLexTest) {
StringRef input_expr("This string has (several ) ::identifiers");
- lldb_private::dil::DILLexer lexer(input_expr);
- lldb_private::dil::Token token;
- token.SetKind(lldb_private::dil::Token::unknown);
-
- auto success = lexer.LexAll();
- if (!success) {
- EXPECT_TRUE(false);
- }
+ llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
+ lldb_private::dil::DILLexer::Create(input_expr);
+ ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
+ lldb_private::dil::DILLexer lexer(*maybe_lexer);
+ lldb_private::dil::Token token =
+ lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>>
- expected_tokens = {
- {lldb_private::dil::Token::identifier, "This"},
- {lldb_private::dil::Token::identifier, "string"},
- {lldb_private::dil::Token::identifier, "has"},
- {lldb_private::dil::Token::l_paren, "("},
- {lldb_private::dil::Token::identifier, "several"},
- {lldb_private::dil::Token::r_paren, ")"},
- {lldb_private::dil::Token::coloncolon, "::"},
- {lldb_private::dil::Token::identifier, "identifiers"},
- };
-
- EXPECT_TRUE(VerifyExpectedTokens(lexer, expected_tokens, 0));
-
- token = lexer.GetNextToken();
+ lexer_tokens_data = ExtractTokenData(lexer);
+
+ EXPECT_THAT(
+ lexer_tokens_data,
+ testing::ElementsAre(
+ testing::Pair(lldb_private::dil::Token::identifier, "This"),
+ testing::Pair(lldb_private::dil::Token::identifier, "string"),
+ testing::Pair(lldb_private::dil::Token::identifier, "has"),
+ testing::Pair(lldb_private::dil::Token::l_paren, "("),
+ testing::Pair(lldb_private::dil::Token::identifier, "several"),
+ testing::Pair(lldb_private::dil::Token::r_paren, ")"),
+ testing::Pair(lldb_private::dil::Token::coloncolon, "::"),
+ testing::Pair(lldb_private::dil::Token::identifier, "identifiers"),
+ testing::Pair(lldb_private::dil::Token::eof, "")));
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetSpelling(), "");
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
}
TEST(DILLexerTests, IdentifiersTest) {
std::vector<std::string> valid_identifiers = {
- "$My_name1",
- "$pc",
- "abcd",
- "ab cd",
- "_",
- "_a",
- "_a_",
- "a_b",
- "this",
- "self",
- "a",
- "MyName"
- };
- std::vector<std::string> invalid_identifiers = {
- "234",
- "2a",
- "2",
- "$",
- "1MyName",
- "",
- "namespace"
- };
+ "$My_name1", "$pc", "abcd", "ab cd", "_", "_a", "_a_",
+ "a_b", "this", "self", "a", "MyName", "namespace"};
+ std::vector<std::string> invalid_identifiers = {"234", "2a", "2",
+ "$", "1MyName", ""};
// Verify that all of the valid identifiers come out as identifier tokens.
for (auto &str : valid_identifiers) {
SCOPED_TRACE(str);
- lldb_private::dil::DILLexer lexer(str);
- lldb_private::dil::Token token;
- token.SetKind(lldb_private::dil::Token::unknown);
-
- auto success = lexer.LexAll();
- if (!success) {
- EXPECT_TRUE(false);
- }
- token = lexer.GetNextToken();
+ llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
+ lldb_private::dil::DILLexer::Create(str);
+ ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
+ lldb_private::dil::DILLexer lexer(*maybe_lexer);
+ lldb_private::dil::Token token =
+ lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
}
// Verify that none of the invalid identifiers come out as identifier tokens.
for (auto &str : invalid_identifiers) {
SCOPED_TRACE(str);
- lldb_private::dil::DILLexer lexer(str);
- lldb_private::dil::Token token;
- token.SetKind(lldb_private::dil::Token::unknown);
-
- auto success = lexer.LexAll();
- // In this case, it's ok for Lex() to return an error.
- if (!success) {
- llvm::consumeError(success.takeError());
+ llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
+ lldb_private::dil::DILLexer::Create(str);
+ if (!maybe_lexer) {
+ llvm::consumeError(maybe_lexer.takeError());
+ // In this case, it's ok for lexing to return an error.
} else {
+ lldb_private::dil::DILLexer lexer(*maybe_lexer);
+ lldb_private::dil::Token token =
+ lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
// We didn't get an error; make sure we did not get an identifier token.
- token = lexer.GetNextToken();
+ lexer.Advance();
+ token = lexer.GetCurrentToken();
EXPECT_TRUE(token.IsNot(lldb_private::dil::Token::identifier));
EXPECT_TRUE(token.IsOneOf(lldb_private::dil::Token::unknown,
- lldb_private::dil::Token::none,
- lldb_private::dil::Token::eof,
- lldb_private::dil::Token::kw_namespace));
+ lldb_private::dil::Token::eof));
}
}
}
>From 29e9f265ea342e84372c63adbfdac0882d2fd434 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Sun, 2 Feb 2025 22:06:04 -0800
Subject: [PATCH 5/8] Address more review comments:
- Use std::move on std::string & std::vector in constructor initializers.
- Remove some unnecessary code.
- Update ExtractTokenData (helper function in unit tests) to set up the lexer
and to the lexing inside the function; return an llvm::Expected value.
- Add 'using namespace lldb_private::dil;' to unit tests; clean up tests
accordingly.
- Minor code cleanups in the unit tests.
---
lldb/include/lldb/ValueObject/DILLexer.h | 9 +-
lldb/source/ValueObject/DILLexer.cpp | 10 +-
lldb/unittests/ValueObject/DILLexerTests.cpp | 162 ++++++++-----------
3 files changed, 72 insertions(+), 109 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 9e6cec18a686720..3935bf7e8e5c5ea 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -34,7 +34,7 @@ class Token {
};
Token(Kind kind, std::string spelling, uint32_t start)
- : m_kind(kind), m_spelling(spelling), m_start_pos(start) {}
+ : m_kind(kind), m_spelling(std::move(spelling)), m_start_pos(start) {}
Kind GetKind() const { return m_kind; }
@@ -88,7 +88,8 @@ class DILLexer {
if (m_tokens_idx + N < m_lexed_tokens.size())
return m_lexed_tokens[m_tokens_idx + N];
- return m_eof_token;
+ // Last token should be an 'eof' token.
+ return m_lexed_tokens.back();
}
/// Return the index for the 'current' token being handled by the DIL parser.
@@ -106,8 +107,8 @@ class DILLexer {
private:
DILLexer(llvm::StringRef dil_expr, std::vector<Token> lexed_tokens)
- : m_expr(dil_expr), m_lexed_tokens(lexed_tokens), m_tokens_idx(UINT_MAX),
- m_eof_token(Token(Token::eof, "", 0)) {}
+ : m_expr(dil_expr), m_lexed_tokens(std::move(lexed_tokens)),
+ m_tokens_idx(UINT_MAX), m_eof_token(Token(Token::eof, "", 0)) {}
static llvm::Expected<Token> Lex(llvm::StringRef expr,
llvm::StringRef &remainder);
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index b92bb86c8219c6f..46ecea9b585f56b 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -108,10 +108,8 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
uint32_t position = cur_pos - expr.begin();
std::optional<llvm::StringRef> maybe_word = IsWord(expr, remainder);
- if (maybe_word) {
- llvm::StringRef word = *maybe_word;
- return Token(Token::identifier, word.str(), position);
- }
+ if (maybe_word)
+ return Token(Token::identifier, maybe_word->str(), position);
constexpr std::pair<Token::Kind, const char *> operators[] = {
{Token::l_paren, "("},
@@ -119,10 +117,8 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
{Token::coloncolon, "::"},
};
for (auto [kind, str] : operators) {
- if (remainder.consume_front(str)) {
- cur_pos += strlen(str);
+ if (remainder.consume_front(str))
return Token(kind, str, position);
- }
}
// Unrecognized character(s) in string; unable to lex it.
diff --git a/lldb/unittests/ValueObject/DILLexerTests.cpp b/lldb/unittests/ValueObject/DILLexerTests.cpp
index f5523d3c5c40684..b6858246b8850ce 100644
--- a/lldb/unittests/ValueObject/DILLexerTests.cpp
+++ b/lldb/unittests/ValueObject/DILLexerTests.cpp
@@ -14,179 +14,145 @@
using llvm::StringRef;
-std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>>
-ExtractTokenData(lldb_private::dil::DILLexer &lexer) {
- std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>> data;
+using namespace lldb_private::dil;
+
+llvm::Expected<std::vector<std::pair<Token::Kind, std::string>>>
+ExtractTokenData(llvm::StringRef input_expr) {
+
+ llvm::Expected<DILLexer> maybe_lexer = DILLexer::Create(input_expr);
+ if (!maybe_lexer)
+ return maybe_lexer.takeError();
+ DILLexer lexer(*maybe_lexer);
+
if (lexer.NumLexedTokens() == 0)
- return data;
+ return llvm::createStringError("No lexed tokens");
lexer.ResetTokenIdx(UINT_MAX);
+ std::vector<std::pair<Token::Kind, std::string>> data;
do {
lexer.Advance();
- lldb_private::dil::Token tok = lexer.GetCurrentToken();
+ Token tok = lexer.GetCurrentToken();
data.push_back(std::make_pair(tok.GetKind(), tok.GetSpelling()));
- } while (data.back().first != lldb_private::dil::Token::eof);
+ } while (data.back().first != Token::eof);
return data;
}
TEST(DILLexerTests, SimpleTest) {
StringRef input_expr("simple_var");
- uint32_t tok_len = 10;
- llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
- lldb_private::dil::DILLexer::Create(input_expr);
+ llvm::Expected<DILLexer> maybe_lexer = DILLexer::Create(input_expr);
ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
- lldb_private::dil::DILLexer lexer(*maybe_lexer);
- lldb_private::dil::Token token =
- lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::unknown);
+ DILLexer lexer(*maybe_lexer);
+ Token token = Token(Token::unknown, "", 0);
+ EXPECT_EQ(token.GetKind(), Token::unknown);
lexer.Advance();
token = lexer.GetCurrentToken();
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(token.GetKind(), Token::identifier);
EXPECT_EQ(token.GetSpelling(), "simple_var");
- EXPECT_EQ(token.GetSpelling().size(), tok_len);
lexer.Advance();
token = lexer.GetCurrentToken();
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
+ EXPECT_EQ(token.GetKind(), Token::eof);
}
TEST(DILLexerTests, TokenKindTest) {
- StringRef input_expr("namespace");
- llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
- lldb_private::dil::DILLexer::Create(input_expr);
- ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
- lldb_private::dil::DILLexer lexer(*maybe_lexer);
- lldb_private::dil::Token token =
- lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
- lexer.Advance();
- token = lexer.GetCurrentToken();
+ Token token = Token(Token::identifier, "ident", 0);
- EXPECT_TRUE(token.Is(lldb_private::dil::Token::identifier));
- EXPECT_FALSE(token.Is(lldb_private::dil::Token::l_paren));
- EXPECT_TRUE(token.IsOneOf(lldb_private::dil::Token::eof,
- lldb_private::dil::Token::identifier));
- EXPECT_FALSE(token.IsOneOf(
- lldb_private::dil::Token::l_paren, lldb_private::dil::Token::r_paren,
- lldb_private::dil::Token::coloncolon, lldb_private::dil::Token::eof));
+ EXPECT_TRUE(token.Is(Token::identifier));
+ EXPECT_FALSE(token.Is(Token::l_paren));
+ EXPECT_TRUE(token.IsOneOf(Token::eof, Token::identifier));
+ EXPECT_FALSE(token.IsOneOf(Token::l_paren, Token::r_paren, Token::coloncolon,
+ Token::eof));
}
TEST(DILLexerTests, LookAheadTest) {
StringRef input_expr("(anonymous namespace)::some_var");
- llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
- lldb_private::dil::DILLexer::Create(input_expr);
+ llvm::Expected<DILLexer> maybe_lexer = DILLexer::Create(input_expr);
ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
- lldb_private::dil::DILLexer lexer(*maybe_lexer);
- lldb_private::dil::Token token =
- lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
- uint32_t expect_loc = 23;
+ DILLexer lexer(*maybe_lexer);
+ Token token = Token(Token::unknown, "", 0);
lexer.Advance();
token = lexer.GetCurrentToken();
// Current token is '('; check the next 4 tokens, to make
// sure they are the identifier 'anonymous', the identifier 'namespace'
// ')' and '::', in that order.
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::l_paren);
- EXPECT_EQ(lexer.LookAhead(1).GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(token.GetKind(), Token::l_paren);
+ EXPECT_EQ(lexer.LookAhead(1).GetKind(), Token::identifier);
EXPECT_EQ(lexer.LookAhead(1).GetSpelling(), "anonymous");
- EXPECT_EQ(lexer.LookAhead(2).GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(lexer.LookAhead(2).GetKind(), Token::identifier);
EXPECT_EQ(lexer.LookAhead(2).GetSpelling(), "namespace");
- EXPECT_EQ(lexer.LookAhead(3).GetKind(), lldb_private::dil::Token::r_paren);
- EXPECT_EQ(lexer.LookAhead(4).GetKind(), lldb_private::dil::Token::coloncolon);
+ EXPECT_EQ(lexer.LookAhead(3).GetKind(), Token::r_paren);
+ EXPECT_EQ(lexer.LookAhead(4).GetKind(), Token::coloncolon);
// Our current index should still be 0, as we only looked ahead; we are still
// officially on the '('.
- EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)0);
+ EXPECT_EQ(lexer.GetCurrentTokenIdx(), 0u);
// Accept the 'lookahead', so our current token is '::', which has the index
// 4 in our vector of tokens (which starts at zero).
lexer.Advance(4);
token = lexer.GetCurrentToken();
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::coloncolon);
- EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)4);
+ EXPECT_EQ(token.GetKind(), Token::coloncolon);
+ EXPECT_EQ(lexer.GetCurrentTokenIdx(), 4u);
lexer.Advance();
token = lexer.GetCurrentToken();
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_EQ(token.GetKind(), Token::identifier);
EXPECT_EQ(token.GetSpelling(), "some_var");
- EXPECT_EQ(lexer.GetCurrentTokenIdx(), (uint32_t)5);
- // Verify we've advanced our position counter (lexing location) in the
- // input 23 characters (the length of '(anonymous namespace)::'.
- EXPECT_EQ(token.GetLocation(), expect_loc);
+ EXPECT_EQ(lexer.GetCurrentTokenIdx(), 5u);
+ EXPECT_EQ(token.GetLocation(), strlen("(anonymous namespace)::"));
lexer.Advance();
token = lexer.GetCurrentToken();
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
+ EXPECT_EQ(token.GetKind(), Token::eof);
}
TEST(DILLexerTests, MultiTokenLexTest) {
- StringRef input_expr("This string has (several ) ::identifiers");
- llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
- lldb_private::dil::DILLexer::Create(input_expr);
- ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
- lldb_private::dil::DILLexer lexer(*maybe_lexer);
- lldb_private::dil::Token token =
- lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
-
- std::vector<std::pair<lldb_private::dil::Token::Kind, std::string>>
- lexer_tokens_data = ExtractTokenData(lexer);
-
- EXPECT_THAT(
- lexer_tokens_data,
- testing::ElementsAre(
- testing::Pair(lldb_private::dil::Token::identifier, "This"),
- testing::Pair(lldb_private::dil::Token::identifier, "string"),
- testing::Pair(lldb_private::dil::Token::identifier, "has"),
- testing::Pair(lldb_private::dil::Token::l_paren, "("),
- testing::Pair(lldb_private::dil::Token::identifier, "several"),
- testing::Pair(lldb_private::dil::Token::r_paren, ")"),
- testing::Pair(lldb_private::dil::Token::coloncolon, "::"),
- testing::Pair(lldb_private::dil::Token::identifier, "identifiers"),
- testing::Pair(lldb_private::dil::Token::eof, "")));
- lexer.Advance();
- token = lexer.GetCurrentToken();
- EXPECT_EQ(token.GetSpelling(), "");
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::eof);
+ EXPECT_THAT_EXPECTED(
+ ExtractTokenData("This string has (several ) ::identifiers"),
+ llvm::HasValue(
+ testing::ElementsAre(testing::Pair(Token::identifier, "This"),
+ testing::Pair(Token::identifier, "string"),
+ testing::Pair(Token::identifier, "has"),
+ testing::Pair(Token::l_paren, "("),
+ testing::Pair(Token::identifier, "several"),
+ testing::Pair(Token::r_paren, ")"),
+ testing::Pair(Token::coloncolon, "::"),
+ testing::Pair(Token::identifier, "identifiers"),
+ testing::Pair(Token::eof, ""))));
}
TEST(DILLexerTests, IdentifiersTest) {
std::vector<std::string> valid_identifiers = {
- "$My_name1", "$pc", "abcd", "ab cd", "_", "_a", "_a_",
- "a_b", "this", "self", "a", "MyName", "namespace"};
+ "$My_name1", "$pc", "abcd", "_", "_a", "_a_",
+ "a_b", "this", "self", "a", "MyName", "namespace"};
std::vector<std::string> invalid_identifiers = {"234", "2a", "2",
"$", "1MyName", ""};
// Verify that all of the valid identifiers come out as identifier tokens.
for (auto &str : valid_identifiers) {
SCOPED_TRACE(str);
- llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
- lldb_private::dil::DILLexer::Create(str);
- ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
- lldb_private::dil::DILLexer lexer(*maybe_lexer);
- lldb_private::dil::Token token =
- lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
- lexer.Advance();
- token = lexer.GetCurrentToken();
- EXPECT_EQ(token.GetKind(), lldb_private::dil::Token::identifier);
+ EXPECT_THAT_EXPECTED(ExtractTokenData(str),
+ llvm::HasValue(testing::ElementsAre(
+ testing::Pair(Token::identifier, str),
+ testing::Pair(Token::eof, ""))));
}
// Verify that none of the invalid identifiers come out as identifier tokens.
for (auto &str : invalid_identifiers) {
SCOPED_TRACE(str);
- llvm::Expected<lldb_private::dil::DILLexer> maybe_lexer =
- lldb_private::dil::DILLexer::Create(str);
+ llvm::Expected<DILLexer> maybe_lexer = DILLexer::Create(str);
if (!maybe_lexer) {
llvm::consumeError(maybe_lexer.takeError());
// In this case, it's ok for lexing to return an error.
} else {
- lldb_private::dil::DILLexer lexer(*maybe_lexer);
- lldb_private::dil::Token token =
- lldb_private::dil::Token(lldb_private::dil::Token::unknown, "", 0);
+ DILLexer lexer(*maybe_lexer);
+ Token token = Token(Token::unknown, "", 0);
// We didn't get an error; make sure we did not get an identifier token.
lexer.Advance();
token = lexer.GetCurrentToken();
- EXPECT_TRUE(token.IsNot(lldb_private::dil::Token::identifier));
- EXPECT_TRUE(token.IsOneOf(lldb_private::dil::Token::unknown,
- lldb_private::dil::Token::eof));
+ EXPECT_TRUE(token.IsNot(Token::identifier));
+ EXPECT_TRUE(token.IsOneOf(Token::unknown, Token::eof));
}
}
}
>From 0b33ab7ea76ef707b26e4359f9fc1336dd703ab0 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Mon, 3 Feb 2025 12:36:26 -0800
Subject: [PATCH 6/8] Address remaining review comments:
- Remove 'unknown' token type.
- Remove UINT_MAX as a valid token index; always start at 0.
- Update IsWord to use Pavel's more efficient StringRef implementation.
- Allow '$' anywhere in an identifer string.
- Adjust unit tests to handle changes mentioned above.
- Clean up test of invalid identifiers (remove if-then-else; split invalid
identifiers from unrecognized strings).
---
lldb/include/lldb/ValueObject/DILLexer.h | 10 +--
lldb/source/ValueObject/DILLexer.cpp | 49 +++----------
lldb/unittests/ValueObject/DILLexerTests.cpp | 74 ++++++++++----------
3 files changed, 50 insertions(+), 83 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 3935bf7e8e5c5ea..3be2533f886a909 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -30,7 +30,6 @@ class Token {
identifier,
l_paren,
r_paren,
- unknown,
};
Token(Kind kind, std::string spelling, uint32_t start)
@@ -72,10 +71,7 @@ class DILLexer {
/// Advance the current token position by N.
void Advance(uint32_t N = 1) {
- // UINT_MAX means uninitialized, no "current" position, so move to start.
- if (m_tokens_idx == UINT_MAX)
- m_tokens_idx = 0;
- else if (m_tokens_idx + N >= m_lexed_tokens.size())
+ if (m_tokens_idx + N >= m_lexed_tokens.size())
// N is too large; advance to the end of the lexed tokens.
m_tokens_idx = m_lexed_tokens.size() - 1;
else
@@ -99,7 +95,7 @@ class DILLexer {
/// to a particular position. Used for either committing 'look ahead' parsing
/// or rolling back tentative parsing.
void ResetTokenIdx(uint32_t new_value) {
- assert(new_value == UINT_MAX || new_value < m_lexed_tokens.size());
+ assert(new_value < m_lexed_tokens.size());
m_tokens_idx = new_value;
}
@@ -108,7 +104,7 @@ class DILLexer {
private:
DILLexer(llvm::StringRef dil_expr, std::vector<Token> lexed_tokens)
: m_expr(dil_expr), m_lexed_tokens(std::move(lexed_tokens)),
- m_tokens_idx(UINT_MAX), m_eof_token(Token(Token::eof, "", 0)) {}
+ m_tokens_idx(0), m_eof_token(Token(Token::eof, "", 0)) {}
static llvm::Expected<Token> Lex(llvm::StringRef expr,
llvm::StringRef &remainder);
diff --git a/lldb/source/ValueObject/DILLexer.cpp b/lldb/source/ValueObject/DILLexer.cpp
index 46ecea9b585f56b..c7acfec347af485 100644
--- a/lldb/source/ValueObject/DILLexer.cpp
+++ b/lldb/source/ValueObject/DILLexer.cpp
@@ -29,8 +29,6 @@ llvm::StringRef Token::GetTokenName(Kind kind) {
return "l_paren";
case Kind::r_paren:
return "r_paren";
- case Kind::unknown:
- return "unknown";
}
}
@@ -44,43 +42,14 @@ static bool IsDigit(char c) { return '0' <= c && c <= '9'; }
// letters ('a'..'z','A'..'Z'), digits ('0'..'9'), and/or underscores.
static std::optional<llvm::StringRef> IsWord(llvm::StringRef expr,
llvm::StringRef &remainder) {
- llvm::StringRef::iterator cur_pos = expr.end() - remainder.size();
- llvm::StringRef::iterator start = cur_pos;
- bool dollar_start = false;
-
- // Must not start with a digit.
- if (cur_pos == expr.end() || IsDigit(*cur_pos))
- return std::nullopt;
-
- // First character *may* be a '$', for a register name or convenience
- // variable.
- if (*cur_pos == '$') {
- dollar_start = true;
- ++cur_pos;
- }
-
- // Contains only letters, digits or underscores
- for (; cur_pos != expr.end(); ++cur_pos) {
- char c = *cur_pos;
- if (!IsLetter(c) && !IsDigit(c) && c != '_')
- break;
- }
-
- // If first char is '$', make sure there's at least one mare char, or it's
- // invalid.
- if (dollar_start && (cur_pos - start <= 1)) {
- cur_pos = start;
- return std::nullopt;
- }
-
- if (cur_pos == start)
+ // Find the longest prefix consisting of letters, digits, underscors and
+ // '$'. If it doesn't start with a digit, then it's a word.
+ llvm::StringRef candidate = remainder.take_while(
+ [](char c) { return IsDigit(c) || IsLetter(c) || c == '_' || c == '$'; });
+ if (candidate.empty() || IsDigit(candidate[0]))
return std::nullopt;
-
- llvm::StringRef word = expr.substr(start - expr.begin(), cur_pos - start);
- if (remainder.consume_front(word))
- return word;
-
- return std::nullopt;
+ remainder = remainder.drop_front(candidate.size());
+ return candidate;
}
llvm::Expected<DILLexer> DILLexer::Create(llvm::StringRef expr) {
@@ -100,10 +69,10 @@ llvm::Expected<Token> DILLexer::Lex(llvm::StringRef expr,
llvm::StringRef &remainder) {
// Skip over whitespace (spaces).
remainder = remainder.ltrim();
- llvm::StringRef::iterator cur_pos = expr.end() - remainder.size();
+ llvm::StringRef::iterator cur_pos = remainder.begin();
// Check to see if we've reached the end of our input string.
- if (remainder.empty() || cur_pos == expr.end())
+ if (remainder.empty())
return Token(Token::eof, "", (uint32_t)expr.size());
uint32_t position = cur_pos - expr.begin();
diff --git a/lldb/unittests/ValueObject/DILLexerTests.cpp b/lldb/unittests/ValueObject/DILLexerTests.cpp
index b6858246b8850ce..e96e82e53d415e3 100644
--- a/lldb/unittests/ValueObject/DILLexerTests.cpp
+++ b/lldb/unittests/ValueObject/DILLexerTests.cpp
@@ -27,13 +27,15 @@ ExtractTokenData(llvm::StringRef input_expr) {
if (lexer.NumLexedTokens() == 0)
return llvm::createStringError("No lexed tokens");
- lexer.ResetTokenIdx(UINT_MAX);
+ lexer.ResetTokenIdx(0);
std::vector<std::pair<Token::Kind, std::string>> data;
do {
- lexer.Advance();
Token tok = lexer.GetCurrentToken();
data.push_back(std::make_pair(tok.GetKind(), tok.GetSpelling()));
+ lexer.Advance();
} while (data.back().first != Token::eof);
+ // Don't return the eof token.
+ data.pop_back();
return data;
}
@@ -42,11 +44,8 @@ TEST(DILLexerTests, SimpleTest) {
llvm::Expected<DILLexer> maybe_lexer = DILLexer::Create(input_expr);
ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
DILLexer lexer(*maybe_lexer);
- Token token = Token(Token::unknown, "", 0);
- EXPECT_EQ(token.GetKind(), Token::unknown);
+ Token token = lexer.GetCurrentToken();
- lexer.Advance();
- token = lexer.GetCurrentToken();
EXPECT_EQ(token.GetKind(), Token::identifier);
EXPECT_EQ(token.GetSpelling(), "simple_var");
lexer.Advance();
@@ -69,9 +68,7 @@ TEST(DILLexerTests, LookAheadTest) {
llvm::Expected<DILLexer> maybe_lexer = DILLexer::Create(input_expr);
ASSERT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
DILLexer lexer(*maybe_lexer);
- Token token = Token(Token::unknown, "", 0);
- lexer.Advance();
- token = lexer.GetCurrentToken();
+ Token token = lexer.GetCurrentToken();
// Current token is '('; check the next 4 tokens, to make
// sure they are the identifier 'anonymous', the identifier 'namespace'
@@ -110,49 +107,54 @@ TEST(DILLexerTests, LookAheadTest) {
TEST(DILLexerTests, MultiTokenLexTest) {
EXPECT_THAT_EXPECTED(
ExtractTokenData("This string has (several ) ::identifiers"),
- llvm::HasValue(
- testing::ElementsAre(testing::Pair(Token::identifier, "This"),
- testing::Pair(Token::identifier, "string"),
- testing::Pair(Token::identifier, "has"),
- testing::Pair(Token::l_paren, "("),
- testing::Pair(Token::identifier, "several"),
- testing::Pair(Token::r_paren, ")"),
- testing::Pair(Token::coloncolon, "::"),
- testing::Pair(Token::identifier, "identifiers"),
- testing::Pair(Token::eof, ""))));
+ llvm::HasValue(testing::ElementsAre(
+ testing::Pair(Token::identifier, "This"),
+ testing::Pair(Token::identifier, "string"),
+ testing::Pair(Token::identifier, "has"),
+ testing::Pair(Token::l_paren, "("),
+ testing::Pair(Token::identifier, "several"),
+ testing::Pair(Token::r_paren, ")"),
+ testing::Pair(Token::coloncolon, "::"),
+ testing::Pair(Token::identifier, "identifiers"))));
}
TEST(DILLexerTests, IdentifiersTest) {
+ // These strings should lex into identifier tokens.
std::vector<std::string> valid_identifiers = {
- "$My_name1", "$pc", "abcd", "_", "_a", "_a_",
+ "$My_name1", "$pc", "abcd", "_", "_a", "_a_", "$",
"a_b", "this", "self", "a", "MyName", "namespace"};
- std::vector<std::string> invalid_identifiers = {"234", "2a", "2",
- "$", "1MyName", ""};
+
+ // The lexer can lex these strings, but they should not be identifiers.
+ std::vector<std::string> invalid_identifiers = {"", "::", "(", ")"};
+
+ // The lexer is expected to fail attempting to lex these strings (it cannot
+ // create valid tokens out of them).
+ std::vector<std::string> invalid_tok_strings = {"234", "2a", "2", "1MyName"};
// Verify that all of the valid identifiers come out as identifier tokens.
for (auto &str : valid_identifiers) {
SCOPED_TRACE(str);
EXPECT_THAT_EXPECTED(ExtractTokenData(str),
llvm::HasValue(testing::ElementsAre(
- testing::Pair(Token::identifier, str),
- testing::Pair(Token::eof, ""))));
+ testing::Pair(Token::identifier, str))));
+ }
+
+ // Verify that the lexer fails on invalid token strings.
+ for (auto &str : invalid_tok_strings) {
+ SCOPED_TRACE(str);
+ auto maybe_lexer = DILLexer::Create(str);
+ EXPECT_THAT_EXPECTED(maybe_lexer, llvm::Failed());
}
// Verify that none of the invalid identifiers come out as identifier tokens.
for (auto &str : invalid_identifiers) {
SCOPED_TRACE(str);
llvm::Expected<DILLexer> maybe_lexer = DILLexer::Create(str);
- if (!maybe_lexer) {
- llvm::consumeError(maybe_lexer.takeError());
- // In this case, it's ok for lexing to return an error.
- } else {
- DILLexer lexer(*maybe_lexer);
- Token token = Token(Token::unknown, "", 0);
- // We didn't get an error; make sure we did not get an identifier token.
- lexer.Advance();
- token = lexer.GetCurrentToken();
- EXPECT_TRUE(token.IsNot(Token::identifier));
- EXPECT_TRUE(token.IsOneOf(Token::unknown, Token::eof));
- }
+ EXPECT_THAT_EXPECTED(maybe_lexer, llvm::Succeeded());
+ DILLexer lexer(*maybe_lexer);
+ Token token = lexer.GetCurrentToken();
+ EXPECT_TRUE(token.IsNot(Token::identifier));
+ EXPECT_TRUE(token.IsOneOf(Token::eof, Token::coloncolon, Token::l_paren,
+ Token::r_paren));
}
}
>From 4103144dcbdb3c1cff9dca5806c855aa093250e1 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Tue, 4 Feb 2025 08:50:07 -0800
Subject: [PATCH 7/8] Remove trailing '_' from LLDB_VALUEOBJECT_DILLEXER_H
---
lldb/include/lldb/ValueObject/DILLexer.h | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
index 3be2533f886a909..fa0b5338834d786 100644
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ b/lldb/include/lldb/ValueObject/DILLexer.h
@@ -6,11 +6,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_VALUEOBJECT_DILLEXER_H_
-#define LLDB_VALUEOBJECT_DILLEXER_H_
+#ifndef LLDB_VALUEOBJECT_DILLEXER_H
+#define LLDB_VALUEOBJECT_DILLEXER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <limits.h>
@@ -125,4 +124,4 @@ class DILLexer {
} // namespace lldb_private::dil
-#endif // LLDB_VALUEOBJECT_DILLEXER_H_
+#endif // LLDB_VALUEOBJECT_DILLEXER_H
>From 29ad86c7f6ffc48f9574813cbc413e33862b9bfa Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Tue, 4 Feb 2025 09:52:34 -0800
Subject: [PATCH 8/8] Clearing the git cache.
---
lldb/include/lldb/ValueObject/DILLexer.h | 127 --
lldb/include/lldb/ValueObject/ValueObject.h | 1103 -----------------
.../lldb/ValueObject/ValueObjectCast.h | 66 -
.../lldb/ValueObject/ValueObjectChild.h | 91 --
.../lldb/ValueObject/ValueObjectConstResult.h | 166 ---
.../ValueObject/ValueObjectConstResultCast.h | 75 --
.../ValueObject/ValueObjectConstResultChild.h | 81 --
.../ValueObject/ValueObjectConstResultImpl.h | 80 --
.../ValueObject/ValueObjectDynamicValue.h | 129 --
.../lldb/ValueObject/ValueObjectList.h | 63 -
.../lldb/ValueObject/ValueObjectMemory.h | 82 --
.../lldb/ValueObject/ValueObjectRegister.h | 143 ---
.../ValueObject/ValueObjectSyntheticFilter.h | 179 ---
.../lldb/ValueObject/ValueObjectUpdater.h | 43 -
.../lldb/ValueObject/ValueObjectVTable.h | 107 --
.../lldb/ValueObject/ValueObjectVariable.h | 93 --
16 files changed, 2628 deletions(-)
delete mode 100644 lldb/include/lldb/ValueObject/DILLexer.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObject.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectCast.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectChild.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectConstResult.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectConstResultCast.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectConstResultChild.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectDynamicValue.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectList.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectMemory.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectRegister.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectSyntheticFilter.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectUpdater.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectVTable.h
delete mode 100644 lldb/include/lldb/ValueObject/ValueObjectVariable.h
diff --git a/lldb/include/lldb/ValueObject/DILLexer.h b/lldb/include/lldb/ValueObject/DILLexer.h
deleted file mode 100644
index fa0b5338834d786..000000000000000
--- a/lldb/include/lldb/ValueObject/DILLexer.h
+++ /dev/null
@@ -1,127 +0,0 @@
-//===-- 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 "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <limits.h>
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace lldb_private::dil {
-
-/// Class defining the tokens generated by the DIL lexer and used by the
-/// DIL parser.
-class Token {
-public:
- enum Kind {
- coloncolon,
- eof,
- identifier,
- l_paren,
- r_paren,
- };
-
- Token(Kind kind, std::string spelling, uint32_t start)
- : m_kind(kind), m_spelling(std::move(spelling)), m_start_pos(start) {}
-
- Kind GetKind() const { return m_kind; }
-
- std::string GetSpelling() const { return m_spelling; }
-
- bool Is(Kind kind) const { return m_kind == kind; }
-
- bool IsNot(Kind kind) const { return m_kind != kind; }
-
- bool IsOneOf(Kind kind1, Kind kind2) const { return Is(kind1) || Is(kind2); }
-
- template <typename... Ts> bool IsOneOf(Kind kind, Ts... Ks) const {
- return Is(kind) || IsOneOf(Ks...);
- }
-
- uint32_t GetLocation() const { return m_start_pos; }
-
- static llvm::StringRef GetTokenName(Kind kind);
-
-private:
- Kind m_kind;
- std::string m_spelling;
- uint32_t m_start_pos; // within entire expression string
-};
-
-/// Class for doing the simple lexing required by DIL.
-class DILLexer {
-public:
- /// Lexes all the tokens in expr and calls the private constructor
- /// with the lexed tokens.
- static llvm::Expected<DILLexer> Create(llvm::StringRef expr);
-
- /// Return the current token to be handled by the DIL parser.
- const Token &GetCurrentToken() { return m_lexed_tokens[m_tokens_idx]; }
-
- /// Advance the current token position by N.
- void Advance(uint32_t N = 1) {
- if (m_tokens_idx + N >= m_lexed_tokens.size())
- // N is too large; advance to the end of the lexed tokens.
- m_tokens_idx = m_lexed_tokens.size() - 1;
- else
- m_tokens_idx += N;
- }
-
- /// Return the lexed token N positions ahead of the 'current' token
- /// being handled by the DIL parser.
- const Token &LookAhead(uint32_t N) {
- if (m_tokens_idx + N < m_lexed_tokens.size())
- return m_lexed_tokens[m_tokens_idx + N];
-
- // Last token should be an 'eof' token.
- return m_lexed_tokens.back();
- }
-
- /// Return the index for the 'current' token being handled by the DIL parser.
- uint32_t GetCurrentTokenIdx() { return m_tokens_idx; }
-
- /// 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.
- void ResetTokenIdx(uint32_t new_value) {
- assert(new_value < m_lexed_tokens.size());
- m_tokens_idx = new_value;
- }
-
- uint32_t NumLexedTokens() { return m_lexed_tokens.size(); }
-
-private:
- DILLexer(llvm::StringRef dil_expr, std::vector<Token> lexed_tokens)
- : m_expr(dil_expr), m_lexed_tokens(std::move(lexed_tokens)),
- m_tokens_idx(0), m_eof_token(Token(Token::eof, "", 0)) {}
-
- static llvm::Expected<Token> Lex(llvm::StringRef expr,
- llvm::StringRef &remainder);
-
- // The input string we are lexing & parsing.
- llvm::StringRef m_expr;
-
- // Holds all of the tokens lexed so far.
- std::vector<Token> 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;
-
- // "eof" token; to be returned by lexer when 'look ahead' fails.
- Token m_eof_token;
-};
-
-} // namespace lldb_private::dil
-
-#endif // LLDB_VALUEOBJECT_DILLEXER_H
diff --git a/lldb/include/lldb/ValueObject/ValueObject.h b/lldb/include/lldb/ValueObject/ValueObject.h
deleted file mode 100644
index 4f77384bb8f1361..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObject.h
+++ /dev/null
@@ -1,1103 +0,0 @@
-//===-- ValueObject.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_VALUEOBJECT_H
-#define LLDB_VALUEOBJECT_VALUEOBJECT_H
-
-#include "lldb/Core/Value.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/SharedCluster.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/UserID.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private-enumerations.h"
-#include "lldb/lldb-types.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-
-#include <functional>
-#include <initializer_list>
-#include <map>
-#include <mutex>
-#include <optional>
-#include <string>
-#include <utility>
-
-#include <cstddef>
-#include <cstdint>
-
-namespace lldb_private {
-class Declaration;
-class DumpValueObjectOptions;
-class EvaluateExpressionOptions;
-class ExecutionContextScope;
-class Log;
-class Scalar;
-class Stream;
-class SymbolContextScope;
-class TypeFormatImpl;
-class TypeSummaryImpl;
-class TypeSummaryOptions;
-
-/// ValueObject:
-///
-/// This abstract class provides an interface to a particular value, be it a
-/// register, a local or global variable,
-/// that is evaluated in some particular scope. The ValueObject also has the
-/// capability of being the "child" of
-/// some other variable object, and in turn of having children.
-/// If a ValueObject is a root variable object - having no parent - then it must
-/// be constructed with respect to some
-/// particular ExecutionContextScope. If it is a child, it inherits the
-/// ExecutionContextScope from its parent.
-/// The ValueObject will update itself if necessary before fetching its value,
-/// summary, object description, etc.
-/// But it will always update itself in the ExecutionContextScope with which it
-/// was originally created.
-
-/// A brief note on life cycle management for ValueObjects. This is a little
-/// tricky because a ValueObject can contain
-/// various other ValueObjects - the Dynamic Value, its children, the
-/// dereference value, etc. Any one of these can be
-/// handed out as a shared pointer, but for that contained value object to be
-/// valid, the root object and potentially other
-/// of the value objects need to stay around.
-/// We solve this problem by handing out shared pointers to the Value Object and
-/// any of its dependents using a shared
-/// ClusterManager. This treats each shared pointer handed out for the entire
-/// cluster as a reference to the whole
-/// cluster. The whole cluster will stay around until the last reference is
-/// released.
-///
-/// The ValueObject mostly handle this automatically, if a value object is made
-/// with a Parent ValueObject, then it adds
-/// itself to the ClusterManager of the parent.
-
-/// It does mean that external to the ValueObjects we should only ever make
-/// available ValueObjectSP's, never ValueObjects
-/// or pointers to them. So all the "Root level" ValueObject derived
-/// constructors should be private, and
-/// should implement a Create function that new's up object and returns a Shared
-/// Pointer that it gets from the GetSP() method.
-///
-/// However, if you are making an derived ValueObject that will be contained in
-/// a parent value object, you should just
-/// hold onto a pointer to it internally, and by virtue of passing the parent
-/// ValueObject into its constructor, it will
-/// be added to the ClusterManager for the parent. Then if you ever hand out a
-/// Shared Pointer to the contained ValueObject,
-/// just do so by calling GetSP() on the contained object.
-
-class ValueObject {
-public:
- enum GetExpressionPathFormat {
- eGetExpressionPathFormatDereferencePointers = 1,
- eGetExpressionPathFormatHonorPointers
- };
-
- enum ValueObjectRepresentationStyle {
- eValueObjectRepresentationStyleValue = 1,
- eValueObjectRepresentationStyleSummary,
- eValueObjectRepresentationStyleLanguageSpecific,
- eValueObjectRepresentationStyleLocation,
- eValueObjectRepresentationStyleChildrenCount,
- eValueObjectRepresentationStyleType,
- eValueObjectRepresentationStyleName,
- eValueObjectRepresentationStyleExpressionPath
- };
-
- enum ExpressionPathScanEndReason {
- /// Out of data to parse.
- eExpressionPathScanEndReasonEndOfString = 1,
- /// Child element not found.
- eExpressionPathScanEndReasonNoSuchChild,
- /// (Synthetic) child element not found.
- eExpressionPathScanEndReasonNoSuchSyntheticChild,
- /// [] only allowed for arrays.
- eExpressionPathScanEndReasonEmptyRangeNotAllowed,
- /// . used when -> should be used.
- eExpressionPathScanEndReasonDotInsteadOfArrow,
- /// -> used when . should be used.
- eExpressionPathScanEndReasonArrowInsteadOfDot,
- /// ObjC ivar expansion not allowed.
- eExpressionPathScanEndReasonFragileIVarNotAllowed,
- /// [] not allowed by options.
- eExpressionPathScanEndReasonRangeOperatorNotAllowed,
- /// [] not valid on objects other than scalars, pointers or arrays.
- eExpressionPathScanEndReasonRangeOperatorInvalid,
- /// [] is good for arrays, but I cannot parse it.
- eExpressionPathScanEndReasonArrayRangeOperatorMet,
- /// [] is good for bitfields, but I cannot parse after it.
- eExpressionPathScanEndReasonBitfieldRangeOperatorMet,
- /// Something is malformed in he expression.
- eExpressionPathScanEndReasonUnexpectedSymbol,
- /// Impossible to apply & operator.
- eExpressionPathScanEndReasonTakingAddressFailed,
- /// Impossible to apply * operator.
- eExpressionPathScanEndReasonDereferencingFailed,
- /// [] was expanded into a VOList.
- eExpressionPathScanEndReasonRangeOperatorExpanded,
- /// getting the synthetic children failed.
- eExpressionPathScanEndReasonSyntheticValueMissing,
- eExpressionPathScanEndReasonUnknown = 0xFFFF
- };
-
- enum ExpressionPathEndResultType {
- /// Anything but...
- eExpressionPathEndResultTypePlain = 1,
- /// A bitfield.
- eExpressionPathEndResultTypeBitfield,
- /// A range [low-high].
- eExpressionPathEndResultTypeBoundedRange,
- /// A range [].
- eExpressionPathEndResultTypeUnboundedRange,
- /// Several items in a VOList.
- eExpressionPathEndResultTypeValueObjectList,
- eExpressionPathEndResultTypeInvalid = 0xFFFF
- };
-
- enum ExpressionPathAftermath {
- /// Just return it.
- eExpressionPathAftermathNothing = 1,
- /// Dereference the target.
- eExpressionPathAftermathDereference,
- /// Take target's address.
- eExpressionPathAftermathTakeAddress
- };
-
- enum ClearUserVisibleDataItems {
- eClearUserVisibleDataItemsNothing = 1u << 0,
- eClearUserVisibleDataItemsValue = 1u << 1,
- eClearUserVisibleDataItemsSummary = 1u << 2,
- eClearUserVisibleDataItemsLocation = 1u << 3,
- eClearUserVisibleDataItemsDescription = 1u << 4,
- eClearUserVisibleDataItemsSyntheticChildren = 1u << 5,
- eClearUserVisibleDataItemsAllStrings =
- eClearUserVisibleDataItemsValue | eClearUserVisibleDataItemsSummary |
- eClearUserVisibleDataItemsLocation |
- eClearUserVisibleDataItemsDescription,
- eClearUserVisibleDataItemsAll = 0xFFFF
- };
-
- struct GetValueForExpressionPathOptions {
- enum class SyntheticChildrenTraversal {
- None,
- ToSynthetic,
- FromSynthetic,
- Both
- };
-
- bool m_check_dot_vs_arrow_syntax;
- bool m_no_fragile_ivar;
- bool m_allow_bitfields_syntax;
- SyntheticChildrenTraversal m_synthetic_children_traversal;
-
- GetValueForExpressionPathOptions(
- bool dot = false, bool no_ivar = false, bool bitfield = true,
- SyntheticChildrenTraversal synth_traverse =
- SyntheticChildrenTraversal::ToSynthetic)
- : m_check_dot_vs_arrow_syntax(dot), m_no_fragile_ivar(no_ivar),
- m_allow_bitfields_syntax(bitfield),
- m_synthetic_children_traversal(synth_traverse) {}
-
- GetValueForExpressionPathOptions &DoCheckDotVsArrowSyntax() {
- m_check_dot_vs_arrow_syntax = true;
- return *this;
- }
-
- GetValueForExpressionPathOptions &DontCheckDotVsArrowSyntax() {
- m_check_dot_vs_arrow_syntax = false;
- return *this;
- }
-
- GetValueForExpressionPathOptions &DoAllowFragileIVar() {
- m_no_fragile_ivar = false;
- return *this;
- }
-
- GetValueForExpressionPathOptions &DontAllowFragileIVar() {
- m_no_fragile_ivar = true;
- return *this;
- }
-
- GetValueForExpressionPathOptions &DoAllowBitfieldSyntax() {
- m_allow_bitfields_syntax = true;
- return *this;
- }
-
- GetValueForExpressionPathOptions &DontAllowBitfieldSyntax() {
- m_allow_bitfields_syntax = false;
- return *this;
- }
-
- GetValueForExpressionPathOptions &
- SetSyntheticChildrenTraversal(SyntheticChildrenTraversal traverse) {
- m_synthetic_children_traversal = traverse;
- return *this;
- }
-
- static const GetValueForExpressionPathOptions DefaultOptions() {
- static GetValueForExpressionPathOptions g_default_options;
-
- return g_default_options;
- }
- };
-
- class EvaluationPoint {
- public:
- EvaluationPoint();
-
- EvaluationPoint(ExecutionContextScope *exe_scope,
- bool use_selected = false);
-
- EvaluationPoint(const EvaluationPoint &rhs);
-
- ~EvaluationPoint();
-
- const ExecutionContextRef &GetExecutionContextRef() const {
- return m_exe_ctx_ref;
- }
-
- void SetIsConstant() {
- SetUpdated();
- m_mod_id.SetInvalid();
- }
-
- bool IsConstant() const { return !m_mod_id.IsValid(); }
-
- ProcessModID GetModID() const { return m_mod_id; }
-
- void SetUpdateID(ProcessModID new_id) { m_mod_id = new_id; }
-
- void SetNeedsUpdate() { m_needs_update = true; }
-
- void SetUpdated();
-
- bool NeedsUpdating(bool accept_invalid_exe_ctx) {
- SyncWithProcessState(accept_invalid_exe_ctx);
- return m_needs_update;
- }
-
- bool IsValid() {
- const bool accept_invalid_exe_ctx = false;
- if (!m_mod_id.IsValid())
- return false;
- else if (SyncWithProcessState(accept_invalid_exe_ctx)) {
- if (!m_mod_id.IsValid())
- return false;
- }
- return true;
- }
-
- void SetInvalid() {
- // Use the stop id to mark us as invalid, leave the thread id and the
- // stack id around for logging and history purposes.
- m_mod_id.SetInvalid();
-
- // Can't update an invalid state.
- m_needs_update = false;
- }
-
- private:
- bool SyncWithProcessState(bool accept_invalid_exe_ctx);
-
- ProcessModID m_mod_id; // This is the stop id when this ValueObject was last
- // evaluated.
- ExecutionContextRef m_exe_ctx_ref;
- bool m_needs_update = true;
- };
-
- virtual ~ValueObject();
-
- const EvaluationPoint &GetUpdatePoint() const { return m_update_point; }
-
- EvaluationPoint &GetUpdatePoint() { return m_update_point; }
-
- const ExecutionContextRef &GetExecutionContextRef() const {
- return m_update_point.GetExecutionContextRef();
- }
-
- lldb::TargetSP GetTargetSP() const {
- return m_update_point.GetExecutionContextRef().GetTargetSP();
- }
-
- lldb::ProcessSP GetProcessSP() const {
- return m_update_point.GetExecutionContextRef().GetProcessSP();
- }
-
- lldb::ThreadSP GetThreadSP() const {
- return m_update_point.GetExecutionContextRef().GetThreadSP();
- }
-
- lldb::StackFrameSP GetFrameSP() const {
- return m_update_point.GetExecutionContextRef().GetFrameSP();
- }
-
- void SetNeedsUpdate();
-
- CompilerType GetCompilerType() { return MaybeCalculateCompleteType(); }
-
- // this vends a TypeImpl that is useful at the SB API layer
- virtual TypeImpl GetTypeImpl() { return TypeImpl(GetCompilerType()); }
-
- virtual bool CanProvideValue();
-
- // Subclasses must implement the functions below.
- virtual std::optional<uint64_t> GetByteSize() = 0;
-
- virtual lldb::ValueType GetValueType() const = 0;
-
- // Subclasses can implement the functions below.
- virtual ConstString GetTypeName() { return GetCompilerType().GetTypeName(); }
-
- virtual ConstString GetDisplayTypeName() { return GetTypeName(); }
-
- virtual ConstString GetQualifiedTypeName() {
- return GetCompilerType().GetTypeName();
- }
-
- lldb::LanguageType GetObjectRuntimeLanguage() {
- return GetCompilerType().GetMinimumLanguage();
- }
-
- uint32_t
- GetTypeInfo(CompilerType *pointee_or_element_compiler_type = nullptr) {
- return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
- }
-
- bool IsPointerType() { return GetCompilerType().IsPointerType(); }
-
- bool IsArrayType() { return GetCompilerType().IsArrayType(); }
-
- bool IsScalarType() { return GetCompilerType().IsScalarType(); }
-
- bool IsPointerOrReferenceType() {
- return GetCompilerType().IsPointerOrReferenceType();
- }
-
- bool IsPossibleDynamicType();
-
- bool IsNilReference();
-
- bool IsUninitializedReference();
-
- virtual bool IsBaseClass() { return false; }
-
- bool IsBaseClass(uint32_t &depth);
-
- virtual bool IsDereferenceOfParent() { return false; }
-
- bool IsIntegerType(bool &is_signed) {
- return GetCompilerType().IsIntegerType(is_signed);
- }
-
- virtual void GetExpressionPath(
- Stream &s,
- GetExpressionPathFormat = eGetExpressionPathFormatDereferencePointers);
-
- lldb::ValueObjectSP GetValueForExpressionPath(
- llvm::StringRef expression,
- ExpressionPathScanEndReason *reason_to_stop = nullptr,
- ExpressionPathEndResultType *final_value_type = nullptr,
- const GetValueForExpressionPathOptions &options =
- GetValueForExpressionPathOptions::DefaultOptions(),
- ExpressionPathAftermath *final_task_on_target = nullptr);
-
- virtual bool IsInScope() { return true; }
-
- virtual lldb::offset_t GetByteOffset() { return 0; }
-
- virtual uint32_t GetBitfieldBitSize() { return 0; }
-
- virtual uint32_t GetBitfieldBitOffset() { return 0; }
-
- bool IsBitfield() {
- return (GetBitfieldBitSize() != 0) || (GetBitfieldBitOffset() != 0);
- }
-
- virtual const char *GetValueAsCString();
-
- virtual bool GetValueAsCString(const lldb_private::TypeFormatImpl &format,
- std::string &destination);
-
- bool GetValueAsCString(lldb::Format format, std::string &destination);
-
- virtual uint64_t GetValueAsUnsigned(uint64_t fail_value,
- bool *success = nullptr);
-
- virtual int64_t GetValueAsSigned(int64_t fail_value, bool *success = nullptr);
-
- /// If the current ValueObject is of an appropriate type, convert the
- /// value to an APSInt and return that. Otherwise return an error.
- llvm::Expected<llvm::APSInt> GetValueAsAPSInt();
-
- /// If the current ValueObject is of an appropriate type, convert the
- /// value to an APFloat and return that. Otherwise return an error.
- llvm::Expected<llvm::APFloat> GetValueAsAPFloat();
-
- /// If the current ValueObject is of an appropriate type, convert the
- /// value to a boolean and return that. Otherwise return an error.
- llvm::Expected<bool> GetValueAsBool();
-
- /// Update an existing integer ValueObject with a new integer value. This
- /// is only intended to be used with 'temporary' ValueObjects, i.e. ones that
- /// are not associated with program variables. It does not update program
- /// memory, registers, stack, etc.
- void SetValueFromInteger(const llvm::APInt &value, Status &error);
-
- /// Update an existing integer ValueObject with an integer value created
- /// frome 'new_val_sp'. This is only intended to be used with 'temporary'
- /// ValueObjects, i.e. ones that are not associated with program variables.
- /// It does not update program memory, registers, stack, etc.
- void SetValueFromInteger(lldb::ValueObjectSP new_val_sp, Status &error);
-
- virtual bool SetValueFromCString(const char *value_str, Status &error);
-
- /// Return the module associated with this value object in case the value is
- /// from an executable file and might have its data in sections of the file.
- /// This can be used for variables.
- virtual lldb::ModuleSP GetModule();
-
- ValueObject *GetRoot();
-
- /// Given a ValueObject, loop over itself and its parent, and its parent's
- /// parent, .. until either the given callback returns false, or you end up at
- /// a null pointer
- ValueObject *FollowParentChain(std::function<bool(ValueObject *)>);
-
- virtual bool GetDeclaration(Declaration &decl);
-
- // The functions below should NOT be modified by subclasses
- const Status &GetError();
-
- ConstString GetName() const { return m_name; }
-
- /// Returns a unique id for this ValueObject.
- lldb::user_id_t GetID() const { return m_id.GetID(); }
-
- virtual lldb::ValueObjectSP GetChildAtIndex(uint32_t idx,
- bool can_create = true);
-
- // The method always creates missing children in the path, if necessary.
- lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef<llvm::StringRef> names);
-
- virtual lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name,
- bool can_create = true);
-
- virtual size_t GetIndexOfChildWithName(llvm::StringRef name);
-
- llvm::Expected<uint32_t> GetNumChildren(uint32_t max = UINT32_MAX);
- /// Like \c GetNumChildren but returns 0 on error. You probably
- /// shouldn't be using this function. It exists primarily to ease the
- /// transition to more pervasive error handling while not all APIs
- /// have been updated.
- uint32_t GetNumChildrenIgnoringErrors(uint32_t max = UINT32_MAX);
- bool HasChildren() { return GetNumChildrenIgnoringErrors() > 0; }
-
- const Value &GetValue() const { return m_value; }
-
- Value &GetValue() { return m_value; }
-
- virtual bool ResolveValue(Scalar &scalar);
-
- // return 'false' whenever you set the error, otherwise callers may assume
- // true means everything is OK - this will break breakpoint conditions among
- // potentially a few others
- virtual bool IsLogicalTrue(Status &error);
-
- virtual const char *GetLocationAsCString() {
- return GetLocationAsCStringImpl(m_value, m_data);
- }
-
- const char *
- GetSummaryAsCString(lldb::LanguageType lang = lldb::eLanguageTypeUnknown);
-
- bool
- GetSummaryAsCString(TypeSummaryImpl *summary_ptr, std::string &destination,
- lldb::LanguageType lang = lldb::eLanguageTypeUnknown);
-
- bool GetSummaryAsCString(std::string &destination,
- const TypeSummaryOptions &options);
-
- bool GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
- std::string &destination,
- const TypeSummaryOptions &options);
-
- llvm::Expected<std::string> GetObjectDescription();
-
- bool HasSpecialPrintableRepresentation(
- ValueObjectRepresentationStyle val_obj_display,
- lldb::Format custom_format);
-
- enum class PrintableRepresentationSpecialCases : bool {
- eDisable = false,
- eAllow = true
- };
-
- bool
- DumpPrintableRepresentation(Stream &s,
- ValueObjectRepresentationStyle val_obj_display =
- eValueObjectRepresentationStyleSummary,
- lldb::Format custom_format = lldb::eFormatInvalid,
- PrintableRepresentationSpecialCases special =
- PrintableRepresentationSpecialCases::eAllow,
- bool do_dump_error = true);
- bool GetValueIsValid() const { return m_flags.m_value_is_valid; }
-
- // If you call this on a newly created ValueObject, it will always return
- // false.
- bool GetValueDidChange() { return m_flags.m_value_did_change; }
-
- bool UpdateValueIfNeeded(bool update_format = true);
-
- bool UpdateFormatsIfNeeded();
-
- lldb::ValueObjectSP GetSP() { return m_manager->GetSharedPointer(this); }
-
- /// Change the name of the current ValueObject. Should *not* be used from a
- /// synthetic child provider as it would change the name of the non synthetic
- /// child as well.
- void SetName(ConstString name) { m_name = name; }
-
- virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
- AddressType *address_type = nullptr);
-
- lldb::addr_t GetPointerValue(AddressType *address_type = nullptr);
-
- lldb::ValueObjectSP GetSyntheticChild(ConstString key) const;
-
- lldb::ValueObjectSP GetSyntheticArrayMember(size_t index, bool can_create);
-
- lldb::ValueObjectSP GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
- bool can_create);
-
- lldb::ValueObjectSP GetSyntheticExpressionPathChild(const char *expression,
- bool can_create);
-
- virtual lldb::ValueObjectSP
- GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type,
- bool can_create,
- ConstString name_const_str = ConstString());
-
- virtual lldb::ValueObjectSP
- GetSyntheticBase(uint32_t offset, const CompilerType &type, bool can_create,
- ConstString name_const_str = ConstString());
-
- virtual lldb::ValueObjectSP GetDynamicValue(lldb::DynamicValueType valueType);
-
- lldb::DynamicValueType GetDynamicValueType();
-
- virtual lldb::ValueObjectSP GetStaticValue() { return GetSP(); }
-
- virtual lldb::ValueObjectSP GetNonSyntheticValue() { return GetSP(); }
-
- lldb::ValueObjectSP GetSyntheticValue();
-
- virtual bool HasSyntheticValue();
-
- virtual bool IsSynthetic() { return false; }
-
- lldb::ValueObjectSP
- GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue,
- bool synthValue);
-
- virtual lldb::ValueObjectSP CreateConstantValue(ConstString name);
-
- virtual lldb::ValueObjectSP Dereference(Status &error);
-
- /// Creates a copy of the ValueObject with a new name and setting the current
- /// ValueObject as its parent. It should be used when we want to change the
- /// name of a ValueObject without modifying the actual ValueObject itself
- /// (e.g. sythetic child provider).
- virtual lldb::ValueObjectSP Clone(ConstString new_name);
-
- virtual lldb::ValueObjectSP AddressOf(Status &error);
-
- virtual lldb::addr_t GetLiveAddress() { return LLDB_INVALID_ADDRESS; }
-
- virtual void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
- AddressType address_type = eAddressTypeLoad) {}
-
- lldb::ValueObjectSP Cast(const CompilerType &compiler_type);
-
- virtual lldb::ValueObjectSP DoCast(const CompilerType &compiler_type);
-
- virtual lldb::ValueObjectSP CastPointerType(const char *name,
- CompilerType &ast_type);
-
- virtual lldb::ValueObjectSP CastPointerType(const char *name,
- lldb::TypeSP &type_sp);
-
- /// Return the target load address associated with this value object.
- lldb::addr_t GetLoadAddress();
-
- /// Take a ValueObject whose type is an inherited class, and cast it to
- /// 'type', which should be one of its base classes. 'base_type_indices'
- /// contains the indices of direct base classes on the path from the
- /// ValueObject's current type to 'type'
- llvm::Expected<lldb::ValueObjectSP>
- CastDerivedToBaseType(CompilerType type,
- const llvm::ArrayRef<uint32_t> &base_type_indices);
-
- /// Take a ValueObject whose type is a base class, and cast it to 'type',
- /// which should be one of its derived classes. 'base_type_indices'
- /// contains the indices of direct base classes on the path from the
- /// ValueObject's current type to 'type'
- llvm::Expected<lldb::ValueObjectSP> CastBaseToDerivedType(CompilerType type,
- uint64_t offset);
-
- // Take a ValueObject that contains a scalar, enum or pointer type, and
- // cast it to a "basic" type (integer, float or boolean).
- lldb::ValueObjectSP CastToBasicType(CompilerType type);
-
- // Take a ValueObject that contain an integer, float or enum, and cast it
- // to an enum.
- lldb::ValueObjectSP CastToEnumType(CompilerType type);
-
- /// If this object represents a C++ class with a vtable, return an object
- /// that represents the virtual function table. If the object isn't a class
- /// with a vtable, return a valid ValueObject with the error set correctly.
- lldb::ValueObjectSP GetVTable();
- // The backing bits of this value object were updated, clear any descriptive
- // string, so we know we have to refetch them.
- void ValueUpdated() {
- ClearUserVisibleData(eClearUserVisibleDataItemsValue |
- eClearUserVisibleDataItemsSummary |
- eClearUserVisibleDataItemsDescription);
- }
-
- virtual bool IsDynamic() { return false; }
-
- virtual bool DoesProvideSyntheticValue() { return false; }
-
- virtual bool IsSyntheticChildrenGenerated() {
- return m_flags.m_is_synthetic_children_generated;
- }
-
- virtual void SetSyntheticChildrenGenerated(bool b) {
- m_flags.m_is_synthetic_children_generated = b;
- }
-
- virtual SymbolContextScope *GetSymbolContextScope();
-
- llvm::Error Dump(Stream &s);
-
- llvm::Error Dump(Stream &s, const DumpValueObjectOptions &options);
-
- static lldb::ValueObjectSP
- CreateValueObjectFromExpression(llvm::StringRef name,
- llvm::StringRef expression,
- const ExecutionContext &exe_ctx);
-
- static lldb::ValueObjectSP
- CreateValueObjectFromExpression(llvm::StringRef name,
- llvm::StringRef expression,
- const ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options);
-
- /// Given an address either create a value object containing the value at
- /// that address, or create a value object containing the address itself
- /// (pointer value), depending on whether the parameter 'do_deref' is true or
- /// false.
- static lldb::ValueObjectSP
- CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
- const ExecutionContext &exe_ctx,
- CompilerType type, bool do_deref = true);
-
- static lldb::ValueObjectSP
- CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data,
- const ExecutionContext &exe_ctx, CompilerType type);
-
- /// Create a value object containing the given APInt value.
- static lldb::ValueObjectSP CreateValueObjectFromAPInt(lldb::TargetSP target,
- const llvm::APInt &v,
- CompilerType type,
- llvm::StringRef name);
-
- /// Create a value object containing the given APFloat value.
- static lldb::ValueObjectSP
- CreateValueObjectFromAPFloat(lldb::TargetSP target, const llvm::APFloat &v,
- CompilerType type, llvm::StringRef name);
-
- /// Create a value object containing the given boolean value.
- static lldb::ValueObjectSP CreateValueObjectFromBool(lldb::TargetSP target,
- bool value,
- llvm::StringRef name);
-
- /// Create a nullptr value object with the specified type (must be a
- /// nullptr type).
- static lldb::ValueObjectSP CreateValueObjectFromNullptr(lldb::TargetSP target,
- CompilerType type,
- llvm::StringRef name);
-
- lldb::ValueObjectSP Persist();
-
- /// Returns true if this is a char* or a char[] if it is a char* and
- /// check_pointer is true, it also checks that the pointer is valid.
- bool IsCStringContainer(bool check_pointer = false);
-
- std::pair<size_t, bool>
- ReadPointedString(lldb::WritableDataBufferSP &buffer_sp, Status &error,
- bool honor_array);
-
- virtual size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
- uint32_t item_count = 1);
-
- virtual uint64_t GetData(DataExtractor &data, Status &error);
-
- virtual bool SetData(DataExtractor &data, Status &error);
-
- virtual bool GetIsConstant() const { return m_update_point.IsConstant(); }
-
- bool NeedsUpdating() {
- const bool accept_invalid_exe_ctx =
- (CanUpdateWithInvalidExecutionContext() == eLazyBoolYes);
- return m_update_point.NeedsUpdating(accept_invalid_exe_ctx);
- }
-
- void SetIsConstant() { m_update_point.SetIsConstant(); }
-
- lldb::Format GetFormat() const;
-
- virtual void SetFormat(lldb::Format format) {
- if (format != m_format)
- ClearUserVisibleData(eClearUserVisibleDataItemsValue);
- m_format = format;
- }
-
- virtual lldb::LanguageType GetPreferredDisplayLanguage();
-
- void SetPreferredDisplayLanguage(lldb::LanguageType lt) {
- m_preferred_display_language = lt;
- }
-
- lldb::TypeSummaryImplSP GetSummaryFormat() {
- UpdateFormatsIfNeeded();
- return m_type_summary_sp;
- }
-
- void SetSummaryFormat(lldb::TypeSummaryImplSP format) {
- m_type_summary_sp = std::move(format);
- ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
- }
-
- void SetDerefValobj(ValueObject *deref) { m_deref_valobj = deref; }
-
- ValueObject *GetDerefValobj() { return m_deref_valobj; }
-
- void SetValueFormat(lldb::TypeFormatImplSP format) {
- m_type_format_sp = std::move(format);
- ClearUserVisibleData(eClearUserVisibleDataItemsValue);
- }
-
- lldb::TypeFormatImplSP GetValueFormat() {
- UpdateFormatsIfNeeded();
- return m_type_format_sp;
- }
-
- void SetSyntheticChildren(const lldb::SyntheticChildrenSP &synth_sp) {
- if (synth_sp.get() == m_synthetic_children_sp.get())
- return;
- ClearUserVisibleData(eClearUserVisibleDataItemsSyntheticChildren);
- m_synthetic_children_sp = synth_sp;
- }
-
- lldb::SyntheticChildrenSP GetSyntheticChildren() {
- UpdateFormatsIfNeeded();
- return m_synthetic_children_sp;
- }
-
- // Use GetParent for display purposes, but if you want to tell the parent to
- // update itself then use m_parent. The ValueObjectDynamicValue's parent is
- // not the correct parent for displaying, they are really siblings, so for
- // display it needs to route through to its grandparent.
- virtual ValueObject *GetParent() { return m_parent; }
-
- virtual const ValueObject *GetParent() const { return m_parent; }
-
- ValueObject *GetNonBaseClassParent();
-
- void SetAddressTypeOfChildren(AddressType at) {
- m_address_type_of_ptr_or_ref_children = at;
- }
-
- AddressType GetAddressTypeOfChildren();
-
- void SetHasCompleteType() {
- m_flags.m_did_calculate_complete_objc_class_type = true;
- }
-
- /// Find out if a ValueObject might have children.
- ///
- /// This call is much more efficient than CalculateNumChildren() as
- /// it doesn't need to complete the underlying type. This is designed
- /// to be used in a UI environment in order to detect if the
- /// disclosure triangle should be displayed or not.
- ///
- /// This function returns true for class, union, structure,
- /// pointers, references, arrays and more. Again, it does so without
- /// doing any expensive type completion.
- ///
- /// \return
- /// Returns \b true if the ValueObject might have children, or \b
- /// false otherwise.
- virtual bool MightHaveChildren();
-
- virtual lldb::VariableSP GetVariable() { return nullptr; }
-
- virtual bool IsRuntimeSupportValue();
-
- virtual uint64_t GetLanguageFlags() { return m_language_flags; }
-
- virtual void SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }
-
-protected:
- typedef ClusterManager<ValueObject> ValueObjectManager;
-
- class ChildrenManager {
- public:
- ChildrenManager() = default;
-
- bool HasChildAtIndex(size_t idx) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- return (m_children.find(idx) != m_children.end());
- }
-
- ValueObject *GetChildAtIndex(uint32_t idx) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- const auto iter = m_children.find(idx);
- return ((iter == m_children.end()) ? nullptr : iter->second);
- }
-
- void SetChildAtIndex(size_t idx, ValueObject *valobj) {
- // we do not need to be mutex-protected to make a pair
- ChildrenPair pair(idx, valobj);
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- m_children.insert(pair);
- }
-
- void SetChildrenCount(size_t count) { Clear(count); }
-
- size_t GetChildrenCount() { return m_children_count; }
-
- void Clear(size_t new_count = 0) {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- m_children_count = new_count;
- m_children.clear();
- }
-
- private:
- typedef std::map<size_t, ValueObject *> ChildrenMap;
- typedef ChildrenMap::iterator ChildrenIterator;
- typedef ChildrenMap::value_type ChildrenPair;
- std::recursive_mutex m_mutex;
- ChildrenMap m_children;
- size_t m_children_count = 0;
- };
-
- // Classes that inherit from ValueObject can see and modify these
-
- /// The parent value object, or nullptr if this has no parent.
- ValueObject *m_parent = nullptr;
- /// The root of the hierarchy for this ValueObject (or nullptr if never
- /// calculated).
- ValueObject *m_root = nullptr;
- /// Stores both the stop id and the full context at which this value was last
- /// updated. When we are asked to update the value object, we check whether
- /// the context & stop id are the same before updating.
- EvaluationPoint m_update_point;
- /// The name of this object.
- ConstString m_name;
- /// A data extractor that can be used to extract the value.
- DataExtractor m_data;
- Value m_value;
- /// An error object that can describe any errors that occur when updating
- /// values.
- Status m_error;
- /// Cached value string that will get cleared if/when the value is updated.
- std::string m_value_str;
- /// Cached old value string from the last time the value was gotten
- std::string m_old_value_str;
- /// Cached location string that will get cleared if/when the value is updated.
- std::string m_location_str;
- /// Cached summary string that will get cleared if/when the value is updated.
- std::string m_summary_str;
- /// Cached result of the "object printer". This differs from the summary
- /// in that the summary is consed up by us, the object_desc_string is builtin.
- std::string m_object_desc_str;
- /// If the type of the value object should be overridden, the type to impose.
- CompilerType m_override_type;
-
- /// This object is managed by the root object (any ValueObject that gets
- /// created without a parent.) The manager gets passed through all the
- /// generations of dependent objects, and will keep the whole cluster of
- /// objects alive as long as a shared pointer to any of them has been handed
- /// out. Shared pointers to value objects must always be made with the GetSP
- /// method.
- ValueObjectManager *m_manager = nullptr;
-
- ChildrenManager m_children;
- std::map<ConstString, ValueObject *> m_synthetic_children;
-
- ValueObject *m_dynamic_value = nullptr;
- ValueObject *m_synthetic_value = nullptr;
- ValueObject *m_deref_valobj = nullptr;
-
- /// We have to hold onto a shared pointer to this one because it is created
- /// as an independent ValueObjectConstResult, which isn't managed by us.
- lldb::ValueObjectSP m_addr_of_valobj_sp;
-
- lldb::Format m_format = lldb::eFormatDefault;
- lldb::Format m_last_format = lldb::eFormatDefault;
- uint32_t m_last_format_mgr_revision = 0;
- lldb::TypeSummaryImplSP m_type_summary_sp;
- lldb::TypeFormatImplSP m_type_format_sp;
- lldb::SyntheticChildrenSP m_synthetic_children_sp;
- ProcessModID m_user_id_of_forced_summary;
- AddressType m_address_type_of_ptr_or_ref_children = eAddressTypeInvalid;
-
- llvm::SmallVector<uint8_t, 16> m_value_checksum;
-
- lldb::LanguageType m_preferred_display_language = lldb::eLanguageTypeUnknown;
-
- uint64_t m_language_flags = 0;
-
- /// Unique identifier for every value object.
- UserID m_id;
-
- // Utility class for initializing all bitfields in ValueObject's constructors.
- // FIXME: This could be done via default initializers once we have C++20.
- struct Bitflags {
- bool m_value_is_valid : 1, m_value_did_change : 1,
- m_children_count_valid : 1, m_old_value_valid : 1,
- m_is_deref_of_parent : 1, m_is_array_item_for_pointer : 1,
- m_is_bitfield_for_scalar : 1, m_is_child_at_offset : 1,
- m_is_getting_summary : 1, m_did_calculate_complete_objc_class_type : 1,
- m_is_synthetic_children_generated : 1;
- Bitflags() {
- m_value_is_valid = false;
- m_value_did_change = false;
- m_children_count_valid = false;
- m_old_value_valid = false;
- m_is_deref_of_parent = false;
- m_is_array_item_for_pointer = false;
- m_is_bitfield_for_scalar = false;
- m_is_child_at_offset = false;
- m_is_getting_summary = false;
- m_did_calculate_complete_objc_class_type = false;
- m_is_synthetic_children_generated = false;
- }
- } m_flags;
-
- friend class ValueObjectChild;
- friend class ExpressionVariable; // For SetName
- friend class Target; // For SetName
- friend class ValueObjectConstResultImpl;
- friend class ValueObjectSynthetic; // For ClearUserVisibleData
-
- /// Use this constructor to create a "root variable object". The ValueObject
- /// will be locked to this context through-out its lifespan.
- ValueObject(ExecutionContextScope *exe_scope, ValueObjectManager &manager,
- AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad);
-
- /// Use this constructor to create a ValueObject owned by another ValueObject.
- /// It will inherit the ExecutionContext of its parent.
- ValueObject(ValueObject &parent);
-
- ValueObjectManager *GetManager() { return m_manager; }
-
- virtual bool UpdateValue() = 0;
-
- virtual LazyBool CanUpdateWithInvalidExecutionContext() {
- return eLazyBoolCalculate;
- }
-
- virtual void CalculateDynamicValue(lldb::DynamicValueType use_dynamic);
-
- virtual lldb::DynamicValueType GetDynamicValueTypeImpl() {
- return lldb::eNoDynamicValues;
- }
-
- virtual bool HasDynamicValueTypeInfo() { return false; }
-
- virtual void CalculateSyntheticValue();
-
- /// Should only be called by ValueObject::GetChildAtIndex().
- ///
- /// \return A ValueObject managed by this ValueObject's manager.
- virtual ValueObject *CreateChildAtIndex(size_t idx);
-
- /// Should only be called by ValueObject::GetSyntheticArrayMember().
- ///
- /// \return A ValueObject managed by this ValueObject's manager.
- virtual ValueObject *CreateSyntheticArrayMember(size_t idx);
-
- /// Should only be called by ValueObject::GetNumChildren().
- virtual llvm::Expected<uint32_t>
- CalculateNumChildren(uint32_t max = UINT32_MAX) = 0;
-
- void SetNumChildren(uint32_t num_children);
-
- void SetValueDidChange(bool value_changed) {
- m_flags.m_value_did_change = value_changed;
- }
-
- void SetValueIsValid(bool valid) { m_flags.m_value_is_valid = valid; }
-
- void ClearUserVisibleData(
- uint32_t items = ValueObject::eClearUserVisibleDataItemsAllStrings);
-
- void AddSyntheticChild(ConstString key, ValueObject *valobj);
-
- DataExtractor &GetDataExtractor();
-
- void ClearDynamicTypeInformation();
-
- // Subclasses must implement the functions below.
-
- virtual CompilerType GetCompilerTypeImpl() = 0;
-
- const char *GetLocationAsCStringImpl(const Value &value,
- const DataExtractor &data);
-
- bool IsChecksumEmpty() { return m_value_checksum.empty(); }
-
- void SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType);
-
-protected:
- virtual void DoUpdateChildrenAddressType(ValueObject &valobj) {};
-
-private:
- virtual CompilerType MaybeCalculateCompleteType();
- void UpdateChildrenAddressType() {
- GetRoot()->DoUpdateChildrenAddressType(*this);
- }
-
- lldb::ValueObjectSP GetValueForExpressionPath_Impl(
- llvm::StringRef expression_cstr,
- ExpressionPathScanEndReason *reason_to_stop,
- ExpressionPathEndResultType *final_value_type,
- const GetValueForExpressionPathOptions &options,
- ExpressionPathAftermath *final_task_on_target);
-
- ValueObject(const ValueObject &) = delete;
- const ValueObject &operator=(const ValueObject &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECT_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectCast.h b/lldb/include/lldb/ValueObject/ValueObjectCast.h
deleted file mode 100644
index 9d174ae5ca609dd..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectCast.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- ValueObjectCast.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_VALUEOBJECTCAST_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTCAST_H
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/ValueObject/ValueObject.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <optional>
-
-namespace lldb_private {
-class ConstString;
-
-/// A ValueObject that represents a given value represented as a different type.
-class ValueObjectCast : public ValueObject {
-public:
- ~ValueObjectCast() override;
-
- static lldb::ValueObjectSP Create(ValueObject &parent, ConstString name,
- const CompilerType &cast_type);
-
- std::optional<uint64_t> GetByteSize() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- lldb::ValueType GetValueType() const override;
-
- bool IsInScope() override;
-
- ValueObject *GetParent() override {
- return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
- }
-
- const ValueObject *GetParent() const override {
- return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
- }
-
-protected:
- ValueObjectCast(ValueObject &parent, ConstString name,
- const CompilerType &cast_type);
-
- bool UpdateValue() override;
-
- CompilerType GetCompilerTypeImpl() override;
-
- CompilerType m_cast_type;
-
-private:
- ValueObjectCast(const ValueObjectCast &) = delete;
- const ValueObjectCast &operator=(const ValueObjectCast &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTCAST_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectChild.h b/lldb/include/lldb/ValueObject/ValueObjectChild.h
deleted file mode 100644
index e8c974a3a10a760..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectChild.h
+++ /dev/null
@@ -1,91 +0,0 @@
-//===-- ValueObjectChild.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_VALUEOBJECTCHILD_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTCHILD_H
-
-#include "lldb/ValueObject/ValueObject.h"
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-private-enumerations.h"
-#include "lldb/lldb-types.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <optional>
-
-namespace lldb_private {
-
-/// A child of another ValueObject.
-class ValueObjectChild : public ValueObject {
-public:
- ~ValueObjectChild() override;
-
- std::optional<uint64_t> GetByteSize() override { return m_byte_size; }
-
- lldb::offset_t GetByteOffset() override { return m_byte_offset; }
-
- uint32_t GetBitfieldBitSize() override { return m_bitfield_bit_size; }
-
- uint32_t GetBitfieldBitOffset() override { return m_bitfield_bit_offset; }
-
- lldb::ValueType GetValueType() const override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- ConstString GetTypeName() override;
-
- ConstString GetQualifiedTypeName() override;
-
- ConstString GetDisplayTypeName() override;
-
- bool IsInScope() override;
-
- bool IsBaseClass() override { return m_is_base_class; }
-
- bool IsDereferenceOfParent() override { return m_is_deref_of_parent; }
-
-protected:
- bool UpdateValue() override;
-
- LazyBool CanUpdateWithInvalidExecutionContext() override;
-
- CompilerType GetCompilerTypeImpl() override { return m_compiler_type; }
-
- CompilerType m_compiler_type;
- ConstString m_type_name;
- uint64_t m_byte_size;
- int32_t m_byte_offset;
- uint8_t m_bitfield_bit_size;
- uint8_t m_bitfield_bit_offset;
- bool m_is_base_class;
- bool m_is_deref_of_parent;
- std::optional<LazyBool> m_can_update_with_invalid_exe_ctx;
-
- friend class ValueObject;
- friend class ValueObjectConstResult;
- friend class ValueObjectConstResultImpl;
- friend class ValueObjectVTable;
-
- ValueObjectChild(ValueObject &parent, const CompilerType &compiler_type,
- ConstString name, uint64_t byte_size, int32_t byte_offset,
- uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
- bool is_base_class, bool is_deref_of_parent,
- AddressType child_ptr_or_ref_addr_type,
- uint64_t language_flags);
-
- ValueObjectChild(const ValueObjectChild &) = delete;
- const ValueObjectChild &operator=(const ValueObjectChild &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTCHILD_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectConstResult.h b/lldb/include/lldb/ValueObject/ValueObjectConstResult.h
deleted file mode 100644
index e4ed1f399bf6bd7..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectConstResult.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//===-- ValueObjectConstResult.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_VALUEOBJECTCONSTRESULT_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULT_H
-
-#include "lldb/Core/Value.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/ValueObject/ValueObject.h"
-#include "lldb/ValueObject/ValueObjectConstResultImpl.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private-enumerations.h"
-#include "lldb/lldb-types.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <optional>
-
-namespace lldb_private {
-class DataExtractor;
-class ExecutionContextScope;
-class Module;
-
-/// A frozen ValueObject copied into host memory.
-class ValueObjectConstResult : public ValueObject {
-public:
- ~ValueObjectConstResult() override;
-
- static lldb::ValueObjectSP
- Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order,
- uint32_t addr_byte_size, lldb::addr_t address = LLDB_INVALID_ADDRESS);
-
- static lldb::ValueObjectSP
- Create(ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
- ConstString name, const DataExtractor &data,
- lldb::addr_t address = LLDB_INVALID_ADDRESS);
-
- static lldb::ValueObjectSP
- Create(ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
- ConstString name, const lldb::DataBufferSP &result_data_sp,
- lldb::ByteOrder byte_order, uint32_t addr_size,
- lldb::addr_t address = LLDB_INVALID_ADDRESS);
-
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- const CompilerType &compiler_type,
- ConstString name, lldb::addr_t address,
- AddressType address_type,
- uint32_t addr_byte_size);
-
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- Value &value, ConstString name,
- Module *module = nullptr);
-
- // When an expression fails to evaluate, we return an error
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- Status &&error);
-
- std::optional<uint64_t> GetByteSize() override;
-
- lldb::ValueType GetValueType() const override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- ConstString GetTypeName() override;
-
- ConstString GetDisplayTypeName() override;
-
- bool IsInScope() override;
-
- void SetByteSize(size_t size);
-
- lldb::ValueObjectSP Dereference(Status &error) override;
-
- lldb::ValueObjectSP GetSyntheticChildAtOffset(
- uint32_t offset, const CompilerType &type, bool can_create,
- ConstString name_const_str = ConstString()) override;
-
- lldb::ValueObjectSP AddressOf(Status &error) override;
-
- lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
- AddressType *address_type = nullptr) override;
-
- size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
- uint32_t item_count = 1) override;
-
- lldb::addr_t GetLiveAddress() override { return m_impl.GetLiveAddress(); }
-
- void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
- AddressType address_type = eAddressTypeLoad) override {
- m_impl.SetLiveAddress(addr, address_type);
- }
-
- lldb::ValueObjectSP
- GetDynamicValue(lldb::DynamicValueType valueType) override;
-
- lldb::LanguageType GetPreferredDisplayLanguage() override;
-
- lldb::ValueObjectSP DoCast(const CompilerType &compiler_type) override;
-
-protected:
- bool UpdateValue() override;
-
- CompilerType GetCompilerTypeImpl() override;
-
- ConstString m_type_name;
- std::optional<uint64_t> m_byte_size;
-
- ValueObjectConstResultImpl m_impl;
-
-private:
- friend class ValueObjectConstResultImpl;
-
- ValueObjectConstResult(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager,
- lldb::ByteOrder byte_order, uint32_t addr_byte_size,
- lldb::addr_t address);
-
- ValueObjectConstResult(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager,
- const CompilerType &compiler_type, ConstString name,
- const DataExtractor &data, lldb::addr_t address);
-
- ValueObjectConstResult(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager,
- const CompilerType &compiler_type, ConstString name,
- const lldb::DataBufferSP &result_data_sp,
- lldb::ByteOrder byte_order, uint32_t addr_size,
- lldb::addr_t address);
-
- ValueObjectConstResult(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager,
- const CompilerType &compiler_type, ConstString name,
- lldb::addr_t address, AddressType address_type,
- uint32_t addr_byte_size);
-
- ValueObjectConstResult(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager, const Value &value,
- ConstString name, Module *module = nullptr);
-
- ValueObjectConstResult(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager, Status &&error);
-
- ValueObject *CreateChildAtIndex(size_t idx) override {
- return m_impl.CreateChildAtIndex(idx);
- }
- ValueObject *CreateSyntheticArrayMember(size_t idx) override {
- return m_impl.CreateSyntheticArrayMember(idx);
- }
-
- ValueObjectConstResult(const ValueObjectConstResult &) = delete;
- const ValueObjectConstResult &
- operator=(const ValueObjectConstResult &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULT_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectConstResultCast.h b/lldb/include/lldb/ValueObject/ValueObjectConstResultCast.h
deleted file mode 100644
index e786467eae6e264..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectConstResultCast.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- ValueObjectConstResultCast.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_VALUEOBJECTCONSTRESULTCAST_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULTCAST_H
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/ValueObject/ValueObjectCast.h"
-#include "lldb/ValueObject/ValueObjectConstResultImpl.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-types.h"
-
-#include <cstddef>
-#include <cstdint>
-
-namespace lldb_private {
-class DataExtractor;
-class Status;
-class ValueObject;
-
-class ValueObjectConstResultCast : public ValueObjectCast {
-public:
- ValueObjectConstResultCast(ValueObject &parent, ConstString name,
- const CompilerType &cast_type,
- lldb::addr_t live_address = LLDB_INVALID_ADDRESS);
-
- ~ValueObjectConstResultCast() override;
-
- lldb::ValueObjectSP Dereference(Status &error) override;
-
- virtual CompilerType GetCompilerType() {
- return ValueObjectCast::GetCompilerType();
- }
-
- lldb::ValueObjectSP GetSyntheticChildAtOffset(
- uint32_t offset, const CompilerType &type, bool can_create,
- ConstString name_const_str = ConstString()) override;
-
- lldb::ValueObjectSP AddressOf(Status &error) override;
-
- size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
- uint32_t item_count = 1) override;
-
- lldb::ValueObjectSP DoCast(const CompilerType &compiler_type) override;
-
-protected:
- ValueObjectConstResultImpl m_impl;
-
-private:
- friend class ValueObject;
- friend class ValueObjectConstResult;
- friend class ValueObjectConstResultImpl;
-
- ValueObject *CreateChildAtIndex(size_t idx) override {
- return m_impl.CreateChildAtIndex(idx);
- }
- ValueObject *CreateSyntheticArrayMember(size_t idx) override {
- return m_impl.CreateSyntheticArrayMember(idx);
- }
-
- ValueObjectConstResultCast(const ValueObjectConstResultCast &) = delete;
- const ValueObjectConstResultCast &
- operator=(const ValueObjectConstResultCast &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULTCAST_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectConstResultChild.h b/lldb/include/lldb/ValueObject/ValueObjectConstResultChild.h
deleted file mode 100644
index ad97b885684ee5f..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectConstResultChild.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//===-- ValueObjectConstResultChild.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_VALUEOBJECTCONSTRESULTCHILD_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULTCHILD_H
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/ValueObject/ValueObjectChild.h"
-#include "lldb/ValueObject/ValueObjectConstResultImpl.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-types.h"
-
-#include <cstddef>
-#include <cstdint>
-
-namespace lldb_private {
-class DataExtractor;
-class Status;
-class ValueObject;
-
-// A child of a ValueObjectConstResult.
-class ValueObjectConstResultChild : public ValueObjectChild {
-public:
- ValueObjectConstResultChild(
- ValueObject &parent, const CompilerType &compiler_type, ConstString name,
- uint32_t byte_size, int32_t byte_offset, uint32_t bitfield_bit_size,
- uint32_t bitfield_bit_offset, bool is_base_class, bool is_deref_of_parent,
- lldb::addr_t live_address, uint64_t language_flags);
-
- ~ValueObjectConstResultChild() override;
-
- lldb::ValueObjectSP Dereference(Status &error) override;
-
- virtual CompilerType GetCompilerType() {
- return ValueObjectChild::GetCompilerType();
- }
-
- lldb::ValueObjectSP GetSyntheticChildAtOffset(
- uint32_t offset, const CompilerType &type, bool can_create,
- ConstString name_const_str = ConstString()) override;
-
- lldb::ValueObjectSP AddressOf(Status &error) override;
-
- lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
- AddressType *address_type = nullptr) override;
-
- size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
- uint32_t item_count = 1) override;
-
- lldb::ValueObjectSP DoCast(const CompilerType &compiler_type) override;
-
-protected:
- ValueObjectConstResultImpl m_impl;
-
-private:
- friend class ValueObject;
- friend class ValueObjectConstResult;
- friend class ValueObjectConstResultImpl;
-
- ValueObject *CreateChildAtIndex(size_t idx) override {
- return m_impl.CreateChildAtIndex(idx);
- }
- ValueObject *CreateSyntheticArrayMember(size_t idx) override {
- return m_impl.CreateSyntheticArrayMember(idx);
- }
-
- ValueObjectConstResultChild(const ValueObjectConstResultChild &) = delete;
- const ValueObjectConstResultChild &
- operator=(const ValueObjectConstResultChild &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULTCHILD_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h b/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
deleted file mode 100644
index dbd68160acb4dcb..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectConstResultImpl.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- ValueObjectConstResultImpl.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_VALUEOBJECTCONSTRESULTIMPL_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULTIMPL_H
-
-#include "lldb/Utility/ConstString.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private-enumerations.h"
-#include "lldb/lldb-types.h"
-
-#include <cstddef>
-#include <cstdint>
-namespace lldb_private {
-class CompilerType;
-class DataExtractor;
-class Status;
-class ValueObject;
-} // namespace lldb_private
-
-namespace lldb_private {
-
-/// A class wrapping common implementation details for operations in
-/// ValueObjectConstResult ( & Child ) that may need to jump from the host
-/// memory space into the target's memory space.
-class ValueObjectConstResultImpl {
-public:
- ValueObjectConstResultImpl(ValueObject *valobj,
- lldb::addr_t live_address = LLDB_INVALID_ADDRESS);
-
- virtual ~ValueObjectConstResultImpl() = default;
-
- lldb::ValueObjectSP Dereference(Status &error);
-
- ValueObject *CreateChildAtIndex(size_t idx);
- ValueObject *CreateSyntheticArrayMember(size_t idx);
-
- lldb::ValueObjectSP
- GetSyntheticChildAtOffset(uint32_t offset, const CompilerType &type,
- bool can_create,
- ConstString name_const_str = ConstString());
-
- lldb::ValueObjectSP AddressOf(Status &error);
-
- lldb::addr_t GetLiveAddress() { return m_live_address; }
-
- lldb::ValueObjectSP Cast(const CompilerType &compiler_type);
-
- void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
- AddressType address_type = eAddressTypeLoad) {
- m_live_address = addr;
- m_live_address_type = address_type;
- }
-
- virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address = true,
- AddressType *address_type = nullptr);
-
- virtual size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0,
- uint32_t item_count = 1);
-
-private:
- ValueObject *m_impl_backend;
- lldb::addr_t m_live_address;
- AddressType m_live_address_type;
- lldb::ValueObjectSP m_address_of_backend;
-
- ValueObjectConstResultImpl(const ValueObjectConstResultImpl &) = delete;
- const ValueObjectConstResultImpl &
- operator=(const ValueObjectConstResultImpl &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTCONSTRESULTIMPL_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectDynamicValue.h b/lldb/include/lldb/ValueObject/ValueObjectDynamicValue.h
deleted file mode 100644
index 145a46e29556672..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectDynamicValue.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===-- ValueObjectDynamicValue.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_VALUEOBJECTDYNAMICVALUE_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTDYNAMICVALUE_H
-
-#include "lldb/Core/Address.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/ValueObject/ValueObject.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private-enumerations.h"
-
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <optional>
-
-namespace lldb_private {
-class DataExtractor;
-class Declaration;
-class Status;
-
-/// A ValueObject that represents memory at a given address, viewed as some
-/// set lldb type.
-class ValueObjectDynamicValue : public ValueObject {
-public:
- ~ValueObjectDynamicValue() override = default;
-
- std::optional<uint64_t> GetByteSize() override;
-
- ConstString GetTypeName() override;
-
- ConstString GetQualifiedTypeName() override;
-
- ConstString GetDisplayTypeName() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- lldb::ValueType GetValueType() const override;
-
- bool IsInScope() override;
-
- bool IsDynamic() override { return true; }
-
- bool IsBaseClass() override {
- if (m_parent)
- return m_parent->IsBaseClass();
- return false;
- }
-
- bool GetIsConstant() const override { return false; }
-
- ValueObject *GetParent() override {
- return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
- }
-
- const ValueObject *GetParent() const override {
- return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
- }
-
- lldb::ValueObjectSP GetStaticValue() override { return m_parent->GetSP(); }
-
- bool SetValueFromCString(const char *value_str, Status &error) override;
-
- bool SetData(DataExtractor &data, Status &error) override;
-
- TypeImpl GetTypeImpl() override;
-
- lldb::VariableSP GetVariable() override {
- return m_parent ? m_parent->GetVariable() : nullptr;
- }
-
- lldb::LanguageType GetPreferredDisplayLanguage() override;
-
- void SetPreferredDisplayLanguage(lldb::LanguageType);
-
- bool IsSyntheticChildrenGenerated() override;
-
- void SetSyntheticChildrenGenerated(bool b) override;
-
- bool GetDeclaration(Declaration &decl) override;
-
- uint64_t GetLanguageFlags() override;
-
- void SetLanguageFlags(uint64_t flags) override;
-
-protected:
- bool UpdateValue() override;
-
- LazyBool CanUpdateWithInvalidExecutionContext() override {
- return eLazyBoolYes;
- }
-
- lldb::DynamicValueType GetDynamicValueTypeImpl() override {
- return m_use_dynamic;
- }
-
- bool HasDynamicValueTypeInfo() override { return true; }
-
- CompilerType GetCompilerTypeImpl() override;
-
- Address m_address; ///< The variable that this value object is based upon
- TypeAndOrName m_dynamic_type_info; // We can have a type_sp or just a name
- lldb::DynamicValueType m_use_dynamic;
- TypeImpl m_type_impl;
-
-private:
- friend class ValueObject;
- friend class ValueObjectConstResult;
- ValueObjectDynamicValue(ValueObject &parent,
- lldb::DynamicValueType use_dynamic);
-
- ValueObjectDynamicValue(const ValueObjectDynamicValue &) = delete;
- const ValueObjectDynamicValue &
- operator=(const ValueObjectDynamicValue &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTDYNAMICVALUE_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectList.h b/lldb/include/lldb/ValueObject/ValueObjectList.h
deleted file mode 100644
index 5d63c65a96e5f3d..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectList.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- ValueObjectList.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_VALUEOBJECTLIST_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTLIST_H
-
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-types.h"
-
-#include <vector>
-
-#include <cstddef>
-
-namespace lldb_private {
-class ValueObject;
-
-/// A collection of ValueObject values that.
-class ValueObjectList {
-public:
- const ValueObjectList &operator=(const ValueObjectList &rhs);
-
- void Append(const lldb::ValueObjectSP &val_obj_sp);
-
- void Append(const ValueObjectList &valobj_list);
-
- lldb::ValueObjectSP FindValueObjectByPointer(ValueObject *valobj);
-
- size_t GetSize() const;
-
- void Resize(size_t size);
-
- lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx);
-
- lldb::ValueObjectSP RemoveValueObjectAtIndex(size_t idx);
-
- void SetValueObjectAtIndex(size_t idx, const lldb::ValueObjectSP &valobj_sp);
-
- lldb::ValueObjectSP FindValueObjectByValueName(const char *name);
-
- lldb::ValueObjectSP FindValueObjectByUID(lldb::user_id_t uid);
-
- void Swap(ValueObjectList &value_object_list);
-
- void Clear() { m_value_objects.clear(); }
-
- const std::vector<lldb::ValueObjectSP> &GetObjects() const {
- return m_value_objects;
- }
-
-protected:
- typedef std::vector<lldb::ValueObjectSP> collection;
- // Classes that inherit from ValueObjectList can see and modify these
- collection m_value_objects;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTLIST_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectMemory.h b/lldb/include/lldb/ValueObject/ValueObjectMemory.h
deleted file mode 100644
index cfc36d0d610dba4..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectMemory.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- ValueObjectMemory.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_VALUEOBJECTMEMORY_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTMEMORY_H
-
-#include "lldb/Core/Address.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/ValueObject/ValueObject.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-#include "llvm/ADT/StringRef.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <optional>
-
-namespace lldb_private {
-class ExecutionContextScope;
-
-/// A ValueObject that represents memory at a given address, viewed as some
-/// set lldb type.
-class ValueObjectMemory : public ValueObject {
-public:
- ~ValueObjectMemory() override;
-
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- llvm::StringRef name,
- const Address &address,
- lldb::TypeSP &type_sp);
-
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- llvm::StringRef name,
- const Address &address,
- const CompilerType &ast_type);
-
- std::optional<uint64_t> GetByteSize() override;
-
- ConstString GetTypeName() override;
-
- ConstString GetDisplayTypeName() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- lldb::ValueType GetValueType() const override;
-
- bool IsInScope() override;
-
- lldb::ModuleSP GetModule() override;
-
-protected:
- bool UpdateValue() override;
-
- CompilerType GetCompilerTypeImpl() override;
-
- Address m_address; ///< The variable that this value object is based upon
- lldb::TypeSP m_type_sp;
- CompilerType m_compiler_type;
-
-private:
- ValueObjectMemory(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager, llvm::StringRef name,
- const Address &address, lldb::TypeSP &type_sp);
-
- ValueObjectMemory(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager, llvm::StringRef name,
- const Address &address, const CompilerType &ast_type);
- // For ValueObject only
- ValueObjectMemory(const ValueObjectMemory &) = delete;
- const ValueObjectMemory &operator=(const ValueObjectMemory &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTMEMORY_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectRegister.h b/lldb/include/lldb/ValueObject/ValueObjectRegister.h
deleted file mode 100644
index fafbfd0341115c4..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectRegister.h
+++ /dev/null
@@ -1,143 +0,0 @@
-//===-- ValueObjectRegister.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_VALUEOBJECTREGISTER_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTREGISTER_H
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/ValueObject/ValueObject.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private-types.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <optional>
-
-namespace lldb_private {
-class DataExtractor;
-class Status;
-class ExecutionContextScope;
-class Scalar;
-class Stream;
-
-class ValueObjectRegisterSet : public ValueObject {
-public:
- ~ValueObjectRegisterSet() override;
-
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- lldb::RegisterContextSP ®_ctx_sp,
- uint32_t set_idx);
-
- std::optional<uint64_t> GetByteSize() override;
-
- lldb::ValueType GetValueType() const override {
- return lldb::eValueTypeRegisterSet;
- }
-
- ConstString GetTypeName() override;
-
- ConstString GetQualifiedTypeName() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name,
- bool can_create = true) override;
-
- size_t GetIndexOfChildWithName(llvm::StringRef name) override;
-
-protected:
- bool UpdateValue() override;
-
- CompilerType GetCompilerTypeImpl() override;
-
- lldb::RegisterContextSP m_reg_ctx_sp;
- const RegisterSet *m_reg_set;
- uint32_t m_reg_set_idx;
-
-private:
- friend class ValueObjectRegisterContext;
-
- ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager,
- lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx);
-
- ValueObject *CreateChildAtIndex(size_t idx) override;
- ValueObject *CreateSyntheticArrayMember(size_t idx) override {
- return nullptr;
- }
-
- // For ValueObject only
- ValueObjectRegisterSet(const ValueObjectRegisterSet &) = delete;
- const ValueObjectRegisterSet &
- operator=(const ValueObjectRegisterSet &) = delete;
-};
-
-class ValueObjectRegister : public ValueObject {
-public:
- ~ValueObjectRegister() override;
-
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- lldb::RegisterContextSP ®_ctx_sp,
- const RegisterInfo *reg_info);
-
- std::optional<uint64_t> GetByteSize() override;
-
- lldb::ValueType GetValueType() const override {
- return lldb::eValueTypeRegister;
- }
-
- ConstString GetTypeName() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- bool SetValueFromCString(const char *value_str, Status &error) override;
-
- bool SetData(DataExtractor &data, Status &error) override;
-
- bool ResolveValue(Scalar &scalar) override;
-
- void
- GetExpressionPath(Stream &s,
- GetExpressionPathFormat epformat =
- eGetExpressionPathFormatDereferencePointers) override;
-
-protected:
- bool UpdateValue() override;
-
- CompilerType GetCompilerTypeImpl() override;
-
- lldb::RegisterContextSP m_reg_ctx_sp;
- RegisterInfo m_reg_info;
- RegisterValue m_reg_value;
- ConstString m_type_name;
- CompilerType m_compiler_type;
-
-private:
- void ConstructObject(const RegisterInfo *reg_info);
-
- friend class ValueObjectRegisterSet;
-
- ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp,
- const RegisterInfo *reg_info);
- ValueObjectRegister(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager,
- lldb::RegisterContextSP ®_ctx_sp,
- const RegisterInfo *reg_info);
-
- // For ValueObject only
- ValueObjectRegister(const ValueObjectRegister &) = delete;
- const ValueObjectRegister &operator=(const ValueObjectRegister &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTREGISTER_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectSyntheticFilter.h b/lldb/include/lldb/ValueObject/ValueObjectSyntheticFilter.h
deleted file mode 100644
index 2811658fd8f1f46..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectSyntheticFilter.h
+++ /dev/null
@@ -1,179 +0,0 @@
-//===-- ValueObjectSyntheticFilter.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_VALUEOBJECTSYNTHETICFILTER_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTSYNTHETICFILTER_H
-
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/ValueObject/ValueObject.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private-enumerations.h"
-
-#include <cstdint>
-#include <memory>
-#include <optional>
-
-#include <cstddef>
-
-namespace lldb_private {
-class Declaration;
-class Status;
-class SyntheticChildrenFrontEnd;
-
-/// A ValueObject that obtains its children from some source other than
-/// real information.
-/// This is currently used to implement Python-based children and filters but
-/// you can bind it to any source of synthetic information and have it behave
-/// accordingly.
-class ValueObjectSynthetic : public ValueObject {
-public:
- ~ValueObjectSynthetic() override;
-
- std::optional<uint64_t> GetByteSize() override;
-
- ConstString GetTypeName() override;
-
- ConstString GetQualifiedTypeName() override;
-
- ConstString GetDisplayTypeName() override;
-
- bool MightHaveChildren() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- lldb::ValueType GetValueType() const override;
-
- lldb::ValueObjectSP GetChildAtIndex(uint32_t idx,
- bool can_create = true) override;
-
- lldb::ValueObjectSP GetChildMemberWithName(llvm::StringRef name,
- bool can_create = true) override;
-
- size_t GetIndexOfChildWithName(llvm::StringRef name) override;
-
- lldb::ValueObjectSP
- GetDynamicValue(lldb::DynamicValueType valueType) override;
-
- bool IsInScope() override;
-
- bool HasSyntheticValue() override { return false; }
-
- bool IsSynthetic() override { return true; }
-
- void CalculateSyntheticValue() override {}
-
- bool IsDynamic() override {
- return ((m_parent != nullptr) ? m_parent->IsDynamic() : false);
- }
-
- lldb::ValueObjectSP GetStaticValue() override {
- return ((m_parent != nullptr) ? m_parent->GetStaticValue() : GetSP());
- }
-
- virtual lldb::DynamicValueType GetDynamicValueType() {
- return ((m_parent != nullptr) ? m_parent->GetDynamicValueType()
- : lldb::eNoDynamicValues);
- }
-
- lldb::VariableSP GetVariable() override {
- return m_parent != nullptr ? m_parent->GetVariable() : nullptr;
- }
-
- ValueObject *GetParent() override {
- return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
- }
-
- const ValueObject *GetParent() const override {
- return ((m_parent != nullptr) ? m_parent->GetParent() : nullptr);
- }
-
- lldb::ValueObjectSP GetNonSyntheticValue() override;
-
- bool CanProvideValue() override;
-
- bool DoesProvideSyntheticValue() override {
- return (UpdateValueIfNeeded(), m_provides_value == eLazyBoolYes);
- }
-
- bool GetIsConstant() const override { return false; }
-
- bool SetValueFromCString(const char *value_str, Status &error) override;
-
- void SetFormat(lldb::Format format) override;
-
- lldb::LanguageType GetPreferredDisplayLanguage() override;
-
- void SetPreferredDisplayLanguage(lldb::LanguageType);
-
- bool IsSyntheticChildrenGenerated() override;
-
- void SetSyntheticChildrenGenerated(bool b) override;
-
- bool GetDeclaration(Declaration &decl) override;
-
- uint64_t GetLanguageFlags() override;
-
- void SetLanguageFlags(uint64_t flags) override;
-
-protected:
- bool UpdateValue() override;
-
- LazyBool CanUpdateWithInvalidExecutionContext() override {
- return eLazyBoolYes;
- }
-
- CompilerType GetCompilerTypeImpl() override;
-
- virtual void CreateSynthFilter();
-
- // we need to hold on to the SyntheticChildren because someone might delete
- // the type binding while we are alive
- lldb::SyntheticChildrenSP m_synth_sp;
- std::unique_ptr<SyntheticChildrenFrontEnd> m_synth_filter_up;
-
- typedef std::map<uint32_t, ValueObject *> ByIndexMap;
- typedef std::map<const char *, uint32_t> NameToIndexMap;
- typedef std::vector<lldb::ValueObjectSP> SyntheticChildrenCache;
-
- typedef ByIndexMap::iterator ByIndexIterator;
- typedef NameToIndexMap::iterator NameToIndexIterator;
-
- std::mutex m_child_mutex;
- /// Guarded by m_child_mutex;
- ByIndexMap m_children_byindex;
- /// Guarded by m_child_mutex;
- NameToIndexMap m_name_toindex;
- /// Guarded by m_child_mutex;
- SyntheticChildrenCache m_synthetic_children_cache;
-
- // FIXME: use the ValueObject's ChildrenManager instead of a special purpose
- // solution.
- uint32_t m_synthetic_children_count;
-
- ConstString m_parent_type_name;
-
- LazyBool m_might_have_children;
-
- LazyBool m_provides_value;
-
-private:
- friend class ValueObject;
- ValueObjectSynthetic(ValueObject &parent, lldb::SyntheticChildrenSP filter);
-
- void CopyValueData(ValueObject *source);
-
- ValueObjectSynthetic(const ValueObjectSynthetic &) = delete;
- const ValueObjectSynthetic &operator=(const ValueObjectSynthetic &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTSYNTHETICFILTER_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectUpdater.h b/lldb/include/lldb/ValueObject/ValueObjectUpdater.h
deleted file mode 100644
index 3f1d887b47a7b6d..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectUpdater.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- ValueObjectUpdater.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_VALUEOBJECTUPDATER_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTUPDATER_H
-
-#include "lldb/ValueObject/ValueObject.h"
-
-namespace lldb_private {
-
-/// A value object class that is seeded with the static variable value
-/// and it vends the user facing value object. If the type is dynamic it can
-/// vend the dynamic type. If this user type also has a synthetic type
-/// associated with it, it will vend the synthetic type. The class watches the
-/// process' stop ID and will update the user type when needed.
-class ValueObjectUpdater {
- /// The root value object is the static typed variable object.
- lldb::ValueObjectSP m_root_valobj_sp;
- /// The user value object is the value object the user wants to see.
- lldb::ValueObjectSP m_user_valobj_sp;
- /// The stop ID that m_user_valobj_sp is valid for.
- uint32_t m_stop_id = UINT32_MAX;
-
-public:
- ValueObjectUpdater(lldb::ValueObjectSP in_valobj_sp);
-
- /// Gets the correct value object from the root object for a given process
- /// stop ID. If dynamic values are enabled, or if synthetic children are
- /// enabled, the value object that the user wants to see might change while
- /// debugging.
- lldb::ValueObjectSP GetSP();
-
- lldb::ProcessSP GetProcessSP() const;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTUPDATER_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectVTable.h b/lldb/include/lldb/ValueObject/ValueObjectVTable.h
deleted file mode 100644
index 9cf13be093a8dbf..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectVTable.h
+++ /dev/null
@@ -1,107 +0,0 @@
-//===-- ValueObjectVTable.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_VALUEOBJECTVTABLE_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTVTABLE_H
-
-#include "lldb/ValueObject/ValueObject.h"
-
-namespace lldb_private {
-
-/// A class that represents a virtual function table for a C++ class.
-///
-/// ValueObject::GetError() will be in the success state if this value
-/// represents a C++ class with a vtable, or an appropriate error describing
-/// that the object isn't a C++ class with a vtable or not a C++ class.
-///
-/// ValueObject::GetName() will be the demangled symbol name for the virtual
-/// function table like "vtable for <classname>".
-///
-/// ValueObject::GetValueAsCString() will be the address of the first vtable
-/// entry if the current ValueObject is a class with a vtable, or nothing the
-/// current ValueObject is not a C++ class or not a C++ class that has a
-/// vtable.
-///
-/// ValueObject::GetValueAtUnsigned(...) will return the address of the first
-/// vtable entry.
-///
-/// ValueObject::GetAddressOf() will return the address of the vtable pointer
-/// found in the parent ValueObject.
-///
-/// ValueObject::GetNumChildren() will return the number of virtual function
-/// pointers in the vtable, or zero on error.
-///
-/// ValueObject::GetChildAtIndex(...) will return each virtual function pointer
-/// as a ValueObject object.
-///
-/// The child ValueObjects will have the following values:
-///
-/// ValueObject::GetError() will indicate success if the vtable entry was
-/// successfully read from memory, or an error if not.
-///
-/// ValueObject::GetName() will be the vtable function index in the form "[%u]"
-/// where %u is the index.
-///
-/// ValueObject::GetValueAsCString() will be the virtual function pointer value
-///
-/// ValueObject::GetValueAtUnsigned(...) will return the virtual function
-/// pointer value.
-///
-/// ValueObject::GetAddressOf() will return the address of the virtual function
-/// pointer.
-///
-/// ValueObject::GetNumChildren() returns 0
-class ValueObjectVTable : public ValueObject {
-public:
- ~ValueObjectVTable() override;
-
- static lldb::ValueObjectSP Create(ValueObject &parent);
-
- std::optional<uint64_t> GetByteSize() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- lldb::ValueType GetValueType() const override;
-
- ConstString GetTypeName() override;
-
- ConstString GetQualifiedTypeName() override;
-
- ConstString GetDisplayTypeName() override;
-
- bool IsInScope() override;
-
-protected:
- bool UpdateValue() override;
-
- CompilerType GetCompilerTypeImpl() override;
-
- /// The symbol for the C++ virtual function table.
- const Symbol *m_vtable_symbol = nullptr;
- /// Cache the number of vtable children when we update the value.
- uint32_t m_num_vtable_entries = 0;
- /// Cache the address size in bytes to avoid checking with the process to
- /// many times.
- uint32_t m_addr_size = 0;
-
-private:
- ValueObjectVTable(ValueObject &parent);
-
- ValueObject *CreateChildAtIndex(size_t idx) override;
- ValueObject *CreateSyntheticArrayMember(size_t idx) override {
- return nullptr;
- }
-
- // For ValueObject only
- ValueObjectVTable(const ValueObjectVTable &) = delete;
- const ValueObjectVTable &operator=(const ValueObjectVTable &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTVTABLE_H
diff --git a/lldb/include/lldb/ValueObject/ValueObjectVariable.h b/lldb/include/lldb/ValueObject/ValueObjectVariable.h
deleted file mode 100644
index 9f66af808425ab9..000000000000000
--- a/lldb/include/lldb/ValueObject/ValueObjectVariable.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//===-- ValueObjectVariable.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_VALUEOBJECTVARIABLE_H
-#define LLDB_VALUEOBJECT_VALUEOBJECTVARIABLE_H
-
-#include "lldb/ValueObject/ValueObject.h"
-
-#include "lldb/Core/Value.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-forward.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <optional>
-
-namespace lldb_private {
-class DataExtractor;
-class Declaration;
-class Status;
-class ExecutionContextScope;
-class SymbolContextScope;
-
-/// A ValueObject that contains a root variable that may or may not
-/// have children.
-class ValueObjectVariable : public ValueObject {
-public:
- ~ValueObjectVariable() override;
-
- static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope,
- const lldb::VariableSP &var_sp);
-
- std::optional<uint64_t> GetByteSize() override;
-
- ConstString GetTypeName() override;
-
- ConstString GetQualifiedTypeName() override;
-
- ConstString GetDisplayTypeName() override;
-
- llvm::Expected<uint32_t> CalculateNumChildren(uint32_t max) override;
-
- lldb::ValueType GetValueType() const override;
-
- bool IsInScope() override;
-
- lldb::ModuleSP GetModule() override;
-
- SymbolContextScope *GetSymbolContextScope() override;
-
- bool GetDeclaration(Declaration &decl) override;
-
- const char *GetLocationAsCString() override;
-
- bool SetValueFromCString(const char *value_str, Status &error) override;
-
- bool SetData(DataExtractor &data, Status &error) override;
-
- lldb::VariableSP GetVariable() override { return m_variable_sp; }
-
-protected:
- bool UpdateValue() override;
-
- void DoUpdateChildrenAddressType(ValueObject &valobj) override;
-
- CompilerType GetCompilerTypeImpl() override;
-
- /// The variable that this value object is based upon.
- lldb::VariableSP m_variable_sp;
- ///< The value that DWARFExpression resolves this variable to before we patch
- ///< it up.
- Value m_resolved_value;
-
-private:
- ValueObjectVariable(ExecutionContextScope *exe_scope,
- ValueObjectManager &manager,
- const lldb::VariableSP &var_sp);
- // For ValueObject only
- ValueObjectVariable(const ValueObjectVariable &) = delete;
- const ValueObjectVariable &operator=(const ValueObjectVariable &) = delete;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_VALUEOBJECT_VALUEOBJECTVARIABLE_H
More information about the lldb-commits
mailing list