summaryrefslogtreecommitdiff
path: root/source/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'source/Utility')
-rw-r--r--source/Utility/ArchSpec.cpp44
-rw-r--r--source/Utility/Args.cpp57
-rw-r--r--source/Utility/Broadcaster.cpp11
-rw-r--r--source/Utility/CompletionRequest.cpp57
-rw-r--r--source/Utility/ConstString.cpp17
-rw-r--r--source/Utility/DataExtractor.cpp37
-rw-r--r--source/Utility/FileCollector.cpp182
-rw-r--r--source/Utility/FileSpec.cpp8
-rw-r--r--source/Utility/GDBRemote.cpp105
-rw-r--r--source/Utility/JSON.cpp550
-rw-r--r--source/Utility/Listener.cpp69
-rw-r--r--source/Utility/Log.cpp39
-rw-r--r--source/Utility/Logging.cpp10
-rw-r--r--source/Utility/ProcessInfo.cpp95
-rw-r--r--source/Utility/RegularExpression.cpp168
-rw-r--r--source/Utility/Reproducer.cpp85
-rw-r--r--source/Utility/Scalar.cpp45
-rw-r--r--source/Utility/SelectHelper.cpp4
-rw-r--r--source/Utility/StreamGDBRemote.cpp45
-rw-r--r--source/Utility/StringExtractor.cpp28
-rw-r--r--source/Utility/StringLexer.cpp2
-rw-r--r--source/Utility/StringList.cpp36
-rw-r--r--source/Utility/StructuredData.cpp244
23 files changed, 537 insertions, 1401 deletions
diff --git a/source/Utility/ArchSpec.cpp b/source/Utility/ArchSpec.cpp
index 81b87fff88d4b..40cc4a092b0d8 100644
--- a/source/Utility/ArchSpec.cpp
+++ b/source/Utility/ArchSpec.cpp
@@ -101,6 +101,8 @@ static const CoreDefinition g_core_definitions[] = {
ArchSpec::eCore_arm_arm64, "arm64"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
ArchSpec::eCore_arm_armv8, "armv8"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::aarch64_32,
+ ArchSpec::eCore_arm_arm64_32, "arm64_32"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
ArchSpec::eCore_arm_aarch64, "aarch64"},
@@ -214,6 +216,7 @@ static const CoreDefinition g_core_definitions[] = {
ArchSpec::eCore_uknownMach32, "unknown-mach-32"},
{eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch,
ArchSpec::eCore_uknownMach64, "unknown-mach-64"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"}
};
// Ensure that we have an entry in the g_core_definitions for each core. If you
@@ -243,19 +246,9 @@ void ArchSpec::ListSupportedArchNames(StringList &list) {
list.AppendString(g_core_definitions[i].name);
}
-size_t ArchSpec::AutoComplete(CompletionRequest &request) {
- if (!request.GetCursorArgumentPrefix().empty()) {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
- if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith,
- request.GetCursorArgumentPrefix()))
- request.AddCompletion(g_core_definitions[i].name);
- }
- } else {
- StringList matches;
- ListSupportedArchNames(matches);
- request.AddCompletions(matches);
- }
- return request.GetNumberOfMatches();
+void ArchSpec::AutoComplete(CompletionRequest &request) {
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+ request.TryCompleteCurrentArg(g_core_definitions[i].name);
}
#define CPU_ANY (UINT32_MAX)
@@ -306,6 +299,10 @@ static const ArchDefinitionEntry g_macho_arch_entries[] = {
SUBTYPE_MASK},
{ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 13, UINT32_MAX,
SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 0,
+ UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64_32, llvm::MachO::CPU_TYPE_ARM64_32, 1,
+ UINT32_MAX, SUBTYPE_MASK},
{ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, CPU_ANY,
UINT32_MAX, SUBTYPE_MASK},
{ArchSpec::eCore_thumb, llvm::MachO::CPU_TYPE_ARM, 0, UINT32_MAX,
@@ -446,6 +443,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = {
ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6el
{ArchSpec::eCore_hexagon_generic, llvm::ELF::EM_HEXAGON,
LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON
+ {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARC
};
static const ArchDefinition g_elf_arch_def = {
@@ -469,7 +468,9 @@ static const ArchDefinitionEntry g_coff_arch_entries[] = {
{ArchSpec::eCore_thumb, llvm::COFF::IMAGE_FILE_MACHINE_THUMB,
LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARMv7
{ArchSpec::eCore_x86_64_x86_64, llvm::COFF::IMAGE_FILE_MACHINE_AMD64,
- LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu} // AMD64
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // AMD64
+ {ArchSpec::eCore_arm_arm64, llvm::COFF::IMAGE_FILE_MACHINE_ARM64,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu} // ARM64
};
static const ArchDefinition g_coff_arch_def = {
@@ -760,6 +761,7 @@ bool ArchSpec::CharIsSignedByDefault() const {
return true;
case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
case llvm::Triple::aarch64_be:
case llvm::Triple::arm:
case llvm::Triple::armeb:
@@ -946,8 +948,10 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
}
} else {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_PLATFORM));
- if (log)
- log->Printf("Unable to find a core definition for cpu 0x%" PRIx32 " sub %" PRId32, cpu, sub);
+ LLDB_LOGF(log,
+ "Unable to find a core definition for cpu 0x%" PRIx32
+ " sub %" PRId32,
+ cpu, sub);
}
}
CoreUpdated(update_triple);
@@ -1245,6 +1249,14 @@ static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
}
break;
+ case ArchSpec::eCore_arm_arm64_32:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_generic)
+ return true;
+ try_inverse = false;
+ }
+ break;
+
case ArchSpec::eCore_mips32:
if (!enforce_exact_match) {
if (core2 >= ArchSpec::kCore_mips32_first &&
diff --git a/source/Utility/Args.cpp b/source/Utility/Args.cpp
index 77b0d43254a16..9fcc833ce432b 100644
--- a/source/Utility/Args.cpp
+++ b/source/Utility/Args.cpp
@@ -163,7 +163,6 @@ Args::ArgEntry::ArgEntry(llvm::StringRef str, char quote) : quote(quote) {
::memcpy(data(), str.data() ? str.data() : "", size);
ptr[size] = 0;
- ref = llvm::StringRef(c_str(), size);
}
// Args constructor
@@ -172,8 +171,8 @@ Args::Args(llvm::StringRef command) { SetCommandString(command); }
Args::Args(const Args &rhs) { *this = rhs; }
Args::Args(const StringList &list) : Args() {
- for (size_t i = 0; i < list.GetSize(); ++i)
- AppendArgument(list[i]);
+ for (const std::string &arg : list)
+ AppendArgument(arg);
}
Args &Args::operator=(const Args &rhs) {
@@ -182,7 +181,7 @@ Args &Args::operator=(const Args &rhs) {
m_argv.clear();
m_entries.clear();
for (auto &entry : rhs.m_entries) {
- m_entries.emplace_back(entry.ref, entry.quote);
+ m_entries.emplace_back(entry.ref(), entry.quote);
m_argv.push_back(m_entries.back().data());
}
m_argv.push_back(nullptr);
@@ -199,7 +198,7 @@ void Args::Dump(Stream &s, const char *label_name) const {
int i = 0;
for (auto &entry : m_entries) {
s.Indent();
- s.Format("{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref);
+ s.Format("{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref());
}
s.Format("{0}[{1}]=NULL\n", label_name, i);
s.EOL();
@@ -211,7 +210,7 @@ bool Args::GetCommandString(std::string &command) const {
for (size_t i = 0; i < m_entries.size(); ++i) {
if (i > 0)
command += ' ';
- command += m_entries[i].ref;
+ command += m_entries[i].ref();
}
return !m_entries.empty();
@@ -226,10 +225,10 @@ bool Args::GetQuotedCommandString(std::string &command) const {
if (m_entries[i].quote) {
command += m_entries[i].quote;
- command += m_entries[i].ref;
+ command += m_entries[i].ref();
command += m_entries[i].quote;
} else {
- command += m_entries[i].ref;
+ command += m_entries[i].ref();
}
}
@@ -260,12 +259,6 @@ const char *Args::GetArgumentAtIndex(size_t idx) const {
return nullptr;
}
-char Args::GetArgumentQuoteCharAtIndex(size_t idx) const {
- if (idx < m_entries.size())
- return m_entries[idx].quote;
- return '\0';
-}
-
char **Args::GetArgumentVector() {
assert(!m_argv.empty());
// TODO: functions like execve and posix_spawnp exhibit undefined behavior
@@ -299,7 +292,7 @@ void Args::AppendArguments(const Args &rhs) {
assert(m_argv.back() == nullptr);
m_argv.pop_back();
for (auto &entry : rhs.m_entries) {
- m_entries.emplace_back(entry.ref, entry.quote);
+ m_entries.emplace_back(entry.ref(), entry.quote);
m_argv.push_back(m_entries.back().data());
}
m_argv.push_back(nullptr);
@@ -342,15 +335,8 @@ void Args::ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
if (idx >= m_entries.size())
return;
- if (arg_str.size() > m_entries[idx].ref.size()) {
- m_entries[idx] = ArgEntry(arg_str, quote_char);
- m_argv[idx] = m_entries[idx].data();
- } else {
- const char *src_data = arg_str.data() ? arg_str.data() : "";
- ::memcpy(m_entries[idx].data(), src_data, arg_str.size());
- m_entries[idx].ptr[arg_str.size()] = 0;
- m_entries[idx].ref = m_entries[idx].ref.take_front(arg_str.size());
- }
+ m_entries[idx] = ArgEntry(arg_str, quote_char);
+ m_argv[idx] = m_entries[idx].data();
}
void Args::DeleteArgumentAtIndex(size_t idx) {
@@ -388,29 +374,6 @@ void Args::Clear() {
m_argv.push_back(nullptr);
}
-const char *Args::StripSpaces(std::string &s, bool leading, bool trailing,
- bool return_null_if_empty) {
- static const char *k_white_space = " \t\v";
- if (!s.empty()) {
- if (leading) {
- size_t pos = s.find_first_not_of(k_white_space);
- if (pos == std::string::npos)
- s.clear();
- else if (pos > 0)
- s.erase(0, pos);
- }
-
- if (trailing) {
- size_t rpos = s.find_last_not_of(k_white_space);
- if (rpos != std::string::npos && rpos + 1 < s.size())
- s.erase(rpos + 1);
- }
- }
- if (return_null_if_empty && s.empty())
- return nullptr;
- return s.c_str();
-}
-
const char *Args::GetShellSafeArgument(const FileSpec &shell,
const char *unsafe_arg,
std::string &safe_arg) {
diff --git a/source/Utility/Broadcaster.cpp b/source/Utility/Broadcaster.cpp
index 597888cfa0e2e..148fdf7ba5b1e 100644
--- a/source/Utility/Broadcaster.cpp
+++ b/source/Utility/Broadcaster.cpp
@@ -214,11 +214,12 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp,
if (Log *log = lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS)) {
StreamString event_description;
event_sp->Dump(&event_description);
- log->Printf("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, "
- "unique =%i) hijack = %p",
- static_cast<void *>(this), GetBroadcasterName(),
- event_description.GetData(), unique,
- static_cast<void *>(hijacking_listener_sp.get()));
+ LLDB_LOGF(log,
+ "%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, "
+ "unique =%i) hijack = %p",
+ static_cast<void *>(this), GetBroadcasterName(),
+ event_description.GetData(), unique,
+ static_cast<void *>(hijacking_listener_sp.get()));
}
if (hijacking_listener_sp) {
diff --git a/source/Utility/CompletionRequest.cpp b/source/Utility/CompletionRequest.cpp
index c62ec4f56ffa9..3b5a4570e3242 100644
--- a/source/Utility/CompletionRequest.cpp
+++ b/source/Utility/CompletionRequest.cpp
@@ -13,46 +13,32 @@ using namespace lldb_private;
CompletionRequest::CompletionRequest(llvm::StringRef command_line,
unsigned raw_cursor_pos,
- int match_start_point,
- int max_return_elements,
CompletionResult &result)
: m_command(command_line), m_raw_cursor_pos(raw_cursor_pos),
- m_match_start_point(match_start_point),
- m_max_return_elements(max_return_elements), m_result(result) {
+ m_result(result) {
+ assert(raw_cursor_pos <= command_line.size() && "Out of bounds cursor?");
// We parse the argument up to the cursor, so the last argument in
// parsed_line is the one containing the cursor, and the cursor is after the
// last character.
- m_parsed_line = Args(command_line);
- m_partial_parsed_line = Args(command_line.substr(0, raw_cursor_pos));
+ llvm::StringRef partial_command(command_line.substr(0, raw_cursor_pos));
+ m_parsed_line = Args(partial_command);
- m_cursor_index = m_partial_parsed_line.GetArgumentCount() - 1;
-
- if (m_cursor_index == -1)
+ if (GetParsedLine().GetArgumentCount() == 0) {
+ m_cursor_index = 0;
m_cursor_char_position = 0;
- else
+ } else {
+ m_cursor_index = GetParsedLine().GetArgumentCount() - 1U;
m_cursor_char_position =
- strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index));
-
- const char *cursor = command_line.data() + raw_cursor_pos;
- if (raw_cursor_pos > 0 && cursor[-1] == ' ') {
- // We are just after a space. If we are in an argument, then we will
- // continue parsing, but if we are between arguments, then we have to
- // complete whatever the next element would be. We can distinguish the two
- // cases because if we are in an argument (e.g. because the space is
- // protected by a quote) then the space will also be in the parsed
- // argument...
-
- const char *current_elem =
- m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index);
- if (m_cursor_char_position == 0 ||
- current_elem[m_cursor_char_position - 1] != ' ') {
- m_parsed_line.InsertArgumentAtIndex(m_cursor_index + 1, llvm::StringRef(),
- '\0');
- m_cursor_index++;
- m_cursor_char_position = 0;
- }
+ strlen(GetParsedLine().GetArgumentAtIndex(m_cursor_index));
}
+
+ // The cursor is after a space but the space is not part of the argument.
+ // Let's add an empty fake argument to the end to make sure the completion
+ // code. Note: The space could be part of the last argument when it's quoted.
+ if (partial_command.endswith(" ") &&
+ !GetCursorArgumentPrefix().endswith(" "))
+ AppendEmptyArgument();
}
std::string CompletionResult::Completion::GetUniqueKey() const {
@@ -66,13 +52,16 @@ std::string CompletionResult::Completion::GetUniqueKey() const {
std::string result;
result.append(std::to_string(m_completion.size()));
result.append(m_completion);
+ result.append(std::to_string(static_cast<int>(m_mode)));
+ result.append(":");
result.append(m_descripton);
return result;
}
void CompletionResult::AddResult(llvm::StringRef completion,
- llvm::StringRef description) {
- Completion r(completion, description);
+ llvm::StringRef description,
+ CompletionMode mode) {
+ Completion r(completion, description, mode);
// Add the completion if we haven't seen the same value before.
if (m_added_values.insert(r.GetUniqueKey()).second)
@@ -82,11 +71,11 @@ void CompletionResult::AddResult(llvm::StringRef completion,
void CompletionResult::GetMatches(StringList &matches) const {
matches.Clear();
for (const Completion &completion : m_results)
- matches.AppendString(completion.m_completion);
+ matches.AppendString(completion.GetCompletion());
}
void CompletionResult::GetDescriptions(StringList &descriptions) const {
descriptions.Clear();
for (const Completion &completion : m_results)
- descriptions.AppendString(completion.m_descripton);
+ descriptions.AppendString(completion.GetDescription());
}
diff --git a/source/Utility/ConstString.cpp b/source/Utility/ConstString.cpp
index 46b7ab259383e..2516ecf6a9897 100644
--- a/source/Utility/ConstString.cpp
+++ b/source/Utility/ConstString.cpp
@@ -59,23 +59,6 @@ public:
return nullptr;
}
- bool SetMangledCounterparts(const char *key_ccstr, const char *value_ccstr) {
- if (key_ccstr != nullptr && value_ccstr != nullptr) {
- {
- const uint8_t h = hash(llvm::StringRef(key_ccstr));
- llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex);
- GetStringMapEntryFromKeyData(key_ccstr).setValue(value_ccstr);
- }
- {
- const uint8_t h = hash(llvm::StringRef(value_ccstr));
- llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex);
- GetStringMapEntryFromKeyData(value_ccstr).setValue(key_ccstr);
- }
- return true;
- }
- return false;
- }
-
const char *GetConstCString(const char *cstr) {
if (cstr != nullptr)
return GetConstCStringWithLength(cstr, strlen(cstr));
diff --git a/source/Utility/DataExtractor.cpp b/source/Utility/DataExtractor.cpp
index 79a1f75d737c1..f642a8fc76392 100644
--- a/source/Utility/DataExtractor.cpp
+++ b/source/Utility/DataExtractor.cpp
@@ -816,26 +816,25 @@ DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
// non-zero and there aren't enough available bytes, nullptr will be returned
// and "offset_ptr" will not be updated.
const char *DataExtractor::GetCStr(offset_t *offset_ptr) const {
- const char *cstr = reinterpret_cast<const char *>(PeekData(*offset_ptr, 1));
- if (cstr) {
- const char *cstr_end = cstr;
- const char *end = reinterpret_cast<const char *>(m_end);
- while (cstr_end < end && *cstr_end)
- ++cstr_end;
-
- // Now we are either at the end of the data or we point to the
- // NULL C string terminator with cstr_end...
- if (*cstr_end == '\0') {
- // Advance the offset with one extra byte for the NULL terminator
- *offset_ptr += (cstr_end - cstr + 1);
- return cstr;
- }
+ const char *start = reinterpret_cast<const char *>(PeekData(*offset_ptr, 1));
+ // Already at the end of the data.
+ if (!start)
+ return nullptr;
- // We reached the end of the data without finding a NULL C string
- // terminator. Fall through and return nullptr otherwise anyone that would
- // have used the result as a C string can wander into unknown memory...
- }
- return nullptr;
+ const char *end = reinterpret_cast<const char *>(m_end);
+
+ // Check all bytes for a null terminator that terminates a C string.
+ const char *terminator_or_end = std::find(start, end, '\0');
+
+ // We didn't find a null terminator, so return nullptr to indicate that there
+ // is no valid C string at that offset.
+ if (terminator_or_end == end)
+ return nullptr;
+
+ // Update offset_ptr for the caller to point to the data behind the
+ // terminator (which is 1 byte long).
+ *offset_ptr += (terminator_or_end - start + 1UL);
+ return start;
}
// Extracts a NULL terminated C string from the fixed length field of length
diff --git a/source/Utility/FileCollector.cpp b/source/Utility/FileCollector.cpp
deleted file mode 100644
index ed93591922056..0000000000000
--- a/source/Utility/FileCollector.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- FileCollector.cpp ---------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/FileCollector.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-
-using namespace lldb_private;
-using namespace llvm;
-
-static bool IsCaseSensitivePath(StringRef path) {
- SmallString<256> tmp_dest = path, upper_dest, real_dest;
-
- // Remove component traversals, links, etc.
- if (!sys::fs::real_path(path, tmp_dest))
- return true; // Current default value in vfs.yaml
- path = tmp_dest;
-
- // Change path to all upper case and ask for its real path, if the latter
- // exists and is equal to path, it's not case sensitive. Default to case
- // sensitive in the absence of real_path, since this is the YAMLVFSWriter
- // default.
- upper_dest = path.upper();
- if (sys::fs::real_path(upper_dest, real_dest) && path.equals(real_dest))
- return false;
- return true;
-}
-
-FileCollector::FileCollector(const FileSpec &root, const FileSpec &overlay_root)
- : m_root(root), m_overlay_root(overlay_root) {
- sys::fs::create_directories(m_root.GetPath(), true);
-}
-
-bool FileCollector::GetRealPath(StringRef src_path,
- SmallVectorImpl<char> &result) {
- SmallString<256> real_path;
- StringRef FileName = sys::path::filename(src_path);
- std::string directory = sys::path::parent_path(src_path).str();
- auto dir_with_symlink = m_symlink_map.find(directory);
-
- // Use real_path to fix any symbolic link component present in a path.
- // Computing the real path is expensive, cache the search through the
- // parent path directory.
- if (dir_with_symlink == m_symlink_map.end()) {
- auto ec = sys::fs::real_path(directory, real_path);
- if (ec)
- return false;
- m_symlink_map[directory] = real_path.str();
- } else {
- real_path = dir_with_symlink->second;
- }
-
- sys::path::append(real_path, FileName);
- result.swap(real_path);
- return true;
-}
-
-void FileCollector::AddFile(const Twine &file) {
- std::lock_guard<std::mutex> lock(m_mutex);
- std::string file_str = file.str();
- if (MarkAsSeen(file_str))
- AddFileImpl(file_str);
-}
-
-void FileCollector::AddFileImpl(StringRef src_path) {
- std::string root = m_root.GetPath();
-
- // We need an absolute src path to append to the root.
- SmallString<256> absolute_src = src_path;
- sys::fs::make_absolute(absolute_src);
-
- // Canonicalize src to a native path to avoid mixed separator styles.
- sys::path::native(absolute_src);
-
- // Remove redundant leading "./" pieces and consecutive separators.
- absolute_src = sys::path::remove_leading_dotslash(absolute_src);
-
- // Canonicalize the source path by removing "..", "." components.
- SmallString<256> virtual_path = absolute_src;
- sys::path::remove_dots(virtual_path, /*remove_dot_dot=*/true);
-
- // If a ".." component is present after a symlink component, remove_dots may
- // lead to the wrong real destination path. Let the source be canonicalized
- // like that but make sure we always use the real path for the destination.
- SmallString<256> copy_from;
- if (!GetRealPath(absolute_src, copy_from))
- copy_from = virtual_path;
-
- SmallString<256> dst_path = StringRef(root);
- sys::path::append(dst_path, sys::path::relative_path(copy_from));
-
- // Always map a canonical src path to its real path into the YAML, by doing
- // this we map different virtual src paths to the same entry in the VFS
- // overlay, which is a way to emulate symlink inside the VFS; this is also
- // needed for correctness, not doing that can lead to module redefinition
- // errors.
- AddFileToMapping(virtual_path, dst_path);
-}
-
-/// Set the access and modification time for the given file from the given
-/// status object.
-static std::error_code
-CopyAccessAndModificationTime(StringRef filename,
- const sys::fs::file_status &stat) {
- int fd;
-
- if (auto ec =
- sys::fs::openFileForWrite(filename, fd, sys::fs::CD_OpenExisting))
- return ec;
-
- if (auto ec = sys::fs::setLastAccessAndModificationTime(
- fd, stat.getLastAccessedTime(), stat.getLastModificationTime()))
- return ec;
-
- if (auto ec = sys::Process::SafelyCloseFileDescriptor(fd))
- return ec;
-
- return {};
-}
-
-std::error_code FileCollector::CopyFiles(bool stop_on_error) {
- for (auto &entry : m_vfs_writer.getMappings()) {
- // Create directory tree.
- if (std::error_code ec =
- sys::fs::create_directories(sys::path::parent_path(entry.RPath),
- /*IgnoreExisting=*/true)) {
- if (stop_on_error)
- return ec;
- }
-
- // Copy file over.
- if (std::error_code ec = sys::fs::copy_file(entry.VPath, entry.RPath)) {
- if (stop_on_error)
- return ec;
- }
-
- // Copy over permissions.
- if (auto perms = sys::fs::getPermissions(entry.VPath)) {
- if (std::error_code ec = sys::fs::setPermissions(entry.RPath, *perms)) {
- if (stop_on_error)
- return ec;
- }
- }
-
- // Copy over modification time.
- sys::fs::file_status stat;
- if (std::error_code ec = sys::fs::status(entry.VPath, stat)) {
- if (stop_on_error)
- return ec;
- continue;
- }
- CopyAccessAndModificationTime(entry.RPath, stat);
- }
- return {};
-}
-
-std::error_code FileCollector::WriteMapping(const FileSpec &mapping_file) {
- std::lock_guard<std::mutex> lock(m_mutex);
-
- std::string root = m_overlay_root.GetPath();
-
- m_vfs_writer.setOverlayDir(root);
- m_vfs_writer.setCaseSensitivity(IsCaseSensitivePath(root));
- m_vfs_writer.setUseExternalNames(false);
-
- std::error_code ec;
- raw_fd_ostream os(mapping_file.GetPath(), ec, sys::fs::F_Text);
- if (ec)
- return ec;
-
- m_vfs_writer.write(os);
-
- return {};
-}
diff --git a/source/Utility/FileSpec.cpp b/source/Utility/FileSpec.cpp
index 35d22404b9480..f22ab4d84e40a 100644
--- a/source/Utility/FileSpec.cpp
+++ b/source/Utility/FileSpec.cpp
@@ -72,8 +72,8 @@ FileSpec::FileSpec(llvm::StringRef path, Style style) : m_style(style) {
SetFile(path, style);
}
-FileSpec::FileSpec(llvm::StringRef path, const llvm::Triple &Triple)
- : FileSpec{path, Triple.isOSWindows() ? Style::windows : Style::posix} {}
+FileSpec::FileSpec(llvm::StringRef path, const llvm::Triple &triple)
+ : FileSpec{path, triple.isOSWindows() ? Style::windows : Style::posix} {}
// Copy constructor
FileSpec::FileSpec(const FileSpec *rhs) : m_directory(), m_filename() {
@@ -228,8 +228,8 @@ void FileSpec::SetFile(llvm::StringRef pathname, Style style) {
m_directory.SetString(directory);
}
-void FileSpec::SetFile(llvm::StringRef path, const llvm::Triple &Triple) {
- return SetFile(path, Triple.isOSWindows() ? Style::windows : Style::posix);
+void FileSpec::SetFile(llvm::StringRef path, const llvm::Triple &triple) {
+ return SetFile(path, triple.isOSWindows() ? Style::windows : Style::posix);
}
// Convert to pointer operator. This allows code to check any FileSpec objects
diff --git a/source/Utility/GDBRemote.cpp b/source/Utility/GDBRemote.cpp
new file mode 100644
index 0000000000000..85c4bc69a8d10
--- /dev/null
+++ b/source/Utility/GDBRemote.cpp
@@ -0,0 +1,105 @@
+//===-- GDBRemote.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/Utility/GDBRemote.h"
+
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/Stream.h"
+
+#include <stdio.h>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
+StreamGDBRemote::StreamGDBRemote() : StreamString() {}
+
+StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size,
+ ByteOrder byte_order)
+ : StreamString(flags, addr_size, byte_order) {}
+
+StreamGDBRemote::~StreamGDBRemote() {}
+
+int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
+ int bytes_written = 0;
+ const uint8_t *src = static_cast<const uint8_t *>(s);
+ bool binary_is_set = m_flags.Test(eBinary);
+ m_flags.Clear(eBinary);
+ while (src_len) {
+ uint8_t byte = *src;
+ src++;
+ src_len--;
+ if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) {
+ bytes_written += PutChar(0x7d);
+ byte ^= 0x20;
+ }
+ bytes_written += PutChar(byte);
+ };
+ if (binary_is_set)
+ m_flags.Set(eBinary);
+ return bytes_written;
+}
+
+void GDBRemotePacket::Serialize(raw_ostream &strm) const {
+ yaml::Output yout(strm);
+ yout << const_cast<GDBRemotePacket &>(*this);
+ strm.flush();
+}
+
+llvm::StringRef GDBRemotePacket::GetTypeStr() const {
+ switch (type) {
+ case GDBRemotePacket::ePacketTypeSend:
+ return "send";
+ case GDBRemotePacket::ePacketTypeRecv:
+ return "read";
+ case GDBRemotePacket::ePacketTypeInvalid:
+ return "invalid";
+ }
+ llvm_unreachable("All enum cases should be handled");
+}
+
+void GDBRemotePacket::Dump(Stream &strm) const {
+ strm.Printf("tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", tid,
+ bytes_transmitted, GetTypeStr().data(), packet.data.c_str());
+}
+
+void yaml::ScalarEnumerationTraits<GDBRemotePacket::Type>::enumeration(
+ IO &io, GDBRemotePacket::Type &value) {
+ io.enumCase(value, "Invalid", GDBRemotePacket::ePacketTypeInvalid);
+ io.enumCase(value, "Send", GDBRemotePacket::ePacketTypeSend);
+ io.enumCase(value, "Recv", GDBRemotePacket::ePacketTypeRecv);
+}
+
+void yaml::ScalarTraits<GDBRemotePacket::BinaryData>::output(
+ const GDBRemotePacket::BinaryData &Val, void *, raw_ostream &Out) {
+ Out << toHex(Val.data);
+}
+
+StringRef yaml::ScalarTraits<GDBRemotePacket::BinaryData>::input(
+ StringRef Scalar, void *, GDBRemotePacket::BinaryData &Val) {
+ Val.data = fromHex(Scalar);
+ return {};
+}
+
+void yaml::MappingTraits<GDBRemotePacket>::mapping(IO &io,
+ GDBRemotePacket &Packet) {
+ io.mapRequired("packet", Packet.packet);
+ io.mapRequired("type", Packet.type);
+ io.mapRequired("bytes", Packet.bytes_transmitted);
+ io.mapRequired("index", Packet.packet_idx);
+ io.mapRequired("tid", Packet.tid);
+}
+
+StringRef
+yaml::MappingTraits<GDBRemotePacket>::validate(IO &io,
+ GDBRemotePacket &Packet) {
+ if (Packet.bytes_transmitted != Packet.packet.data.size())
+ return "BinaryData size doesn't match bytes transmitted";
+
+ return {};
+}
diff --git a/source/Utility/JSON.cpp b/source/Utility/JSON.cpp
deleted file mode 100644
index 2c3f6229eda11..0000000000000
--- a/source/Utility/JSON.cpp
+++ /dev/null
@@ -1,550 +0,0 @@
-//===--------------------- JSON.cpp -----------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/JSON.h"
-
-#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/StreamString.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ErrorHandling.h"
-
-#include <inttypes.h>
-#include <limits.h>
-#include <stddef.h>
-#include <utility>
-
-using namespace lldb_private;
-
-std::string JSONString::json_string_quote_metachars(const std::string &s) {
- if (s.find_first_of("\\\n\"") == std::string::npos)
- return s;
-
- std::string output;
- const size_t s_size = s.size();
- const char *s_chars = s.c_str();
- for (size_t i = 0; i < s_size; i++) {
- unsigned char ch = *(s_chars + i);
- if (ch == '"' || ch == '\\' || ch == '\n') {
- output.push_back('\\');
- if (ch == '\n') ch = 'n';
- }
- output.push_back(ch);
- }
- return output;
-}
-
-JSONString::JSONString() : JSONValue(JSONValue::Kind::String), m_data() {}
-
-JSONString::JSONString(const char *s)
- : JSONValue(JSONValue::Kind::String), m_data(s ? s : "") {}
-
-JSONString::JSONString(const std::string &s)
- : JSONValue(JSONValue::Kind::String), m_data(s) {}
-
-void JSONString::Write(Stream &s) {
- s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str());
-}
-
-uint64_t JSONNumber::GetAsUnsigned() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return m_data.m_unsigned;
- case DataType::Signed:
- return static_cast<uint64_t>(m_data.m_signed);
- case DataType::Double:
- return static_cast<uint64_t>(m_data.m_double);
- }
- llvm_unreachable("Unhandled data type");
-}
-
-int64_t JSONNumber::GetAsSigned() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return static_cast<int64_t>(m_data.m_unsigned);
- case DataType::Signed:
- return m_data.m_signed;
- case DataType::Double:
- return static_cast<int64_t>(m_data.m_double);
- }
- llvm_unreachable("Unhandled data type");
-}
-
-double JSONNumber::GetAsDouble() const {
- switch (m_data_type) {
- case DataType::Unsigned:
- return static_cast<double>(m_data.m_unsigned);
- case DataType::Signed:
- return static_cast<double>(m_data.m_signed);
- case DataType::Double:
- return m_data.m_double;
- }
- llvm_unreachable("Unhandled data type");
-}
-
-void JSONNumber::Write(Stream &s) {
- switch (m_data_type) {
- case DataType::Unsigned:
- s.Printf("%" PRIu64, m_data.m_unsigned);
- break;
- case DataType::Signed:
- s.Printf("%" PRId64, m_data.m_signed);
- break;
- case DataType::Double:
- s.Printf("%g", m_data.m_double);
- break;
- }
-}
-
-JSONTrue::JSONTrue() : JSONValue(JSONValue::Kind::True) {}
-
-void JSONTrue::Write(Stream &s) { s.Printf("true"); }
-
-JSONFalse::JSONFalse() : JSONValue(JSONValue::Kind::False) {}
-
-void JSONFalse::Write(Stream &s) { s.Printf("false"); }
-
-JSONNull::JSONNull() : JSONValue(JSONValue::Kind::Null) {}
-
-void JSONNull::Write(Stream &s) { s.Printf("null"); }
-
-JSONObject::JSONObject() : JSONValue(JSONValue::Kind::Object) {}
-
-void JSONObject::Write(Stream &s) {
- bool first = true;
- s.PutChar('{');
- auto iter = m_elements.begin(), end = m_elements.end();
- for (; iter != end; iter++) {
- if (first)
- first = false;
- else
- s.PutChar(',');
- JSONString key(iter->first);
- JSONValue::SP value(iter->second);
- key.Write(s);
- s.PutChar(':');
- value->Write(s);
- }
- s.PutChar('}');
-}
-
-bool JSONObject::SetObject(const std::string &key, JSONValue::SP value) {
- if (key.empty() || nullptr == value.get())
- return false;
- m_elements[key] = value;
- return true;
-}
-
-JSONValue::SP JSONObject::GetObject(const std::string &key) {
- auto iter = m_elements.find(key), end = m_elements.end();
- if (iter == end)
- return JSONValue::SP();
- return iter->second;
-}
-
-JSONArray::JSONArray() : JSONValue(JSONValue::Kind::Array) {}
-
-void JSONArray::Write(Stream &s) {
- bool first = true;
- s.PutChar('[');
- auto iter = m_elements.begin(), end = m_elements.end();
- for (; iter != end; iter++) {
- if (first)
- first = false;
- else
- s.PutChar(',');
- (*iter)->Write(s);
- }
- s.PutChar(']');
-}
-
-bool JSONArray::SetObject(Index i, JSONValue::SP value) {
- if (value.get() == nullptr)
- return false;
- if (i < m_elements.size()) {
- m_elements[i] = value;
- return true;
- }
- if (i == m_elements.size()) {
- m_elements.push_back(value);
- return true;
- }
- return false;
-}
-
-bool JSONArray::AppendObject(JSONValue::SP value) {
- if (value.get() == nullptr)
- return false;
- m_elements.push_back(value);
- return true;
-}
-
-JSONValue::SP JSONArray::GetObject(Index i) {
- if (i < m_elements.size())
- return m_elements[i];
- return JSONValue::SP();
-}
-
-JSONArray::Size JSONArray::GetNumElements() { return m_elements.size(); }
-
-JSONParser::JSONParser(llvm::StringRef data) : StringExtractor(data) {}
-
-JSONParser::Token JSONParser::GetToken(std::string &value) {
- StreamString error;
-
- value.clear();
- SkipSpaces();
- const uint64_t start_index = m_index;
- const char ch = GetChar();
- switch (ch) {
- case '{':
- return Token::ObjectStart;
- case '}':
- return Token::ObjectEnd;
- case '[':
- return Token::ArrayStart;
- case ']':
- return Token::ArrayEnd;
- case ',':
- return Token::Comma;
- case ':':
- return Token::Colon;
- case '\0':
- return Token::EndOfFile;
- case 't':
- if (GetChar() == 'r')
- if (GetChar() == 'u')
- if (GetChar() == 'e')
- return Token::True;
- break;
-
- case 'f':
- if (GetChar() == 'a')
- if (GetChar() == 'l')
- if (GetChar() == 's')
- if (GetChar() == 'e')
- return Token::False;
- break;
-
- case 'n':
- if (GetChar() == 'u')
- if (GetChar() == 'l')
- if (GetChar() == 'l')
- return Token::Null;
- break;
-
- case '"': {
- while (true) {
- bool was_escaped = false;
- int escaped_ch = GetEscapedChar(was_escaped);
- if (escaped_ch == -1) {
- error.Printf(
- "error: an error occurred getting a character from offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
-
- } else {
- const bool is_end_quote = escaped_ch == '"';
- const bool is_null = escaped_ch == 0;
- if (was_escaped || (!is_end_quote && !is_null)) {
- if (CHAR_MIN <= escaped_ch && escaped_ch <= CHAR_MAX) {
- value.append(1, static_cast<char>(escaped_ch));
- } else {
- error.Printf("error: wide character support is needed for unicode "
- "character 0x%4.4x at offset %" PRIu64,
- escaped_ch, start_index);
- value = std::move(error.GetString());
- return Token::Status;
- }
- } else if (is_end_quote) {
- return Token::String;
- } else if (is_null) {
- value = "error: missing end quote for string";
- return Token::Status;
- }
- }
- }
- } break;
-
- case '-':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- bool done = false;
- bool got_decimal_point = false;
- uint64_t exp_index = 0;
- bool got_int_digits = (ch >= '0') && (ch <= '9');
- bool got_frac_digits = false;
- bool got_exp_digits = false;
- while (!done) {
- const char next_ch = PeekChar();
- switch (next_ch) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (exp_index != 0) {
- got_exp_digits = true;
- } else if (got_decimal_point) {
- got_frac_digits = true;
- } else {
- got_int_digits = true;
- }
- ++m_index; // Skip this character
- break;
-
- case '.':
- if (got_decimal_point) {
- error.Printf("error: extra decimal point found at offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
- } else {
- got_decimal_point = true;
- ++m_index; // Skip this character
- }
- break;
-
- case 'e':
- case 'E':
- if (exp_index != 0) {
- error.Printf(
- "error: extra exponent character found at offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
- } else {
- exp_index = m_index;
- ++m_index; // Skip this character
- }
- break;
-
- case '+':
- case '-':
- // The '+' and '-' can only come after an exponent character...
- if (exp_index == m_index - 1) {
- ++m_index; // Skip the exponent sign character
- } else {
- error.Printf("error: unexpected %c character at offset %" PRIu64,
- next_ch, start_index);
- value = std::move(error.GetString());
- return Token::Status;
- }
- break;
-
- default:
- done = true;
- break;
- }
- }
-
- if (m_index > start_index) {
- value = m_packet.substr(start_index, m_index - start_index);
- if (got_decimal_point) {
- if (exp_index != 0) {
- // We have an exponent, make sure we got exponent digits
- if (got_exp_digits) {
- return Token::Float;
- } else {
- error.Printf("error: got exponent character but no exponent digits "
- "at offset in float value \"%s\"",
- value.c_str());
- value = std::move(error.GetString());
- return Token::Status;
- }
- } else {
- // No exponent, but we need at least one decimal after the decimal
- // point
- if (got_frac_digits) {
- return Token::Float;
- } else {
- error.Printf("error: no digits after decimal point \"%s\"",
- value.c_str());
- value = std::move(error.GetString());
- return Token::Status;
- }
- }
- } else {
- // No decimal point
- if (got_int_digits) {
- // We need at least some integer digits to make an integer
- return Token::Integer;
- } else {
- error.Printf("error: no digits negate sign \"%s\"", value.c_str());
- value = std::move(error.GetString());
- return Token::Status;
- }
- }
- } else {
- error.Printf("error: invalid number found at offset %" PRIu64,
- start_index);
- value = std::move(error.GetString());
- return Token::Status;
- }
- } break;
- default:
- break;
- }
- error.Printf("error: failed to parse token at offset %" PRIu64
- " (around character '%c')",
- start_index, ch);
- value = std::move(error.GetString());
- return Token::Status;
-}
-
-int JSONParser::GetEscapedChar(bool &was_escaped) {
- was_escaped = false;
- const char ch = GetChar();
- if (ch == '\\') {
- was_escaped = true;
- const char ch2 = GetChar();
- switch (ch2) {
- case '"':
- case '\\':
- case '/':
- default:
- break;
-
- case 'b':
- return '\b';
- case 'f':
- return '\f';
- case 'n':
- return '\n';
- case 'r':
- return '\r';
- case 't':
- return '\t';
- case 'u': {
- const int hi_byte = DecodeHexU8();
- const int lo_byte = DecodeHexU8();
- if (hi_byte >= 0 && lo_byte >= 0)
- return hi_byte << 8 | lo_byte;
- return -1;
- } break;
- }
- return ch2;
- }
- return ch;
-}
-
-JSONValue::SP JSONParser::ParseJSONObject() {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- std::unique_ptr<JSONObject> dict_up(new JSONObject());
-
- std::string value;
- std::string key;
- while (true) {
- JSONParser::Token token = GetToken(value);
-
- if (token == JSONParser::Token::String) {
- key.swap(value);
- token = GetToken(value);
- if (token == JSONParser::Token::Colon) {
- JSONValue::SP value_sp = ParseJSONValue();
- if (value_sp)
- dict_up->SetObject(key, value_sp);
- else
- break;
- }
- } else if (token == JSONParser::Token::ObjectEnd) {
- return JSONValue::SP(dict_up.release());
- } else if (token == JSONParser::Token::Comma) {
- continue;
- } else {
- break;
- }
- }
- return JSONValue::SP();
-}
-
-JSONValue::SP JSONParser::ParseJSONArray() {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- std::unique_ptr<JSONArray> array_up(new JSONArray());
-
- std::string value;
- std::string key;
- while (true) {
- JSONValue::SP value_sp = ParseJSONValue();
- if (value_sp)
- array_up->AppendObject(value_sp);
- else
- break;
-
- JSONParser::Token token = GetToken(value);
- if (token == JSONParser::Token::Comma) {
- continue;
- } else if (token == JSONParser::Token::ArrayEnd) {
- return JSONValue::SP(array_up.release());
- } else {
- break;
- }
- }
- return JSONValue::SP();
-}
-
-JSONValue::SP JSONParser::ParseJSONValue() {
- std::string value;
- const JSONParser::Token token = GetToken(value);
- switch (token) {
- case JSONParser::Token::ObjectStart:
- return ParseJSONObject();
-
- case JSONParser::Token::ArrayStart:
- return ParseJSONArray();
-
- case JSONParser::Token::Integer: {
- if (value.front() == '-') {
- int64_t sval = 0;
- if (!llvm::StringRef(value).getAsInteger(0, sval))
- return JSONValue::SP(new JSONNumber(sval));
- } else {
- uint64_t uval = 0;
- if (!llvm::StringRef(value).getAsInteger(0, uval))
- return JSONValue::SP(new JSONNumber(uval));
- }
- } break;
-
- case JSONParser::Token::Float: {
- double D;
- if (!llvm::StringRef(value).getAsDouble(D))
- return JSONValue::SP(new JSONNumber(D));
- } break;
-
- case JSONParser::Token::String:
- return JSONValue::SP(new JSONString(value));
-
- case JSONParser::Token::True:
- return JSONValue::SP(new JSONTrue());
-
- case JSONParser::Token::False:
- return JSONValue::SP(new JSONFalse());
-
- case JSONParser::Token::Null:
- return JSONValue::SP(new JSONNull());
-
- default:
- break;
- }
- return JSONValue::SP();
-}
diff --git a/source/Utility/Listener.cpp b/source/Utility/Listener.cpp
index 50c56406c2ca5..c2e537ba7dee0 100644
--- a/source/Utility/Listener.cpp
+++ b/source/Utility/Listener.cpp
@@ -42,8 +42,8 @@ Listener::Listener(const char *name)
m_events_mutex() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
if (log != nullptr)
- log->Printf("%p Listener::Listener('%s')", static_cast<void *>(this),
- m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast<void *>(this),
+ m_name.c_str());
}
Listener::~Listener() {
@@ -51,9 +51,8 @@ Listener::~Listener() {
Clear();
- if (log)
- log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
- __FUNCTION__, m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
}
void Listener::Clear() {
@@ -78,9 +77,8 @@ void Listener::Clear() {
manager_sp->RemoveListener(this);
}
- if (log)
- log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
- __FUNCTION__, m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
}
uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
@@ -101,10 +99,11 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
if (log != nullptr)
- log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
- "mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
- static_cast<void *>(this), static_cast<void *>(broadcaster),
- event_mask, acquired_mask, m_name.c_str());
+ LLDB_LOGF(log,
+ "%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, acquired_mask, m_name.c_str());
return acquired_mask;
}
@@ -132,12 +131,13 @@ uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
if (log != nullptr) {
void **pointer = reinterpret_cast<void **>(&callback);
- log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
- "mask = 0x%8.8x, callback = %p, user_data = %p) "
- "acquired_mask = 0x%8.8x for %s",
- static_cast<void *>(this), static_cast<void *>(broadcaster),
- event_mask, *pointer, static_cast<void *>(callback_user_data),
- acquired_mask, m_name.c_str());
+ LLDB_LOGF(log,
+ "%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x, callback = %p, user_data = %p) "
+ "acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, *pointer, static_cast<void *>(callback_user_data),
+ acquired_mask, m_name.c_str());
}
return acquired_mask;
@@ -202,9 +202,9 @@ void Listener::BroadcasterManagerWillDestruct(BroadcasterManagerSP manager_sp) {
void Listener::AddEvent(EventSP &event_sp) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
if (log != nullptr)
- log->Printf("%p Listener('%s')::AddEvent (event_sp = {%p})",
- static_cast<void *>(this), m_name.c_str(),
- static_cast<void *>(event_sp.get()));
+ LLDB_LOGF(log, "%p Listener('%s')::AddEvent (event_sp = {%p})",
+ static_cast<void *>(this), m_name.c_str(),
+ static_cast<void *>(event_sp.get()));
std::lock_guard<std::mutex> guard(m_events_mutex);
m_events.push_back(event_sp);
@@ -290,14 +290,15 @@ bool Listener::FindNextEventInternal(
event_sp = *pos;
if (log != nullptr)
- log->Printf("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, "
- "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, "
- "remove=%i) event %p",
- static_cast<void *>(this), GetName(),
- static_cast<void *>(broadcaster),
- static_cast<const void *>(broadcaster_names),
- num_broadcaster_names, event_type_mask, remove,
- static_cast<void *>(event_sp.get()));
+ LLDB_LOGF(log,
+ "%p '%s' Listener::FindNextEventInternal(broadcaster=%p, "
+ "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, "
+ "remove=%i) event %p",
+ static_cast<void *>(this), GetName(),
+ static_cast<void *>(broadcaster),
+ static_cast<const void *>(broadcaster_names),
+ num_broadcaster_names, event_type_mask, remove,
+ static_cast<void *>(event_sp.get()));
if (remove) {
m_events.erase(pos);
@@ -366,15 +367,13 @@ bool Listener::GetEventInternal(
if (result == std::cv_status::timeout) {
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
- if (log)
- log->Printf("%p Listener::GetEventInternal() timed out for %s",
- static_cast<void *>(this), m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::GetEventInternal() timed out for %s",
+ static_cast<void *>(this), m_name.c_str());
return false;
} else if (result != std::cv_status::no_timeout) {
log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
- if (log)
- log->Printf("%p Listener::GetEventInternal() unknown error for %s",
- static_cast<void *>(this), m_name.c_str());
+ LLDB_LOGF(log, "%p Listener::GetEventInternal() unknown error for %s",
+ static_cast<void *>(this), m_name.c_str());
return false;
}
}
diff --git a/source/Utility/Log.cpp b/source/Utility/Log.cpp
index 217b0d2ba97b1..ab5e630114a6b 100644
--- a/source/Utility/Log.cpp
+++ b/source/Utility/Log.cpp
@@ -9,7 +9,6 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/VASPrintf.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator.h"
@@ -38,13 +37,22 @@ using namespace lldb_private;
llvm::ManagedStatic<Log::ChannelMap> Log::g_channel_map;
-void Log::ListCategories(llvm::raw_ostream &stream, const ChannelMap::value_type &entry) {
- stream << llvm::formatv("Logging categories for '{0}':\n", entry.first());
- stream << " all - all available logging categories\n";
- stream << " default - default set of logging categories\n";
+void Log::ForEachCategory(
+ const Log::ChannelMap::value_type &entry,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda) {
+ lambda("all", "all available logging categories");
+ lambda("default", "default set of logging categories");
for (const auto &category : entry.second.m_channel.categories)
- stream << llvm::formatv(" {0} - {1}\n", category.name,
- category.description);
+ lambda(category.name, category.description);
+}
+
+void Log::ListCategories(llvm::raw_ostream &stream,
+ const ChannelMap::value_type &entry) {
+ stream << llvm::formatv("Logging categories for '{0}':\n", entry.first());
+ ForEachCategory(entry,
+ [&stream](llvm::StringRef name, llvm::StringRef description) {
+ stream << llvm::formatv(" {0} - {1}\n", name, description);
+ });
}
uint32_t Log::GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
@@ -237,6 +245,23 @@ void Log::DisableAllLogChannels() {
entry.second.Disable(UINT32_MAX);
}
+void Log::ForEachChannelCategory(
+ llvm::StringRef channel,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda) {
+ auto ch = g_channel_map->find(channel);
+ if (ch == g_channel_map->end())
+ return;
+
+ ForEachCategory(*ch, lambda);
+}
+
+std::vector<llvm::StringRef> Log::ListChannels() {
+ std::vector<llvm::StringRef> result;
+ for (const auto &channel : *g_channel_map)
+ result.push_back(channel.first());
+ return result;
+}
+
void Log::ListAllLogChannels(llvm::raw_ostream &stream) {
if (g_channel_map->empty()) {
stream << "No logging channels are currently registered.\n";
diff --git a/source/Utility/Logging.cpp b/source/Utility/Logging.cpp
index c0856e5d9267d..22f38192fa5d1 100644
--- a/source/Utility/Logging.cpp
+++ b/source/Utility/Logging.cpp
@@ -62,13 +62,3 @@ Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) {
Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) {
return g_log_channel.GetLogIfAny(mask);
}
-
-
-void lldb_private::LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...) {
- if (Log *log = GetLogIfAnyCategoriesSet(mask)) {
- va_list args;
- va_start(args, format);
- log->VAPrintf(format, args);
- va_end(args);
- }
-}
diff --git a/source/Utility/ProcessInfo.cpp b/source/Utility/ProcessInfo.cpp
index b67ae87790006..5743d223be4fa 100644
--- a/source/Utility/ProcessInfo.cpp
+++ b/source/Utility/ProcessInfo.cpp
@@ -42,8 +42,8 @@ const char *ProcessInfo::GetName() const {
return m_executable.GetFilename().GetCString();
}
-size_t ProcessInfo::GetNameLength() const {
- return m_executable.GetFilename().GetLength();
+llvm::StringRef ProcessInfo::GetNameAsStringRef() const {
+ return m_executable.GetFilename().GetStringRef();
}
void ProcessInfo::Dump(Stream &s, Platform *platform) const {
@@ -169,13 +169,15 @@ void ProcessInstanceInfo::DumpTableHeader(Stream &s, bool show_args,
if (verbose) {
s.Printf("PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE "
- " %s\n",
+ " %s\n",
label);
- s.PutCString("====== ====== ========== ========== ========== ========== "
- "======================== ============================\n");
+ s.PutCString(
+ "====== ====== ========== ========== ========== ========== "
+ "============================== ============================\n");
} else {
- s.Printf("PID PARENT USER TRIPLE %s\n", label);
- s.PutCString("====== ====== ========== ======================== "
+ s.Printf("PID PARENT USER TRIPLE %s\n",
+ label);
+ s.PutCString("====== ====== ========== ============================== "
"============================\n");
}
}
@@ -189,34 +191,47 @@ void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,
if (m_arch.IsValid())
m_arch.DumpTriple(arch_strm);
- auto print = [&](UserIDResolver::id_t id,
- llvm::Optional<llvm::StringRef> (UserIDResolver::*get)(
+ auto print = [&](bool (ProcessInstanceInfo::*isValid)() const,
+ uint32_t (ProcessInstanceInfo::*getID)() const,
+ llvm::Optional<llvm::StringRef> (UserIDResolver::*getName)(
UserIDResolver::id_t id)) {
- if (auto name = (resolver.*get)(id))
- s.Format("{0,-10} ", *name);
+ const char *format = "{0,-10} ";
+ if (!(this->*isValid)()) {
+ s.Format(format, "");
+ return;
+ }
+ uint32_t id = (this->*getID)();
+ if (auto name = (resolver.*getName)(id))
+ s.Format(format, *name);
else
- s.Format("{0,-10} ", id);
+ s.Format(format, id);
};
if (verbose) {
- print(m_uid, &UserIDResolver::GetUserName);
- print(m_gid, &UserIDResolver::GetGroupName);
- print(m_euid, &UserIDResolver::GetUserName);
- print(m_egid, &UserIDResolver::GetGroupName);
-
- s.Printf("%-24s ", arch_strm.GetData());
+ print(&ProcessInstanceInfo::UserIDIsValid,
+ &ProcessInstanceInfo::GetUserID, &UserIDResolver::GetUserName);
+ print(&ProcessInstanceInfo::GroupIDIsValid,
+ &ProcessInstanceInfo::GetGroupID, &UserIDResolver::GetGroupName);
+ print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
+ &ProcessInstanceInfo::GetEffectiveUserID,
+ &UserIDResolver::GetUserName);
+ print(&ProcessInstanceInfo::EffectiveGroupIDIsValid,
+ &ProcessInstanceInfo::GetEffectiveGroupID,
+ &UserIDResolver::GetGroupName);
+
+ s.Printf("%-30s ", arch_strm.GetData());
} else {
- print(m_euid, &UserIDResolver::GetUserName);
- s.Printf(" %-24s ", arch_strm.GetData());
+ print(&ProcessInstanceInfo::EffectiveUserIDIsValid,
+ &ProcessInstanceInfo::GetEffectiveUserID,
+ &UserIDResolver::GetUserName);
+ s.Printf("%-30s ", arch_strm.GetData());
}
if (verbose || show_args) {
+ s.PutCString(m_arg0);
const uint32_t argc = m_arguments.GetArgumentCount();
- if (argc > 0) {
- for (uint32_t i = 0; i < argc; i++) {
- if (i > 0)
- s.PutChar(' ');
- s.PutCString(m_arguments.GetArgumentAtIndex(i));
- }
+ for (uint32_t i = 0; i < argc; i++) {
+ s.PutChar(' ');
+ s.PutCString(m_arguments.GetArgumentAtIndex(i));
}
} else {
s.PutCString(GetName());
@@ -226,8 +241,14 @@ void ProcessInstanceInfo::DumpAsTableRow(Stream &s, UserIDResolver &resolver,
}
}
+bool ProcessInstanceInfoMatch::ArchitectureMatches(
+ const ArchSpec &arch_spec) const {
+ return !m_match_info.GetArchitecture().IsValid() ||
+ m_match_info.GetArchitecture().IsCompatibleMatch(arch_spec);
+}
+
bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
- if (m_name_match_type == NameMatch::Ignore || process_name == nullptr)
+ if (m_name_match_type == NameMatch::Ignore)
return true;
const char *match_name = m_match_info.GetName();
if (!match_name)
@@ -236,11 +257,8 @@ bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const {
return lldb_private::NameMatches(process_name, m_name_match_type, match_name);
}
-bool ProcessInstanceInfoMatch::Matches(
+bool ProcessInstanceInfoMatch::ProcessIDsMatch(
const ProcessInstanceInfo &proc_info) const {
- if (!NameMatches(proc_info.GetName()))
- return false;
-
if (m_match_info.ProcessIDIsValid() &&
m_match_info.GetProcessID() != proc_info.GetProcessID())
return false;
@@ -248,7 +266,11 @@ bool ProcessInstanceInfoMatch::Matches(
if (m_match_info.ParentProcessIDIsValid() &&
m_match_info.GetParentProcessID() != proc_info.GetParentProcessID())
return false;
+ return true;
+}
+bool ProcessInstanceInfoMatch::UserIDsMatch(
+ const ProcessInstanceInfo &proc_info) const {
if (m_match_info.UserIDIsValid() &&
m_match_info.GetUserID() != proc_info.GetUserID())
return false;
@@ -264,13 +286,14 @@ bool ProcessInstanceInfoMatch::Matches(
if (m_match_info.EffectiveGroupIDIsValid() &&
m_match_info.GetEffectiveGroupID() != proc_info.GetEffectiveGroupID())
return false;
-
- if (m_match_info.GetArchitecture().IsValid() &&
- !m_match_info.GetArchitecture().IsCompatibleMatch(
- proc_info.GetArchitecture()))
- return false;
return true;
}
+bool ProcessInstanceInfoMatch::Matches(
+ const ProcessInstanceInfo &proc_info) const {
+ return ArchitectureMatches(proc_info.GetArchitecture()) &&
+ ProcessIDsMatch(proc_info) && UserIDsMatch(proc_info) &&
+ NameMatches(proc_info.GetName());
+}
bool ProcessInstanceInfoMatch::MatchAllProcesses() const {
if (m_name_match_type != NameMatch::Ignore)
diff --git a/source/Utility/RegularExpression.cpp b/source/Utility/RegularExpression.cpp
index 0192e8b8a01a0..fd9d963f7294c 100644
--- a/source/Utility/RegularExpression.cpp
+++ b/source/Utility/RegularExpression.cpp
@@ -8,168 +8,34 @@
#include "lldb/Utility/RegularExpression.h"
-#include "llvm/ADT/StringRef.h"
-
#include <string>
-// Enable enhanced mode if it is available. This allows for things like \d for
-// digit, \s for space, and many more, but it isn't available everywhere.
-#if defined(REG_ENHANCED)
-#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED)
-#else
-#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
-#endif
-
using namespace lldb_private;
-RegularExpression::RegularExpression() : m_re(), m_comp_err(1), m_preg() {
- memset(&m_preg, 0, sizeof(m_preg));
-}
-
-// Constructor that compiles "re" using "flags" and stores the resulting
-// compiled regular expression into this object.
RegularExpression::RegularExpression(llvm::StringRef str)
- : RegularExpression() {
- Compile(str);
-}
+ : m_regex_text(str),
+ // m_regex does not reference str anymore after it is constructed.
+ m_regex(llvm::Regex(str)) {}
RegularExpression::RegularExpression(const RegularExpression &rhs)
- : RegularExpression() {
- Compile(rhs.GetText());
-}
-
-const RegularExpression &RegularExpression::
-operator=(const RegularExpression &rhs) {
- if (&rhs != this)
- Compile(rhs.GetText());
- return *this;
-}
-
-// Destructor
-//
-// Any previously compiled regular expression contained in this object will be
-// freed.
-RegularExpression::~RegularExpression() { Free(); }
-
-// Compile a regular expression using the supplied regular expression text and
-// flags. The compiled regular expression lives in this object so that it can
-// be readily used for regular expression matches. Execute() can be called
-// after the regular expression is compiled. Any previously compiled regular
-// expression contained in this object will be freed.
-//
-// RETURNS
-// True if the regular expression compiles successfully, false
-// otherwise.
-bool RegularExpression::Compile(llvm::StringRef str) {
- Free();
-
- // regcomp() on darwin does not recognize "" as a valid regular expression,
- // so we substitute it with an equivalent non-empty one.
- m_re = str.empty() ? "()" : str;
- m_comp_err = ::regcomp(&m_preg, m_re.c_str(), DEFAULT_COMPILE_FLAGS);
- return m_comp_err == 0;
-}
+ : RegularExpression(rhs.GetText()) {}
-// Execute a regular expression match using the compiled regular expression
-// that is already in this object against the match string "s". If any parens
-// are used for regular expression matches "match_count" should indicate the
-// number of regmatch_t values that are present in "match_ptr". The regular
-// expression will be executed using the "execute_flags".
-bool RegularExpression::Execute(llvm::StringRef str, Match *match) const {
- int err = 1;
- if (m_comp_err == 0) {
- // Argument to regexec must be null-terminated.
- std::string reg_str = str;
- if (match) {
- err = ::regexec(&m_preg, reg_str.c_str(), match->GetSize(),
- match->GetData(), 0);
- } else {
- err = ::regexec(&m_preg, reg_str.c_str(), 0, nullptr, 0);
- }
- }
-
- if (err != 0) {
- // The regular expression didn't compile, so clear the matches
- if (match)
- match->Clear();
+bool RegularExpression::Execute(
+ llvm::StringRef str,
+ llvm::SmallVectorImpl<llvm::StringRef> *matches) const {
+ if (!IsValid())
return false;
- }
- return true;
-}
-
-bool RegularExpression::Match::GetMatchAtIndex(llvm::StringRef s, uint32_t idx,
- std::string &match_str) const {
- llvm::StringRef match_str_ref;
- if (GetMatchAtIndex(s, idx, match_str_ref)) {
- match_str = match_str_ref.str();
- return true;
- }
- return false;
+ return m_regex.match(str, matches);
}
-bool RegularExpression::Match::GetMatchAtIndex(
- llvm::StringRef s, uint32_t idx, llvm::StringRef &match_str) const {
- if (idx < m_matches.size()) {
- if (m_matches[idx].rm_eo == -1 && m_matches[idx].rm_so == -1)
- return false;
-
- if (m_matches[idx].rm_eo == m_matches[idx].rm_so) {
- // Matched the empty string...
- match_str = llvm::StringRef();
- return true;
- } else if (m_matches[idx].rm_eo > m_matches[idx].rm_so) {
- match_str = s.substr(m_matches[idx].rm_so,
- m_matches[idx].rm_eo - m_matches[idx].rm_so);
- return true;
- }
- }
- return false;
-}
-
-bool RegularExpression::Match::GetMatchSpanningIndices(
- llvm::StringRef s, uint32_t idx1, uint32_t idx2,
- llvm::StringRef &match_str) const {
- if (idx1 < m_matches.size() && idx2 < m_matches.size()) {
- if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo) {
- // Matched the empty string...
- match_str = llvm::StringRef();
- return true;
- } else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo) {
- match_str = s.substr(m_matches[idx1].rm_so,
- m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
- return true;
- }
- }
- return false;
-}
+bool RegularExpression::IsValid() const { return m_regex.isValid(); }
-// Returns true if the regular expression compiled and is ready for execution.
-bool RegularExpression::IsValid() const { return m_comp_err == 0; }
-
-// Returns the text that was used to compile the current regular expression.
-llvm::StringRef RegularExpression::GetText() const { return m_re; }
-
-// Free any contained compiled regular expressions.
-void RegularExpression::Free() {
- if (m_comp_err == 0) {
- m_re.clear();
- regfree(&m_preg);
- // Set a compile error since we no longer have a valid regex
- m_comp_err = 1;
- }
-}
-
-size_t RegularExpression::GetErrorAsCString(char *err_str,
- size_t err_str_max_len) const {
- if (m_comp_err == 0) {
- if (err_str && err_str_max_len)
- *err_str = '\0';
- return 0;
- }
-
- return ::regerror(m_comp_err, &m_preg, err_str, err_str_max_len);
-}
+llvm::StringRef RegularExpression::GetText() const { return m_regex_text; }
-bool RegularExpression::operator<(const RegularExpression &rhs) const {
- return (m_re < rhs.m_re);
+llvm::Error RegularExpression::GetError() const {
+ std::string error;
+ if (!m_regex.isValid(error))
+ return llvm::make_error<llvm::StringError>(llvm::inconvertibleErrorCode(),
+ error);
+ return llvm::Error::success();
}
diff --git a/source/Utility/Reproducer.cpp b/source/Utility/Reproducer.cpp
index 479ed311d1ded..4777d7576a321 100644
--- a/source/Utility/Reproducer.cpp
+++ b/source/Utility/Reproducer.cpp
@@ -136,7 +136,17 @@ FileSpec Reproducer::GetReproducerPath() const {
return {};
}
-Generator::Generator(const FileSpec &root) : m_root(root), m_done(false) {}
+static FileSpec MakeAbsolute(FileSpec file_spec) {
+ SmallString<128> path;
+ file_spec.GetPath(path, false);
+ llvm::sys::fs::make_absolute(path);
+ return FileSpec(path, file_spec.GetPathStyle());
+}
+
+Generator::Generator(FileSpec root)
+ : m_root(MakeAbsolute(std::move(root))), m_done(false) {
+ GetOrCreate<repro::WorkingDirectoryProvider>();
+}
Generator::~Generator() {}
@@ -175,8 +185,8 @@ void Generator::AddProvidersToIndex() {
index.AppendPathComponent("index.yaml");
std::error_code EC;
- auto strm = llvm::make_unique<raw_fd_ostream>(index.GetPath(), EC,
- sys::fs::OpenFlags::F_None);
+ auto strm = std::make_unique<raw_fd_ostream>(index.GetPath(), EC,
+ sys::fs::OpenFlags::OF_None);
yaml::Output yout(*strm);
std::vector<std::string> files;
@@ -188,7 +198,8 @@ void Generator::AddProvidersToIndex() {
yout << files;
}
-Loader::Loader(const FileSpec &root) : m_root(root), m_loaded(false) {}
+Loader::Loader(FileSpec root)
+ : m_root(MakeAbsolute(std::move(root))), m_loaded(false) {}
llvm::Error Loader::LoadIndex() {
if (m_loaded)
@@ -223,7 +234,7 @@ bool Loader::HasFile(StringRef file) {
llvm::Expected<std::unique_ptr<DataRecorder>>
DataRecorder::Create(const FileSpec &filename) {
std::error_code ec;
- auto recorder = llvm::make_unique<DataRecorder>(std::move(filename), ec);
+ auto recorder = std::make_unique<DataRecorder>(std::move(filename), ec);
if (ec)
return llvm::errorCodeToError(ec);
return std::move(recorder);
@@ -254,7 +265,7 @@ void CommandProvider::Keep() {
FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::F_Text);
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
if (ec)
return;
yaml::Output yout(os);
@@ -266,20 +277,78 @@ void CommandProvider::Discard() { m_data_recorders.clear(); }
void VersionProvider::Keep() {
FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
std::error_code ec;
- llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::F_Text);
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
if (ec)
return;
os << m_version << "\n";
}
+void WorkingDirectoryProvider::Keep() {
+ FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ os << m_cwd << "\n";
+}
+
+llvm::raw_ostream *ProcessGDBRemoteProvider::GetHistoryStream() {
+ FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);
+
+ std::error_code EC;
+ m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
+ sys::fs::OpenFlags::OF_Text);
+ return m_stream_up.get();
+}
+
+std::unique_ptr<CommandLoader> CommandLoader::Create(Loader *loader) {
+ if (!loader)
+ return {};
+
+ FileSpec file = loader->GetFile<repro::CommandProvider::Info>();
+ if (!file)
+ return {};
+
+ auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
+ if (auto err = error_or_file.getError())
+ return {};
+
+ std::vector<std::string> files;
+ llvm::yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> files;
+
+ if (auto err = yin.error())
+ return {};
+
+ for (auto &file : files) {
+ FileSpec absolute_path =
+ loader->GetRoot().CopyByAppendingPathComponent(file);
+ file = absolute_path.GetPath();
+ }
+
+ return std::make_unique<CommandLoader>(std::move(files));
+}
+
+llvm::Optional<std::string> CommandLoader::GetNextFile() {
+ if (m_index >= m_files.size())
+ return {};
+ return m_files[m_index++];
+}
+
void ProviderBase::anchor() {}
-char ProviderBase::ID = 0;
char CommandProvider::ID = 0;
char FileProvider::ID = 0;
+char ProcessGDBRemoteProvider::ID = 0;
+char ProviderBase::ID = 0;
char VersionProvider::ID = 0;
+char WorkingDirectoryProvider::ID = 0;
const char *CommandProvider::Info::file = "command-interpreter.yaml";
const char *CommandProvider::Info::name = "command-interpreter";
const char *FileProvider::Info::file = "files.yaml";
const char *FileProvider::Info::name = "files";
+const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
+const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
const char *VersionProvider::Info::file = "version.txt";
const char *VersionProvider::Info::name = "version";
+const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
+const char *WorkingDirectoryProvider::Info::name = "cwd";
diff --git a/source/Utility/Scalar.cpp b/source/Utility/Scalar.cpp
index 23d50b9eaba50..e9aec17b6650d 100644
--- a/source/Utility/Scalar.cpp
+++ b/source/Utility/Scalar.cpp
@@ -416,6 +416,51 @@ Scalar &Scalar::operator=(llvm::APInt rhs) {
Scalar::~Scalar() = default;
+Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) {
+ // Scalar types are always host types, hence the sizeof().
+ if (sign) {
+ if (bit_size <= sizeof(int)*8) return Scalar::e_sint;
+ if (bit_size <= sizeof(long)*8) return Scalar::e_slong;
+ if (bit_size <= sizeof(long long)*8) return Scalar::e_slonglong;
+ if (bit_size <= 128) return Scalar::e_sint128;
+ if (bit_size <= 256) return Scalar::e_sint256;
+ if (bit_size <= 512) return Scalar::e_sint512;
+ } else {
+ if (bit_size <= sizeof(unsigned int)*8) return Scalar::e_uint;
+ if (bit_size <= sizeof(unsigned long)*8) return Scalar::e_ulong;
+ if (bit_size <= sizeof(unsigned long long)*8) return Scalar::e_ulonglong;
+ if (bit_size <= 128) return Scalar::e_uint128;
+ if (bit_size <= 256) return Scalar::e_uint256;
+ if (bit_size <= 512) return Scalar::e_uint512;
+ }
+ return Scalar::e_void;
+}
+
+void Scalar::TruncOrExtendTo(Scalar::Type type, uint16_t bits) {
+ switch (type) {
+ case e_sint:
+ case e_slong:
+ case e_slonglong:
+ case e_sint128:
+ case e_sint256:
+ case e_sint512:
+ m_integer = m_integer.sextOrTrunc(bits);
+ break;
+ case e_uint:
+ case e_ulong:
+ case e_ulonglong:
+ case e_uint128:
+ case e_uint256:
+ case e_uint512:
+ m_integer = m_integer.zextOrTrunc(bits);
+ break;
+ default:
+ llvm_unreachable("Promoting a Scalar to a specific number of bits is only "
+ "supported for integer types.");
+ }
+ m_type = type;
+}
+
bool Scalar::Promote(Scalar::Type type) {
bool success = false;
switch (m_type) {
diff --git a/source/Utility/SelectHelper.cpp b/source/Utility/SelectHelper.cpp
index ff21d99e400ab..9f5ca586e1ef9 100644
--- a/source/Utility/SelectHelper.cpp
+++ b/source/Utility/SelectHelper.cpp
@@ -92,7 +92,7 @@ static void updateMaxFd(llvm::Optional<lldb::socket_t> &vold,
lldb_private::Status SelectHelper::Select() {
lldb_private::Status error;
-#ifdef _MSC_VER
+#ifdef _WIN32
// On windows FD_SETSIZE limits the number of file descriptors, not their
// numeric value.
lldbassert(m_fd_map.size() <= FD_SETSIZE);
@@ -107,7 +107,7 @@ lldb_private::Status SelectHelper::Select() {
for (auto &pair : m_fd_map) {
pair.second.PrepareForSelect();
const lldb::socket_t fd = pair.first;
-#if !defined(__APPLE__) && !defined(_MSC_VER)
+#if !defined(__APPLE__) && !defined(_WIN32)
lldbassert(fd < static_cast<int>(FD_SETSIZE));
if (fd >= static_cast<int>(FD_SETSIZE)) {
error.SetErrorStringWithFormat("%i is too large for select()", fd);
diff --git a/source/Utility/StreamGDBRemote.cpp b/source/Utility/StreamGDBRemote.cpp
deleted file mode 100644
index c710bbe3eecb3..0000000000000
--- a/source/Utility/StreamGDBRemote.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- StreamGDBRemote.cpp -------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/StreamGDBRemote.h"
-
-#include "lldb/Utility/Flags.h"
-#include "lldb/Utility/Stream.h"
-
-#include <stdio.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-StreamGDBRemote::StreamGDBRemote() : StreamString() {}
-
-StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size,
- ByteOrder byte_order)
- : StreamString(flags, addr_size, byte_order) {}
-
-StreamGDBRemote::~StreamGDBRemote() {}
-
-int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
- int bytes_written = 0;
- const uint8_t *src = static_cast<const uint8_t *>(s);
- bool binary_is_set = m_flags.Test(eBinary);
- m_flags.Clear(eBinary);
- while (src_len) {
- uint8_t byte = *src;
- src++;
- src_len--;
- if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) {
- bytes_written += PutChar(0x7d);
- byte ^= 0x20;
- }
- bytes_written += PutChar(byte);
- };
- if (binary_is_set)
- m_flags.Set(eBinary);
- return bytes_written;
-}
diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp
index 502f468da3ccc..87fe4f13e450c 100644
--- a/source/Utility/StringExtractor.cpp
+++ b/source/Utility/StringExtractor.cpp
@@ -296,34 +296,6 @@ size_t StringExtractor::GetHexBytesAvail(llvm::MutableArrayRef<uint8_t> dest) {
return bytes_extracted;
}
-// Consume ASCII hex nibble character pairs until we have decoded byte_size
-// bytes of data.
-
-uint64_t StringExtractor::GetHexWithFixedSize(uint32_t byte_size,
- bool little_endian,
- uint64_t fail_value) {
- if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2) {
- uint64_t result = 0;
- uint32_t i;
- if (little_endian) {
- // Little Endian
- uint32_t shift_amount;
- for (i = 0, shift_amount = 0; i < byte_size && IsGood();
- ++i, shift_amount += 8) {
- result |= (static_cast<uint64_t>(GetHexU8()) << shift_amount);
- }
- } else {
- // Big Endian
- for (i = 0; i < byte_size && IsGood(); ++i) {
- result <<= 8;
- result |= GetHexU8();
- }
- }
- }
- m_index = UINT64_MAX;
- return fail_value;
-}
-
size_t StringExtractor::GetHexByteString(std::string &str) {
str.clear();
str.reserve(GetBytesLeft() / 2);
diff --git a/source/Utility/StringLexer.cpp b/source/Utility/StringLexer.cpp
index 958a9580db7ac..c357cb0fb5530 100644
--- a/source/Utility/StringLexer.cpp
+++ b/source/Utility/StringLexer.cpp
@@ -11,7 +11,7 @@
#include <algorithm>
#include <assert.h>
-using namespace lldb_utility;
+using namespace lldb_private;
StringLexer::StringLexer(std::string s) : m_data(s), m_position(0) {}
diff --git a/source/Utility/StringList.cpp b/source/Utility/StringList.cpp
index fb0d9be8797d4..5e06b6b69fc09 100644
--- a/source/Utility/StringList.cpp
+++ b/source/Utility/StringList.cpp
@@ -61,10 +61,8 @@ void StringList::AppendList(const char **strv, int strc) {
}
void StringList::AppendList(StringList strings) {
- size_t len = strings.GetSize();
-
- for (size_t i = 0; i < len; ++i)
- m_strings.push_back(strings.GetStringAtIndex(i));
+ m_strings.reserve(m_strings.size() + strings.GetSize());
+ m_strings.insert(m_strings.end(), strings.begin(), strings.end());
}
size_t StringList::GetSize() const { return m_strings.size(); }
@@ -100,10 +98,9 @@ void StringList::Join(const char *separator, Stream &strm) {
void StringList::Clear() { m_strings.clear(); }
-void StringList::LongestCommonPrefix(std::string &common_prefix) {
- common_prefix.clear();
+std::string StringList::LongestCommonPrefix() {
if (m_strings.empty())
- return;
+ return {};
auto args = llvm::makeArrayRef(m_strings);
llvm::StringRef prefix = args.front();
@@ -115,7 +112,7 @@ void StringList::LongestCommonPrefix(std::string &common_prefix) {
}
prefix = prefix.take_front(count);
}
- common_prefix = prefix;
+ return prefix.str();
}
void StringList::InsertStringAtIndex(size_t idx, const char *str) {
@@ -226,29 +223,6 @@ StringList &StringList::operator=(const std::vector<std::string> &rhs) {
return *this;
}
-size_t StringList::AutoComplete(llvm::StringRef s, StringList &matches,
- size_t &exact_idx) const {
- matches.Clear();
- exact_idx = SIZE_MAX;
- if (s.empty()) {
- // No string, so it matches everything
- matches = *this;
- return matches.GetSize();
- }
-
- const size_t s_len = s.size();
- const size_t num_strings = m_strings.size();
-
- for (size_t i = 0; i < num_strings; ++i) {
- if (m_strings[i].find(s) == 0) {
- if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len)
- exact_idx = matches.GetSize();
- matches.AppendString(m_strings[i]);
- }
- }
- return matches.GetSize();
-}
-
void StringList::LogDump(Log *log, const char *name) {
if (!log)
return;
diff --git a/source/Utility/StructuredData.cpp b/source/Utility/StructuredData.cpp
index 0e203f9739d16..783a080821744 100644
--- a/source/Utility/StructuredData.cpp
+++ b/source/Utility/StructuredData.cpp
@@ -9,9 +9,7 @@
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -21,11 +19,20 @@
#include <limits>
using namespace lldb_private;
+using namespace llvm;
-// Functions that use a JSONParser to parse JSON into StructuredData
-static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser);
-static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser);
-static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser);
+static StructuredData::ObjectSP ParseJSONValue(json::Value &value);
+static StructuredData::ObjectSP ParseJSONObject(json::Object *object);
+static StructuredData::ObjectSP ParseJSONArray(json::Array *array);
+
+StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
+ llvm::Expected<json::Value> value = json::parse(json_text);
+ if (!value) {
+ llvm::consumeError(value.takeError());
+ return nullptr;
+ }
+ return ParseJSONValue(*value);
+}
StructuredData::ObjectSP
StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
@@ -38,112 +45,53 @@ StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
buffer_or_error.getError().message());
return return_sp;
}
-
- JSONParser json_parser(buffer_or_error.get()->getBuffer());
- return_sp = ParseJSONValue(json_parser);
- return return_sp;
+ return ParseJSON(buffer_or_error.get()->getBuffer().str());
}
-static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- auto dict_up = llvm::make_unique<StructuredData::Dictionary>();
+static StructuredData::ObjectSP ParseJSONValue(json::Value &value) {
+ if (json::Object *O = value.getAsObject())
+ return ParseJSONObject(O);
- std::string value;
- std::string key;
- while (true) {
- JSONParser::Token token = json_parser.GetToken(value);
+ if (json::Array *A = value.getAsArray())
+ return ParseJSONArray(A);
- if (token == JSONParser::Token::String) {
- key.swap(value);
- token = json_parser.GetToken(value);
- if (token == JSONParser::Token::Colon) {
- StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
- if (value_sp)
- dict_up->AddItem(key, value_sp);
- else
- break;
- }
- } else if (token == JSONParser::Token::ObjectEnd) {
- return StructuredData::ObjectSP(dict_up.release());
- } else if (token == JSONParser::Token::Comma) {
- continue;
- } else {
- break;
- }
- }
- return StructuredData::ObjectSP();
-}
+ std::string s;
+ if (json::fromJSON(value, s))
+ return std::make_shared<StructuredData::String>(s);
-static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) {
- // The "JSONParser::Token::ObjectStart" token should have already been
- // consumed by the time this function is called
- auto array_up = llvm::make_unique<StructuredData::Array>();
+ bool b;
+ if (json::fromJSON(value, b))
+ return std::make_shared<StructuredData::Boolean>(b);
- std::string value;
- std::string key;
- while (true) {
- StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
- if (value_sp)
- array_up->AddItem(value_sp);
- else
- break;
+ int64_t i;
+ if (json::fromJSON(value, i))
+ return std::make_shared<StructuredData::Integer>(i);
+
+ double d;
+ if (json::fromJSON(value, d))
+ return std::make_shared<StructuredData::Float>(d);
- JSONParser::Token token = json_parser.GetToken(value);
- if (token == JSONParser::Token::Comma) {
- continue;
- } else if (token == JSONParser::Token::ArrayEnd) {
- return StructuredData::ObjectSP(array_up.release());
- } else {
- break;
- }
- }
return StructuredData::ObjectSP();
}
-static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) {
- std::string value;
- const JSONParser::Token token = json_parser.GetToken(value);
- switch (token) {
- case JSONParser::Token::ObjectStart:
- return ParseJSONObject(json_parser);
-
- case JSONParser::Token::ArrayStart:
- return ParseJSONArray(json_parser);
-
- case JSONParser::Token::Integer: {
- uint64_t uval;
- if (llvm::to_integer(value, uval, 0))
- return std::make_shared<StructuredData::Integer>(uval);
- } break;
-
- case JSONParser::Token::Float: {
- double val;
- if (llvm::to_float(value, val))
- return std::make_shared<StructuredData::Float>(val);
- } break;
-
- case JSONParser::Token::String:
- return std::make_shared<StructuredData::String>(value);
-
- case JSONParser::Token::True:
- case JSONParser::Token::False:
- return std::make_shared<StructuredData::Boolean>(token ==
- JSONParser::Token::True);
-
- case JSONParser::Token::Null:
- return std::make_shared<StructuredData::Null>();
-
- default:
- break;
+static StructuredData::ObjectSP ParseJSONObject(json::Object *object) {
+ auto dict_up = std::make_unique<StructuredData::Dictionary>();
+ for (auto &KV : *object) {
+ StringRef key = KV.first;
+ json::Value value = KV.second;
+ if (StructuredData::ObjectSP value_sp = ParseJSONValue(value))
+ dict_up->AddItem(key, value_sp);
}
- return StructuredData::ObjectSP();
+ return dict_up;
}
-StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
- JSONParser json_parser(json_text);
- StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
- return object_sp;
+static StructuredData::ObjectSP ParseJSONArray(json::Array *array) {
+ auto array_up = std::make_unique<StructuredData::Array>();
+ for (json::Value &value : *array) {
+ if (StructuredData::ObjectSP value_sp = ParseJSONValue(value))
+ array_up->AddItem(value_sp);
+ }
+ return array_up;
}
StructuredData::ObjectSP
@@ -181,98 +129,48 @@ StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) {
}
void StructuredData::Object::DumpToStdout(bool pretty_print) const {
- StreamString stream;
- Dump(stream, pretty_print);
- llvm::outs() << stream.GetString();
+ json::OStream stream(llvm::outs(), pretty_print ? 2 : 0);
+ Serialize(stream);
}
-void StructuredData::Array::Dump(Stream &s, bool pretty_print) const {
- bool first = true;
- s << "[";
- if (pretty_print) {
- s << "\n";
- s.IndentMore();
- }
+void StructuredData::Array::Serialize(json::OStream &s) const {
+ s.arrayBegin();
for (const auto &item_sp : m_items) {
- if (first) {
- first = false;
- } else {
- s << ",";
- if (pretty_print)
- s << "\n";
- }
-
- if (pretty_print)
- s.Indent();
- item_sp->Dump(s, pretty_print);
- }
- if (pretty_print) {
- s.IndentLess();
- s.EOL();
- s.Indent();
+ item_sp->Serialize(s);
}
- s << "]";
+ s.arrayEnd();
}
-void StructuredData::Integer::Dump(Stream &s, bool pretty_print) const {
- s.Printf("%" PRIu64, m_value);
+void StructuredData::Integer::Serialize(json::OStream &s) const {
+ s.value(static_cast<int64_t>(m_value));
}
-void StructuredData::Float::Dump(Stream &s, bool pretty_print) const {
- s.Printf("%lg", m_value);
+void StructuredData::Float::Serialize(json::OStream &s) const {
+ s.value(m_value);
}
-void StructuredData::Boolean::Dump(Stream &s, bool pretty_print) const {
- if (m_value)
- s.PutCString("true");
- else
- s.PutCString("false");
+void StructuredData::Boolean::Serialize(json::OStream &s) const {
+ s.value(m_value);
}
-void StructuredData::String::Dump(Stream &s, bool pretty_print) const {
- std::string quoted;
- const size_t strsize = m_value.size();
- for (size_t i = 0; i < strsize; ++i) {
- char ch = m_value[i];
- if (ch == '"' || ch == '\\')
- quoted.push_back('\\');
- quoted.push_back(ch);
- }
- s.Printf("\"%s\"", quoted.c_str());
+void StructuredData::String::Serialize(json::OStream &s) const {
+ s.value(m_value);
}
-void StructuredData::Dictionary::Dump(Stream &s, bool pretty_print) const {
- bool first = true;
- s << "{";
- if (pretty_print) {
- s << "\n";
- s.IndentMore();
- }
+void StructuredData::Dictionary::Serialize(json::OStream &s) const {
+ s.objectBegin();
for (const auto &pair : m_dict) {
- if (first)
- first = false;
- else {
- s << ",";
- if (pretty_print)
- s << "\n";
- }
- if (pretty_print)
- s.Indent();
- s << "\"" << pair.first.AsCString() << "\" : ";
- pair.second->Dump(s, pretty_print);
- }
- if (pretty_print) {
- s.IndentLess();
- s.EOL();
- s.Indent();
+ s.attributeBegin(pair.first.AsCString());
+ pair.second->Serialize(s);
+ s.attributeEnd();
}
- s << "}";
+ s.objectEnd();
}
-void StructuredData::Null::Dump(Stream &s, bool pretty_print) const {
- s << "null";
+void StructuredData::Null::Serialize(json::OStream &s) const {
+ s.value(nullptr);
}
-void StructuredData::Generic::Dump(Stream &s, bool pretty_print) const {
- s << "0x" << m_object;
+void StructuredData::Generic::Serialize(json::OStream &s) const {
+ s.value(llvm::formatv("{0:X}", m_object));
}