aboutsummaryrefslogtreecommitdiffstats
path: root/include/lldb/Utility
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:53:01 +0000
commitead246455adf1a215ec2715dad6533073a6beb4e (patch)
treef3f97a47d77053bf96fe74cdbd6fae74380e8a92 /include/lldb/Utility
parentfdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff)
downloadsrc-vendor/lldb.tar.gz
src-vendor/lldb.zip
Vendor import of stripped lldb trunk r375505, the last commit before thevendor/lldb/lldb-trunk-r375505vendor/lldb
upstream Subversion repository was made read-only, and the LLVM project migrated to GitHub: https://llvm.org/svn/llvm-project/lldb/trunk@375505
Notes
Notes: svn path=/vendor/lldb/dist/; revision=353952 svn path=/vendor/lldb/lldb-r375505/; revision=353953; tag=vendor/lldb/lldb-trunk-r375505
Diffstat (limited to 'include/lldb/Utility')
-rw-r--r--include/lldb/Utility/AnsiTerminal.h4
-rw-r--r--include/lldb/Utility/ArchSpec.h5
-rw-r--r--include/lldb/Utility/Args.h35
-rw-r--r--include/lldb/Utility/CleanUp.h42
-rw-r--r--include/lldb/Utility/CompletionRequest.h128
-rw-r--r--include/lldb/Utility/ConstString.h48
-rw-r--r--include/lldb/Utility/DataEncoder.h24
-rw-r--r--include/lldb/Utility/DataExtractor.h54
-rw-r--r--include/lldb/Utility/FileCollector.h77
-rw-r--r--include/lldb/Utility/FileSpec.h37
-rw-r--r--include/lldb/Utility/Flags.h26
-rw-r--r--include/lldb/Utility/GDBRemote.h117
-rw-r--r--include/lldb/Utility/IOObject.h5
-rw-r--r--include/lldb/Utility/JSON.h283
-rw-r--r--include/lldb/Utility/Log.h48
-rw-r--r--include/lldb/Utility/Logging.h2
-rw-r--r--include/lldb/Utility/Predicate.h10
-rw-r--r--include/lldb/Utility/ProcessInfo.h22
-rw-r--r--include/lldb/Utility/RangeMap.h14
-rw-r--r--include/lldb/Utility/RegularExpression.h187
-rw-r--r--include/lldb/Utility/Reproducer.h99
-rw-r--r--include/lldb/Utility/ReproducerInstrumentation.h36
-rw-r--r--include/lldb/Utility/Scalar.h28
-rw-r--r--include/lldb/Utility/Status.h22
-rw-r--r--include/lldb/Utility/Stream.h2
-rw-r--r--include/lldb/Utility/StreamGDBRemote.h45
-rw-r--r--include/lldb/Utility/StringExtractor.h21
-rw-r--r--include/lldb/Utility/StringLexer.h4
-rw-r--r--include/lldb/Utility/StringList.h22
-rw-r--r--include/lldb/Utility/StructuredData.h27
-rw-r--r--include/lldb/Utility/UUID.h24
31 files changed, 598 insertions, 900 deletions
diff --git a/include/lldb/Utility/AnsiTerminal.h b/include/lldb/Utility/AnsiTerminal.h
index 1473c60eeaf2..21375e3821ca 100644
--- a/include/lldb/Utility/AnsiTerminal.h
+++ b/include/lldb/Utility/AnsiTerminal.h
@@ -55,7 +55,7 @@
#include <string>
-namespace lldb_utility {
+namespace lldb_private {
namespace ansi {
@@ -137,4 +137,4 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
return fmt;
}
}
-}
+} // namespace lldb_private
diff --git a/include/lldb/Utility/ArchSpec.h b/include/lldb/Utility/ArchSpec.h
index 7a32556310c4..3bfc988abf0b 100644
--- a/include/lldb/Utility/ArchSpec.h
+++ b/include/lldb/Utility/ArchSpec.h
@@ -122,6 +122,7 @@ public:
eCore_thumbv7em,
eCore_arm_arm64,
eCore_arm_armv8,
+ eCore_arm_arm64_32,
eCore_arm_aarch64,
eCore_mips32,
@@ -183,6 +184,8 @@ public:
eCore_uknownMach32,
eCore_uknownMach64,
+ eCore_arc, // little endian ARC
+
kNumCores,
kCore_invalid,
@@ -268,7 +271,7 @@ public:
static bool ContainsOnlyArch(const llvm::Triple &normalized_triple);
static void ListSupportedArchNames(StringList &list);
- static size_t AutoComplete(CompletionRequest &request);
+ static void AutoComplete(CompletionRequest &request);
/// Returns a static string representing the current architecture.
///
diff --git a/include/lldb/Utility/Args.h b/include/lldb/Utility/Args.h
index 6f258498d5ba..7987787e7af5 100644
--- a/include/lldb/Utility/Args.h
+++ b/include/lldb/Utility/Args.h
@@ -35,6 +35,7 @@ public:
private:
friend class Args;
std::unique_ptr<char[]> ptr;
+ char quote;
char *data() { return ptr.get(); }
@@ -42,12 +43,12 @@ public:
ArgEntry() = default;
ArgEntry(llvm::StringRef str, char quote);
- llvm::StringRef ref;
- char quote;
+ llvm::StringRef ref() const { return c_str(); }
const char *c_str() const { return ptr.get(); }
/// Returns true if this argument was quoted in any way.
bool IsQuoted() const { return quote != '\0'; }
+ char GetQuoteChar() const { return quote; }
};
/// Construct with an option command string.
@@ -121,7 +122,6 @@ public:
const char *GetArgumentAtIndex(size_t idx) const;
llvm::ArrayRef<ArgEntry> entries() const { return m_entries; }
- char GetArgumentQuoteCharAtIndex(size_t idx) const;
using const_iterator = std::vector<ArgEntry>::const_iterator;
@@ -168,8 +168,8 @@ public:
/// Appends a new argument to the end of the list argument list.
///
- /// \param[in] arg_cstr
- /// The new argument as a NULL terminated C string.
+ /// \param[in] arg_str
+ /// The new argument.
///
/// \param[in] quote_char
/// If the argument was originally quoted, put in the quote char here.
@@ -179,30 +179,27 @@ public:
void AppendArguments(const char **argv);
- /// Insert the argument value at index \a idx to \a arg_cstr.
+ /// Insert the argument value at index \a idx to \a arg_str.
///
/// \param[in] idx
/// The index of where to insert the argument.
///
- /// \param[in] arg_cstr
- /// The new argument as a NULL terminated C string.
+ /// \param[in] arg_str
+ /// The new argument.
///
/// \param[in] quote_char
/// If the argument was originally quoted, put in the quote char here.
- ///
- /// \return
- /// The NULL terminated C string of the copy of \a arg_cstr.
void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
char quote_char = '\0');
- /// Replaces the argument value at index \a idx to \a arg_cstr if \a idx is
+ /// Replaces the argument value at index \a idx to \a arg_str if \a idx is
/// a valid argument index.
///
/// \param[in] idx
/// The index of the argument that will have its value replaced.
///
- /// \param[in] arg_cstr
- /// The new argument as a NULL terminated C string.
+ /// \param[in] arg_str
+ /// The new argument.
///
/// \param[in] quote_char
/// If the argument was originally quoted, put in the quote char here.
@@ -238,12 +235,12 @@ public:
/// \see Args::GetArgumentAtIndex (size_t) const
void Shift();
- /// Inserts a class owned copy of \a arg_cstr at the beginning of the
+ /// Inserts a class owned copy of \a arg_str at the beginning of the
/// argument vector.
///
- /// A copy \a arg_cstr will be made.
+ /// A copy \a arg_str will be made.
///
- /// \param[in] arg_cstr
+ /// \param[in] arg_str
/// The argument to push on the front of the argument stack.
///
/// \param[in] quote_char
@@ -255,10 +252,6 @@ public:
// For re-setting or blanking out the list of arguments.
void Clear();
- static const char *StripSpaces(std::string &s, bool leading = true,
- bool trailing = true,
- bool return_null_if_empty = true);
-
static bool UInt64ValueIsValidForByteSize(uint64_t uval64,
size_t total_byte_size) {
if (total_byte_size > 8)
diff --git a/include/lldb/Utility/CleanUp.h b/include/lldb/Utility/CleanUp.h
deleted file mode 100644
index 6cd5f332ef95..000000000000
--- a/include/lldb/Utility/CleanUp.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- CleanUp.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 liblldb_CleanUp_h_
-#define liblldb_CleanUp_h_
-
-#include "lldb/lldb-public.h"
-#include <functional>
-
-namespace lldb_private {
-
-/// Run a cleanup function on scope exit unless it's explicitly disabled.
-class CleanUp {
- std::function<void()> Clean;
-
-public:
- /// Register a cleanup function which applies \p Func to a list of arguments.
- /// Use caution with arguments which are references: they will be copied.
- template <typename F, typename... Args>
- CleanUp(F &&Func, Args &&... args)
- : Clean(std::bind(std::forward<F>(Func), std::forward<Args>(args)...)) {}
-
- ~CleanUp() {
- if (Clean)
- Clean();
- }
-
- /// Disable the cleanup.
- void disable() { Clean = nullptr; }
-
- // Prevent cleanups from being run more than once.
- DISALLOW_COPY_AND_ASSIGN(CleanUp);
-};
-
-} // namespace lldb_private
-
-#endif // #ifndef liblldb_CleanUp_h_
diff --git a/include/lldb/Utility/CompletionRequest.h b/include/lldb/Utility/CompletionRequest.h
index f5ccb01ca16f..570f626ac54e 100644
--- a/include/lldb/Utility/CompletionRequest.h
+++ b/include/lldb/Utility/CompletionRequest.h
@@ -16,25 +16,53 @@
#include "llvm/ADT/StringSet.h"
namespace lldb_private {
+enum class CompletionMode {
+ // The current token has been completed.
+ Normal,
+ // The current token has been partially completed. This means that we found
+ // a completion, but that the completed token is still incomplete. Examples
+ // for this are file paths, where we want to complete "/bi" to "/bin/", but
+ // the file path token is still incomplete after the completion. Clients
+ // should not indicate to the user that this is a full completion (e.g. by
+ // not inserting the usual trailing space after a successful completion).
+ Partial,
+ // The full line has been rewritten by the completion.
+ RewriteLine,
+};
+
class CompletionResult {
+public:
/// A single completion and all associated data.
- struct Completion {
- Completion(llvm::StringRef completion, llvm::StringRef description)
- : m_completion(completion.str()), m_descripton(description.str()) {}
+ class Completion {
std::string m_completion;
std::string m_descripton;
+ CompletionMode m_mode;
+
+ public:
+ Completion(llvm::StringRef completion, llvm::StringRef description,
+ CompletionMode mode)
+ : m_completion(completion.str()), m_descripton(description.str()),
+ m_mode(mode) {}
+ const std::string &GetCompletion() const { return m_completion; }
+ const std::string &GetDescription() const { return m_descripton; }
+ CompletionMode GetMode() const { return m_mode; }
/// Generates a string that uniquely identifies this completion result.
std::string GetUniqueKey() const;
};
+
+private:
std::vector<Completion> m_results;
/// List of added completions so far. Used to filter out duplicates.
llvm::StringSet<> m_added_values;
public:
- void AddResult(llvm::StringRef completion, llvm::StringRef description);
+ void AddResult(llvm::StringRef completion, llvm::StringRef description,
+ CompletionMode mode);
+
+ llvm::ArrayRef<Completion> GetResults() const { return m_results; }
/// Adds all collected completion matches to the given list.
/// The list will be cleared before the results are added. The number of
@@ -68,18 +96,10 @@ public:
/// the cursor is at the start of the line. The completion starts from
/// this cursor position.
///
- /// \param [in] match_start_point
- /// \param [in] max_return_elements
- /// If there is a match that is expensive to compute, these are here to
- /// allow you to compute the completions in batches. Start the
- /// completion from match_start_point, and return match_return_elements
- /// elements.
- ///
/// \param [out] result
/// The CompletionResult that will be filled with the results after this
/// request has been handled.
CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos,
- int match_start_point, int max_return_elements,
CompletionResult &result);
llvm::StringRef GetRawLine() const { return m_command; }
@@ -90,21 +110,25 @@ public:
Args &GetParsedLine() { return m_parsed_line; }
- const Args &GetPartialParsedLine() const { return m_partial_parsed_line; }
-
- void SetCursorIndex(int i) { m_cursor_index = i; }
- int GetCursorIndex() const { return m_cursor_index; }
-
- void SetCursorCharPosition(int pos) { m_cursor_char_position = pos; }
- int GetCursorCharPosition() const { return m_cursor_char_position; }
-
- int GetMatchStartPoint() const { return m_match_start_point; }
+ const Args::ArgEntry &GetParsedArg() {
+ return GetParsedLine()[GetCursorIndex()];
+ }
- int GetMaxReturnElements() const { return m_max_return_elements; }
+ /// Drops the first argument from the argument list.
+ void ShiftArguments() {
+ m_cursor_index--;
+ m_parsed_line.Shift();
+ }
- bool GetWordComplete() { return m_word_complete; }
+ /// Adds an empty argument at the end of the argument list and moves
+ /// the cursor to this new argument.
+ void AppendEmptyArgument() {
+ m_parsed_line.AppendArgument(llvm::StringRef());
+ m_cursor_index++;
+ m_cursor_char_position = 0;
+ }
- void SetWordComplete(bool v) { m_word_complete = v; }
+ size_t GetCursorIndex() const { return m_cursor_index; }
/// Adds a possible completion string. If the completion was already
/// suggested before, it will not be added to the list of results. A copy of
@@ -112,11 +136,31 @@ public:
/// afterwards.
///
/// \param match The suggested completion.
- /// \param match An optional description of the completion string. The
+ /// \param completion An optional description of the completion string. The
/// description will be displayed to the user alongside the completion.
+ /// \param mode The CompletionMode for this completion.
void AddCompletion(llvm::StringRef completion,
- llvm::StringRef description = "") {
- m_result.AddResult(completion, description);
+ llvm::StringRef description = "",
+ CompletionMode mode = CompletionMode::Normal) {
+ m_result.AddResult(completion, description, mode);
+ }
+
+ /// Adds a possible completion string if the completion would complete the
+ /// current argument.
+ ///
+ /// \param match The suggested completion.
+ /// \param description An optional description of the completion string. The
+ /// description will be displayed to the user alongside the completion.
+ template <CompletionMode M = CompletionMode::Normal>
+ void TryCompleteCurrentArg(llvm::StringRef completion,
+ llvm::StringRef description = "") {
+ // Trying to rewrite the whole line while checking for the current
+ // argument never makes sense. Completion modes are always hardcoded, so
+ // this can be a static_assert.
+ static_assert(M != CompletionMode::RewriteLine,
+ "Shouldn't rewrite line with this function");
+ if (completion.startswith(GetCursorArgumentPrefix()))
+ AddCompletion(completion, description, M);
}
/// Adds multiple possible completion strings.
@@ -125,8 +169,8 @@ public:
///
/// \see AddCompletion
void AddCompletions(const StringList &completions) {
- for (std::size_t i = 0; i < completions.GetSize(); ++i)
- AddCompletion(completions.GetStringAtIndex(i));
+ for (const std::string &completion : completions)
+ AddCompletion(completion);
}
/// Adds multiple possible completion strings alongside their descriptions.
@@ -145,16 +189,8 @@ public:
descriptions.GetStringAtIndex(i));
}
- std::size_t GetNumberOfMatches() const {
- return m_result.GetNumberOfResults();
- }
-
- llvm::StringRef GetCursorArgument() const {
- return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
- }
-
llvm::StringRef GetCursorArgumentPrefix() const {
- return GetCursorArgument().substr(0, GetCursorCharPosition());
+ return GetParsedLine().GetArgumentAtIndex(GetCursorIndex());
}
private:
@@ -164,22 +200,10 @@ private:
unsigned m_raw_cursor_pos;
/// The command line parsed as arguments.
Args m_parsed_line;
- /// The command line until the cursor position parsed as arguments.
- Args m_partial_parsed_line;
/// The index of the argument in which the completion cursor is.
- int m_cursor_index;
+ size_t m_cursor_index;
/// The cursor position in the argument indexed by m_cursor_index.
- int m_cursor_char_position;
- /// If there is a match that is expensive
- /// to compute, these are here to allow you to compute the completions in
- /// batches. Start the completion from \amatch_start_point, and return
- /// \amatch_return_elements elements.
- // FIXME: These two values are not implemented.
- int m_match_start_point;
- int m_max_return_elements;
- /// \btrue if this is a complete option value (a space will be inserted
- /// after the completion.) \bfalse otherwise.
- bool m_word_complete = false;
+ size_t m_cursor_char_position;
/// The result this request is supposed to fill out.
/// We keep this object private to ensure that no backend can in any way
diff --git a/include/lldb/Utility/ConstString.h b/include/lldb/Utility/ConstString.h
index 8576c18ddcd8..9a9ee458239f 100644
--- a/include/lldb/Utility/ConstString.h
+++ b/include/lldb/Utility/ConstString.h
@@ -10,6 +10,7 @@
#define liblldb_ConstString_h_
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/FormatVariadic.h"
#include <stddef.h>
@@ -204,9 +205,7 @@ public:
/// \param[in] rhs
/// Another string object to compare this object to.
///
- /// \return
- /// \li \b true if this object is not equal to \a rhs.
- /// \li \b false if this object is equal to \a rhs.
+ /// \return \b true if this object is not equal to \a rhs, false otherwise.
bool operator!=(const char *rhs) const { return !(*this == rhs); }
bool operator<(ConstString rhs) const;
@@ -218,8 +217,7 @@ public:
///
/// If \a value_if_empty is nullptr, then nullptr will be returned.
///
- /// \return
- /// Returns \a value_if_empty if the string is empty, otherwise
+ /// \return Returns \a value_if_empty if the string is empty, otherwise
/// the C string value contained in this object.
const char *AsCString(const char *value_if_empty = nullptr) const {
return (IsEmpty() ? value_if_empty : m_string);
@@ -269,7 +267,7 @@ public:
/// in a pointer comparison since all strings are in a uniqued in a global
/// string pool.
///
- /// \param[in] rhs
+ /// \param[in] lhs
/// The Left Hand Side const ConstString object reference.
///
/// \param[in] rhs
@@ -279,9 +277,7 @@ public:
/// Case sensitivity. If true, case sensitive equality
/// will be tested, otherwise character case will be ignored
///
- /// \return
- /// \li \b true if this object is equal to \a rhs.
- /// \li \b false if this object is not equal to \a rhs.
+ /// \return \b true if this object is equal to \a rhs, \b false otherwise.
static bool Equals(ConstString lhs, ConstString rhs,
const bool case_sensitive = true);
@@ -305,10 +301,7 @@ public:
/// Case sensitivity of compare. If true, case sensitive compare
/// will be performed, otherwise character case will be ignored
///
- /// \return
- /// \li -1 if lhs < rhs
- /// \li 0 if lhs == rhs
- /// \li 1 if lhs > rhs
+ /// \return -1 if lhs < rhs, 0 if lhs == rhs, 1 if lhs > rhs
static int Compare(ConstString lhs, ConstString rhs,
const bool case_sensitive = true);
@@ -445,6 +438,14 @@ public:
static size_t StaticMemorySize();
protected:
+ template <typename T> friend struct ::llvm::DenseMapInfo;
+ /// Only used by DenseMapInfo.
+ static ConstString FromStringPoolPointer(const char *ptr) {
+ ConstString s;
+ s.m_string = ptr;
+ return s;
+ };
+
// Member variables
const char *m_string;
};
@@ -459,6 +460,27 @@ template <> struct format_provider<lldb_private::ConstString> {
static void format(const lldb_private::ConstString &CS, llvm::raw_ostream &OS,
llvm::StringRef Options);
};
+
+/// DenseMapInfo implementation.
+/// \{
+template <> struct DenseMapInfo<lldb_private::ConstString> {
+ static inline lldb_private::ConstString getEmptyKey() {
+ return lldb_private::ConstString::FromStringPoolPointer(
+ DenseMapInfo<const char *>::getEmptyKey());
+ }
+ static inline lldb_private::ConstString getTombstoneKey() {
+ return lldb_private::ConstString::FromStringPoolPointer(
+ DenseMapInfo<const char *>::getTombstoneKey());
+ }
+ static unsigned getHashValue(lldb_private::ConstString val) {
+ return DenseMapInfo<const char *>::getHashValue(val.m_string);
+ }
+ static bool isEqual(lldb_private::ConstString LHS,
+ lldb_private::ConstString RHS) {
+ return LHS == RHS;
+ }
+};
+/// \}
}
#endif // liblldb_ConstString_h_
diff --git a/include/lldb/Utility/DataEncoder.h b/include/lldb/Utility/DataEncoder.h
index 19b7cef9f0ca..7d44afd2ce69 100644
--- a/include/lldb/Utility/DataEncoder.h
+++ b/include/lldb/Utility/DataEncoder.h
@@ -204,12 +204,11 @@ public:
/// m_addr_size member variable and should be set correctly prior to
/// extracting any address values.
///
- /// \param[in,out] offset_ptr
- /// A pointer to an offset within the data that will be advanced
- /// by the appropriate number of bytes if the value is extracted
- /// correctly. If the offset is out of bounds or there are not
- /// enough bytes to extract this value, the offset will be left
- /// unmodified.
+ /// \param[in] offset
+ /// The offset where to encode the address.
+ ///
+ /// \param[in] addr
+ /// The address to encode.
///
/// \return
/// The next valid offset within data if the put operation
@@ -220,19 +219,18 @@ public:
///
/// Encodes a C string into the existing data including the terminating
///
- /// \param[in,out] offset_ptr
- /// A pointer to an offset within the data that will be advanced
- /// by the appropriate number of bytes if the value is extracted
- /// correctly. If the offset is out of bounds or there are not
- /// enough bytes to extract this value, the offset will be left
- /// unmodified.
+ /// \param[in] offset
+ /// The offset where to encode the string.
+ ///
+ /// \param[in] cstr
+ /// The string to encode.
///
/// \return
/// A pointer to the C string value in the data. If the offset
/// pointed to by \a offset_ptr is out of bounds, or if the
/// offset plus the length of the C string is out of bounds,
/// NULL will be returned.
- uint32_t PutCString(uint32_t offset_ptr, const char *cstr);
+ uint32_t PutCString(uint32_t offset, const char *cstr);
lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; }
diff --git a/include/lldb/Utility/DataExtractor.h b/include/lldb/Utility/DataExtractor.h
index 74174b34ce99..333baf9fd349 100644
--- a/include/lldb/Utility/DataExtractor.h
+++ b/include/lldb/Utility/DataExtractor.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataExtractor.h"
#include <cassert>
#include <stdint.h>
@@ -167,9 +168,8 @@ public:
/// the beginning of each line and can be offset by base address \a
/// base_addr. \a num_per_line objects will be displayed on each line.
///
- /// \param[in] s
- /// The stream to dump the output to. If nullptr the output will
- /// be dumped to Log().
+ /// \param[in] log
+ /// The log to dump the output to.
///
/// \param[in] offset
/// The offset into the data at which to start dumping.
@@ -362,30 +362,29 @@ public:
/// when say copying a partial data value into a register.
///
/// \param[in] src_offset
- /// The offset into this data from which to start copying an
- /// endian entity
+ /// The offset into this data from which to start copying an endian
+ /// entity
///
/// \param[in] src_len
- /// The length of the endian data to copy from this object
- /// into the \a dst object
+ /// The length of the endian data to copy from this object into the \a
+ /// dst object
///
/// \param[out] dst
- /// The buffer where to place the endian data. The data might
- /// need to be byte swapped (and appropriately padded with
- /// zeroes if \a src_len != \a dst_len) if \a dst_byte_order
- /// does not match the byte order in this object.
+ /// The buffer where to place the endian data. The data might need to be
+ /// byte swapped (and appropriately padded with zeroes if \a src_len !=
+ /// \a dst_len) if \a dst_byte_order does not match the byte order in
+ /// this object.
///
/// \param[in] dst_len
- /// The length number of bytes that the endian value will
- /// occupy is \a dst.
+ /// The length number of bytes that the endian value will occupy is \a
+ /// dst.
///
- /// \param[in] byte_order
- /// The byte order that the endian value should be in the \a dst
- /// buffer.
+ /// \param[in] dst_byte_order
+ /// The byte order that the endian value should be in the \a dst buffer.
///
/// \return
- /// Returns the number of bytes that were copied, or zero if
- /// anything goes wrong.
+ /// Returns the number of bytes that were copied, or zero if anything
+ /// goes wrong.
lldb::offset_t CopyByteOrderedData(lldb::offset_t src_offset,
lldb::offset_t src_len, void *dst,
lldb::offset_t dst_len,
@@ -520,7 +519,7 @@ public:
/// enough bytes to extract this value, the offset will be left
/// unmodified.
///
- /// \param[in] byte_size
+ /// \param[in] size
/// The size in byte of the integer to extract.
///
/// \param[in] bitfield_bit_size
@@ -558,7 +557,7 @@ public:
/// enough bytes to extract this value, the offset will be left
/// unmodified.
///
- /// \param[in] byte_size
+ /// \param[in] size
/// The size in bytes of the integer to extract.
///
/// \param[in] bitfield_bit_size
@@ -956,14 +955,14 @@ public:
/// unmodified.
///
/// \return
- // The number of bytes consumed during the extraction.
+ /// The number of bytes consumed during the extraction.
uint32_t Skip_LEB128(lldb::offset_t *offset_ptr) const;
/// Test the validity of \a offset.
///
/// \return
- /// \b true if \a offset is a valid offset into the data in this
- /// object, \b false otherwise.
+ /// true if \a offset is a valid offset into the data in this object,
+ /// false otherwise.
bool ValidOffset(lldb::offset_t offset) const {
return offset < GetByteSize();
}
@@ -971,8 +970,8 @@ public:
/// Test the availability of \a length bytes of data from \a offset.
///
/// \return
- /// \b true if \a offset is a valid offset and there are \a
- /// length bytes available at that offset, \b false otherwise.
+ /// true if \a offset is a valid offset and there are \a
+ /// length bytes available at that offset, false otherwise.
bool ValidOffsetForDataOfSize(lldb::offset_t offset,
lldb::offset_t length) const {
return length <= BytesLeft(offset);
@@ -997,6 +996,11 @@ public:
return {GetDataStart(), size_t(GetByteSize())};
}
+ llvm::DataExtractor GetAsLLVM() const {
+ return {GetData(), GetByteOrder() == lldb::eByteOrderLittle,
+ uint8_t(GetAddressByteSize())};
+ }
+
protected:
// Member variables
const uint8_t *m_start; ///< A pointer to the first byte of data.
diff --git a/include/lldb/Utility/FileCollector.h b/include/lldb/Utility/FileCollector.h
deleted file mode 100644
index a89206747fe1..000000000000
--- a/include/lldb/Utility/FileCollector.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- FileCollector.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_UTILITY_FILE_COLLECTOR_H
-#define LLDB_UTILITY_FILE_COLLECTOR_H
-
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/VirtualFileSystem.h"
-
-#include <mutex>
-
-namespace lldb_private {
-
-/// Collects files into a directory and generates a mapping that can be used by
-/// the VFS.
-class FileCollector {
-public:
- FileCollector(const FileSpec &root, const FileSpec &overlay);
-
- void AddFile(const llvm::Twine &file);
- void AddFile(const FileSpec &file) { return AddFile(file.GetPath()); }
-
- /// Write the yaml mapping (for the VFS) to the given file.
- std::error_code WriteMapping(const FileSpec &mapping_file);
-
- /// Copy the files into the root directory.
- ///
- /// When stop_on_error is true (the default) we abort as soon as one file
- /// cannot be copied. This is relatively common, for example when a file was
- /// removed after it was added to the mapping.
- std::error_code CopyFiles(bool stop_on_error = true);
-
-protected:
- void AddFileImpl(llvm::StringRef src_path);
-
- bool MarkAsSeen(llvm::StringRef path) { return m_seen.insert(path).second; }
-
- bool GetRealPath(llvm::StringRef src_path,
- llvm::SmallVectorImpl<char> &result);
-
- void AddFileToMapping(llvm::StringRef virtual_path,
- llvm::StringRef real_path) {
- m_vfs_writer.addFileMapping(virtual_path, real_path);
- }
-
- /// Synchronizes adding files.
- std::mutex m_mutex;
-
- /// The root directory where files are copied.
- FileSpec m_root;
-
- /// The root directory where the VFS overlay lives.
- FileSpec m_overlay_root;
-
- /// Tracks already seen files so they can be skipped.
- llvm::StringSet<> m_seen;
-
- /// The yaml mapping writer.
- llvm::vfs::YAMLVFSWriter m_vfs_writer;
-
- /// Caches real_path calls when resolving symlinks.
- llvm::StringMap<std::string> m_symlink_map;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_UTILITY_FILE_COLLECTOR_H
diff --git a/include/lldb/Utility/FileSpec.h b/include/lldb/Utility/FileSpec.h
index f0bc5c89fec7..50ad1f1600d8 100644
--- a/include/lldb/Utility/FileSpec.h
+++ b/include/lldb/Utility/FileSpec.h
@@ -73,7 +73,7 @@ public:
/// \see FileSpec::SetFile (const char *path)
explicit FileSpec(llvm::StringRef path, Style style = Style::native);
- explicit FileSpec(llvm::StringRef path, const llvm::Triple &Triple);
+ explicit FileSpec(llvm::StringRef path, const llvm::Triple &triple);
/// Copy constructor
///
@@ -200,10 +200,8 @@ public:
/// only the filename will be compared, else a full comparison
/// is done.
///
- /// \return
- /// \li -1 if \a lhs is less than \a rhs
- /// \li 0 if \a lhs is equal to \a rhs
- /// \li 1 if \a lhs is greater than \a rhs
+ /// \return -1 if \a lhs is less than \a rhs, 0 if \a lhs is equal to \a rhs,
+ /// 1 if \a lhs is greater than \a rhs
static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full);
static bool Equal(const FileSpec &a, const FileSpec &b, bool full);
@@ -322,10 +320,6 @@ public:
/// Extract the full path to the file.
///
/// Extract the directory and path into an llvm::SmallVectorImpl<>
- ///
- /// \return
- /// Returns a std::string with the directory and filename
- /// concatenated.
void GetPath(llvm::SmallVectorImpl<char> &path,
bool denormalize = true) const;
@@ -336,8 +330,7 @@ public:
/// filename has no extension, ConstString(nullptr) is returned. The dot
/// ('.') character is not returned as part of the extension
///
- /// \return
- /// Returns the extension of the file as a ConstString object.
+ /// \return Returns the extension of the file as a ConstString object.
ConstString GetFileNameExtension() const;
/// Return the filename without the extension part
@@ -346,9 +339,7 @@ public:
/// without the extension part (e.g. for a file named "foo.bar", "foo" is
/// returned)
///
- /// \return
- /// Returns the filename without extension
- /// as a ConstString object.
+ /// \return Returns the filename without extension as a ConstString object.
ConstString GetFileNameStrippingExtension() const;
/// Get the memory cost of this object.
@@ -372,12 +363,22 @@ public:
/// \param[in] path
/// A full, partial, or relative path to a file.
///
- /// \param[in] resolve_path
- /// If \b true, then we will try to resolve links the path using
- /// the static FileSpec::Resolve.
+ /// \param[in] style
+ /// The style for the given path.
void SetFile(llvm::StringRef path, Style style);
- void SetFile(llvm::StringRef path, const llvm::Triple &Triple);
+ /// Change the file specified with a new path.
+ ///
+ /// Update the contents of this object with a new path. The path will be
+ /// split up into a directory and filename and stored as uniqued string
+ /// values for quick comparison and efficient memory usage.
+ ///
+ /// \param[in] path
+ /// A full, partial, or relative path to a file.
+ ///
+ /// \param[in] triple
+ /// The triple which is used to set the Path style.
+ void SetFile(llvm::StringRef path, const llvm::Triple &triple);
bool IsResolved() const { return m_is_resolved; }
diff --git a/include/lldb/Utility/Flags.h b/include/lldb/Utility/Flags.h
index 48b14e7d2a2c..aa869eca0c6e 100644
--- a/include/lldb/Utility/Flags.h
+++ b/include/lldb/Utility/Flags.h
@@ -121,32 +121,6 @@ public:
/// \b true if \a bit is 0, \b false otherwise.
bool IsClear(ValueType bit) const { return (m_flags & bit) == 0; }
- /// Get the number of zero bits in \a m_flags.
- ///
- /// \return
- /// The number of bits that are set to 0 in the current flags.
- size_t ClearCount() const {
- size_t count = 0;
- for (ValueType shift = 0; shift < sizeof(ValueType) * 8; ++shift) {
- if ((m_flags & (1u << shift)) == 0)
- ++count;
- }
- return count;
- }
-
- /// Get the number of one bits in \a m_flags.
- ///
- /// \return
- /// The number of bits that are set to 1 in the current flags.
- size_t SetCount() const {
- size_t count = 0;
- for (ValueType mask = m_flags; mask; mask >>= 1) {
- if (mask & 1u)
- ++count;
- }
- return count;
- }
-
protected:
ValueType m_flags; ///< The flags.
};
diff --git a/include/lldb/Utility/GDBRemote.h b/include/lldb/Utility/GDBRemote.h
new file mode 100644
index 000000000000..b4adeb368524
--- /dev/null
+++ b/include/lldb/Utility/GDBRemote.h
@@ -0,0 +1,117 @@
+//===-- GDBRemote.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 liblldb_GDBRemote_h_
+#define liblldb_GDBRemote_h_
+
+#include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-public.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace lldb_private {
+
+class StreamGDBRemote : public StreamString {
+public:
+ StreamGDBRemote();
+
+ StreamGDBRemote(uint32_t flags, uint32_t addr_size,
+ lldb::ByteOrder byte_order);
+
+ ~StreamGDBRemote() override;
+
+ /// Output a block of data to the stream performing GDB-remote escaping.
+ ///
+ /// \param[in] s
+ /// A block of data.
+ ///
+ /// \param[in] src_len
+ /// The amount of data to write.
+ ///
+ /// \return
+ /// Number of bytes written.
+ // TODO: Convert this function to take ArrayRef<uint8_t>
+ int PutEscapedBytes(const void *s, size_t src_len);
+};
+
+/// GDB remote packet as used by the reproducer and the GDB remote
+/// communication history. Packets can be serialized to file.
+struct GDBRemotePacket {
+
+ friend llvm::yaml::MappingTraits<GDBRemotePacket>;
+
+ enum Type { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
+
+ GDBRemotePacket()
+ : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), packet_idx(0),
+ tid(LLDB_INVALID_THREAD_ID) {}
+
+ void Clear() {
+ packet.data.clear();
+ type = ePacketTypeInvalid;
+ bytes_transmitted = 0;
+ packet_idx = 0;
+ tid = LLDB_INVALID_THREAD_ID;
+ }
+
+ struct BinaryData {
+ std::string data;
+ };
+
+ void Serialize(llvm::raw_ostream &strm) const;
+ void Dump(Stream &strm) const;
+
+ BinaryData packet;
+ Type type;
+ uint32_t bytes_transmitted;
+ uint32_t packet_idx;
+ lldb::tid_t tid;
+
+private:
+ llvm::StringRef GetTypeStr() const;
+};
+
+} // namespace lldb_private
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::GDBRemotePacket)
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(std::vector<lldb_private::GDBRemotePacket>)
+
+namespace llvm {
+namespace yaml {
+
+template <>
+struct ScalarEnumerationTraits<lldb_private::GDBRemotePacket::Type> {
+ static void enumeration(IO &io, lldb_private::GDBRemotePacket::Type &value);
+};
+
+template <> struct ScalarTraits<lldb_private::GDBRemotePacket::BinaryData> {
+ static void output(const lldb_private::GDBRemotePacket::BinaryData &, void *,
+ raw_ostream &);
+
+ static StringRef input(StringRef, void *,
+ lldb_private::GDBRemotePacket::BinaryData &);
+
+ static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
+};
+
+template <> struct MappingTraits<lldb_private::GDBRemotePacket> {
+ static void mapping(IO &io, lldb_private::GDBRemotePacket &Packet);
+
+ static StringRef validate(IO &io, lldb_private::GDBRemotePacket &);
+};
+
+} // namespace yaml
+} // namespace llvm
+
+#endif // liblldb_GDBRemote_h_
diff --git a/include/lldb/Utility/IOObject.h b/include/lldb/Utility/IOObject.h
index 1640200a01d9..16ed580abf71 100644
--- a/include/lldb/Utility/IOObject.h
+++ b/include/lldb/Utility/IOObject.h
@@ -29,8 +29,7 @@ public:
typedef int WaitableHandle;
static const WaitableHandle kInvalidHandleValue;
- IOObject(FDType type, bool should_close)
- : m_fd_type(type), m_should_close_fd(should_close) {}
+ IOObject(FDType type) : m_fd_type(type) {}
virtual ~IOObject();
virtual Status Read(void *buf, size_t &num_bytes) = 0;
@@ -44,8 +43,6 @@ public:
protected:
FDType m_fd_type;
- bool m_should_close_fd; // True if this class should close the file descriptor
- // when it goes away.
private:
DISALLOW_COPY_AND_ASSIGN(IOObject);
diff --git a/include/lldb/Utility/JSON.h b/include/lldb/Utility/JSON.h
deleted file mode 100644
index 172f77afb01f..000000000000
--- a/include/lldb/Utility/JSON.h
+++ /dev/null
@@ -1,283 +0,0 @@
-//===---------------------JSON.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 utility_JSON_h_
-#define utility_JSON_h_
-
-#include "lldb/Utility/StringExtractor.h"
-
-#include <map>
-#include <memory>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include <stdint.h>
-
-namespace lldb_private {
-class Stream;
-
-class JSONValue {
-public:
- virtual void Write(Stream &s) = 0;
-
- typedef std::shared_ptr<JSONValue> SP;
-
- enum class Kind { String, Number, True, False, Null, Object, Array };
-
- JSONValue(Kind k) : m_kind(k) {}
-
- Kind GetKind() const { return m_kind; }
-
- virtual ~JSONValue() = default;
-
-private:
- const Kind m_kind;
-};
-
-class JSONString : public JSONValue {
-public:
- JSONString();
- JSONString(const char *s);
- JSONString(const std::string &s);
-
- JSONString(const JSONString &s) = delete;
- JSONString &operator=(const JSONString &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONString> SP;
-
- std::string GetData() { return m_data; }
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::String;
- }
-
- ~JSONString() override = default;
-
-private:
- static std::string json_string_quote_metachars(const std::string &);
-
- std::string m_data;
-};
-
-class JSONNumber : public JSONValue {
-public:
- typedef std::shared_ptr<JSONNumber> SP;
-
- // We cretae a constructor for all integer and floating point type with using
- // templates and
- // SFINAE to avoid having ambiguous overloads because of the implicit type
- // promotion. If we
- // would have constructors only with int64_t, uint64_t and double types then
- // constructing a JSONNumber from an int32_t (or any other similar type)
- // would fail to compile.
-
- template <typename T, typename std::enable_if<
- std::is_integral<T>::value &&
- std::is_unsigned<T>::value>::type * = nullptr>
- explicit JSONNumber(T u)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {
- m_data.m_unsigned = u;
- }
-
- template <typename T,
- typename std::enable_if<std::is_integral<T>::value &&
- std::is_signed<T>::value>::type * = nullptr>
- explicit JSONNumber(T s)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {
- m_data.m_signed = s;
- }
-
- template <typename T, typename std::enable_if<
- std::is_floating_point<T>::value>::type * = nullptr>
- explicit JSONNumber(T d)
- : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {
- m_data.m_double = d;
- }
-
- ~JSONNumber() override = default;
-
- JSONNumber(const JSONNumber &s) = delete;
- JSONNumber &operator=(const JSONNumber &s) = delete;
-
- void Write(Stream &s) override;
-
- uint64_t GetAsUnsigned() const;
-
- int64_t GetAsSigned() const;
-
- double GetAsDouble() const;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Number;
- }
-
-private:
- enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;
-
- union {
- uint64_t m_unsigned;
- int64_t m_signed;
- double m_double;
- } m_data;
-};
-
-class JSONTrue : public JSONValue {
-public:
- JSONTrue();
-
- JSONTrue(const JSONTrue &s) = delete;
- JSONTrue &operator=(const JSONTrue &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONTrue> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::True;
- }
-
- ~JSONTrue() override = default;
-};
-
-class JSONFalse : public JSONValue {
-public:
- JSONFalse();
-
- JSONFalse(const JSONFalse &s) = delete;
- JSONFalse &operator=(const JSONFalse &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONFalse> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::False;
- }
-
- ~JSONFalse() override = default;
-};
-
-class JSONNull : public JSONValue {
-public:
- JSONNull();
-
- JSONNull(const JSONNull &s) = delete;
- JSONNull &operator=(const JSONNull &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONNull> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Null;
- }
-
- ~JSONNull() override = default;
-};
-
-class JSONObject : public JSONValue {
-public:
- JSONObject();
-
- JSONObject(const JSONObject &s) = delete;
- JSONObject &operator=(const JSONObject &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONObject> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Object;
- }
-
- bool SetObject(const std::string &key, JSONValue::SP value);
-
- JSONValue::SP GetObject(const std::string &key);
-
- ~JSONObject() override = default;
-
-private:
- typedef std::map<std::string, JSONValue::SP> Map;
- typedef Map::iterator Iterator;
- Map m_elements;
-};
-
-class JSONArray : public JSONValue {
-public:
- JSONArray();
-
- JSONArray(const JSONArray &s) = delete;
- JSONArray &operator=(const JSONArray &s) = delete;
-
- void Write(Stream &s) override;
-
- typedef std::shared_ptr<JSONArray> SP;
-
- static bool classof(const JSONValue *V) {
- return V->GetKind() == JSONValue::Kind::Array;
- }
-
-private:
- typedef std::vector<JSONValue::SP> Vector;
- typedef Vector::iterator Iterator;
- typedef Vector::size_type Index;
- typedef Vector::size_type Size;
-
-public:
- bool SetObject(Index i, JSONValue::SP value);
-
- bool AppendObject(JSONValue::SP value);
-
- JSONValue::SP GetObject(Index i);
-
- Size GetNumElements();
-
- ~JSONArray() override = default;
-
- Vector m_elements;
-};
-
-class JSONParser : public StringExtractor {
-public:
- enum Token {
- Invalid,
- Status,
- ObjectStart,
- ObjectEnd,
- ArrayStart,
- ArrayEnd,
- Comma,
- Colon,
- String,
- Integer,
- Float,
- True,
- False,
- Null,
- EndOfFile
- };
-
- JSONParser(llvm::StringRef data);
-
- int GetEscapedChar(bool &was_escaped);
-
- Token GetToken(std::string &value);
-
- JSONValue::SP ParseJSONValue();
-
-protected:
- JSONValue::SP ParseJSONObject();
-
- JSONValue::SP ParseJSONArray();
-};
-} // namespace lldb_private
-
-#endif // utility_JSON_h_
diff --git a/include/lldb/Utility/Log.h b/include/lldb/Utility/Log.h
index 949de69c8e5a..09c0f6954478 100644
--- a/include/lldb/Utility/Log.h
+++ b/include/lldb/Utility/Log.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-defines.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -112,6 +113,14 @@ public:
static bool ListChannelCategories(llvm::StringRef channel,
llvm::raw_ostream &stream);
+ /// Returns the list of log channels.
+ static std::vector<llvm::StringRef> ListChannels();
+ /// Calls the given lambda for every category in the given channel.
+ /// If no channel with the given name exists, lambda is never called.
+ static void ForEachChannelCategory(
+ llvm::StringRef channel,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda);
+
static void DisableAllLogChannels();
static void ListAllLogChannels(llvm::raw_ostream &stream);
@@ -142,14 +151,11 @@ public:
std::forward<Args>(args)...));
}
+ /// Prefer using LLDB_LOGF whenever possible.
void Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
- void VAPrintf(const char *format, va_list args);
-
void Error(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
- void VAError(const char *format, va_list args);
-
void Verbose(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
void Warning(const char *fmt, ...) __attribute__((format(printf, 2, 3)));
@@ -161,6 +167,9 @@ public:
bool GetVerbose() const;
private:
+ void VAPrintf(const char *format, va_list args);
+ void VAError(const char *format, va_list args);
+
Channel &m_channel;
// The mutex makes sure enable/disable operations are thread-safe. The
@@ -193,6 +202,10 @@ private:
typedef llvm::StringMap<Log> ChannelMap;
static llvm::ManagedStatic<ChannelMap> g_channel_map;
+ static void ForEachCategory(
+ const Log::ChannelMap::value_type &entry,
+ llvm::function_ref<void(llvm::StringRef, llvm::StringRef)> lambda);
+
static void ListCategories(llvm::raw_ostream &stream,
const ChannelMap::value_type &entry);
static uint32_t GetFlags(llvm::raw_ostream &stream, const ChannelMap::value_type &entry,
@@ -206,6 +219,26 @@ private:
} // namespace lldb_private
+/// The LLDB_LOG* macros defined below are the way to emit log messages.
+///
+/// Note that the macros surround the arguments in a check for the log
+/// being on, so you can freely call methods in arguments without affecting
+/// the non-log execution flow.
+///
+/// If you need to do more complex computations to prepare the log message
+/// be sure to add your own if (log) check, since we don't want logging to
+/// have any effect when not on.
+///
+/// However, the LLDB_LOG macro uses the llvm::formatv system (see the
+/// ProgrammersManual page in the llvm docs for more details). This allows
+/// the use of "format_providers" to auto-format datatypes, and there are
+/// already formatters for some of the llvm and lldb datatypes.
+///
+/// So if you need to do non-trivial formatting of one of these types, be
+/// sure to grep the lldb and llvm sources for "format_provider" to see if
+/// there is already a formatter before doing in situ formatting, and if
+/// possible add a provider if one does not already exist.
+
#define LLDB_LOG(log, ...) \
do { \
::lldb_private::Log *log_private = (log); \
@@ -213,6 +246,13 @@ private:
log_private->Format(__FILE__, __func__, __VA_ARGS__); \
} while (0)
+#define LLDB_LOGF(log, ...) \
+ do { \
+ ::lldb_private::Log *log_private = (log); \
+ if (log_private) \
+ log_private->Printf(__VA_ARGS__); \
+ } while (0)
+
#define LLDB_LOGV(log, ...) \
do { \
::lldb_private::Log *log_private = (log); \
diff --git a/include/lldb/Utility/Logging.h b/include/lldb/Utility/Logging.h
index 41086fedf8c2..1a8a1022c5c0 100644
--- a/include/lldb/Utility/Logging.h
+++ b/include/lldb/Utility/Logging.h
@@ -54,8 +54,6 @@ namespace lldb_private {
class Log;
-void LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...);
-
Log *GetLogIfAllCategoriesSet(uint32_t mask);
Log *GetLogIfAnyCategoriesSet(uint32_t mask);
diff --git a/include/lldb/Utility/Predicate.h b/include/lldb/Utility/Predicate.h
index f1539b576686..cbccc3e91a8b 100644
--- a/include/lldb/Utility/Predicate.h
+++ b/include/lldb/Utility/Predicate.h
@@ -117,8 +117,7 @@ public:
/// How long to wait for the condition to hold.
///
/// \return
- /// \li m_value if Cond(m_value) is true.
- /// \li None otherwise (timeout occurred).
+ /// m_value if Cond(m_value) is true, None otherwise (timeout occurred).
template <typename C>
llvm::Optional<T> WaitFor(C Cond, const Timeout<std::micro> &timeout) {
std::unique_lock<std::mutex> lock(m_mutex);
@@ -151,8 +150,8 @@ public:
/// How long to wait for the condition to hold.
///
/// \return
- /// \li \b true if the \a m_value is equal to \a value
- /// \li \b false otherwise (timeout occurred)
+ /// true if the \a m_value is equal to \a value, false otherwise (timeout
+ /// occurred).
bool WaitForValueEqualTo(T value,
const Timeout<std::micro> &timeout = llvm::None) {
return WaitFor([&value](T current) { return value == current; }, timeout) !=
@@ -179,8 +178,7 @@ public:
/// How long to wait for the condition to hold.
///
/// \return
- /// \li m_value if m_value != value
- /// \li None otherwise (timeout occurred).
+ /// m_value if m_value != value, None otherwise (timeout occurred).
llvm::Optional<T>
WaitForValueNotEqualTo(T value,
const Timeout<std::micro> &timeout = llvm::None) {
diff --git a/include/lldb/Utility/ProcessInfo.h b/include/lldb/Utility/ProcessInfo.h
index a25c06cabdf6..9188bf3b7090 100644
--- a/include/lldb/Utility/ProcessInfo.h
+++ b/include/lldb/Utility/ProcessInfo.h
@@ -38,7 +38,7 @@ public:
const char *GetName() const;
- size_t GetNameLength() const;
+ llvm::StringRef GetNameAsStringRef() const;
FileSpec &GetExecutableFile() { return m_executable; }
@@ -165,12 +165,8 @@ public:
void Append(const ProcessInstanceInfo &info) { m_infos.push_back(info); }
- const char *GetProcessNameAtIndex(size_t idx) {
- return ((idx < m_infos.size()) ? m_infos[idx].GetName() : nullptr);
- }
-
- size_t GetProcessNameLengthAtIndex(size_t idx) {
- return ((idx < m_infos.size()) ? m_infos[idx].GetNameLength() : 0);
+ llvm::StringRef GetProcessNameAtIndex(size_t idx) {
+ return ((idx < m_infos.size()) ? m_infos[idx].GetNameAsStringRef() : "");
}
lldb::pid_t GetProcessIDAtIndex(size_t idx) {
@@ -227,8 +223,20 @@ public:
m_name_match_type = name_match_type;
}
+ /// Return true iff the architecture in this object matches arch_spec.
+ bool ArchitectureMatches(const ArchSpec &arch_spec) const;
+
+ /// Return true iff the process name in this object matches process_name.
bool NameMatches(const char *process_name) const;
+ /// Return true iff the process ID and parent process IDs in this object match
+ /// the ones in proc_info.
+ bool ProcessIDsMatch(const ProcessInstanceInfo &proc_info) const;
+
+ /// Return true iff the (both effective and real) user and group IDs in this
+ /// object match the ones in proc_info.
+ bool UserIDsMatch(const ProcessInstanceInfo &proc_info) const;
+
bool Matches(const ProcessInstanceInfo &proc_info) const;
bool MatchAllProcesses() const;
diff --git a/include/lldb/Utility/RangeMap.h b/include/lldb/Utility/RangeMap.h
index 36401f59d34f..709b5d2f66c7 100644
--- a/include/lldb/Utility/RangeMap.h
+++ b/include/lldb/Utility/RangeMap.h
@@ -724,12 +724,14 @@ public:
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert(IsSorted());
#endif
-
- if (!m_entries.empty()) {
- for (const auto &entry : m_entries) {
- if (entry.Contains(addr))
- indexes.push_back(entry.data);
- }
+ // Search the entries until the first entry that has a larger base address
+ // than `addr`. As m_entries is sorted by their base address, all following
+ // entries can't contain `addr` as their base address is already larger.
+ for (const auto &entry : m_entries) {
+ if (entry.Contains(addr))
+ indexes.push_back(entry.data);
+ else if (entry.GetRangeBase() > addr)
+ break;
}
return indexes.size();
}
diff --git a/include/lldb/Utility/RegularExpression.h b/include/lldb/Utility/RegularExpression.h
index 54f3dd89c7a2..6acc203d8e7c 100644
--- a/include/lldb/Utility/RegularExpression.h
+++ b/include/lldb/Utility/RegularExpression.h
@@ -9,189 +9,84 @@
#ifndef liblldb_RegularExpression_h_
#define liblldb_RegularExpression_h_
-#ifdef _WIN32
-#include "../lib/Support/regex_impl.h"
-
-typedef llvm_regmatch_t regmatch_t;
-typedef llvm_regex_t regex_t;
-
-inline int regcomp(llvm_regex_t *a, const char *b, int c) {
- return llvm_regcomp(a, b, c);
-}
-
-inline size_t regerror(int a, const llvm_regex_t *b, char *c, size_t d) {
- return llvm_regerror(a, b, c, d);
-}
-
-inline int regexec(const llvm_regex_t *a, const char *b, size_t c,
- llvm_regmatch_t d[], int e) {
- return llvm_regexec(a, b, c, d, e);
-}
-
-inline void regfree(llvm_regex_t *a) { llvm_regfree(a); }
-#else
-#ifdef __ANDROID__
-#include <regex>
-#endif
-#include <regex.h>
-#endif
-
-#include <string>
-#include <vector>
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace llvm {
-class StringRef;
-} // namespace llvm
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
namespace lldb_private {
-/// \class RegularExpression RegularExpression.h
-/// "lldb/Utility/RegularExpression.h"
-/// A C++ wrapper class for regex.
-///
-/// This regular expression class wraps the posix regex functions \c
-/// regcomp(), \c regerror(), \c regexec(), and \c regfree() from the header
-/// file in \c /usr/include/regex\.h.
class RegularExpression {
public:
- class Match {
- public:
- Match(uint32_t max_matches) : m_matches() {
- if (max_matches > 0)
- m_matches.resize(max_matches + 1);
- }
-
- void Clear() {
- const size_t num_matches = m_matches.size();
- regmatch_t invalid_match = {-1, -1};
- for (size_t i = 0; i < num_matches; ++i)
- m_matches[i] = invalid_match;
- }
-
- size_t GetSize() const { return m_matches.size(); }
-
- regmatch_t *GetData() {
- return (m_matches.empty() ? nullptr : m_matches.data());
- }
-
- bool GetMatchAtIndex(llvm::StringRef s, uint32_t idx,
- std::string &match_str) const;
-
- bool GetMatchAtIndex(llvm::StringRef s, uint32_t idx,
- llvm::StringRef &match_str) const;
-
- bool GetMatchSpanningIndices(llvm::StringRef s, uint32_t idx1,
- uint32_t idx2,
- llvm::StringRef &match_str) const;
-
- protected:
- std::vector<regmatch_t>
- m_matches; ///< Where parenthesized subexpressions results are stored
- };
-
- /// Default constructor.
- ///
/// The default constructor that initializes the object state such that it
/// contains no compiled regular expression.
- RegularExpression();
+ RegularExpression() = default;
- explicit RegularExpression(llvm::StringRef string);
-
- /// Destructor.
- ///
- /// Any previously compiled regular expression contained in this object will
- /// be freed.
- ~RegularExpression();
-
- RegularExpression(const RegularExpression &rhs);
-
- const RegularExpression &operator=(const RegularExpression &rhs);
-
- /// Compile a regular expression.
+ /// Constructor for a regular expression.
///
/// Compile a regular expression using the supplied regular expression text.
/// 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.
+ /// after the regular expression is compiled.
///
- /// \param[in] re
- /// A NULL terminated C string that represents the regular
- /// expression to compile.
- ///
- /// \return
- /// \b true if the regular expression compiles successfully,
- /// \b false otherwise.
- bool Compile(llvm::StringRef string);
- bool Compile(const char *) = delete;
+ /// \param[in] string
+ /// An llvm::StringRef that represents the regular expression to compile.
+ // String is not referenced anymore after the object is constructed.
+ explicit RegularExpression(llvm::StringRef string);
+
+ ~RegularExpression() = default;
+
+ RegularExpression(const RegularExpression &rhs);
+ RegularExpression(RegularExpression &&rhs) = default;
+
+ RegularExpression &operator=(RegularExpression &&rhs) = default;
+ RegularExpression &operator=(const RegularExpression &rhs) = default;
- /// Executes a regular expression.
- ///
/// Execute a regular expression match using the compiled regular expression
- /// that is already in this object against the match string \a s. If any
- /// parens are used for regular expression matches \a match_count should
- /// indicate the number of regmatch_t values that are present in \a
- /// match_ptr.
+ /// that is already in this object against the given \a string. If any parens
+ /// are used for regular expression matches.
///
/// \param[in] string
/// The string to match against the compile regular expression.
///
- /// \param[in] match
- /// A pointer to a RegularExpression::Match structure that was
- /// properly initialized with the desired number of maximum
- /// matches, or nullptr if no parenthesized matching is needed.
+ /// \param[out] matches
+ /// A pointer to a SmallVector to hold the matches.
///
/// \return
- /// \b true if \a string matches the compiled regular
- /// expression, \b false otherwise.
- bool Execute(llvm::StringRef string, Match *match = nullptr) const;
- bool Execute(const char *, Match * = nullptr) = delete;
-
- size_t GetErrorAsCString(char *err_str, size_t err_str_max_len) const;
-
- /// Free the compiled regular expression.
- ///
- /// If this object contains a valid compiled regular expression, this
- /// function will free any resources it was consuming.
- void Free();
+ /// true if \a string matches the compiled regular expression, false
+ /// otherwise incl. the case regular exression failed to compile.
+ bool Execute(llvm::StringRef string,
+ llvm::SmallVectorImpl<llvm::StringRef> *matches = nullptr) const;
/// Access the regular expression text.
///
- /// Returns the text that was used to compile the current regular
- /// expression.
- ///
/// \return
/// The NULL terminated C string that was used to compile the
/// current regular expression
llvm::StringRef GetText() const;
- /// Test if valid.
- ///
/// Test if this object contains a valid regular expression.
///
/// \return
- /// \b true if the regular expression compiled and is ready
- /// for execution, \b false otherwise.
+ /// true if the regular expression compiled and is ready for execution,
+ /// false otherwise.
bool IsValid() const;
- void Clear() {
- Free();
- m_re.clear();
- m_comp_err = 1;
- }
-
- int GetErrorCode() const { return m_comp_err; }
+ /// Return an error if the regular expression failed to compile.
+ ///
+ /// \return
+ /// A string error if the regular expression failed to compile, success
+ /// otherwise.
+ llvm::Error GetError() const;
- bool operator<(const RegularExpression &rhs) const;
+ bool operator==(const RegularExpression &rhs) const {
+ return GetText() == rhs.GetText();
+ }
private:
- // Member variables
- std::string m_re; ///< A copy of the original regular expression text
- int m_comp_err; ///< Status code for the regular expression compilation
- regex_t m_preg; ///< The compiled regular expression
+ /// A copy of the original regular expression text.
+ std::string m_regex_text;
+ /// The compiled regular expression.
+ mutable llvm::Regex m_regex;
};
} // namespace lldb_private
diff --git a/include/lldb/Utility/Reproducer.h b/include/lldb/Utility/Reproducer.h
index 670041d06bba..3db98a781d4c 100644
--- a/include/lldb/Utility/Reproducer.h
+++ b/include/lldb/Utility/Reproducer.h
@@ -9,11 +9,10 @@
#ifndef LLDB_UTILITY_REPRODUCER_H
#define LLDB_UTILITY_REPRODUCER_H
-#include "lldb/Utility/FileCollector.h"
#include "lldb/Utility/FileSpec.h"
-
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/FileCollector.h"
#include "llvm/Support/YAMLTraits.h"
#include <mutex>
@@ -91,23 +90,26 @@ public:
FileProvider(const FileSpec &directory)
: Provider(directory),
- m_collector(directory.CopyByAppendingPathComponent("root"), directory) {
- }
+ m_collector(std::make_shared<llvm::FileCollector>(
+ directory.CopyByAppendingPathComponent("root").GetPath(),
+ directory.GetPath())) {}
- FileCollector &GetFileCollector() { return m_collector; }
+ std::shared_ptr<llvm::FileCollector> GetFileCollector() {
+ return m_collector;
+ }
void Keep() override {
auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file);
// Temporary files that are removed during execution can cause copy errors.
- if (auto ec = m_collector.CopyFiles(/*stop_on_error=*/false))
+ if (auto ec = m_collector->copyFiles(/*stop_on_error=*/false))
return;
- m_collector.WriteMapping(mapping);
+ m_collector->writeMapping(mapping.GetPath());
}
static char ID;
private:
- FileCollector m_collector;
+ std::shared_ptr<llvm::FileCollector> m_collector;
};
/// Provider for the LLDB version number.
@@ -130,11 +132,32 @@ public:
static char ID;
};
+/// Provider for the LLDB current working directroy.
+///
+/// When the reproducer is kept, it writes lldb's current working directory to
+/// a file named cwd.txt in the reproducer root.
+class WorkingDirectoryProvider : public Provider<WorkingDirectoryProvider> {
+public:
+ WorkingDirectoryProvider(const FileSpec &directory) : Provider(directory) {
+ llvm::SmallString<128> cwd;
+ if (std::error_code EC = llvm::sys::fs::current_path(cwd))
+ return;
+ m_cwd = cwd.str();
+ }
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ void Keep() override;
+ std::string m_cwd;
+ static char ID;
+};
+
class DataRecorder {
public:
DataRecorder(const FileSpec &filename, std::error_code &ec)
: m_filename(filename.GetFilename().GetStringRef()),
- m_os(filename.GetPath(), ec, llvm::sys::fs::F_Text), m_record(true) {}
+ m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {}
static llvm::Expected<std::unique_ptr<DataRecorder>>
Create(const FileSpec &filename);
@@ -181,12 +204,39 @@ private:
std::vector<std::unique_ptr<DataRecorder>> m_data_recorders;
};
+class ProcessGDBRemoteProvider
+ : public repro::Provider<ProcessGDBRemoteProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {}
+
+ llvm::raw_ostream *GetHistoryStream();
+
+ void SetCallback(std::function<void()> callback) {
+ m_callback = std::move(callback);
+ }
+
+ void Keep() override { m_callback(); }
+ void Discard() override { m_callback(); }
+
+ static char ID;
+
+private:
+ std::function<void()> m_callback;
+ std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
+};
+
/// The generator is responsible for the logic needed to generate a
/// reproducer. For doing so it relies on providers, who serialize data that
/// is necessary for reproducing a failure.
class Generator final {
+
public:
- Generator(const FileSpec &root);
+ Generator(FileSpec root);
~Generator();
/// Method to indicate we want to keep the reproducer. If reproducer
@@ -200,7 +250,7 @@ public:
/// Create and register a new provider.
template <typename T> T *Create() {
- std::unique_ptr<ProviderBase> provider = llvm::make_unique<T>(m_root);
+ std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
return static_cast<T *>(Register(std::move(provider)));
}
@@ -243,7 +293,7 @@ private:
class Loader final {
public:
- Loader(const FileSpec &root);
+ Loader(FileSpec root);
template <typename T> FileSpec GetFile() {
if (!HasFile(T::file))
@@ -252,6 +302,15 @@ public:
return GetRoot().CopyByAppendingPathComponent(T::file);
}
+ template <typename T> llvm::Expected<std::string> LoadBuffer() {
+ FileSpec file = GetFile<typename T::Info>();
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
+ llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath());
+ if (!buffer)
+ return llvm::errorCodeToError(buffer.getError());
+ return (*buffer)->getBuffer().str();
+ }
+
llvm::Error LoadIndex();
const FileSpec &GetRoot() const { return m_root; }
@@ -284,6 +343,9 @@ public:
FileSpec GetReproducerPath() const;
+ bool IsCapturing() { return static_cast<bool>(m_generator); };
+ bool IsReplaying() { return static_cast<bool>(m_loader); };
+
protected:
llvm::Error SetCapture(llvm::Optional<FileSpec> root);
llvm::Error SetReplay(llvm::Optional<FileSpec> root);
@@ -297,6 +359,19 @@ private:
mutable std::mutex m_mutex;
};
+/// Helper class for replaying commands through the reproducer.
+class CommandLoader {
+public:
+ CommandLoader(std::vector<std::string> files) : m_files(files) {}
+
+ static std::unique_ptr<CommandLoader> Create(Loader *loader);
+ llvm::Optional<std::string> GetNextFile();
+
+private:
+ std::vector<std::string> m_files;
+ unsigned m_index = 0;
+};
+
} // namespace repro
} // namespace lldb_private
diff --git a/include/lldb/Utility/ReproducerInstrumentation.h b/include/lldb/Utility/ReproducerInstrumentation.h
index f90ce4bc767a..75d66045758f 100644
--- a/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/include/lldb/Utility/ReproducerInstrumentation.h
@@ -40,7 +40,7 @@ inline void stringify_append(llvm::raw_string_ostream &ss, const T *t) {
template <>
inline void stringify_append<char>(llvm::raw_string_ostream &ss,
const char *t) {
- ss << t;
+ ss << '\"' << t << '\"';
}
template <typename Head>
@@ -105,8 +105,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
+ lldb_private::repro::Recorder sb_recorder( \
+ LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record( \
@@ -117,8 +117,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
+ lldb_private::repro::Recorder sb_recorder( \
+ LLVM_PRETTY_FUNCTION, stringify_args(*this, __VA_ARGS__)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record( \
@@ -129,7 +129,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
+ lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
+ stringify_args(*this)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \
@@ -139,7 +140,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
}
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
+ lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
+ stringify_args(*this)); \
if (lldb_private::repro::InstrumentationData data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
sb_recorder.Record( \
@@ -175,6 +177,8 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
#define LLDB_RECORD_DUMMY(Result, Class, Method, Signature, ...) \
lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
stringify_args(__VA_ARGS__));
+#define LLDB_RECORD_DUMMY_NO_ARGS(Result, Class, Method) \
+ lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION);
namespace lldb_private {
namespace repro {
@@ -234,9 +238,12 @@ struct ReferenceTag {};
struct ValueTag {};
struct FundamentalPointerTag {};
struct FundamentalReferenceTag {};
+struct NotImplementedTag {};
/// Return the deserialization tag for the given type T.
-template <class T> struct serializer_tag { typedef ValueTag type; };
+template <class T> struct serializer_tag {
+ typedef typename std::conditional<std::is_trivially_copyable<T>::value, ValueTag, NotImplementedTag>::type type;
+};
template <class T> struct serializer_tag<T *> {
typedef
typename std::conditional<std::is_fundamental<T>::value,
@@ -300,6 +307,11 @@ public:
}
private:
+ template <typename T> T Read(NotImplementedTag) {
+ m_buffer = m_buffer.drop_front(sizeof(T));
+ return T();
+ }
+
template <typename T> T Read(ValueTag) {
assert(HasData(sizeof(T)));
T t;
@@ -442,7 +454,7 @@ public:
void Register(Signature *f, llvm::StringRef result = {},
llvm::StringRef scope = {}, llvm::StringRef name = {},
llvm::StringRef args = {}) {
- DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(f),
+ DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(f),
SignatureStr(result, scope, name, args));
}
@@ -452,7 +464,7 @@ public:
void Register(Signature *f, Signature *g, llvm::StringRef result = {},
llvm::StringRef scope = {}, llvm::StringRef name = {},
llvm::StringRef args = {}) {
- DoRegister(uintptr_t(f), llvm::make_unique<DefaultReplayer<Signature>>(g),
+ DoRegister(uintptr_t(f), std::make_unique<DefaultReplayer<Signature>>(g),
SignatureStr(result, scope, name, args));
}
@@ -542,9 +554,7 @@ public:
SerializeAll(tail...);
}
- void SerializeAll() {
- m_stream.flush();
- }
+ void SerializeAll() { m_stream.flush(); }
private:
/// Serialize pointers. We need to differentiate between pointers to
diff --git a/include/lldb/Utility/Scalar.h b/include/lldb/Utility/Scalar.h
index 62ee9f666e89..72f153ff97cd 100644
--- a/include/lldb/Utility/Scalar.h
+++ b/include/lldb/Utility/Scalar.h
@@ -38,6 +38,7 @@ namespace lldb_private {
// follows the ANSI C type promotion rules.
class Scalar {
public:
+ // FIXME: These are host types which seems to be an odd choice.
enum Type {
e_void = 0,
e_sint,
@@ -98,30 +99,14 @@ public:
}
Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) {
m_integer = llvm::APInt(v);
- switch (m_integer.getBitWidth()) {
- case 8:
- case 16:
- case 32:
- m_type = e_sint;
- return;
- case 64:
- m_type = e_slonglong;
- return;
- case 128:
- m_type = e_sint128;
- return;
- case 256:
- m_type = e_sint256;
- return;
- case 512:
- m_type = e_sint512;
- return;
- }
- lldbassert(false && "unsupported bitwidth");
+ m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true);
}
// Scalar(const RegisterValue& reg_value);
virtual ~Scalar();
+ /// Return the most efficient Scalar::Type for the requested bit size.
+ static Type GetBestTypeForBitSize(size_t bit_size, bool sign);
+
bool SignExtend(uint32_t bit_pos);
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
@@ -154,6 +139,9 @@ public:
return (m_type >= e_sint) && (m_type <= e_long_double);
}
+ /// Convert integer to \p type, limited to \p bits size.
+ void TruncOrExtendTo(Scalar::Type type, uint16_t bits);
+
bool Promote(Scalar::Type type);
bool MakeSigned();
diff --git a/include/lldb/Utility/Status.h b/include/lldb/Utility/Status.h
index ae730b90dffe..e6a0a8e7fce1 100644
--- a/include/lldb/Utility/Status.h
+++ b/include/lldb/Utility/Status.h
@@ -47,8 +47,8 @@ public:
/// into ValueType.
typedef uint32_t ValueType;
- /// Default constructor.
- ///
+ Status();
+
/// Initialize the error object with a generic success value.
///
/// \param[in] err
@@ -56,23 +56,14 @@ public:
///
/// \param[in] type
/// The type for \a err.
- Status();
-
explicit Status(ValueType err,
lldb::ErrorType type = lldb::eErrorTypeGeneric);
- /* implicit */ Status(std::error_code EC);
+ Status(std::error_code EC);
explicit Status(const char *format, ...)
__attribute__((format(printf, 2, 3)));
- /// Assignment operator.
- ///
- /// \param[in] err
- /// An error code.
- ///
- /// \return
- /// A const reference to this object.
const Status &operator=(const Status &rhs);
~Status();
@@ -221,4 +212,11 @@ template <> struct format_provider<lldb_private::Status> {
};
}
+#define LLDB_ERRORF(status, fmt, ...) \
+ do { \
+ if (status) { \
+ (status)->SetErrorStringWithFormat((fmt), __VA_ARGS__); \
+ } \
+ } while (0);
+
#endif // #ifndef LLDB_UTILITY_STATUS_H
diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h
index b24d4e457177..414f92177303 100644
--- a/include/lldb/Utility/Stream.h
+++ b/include/lldb/Utility/Stream.h
@@ -35,11 +35,11 @@ public:
/// Utility class for counting the bytes that were written to a stream in a
/// certain time span.
+ ///
/// \example
/// ByteDelta delta(*this);
/// WriteDataToStream("foo");
/// return *delta;
- /// \endcode
class ByteDelta {
Stream *m_stream;
/// Bytes we have written so far when ByteDelta was created.
diff --git a/include/lldb/Utility/StreamGDBRemote.h b/include/lldb/Utility/StreamGDBRemote.h
deleted file mode 100644
index dd0ea31126d9..000000000000
--- a/include/lldb/Utility/StreamGDBRemote.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- StreamGDBRemote.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 liblldb_StreamGDBRemote_h_
-#define liblldb_StreamGDBRemote_h_
-
-#include "lldb/Utility/StreamString.h"
-#include "lldb/lldb-enumerations.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-namespace lldb_private {
-
-class StreamGDBRemote : public StreamString {
-public:
- StreamGDBRemote();
-
- StreamGDBRemote(uint32_t flags, uint32_t addr_size,
- lldb::ByteOrder byte_order);
-
- ~StreamGDBRemote() override;
-
- /// Output a block of data to the stream performing GDB-remote escaping.
- ///
- /// \param[in] s
- /// A block of data.
- ///
- /// \param[in] src_len
- /// The amount of data to write.
- ///
- /// \return
- /// Number of bytes written.
- // TODO: Convert this function to take ArrayRef<uint8_t>
- int PutEscapedBytes(const void *s, size_t src_len);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_StreamGDBRemote_h_
diff --git a/include/lldb/Utility/StringExtractor.h b/include/lldb/Utility/StringExtractor.h
index f20ec92199bb..293fef2fbe6b 100644
--- a/include/lldb/Utility/StringExtractor.h
+++ b/include/lldb/Utility/StringExtractor.h
@@ -45,9 +45,7 @@ public:
void SkipSpaces();
- std::string &GetStringRef() { return m_packet; }
-
- const std::string &GetStringRef() const { return m_packet; }
+ llvm::StringRef GetStringRef() const { return m_packet; }
bool Empty() { return m_packet.empty(); }
@@ -91,9 +89,6 @@ public:
size_t GetHexBytesAvail(llvm::MutableArrayRef<uint8_t> dest);
- uint64_t GetHexWithFixedSize(uint32_t byte_size, bool little_endian,
- uint64_t fail_value);
-
size_t GetHexByteString(std::string &str);
size_t GetHexByteStringFixedLength(std::string &str, uint32_t nibble_length);
@@ -113,12 +108,14 @@ protected:
m_index = UINT64_MAX;
return false;
}
- // For StringExtractor only
- std::string m_packet; // The string in which to extract data.
- uint64_t m_index; // When extracting data from a packet, this index
- // will march along as things get extracted. If set to
- // UINT64_MAX the end of the packet data was reached
- // when decoding information
+
+ /// The string in which to extract data.
+ std::string m_packet;
+
+ /// When extracting data from a packet, this index will march along as things
+ /// get extracted. If set to UINT64_MAX the end of the packet data was
+ /// reached when decoding information.
+ uint64_t m_index;
};
#endif // utility_StringExtractor_h_
diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h
index d9806c1b37d7..533fd4fb896e 100644
--- a/include/lldb/Utility/StringLexer.h
+++ b/include/lldb/Utility/StringLexer.h
@@ -1,4 +1,4 @@
-//===--------------------- StringLexer.h ------------------------*- C++ -*-===//
+//===-- StringLexer.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.
@@ -13,7 +13,7 @@
#include <string>
#include <utility>
-namespace lldb_utility {
+namespace lldb_private {
class StringLexer {
public:
diff --git a/include/lldb/Utility/StringList.h b/include/lldb/Utility/StringList.h
index 68c1f87510f6..0b1d955678b3 100644
--- a/include/lldb/Utility/StringList.h
+++ b/include/lldb/Utility/StringList.h
@@ -23,6 +23,8 @@ class Stream;
namespace lldb_private {
class StringList {
+ typedef std::vector<std::string> collection;
+
public:
StringList();
@@ -52,6 +54,14 @@ public:
size_t GetMaxStringLength() const;
+ typedef collection::iterator iterator;
+ typedef collection::const_iterator const_iterator;
+
+ iterator begin() { return m_strings.begin(); }
+ iterator end() { return m_strings.end(); }
+ const_iterator begin() const { return m_strings.begin(); }
+ const_iterator end() const { return m_strings.end(); }
+
std::string &operator[](size_t idx) {
// No bounds checking, verify "idx" is good prior to calling this function
return m_strings[idx];
@@ -69,7 +79,7 @@ public:
void Clear();
- void LongestCommonPrefix(std::string &common_prefix);
+ std::string LongestCommonPrefix();
void InsertStringAtIndex(size_t idx, const std::string &str);
@@ -97,14 +107,6 @@ public:
// Copy assignment for a vector of strings
StringList &operator=(const std::vector<std::string> &rhs);
- // This string list contains a list of valid auto completion strings, and the
- // "s" is passed in. "matches" is filled in with zero or more string values
- // that start with "s", and the first string to exactly match one of the
- // string values in this collection, will have "exact_matches_idx" filled in
- // to match the index, or "exact_matches_idx" will have SIZE_MAX
- size_t AutoComplete(llvm::StringRef s, StringList &matches,
- size_t &exact_matches_idx) const;
-
// Dump the StringList to the given lldb_private::Log, `log`, one item per
// line. If given, `name` will be used to identify the start and end of the
// list in the output.
@@ -125,7 +127,7 @@ public:
}
private:
- std::vector<std::string> m_strings;
+ collection m_strings;
};
} // namespace lldb_private
diff --git a/include/lldb/Utility/StructuredData.h b/include/lldb/Utility/StructuredData.h
index 75eb2f7b7291..01b14fc3d4d3 100644
--- a/include/lldb/Utility/StructuredData.h
+++ b/include/lldb/Utility/StructuredData.h
@@ -10,9 +10,11 @@
#define liblldb_StructuredData_h_
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/JSON.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Stream.h"
#include "lldb/lldb-enumerations.h"
#include <cassert>
@@ -28,7 +30,6 @@
namespace lldb_private {
class Status;
-class Stream;
}
namespace lldb_private {
@@ -150,7 +151,12 @@ public:
void DumpToStdout(bool pretty_print = true) const;
- virtual void Dump(Stream &s, bool pretty_print = true) const = 0;
+ virtual void Serialize(llvm::json::OStream &s) const = 0;
+
+ void Dump(lldb_private::Stream &s, bool pretty_print = true) const {
+ llvm::json::OStream jso(s.AsRawOstream(), pretty_print ? 2 : 0);
+ Serialize(jso);
+ }
private:
lldb::StructuredDataType m_type;
@@ -269,7 +275,7 @@ public:
void AddItem(ObjectSP item) { m_items.push_back(item); }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
typedef std::vector<ObjectSP> collection;
@@ -287,7 +293,7 @@ public:
uint64_t GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
uint64_t m_value;
@@ -304,7 +310,7 @@ public:
double GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
double m_value;
@@ -321,7 +327,7 @@ public:
bool GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
bool m_value;
@@ -337,7 +343,7 @@ public:
llvm::StringRef GetValue() { return m_value; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
std::string m_value;
@@ -506,7 +512,7 @@ public:
AddItem(key, std::make_shared<Boolean>(value));
}
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
protected:
typedef std::map<ConstString, ObjectSP> collection;
@@ -521,7 +527,7 @@ public:
bool IsValid() const override { return false; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
};
class Generic : public Object {
@@ -535,14 +541,13 @@ public:
bool IsValid() const override { return m_object != nullptr; }
- void Dump(Stream &s, bool pretty_print = true) const override;
+ void Serialize(llvm::json::OStream &s) const override;
private:
void *m_object;
};
static ObjectSP ParseJSON(std::string json_text);
-
static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
};
diff --git a/include/lldb/Utility/UUID.h b/include/lldb/Utility/UUID.h
index dbeb9db611b2..0284357be44a 100644
--- a/include/lldb/Utility/UUID.h
+++ b/include/lldb/Utility/UUID.h
@@ -9,14 +9,11 @@
#ifndef LLDB_UTILITY_UUID_H
#define LLDB_UTILITY_UUID_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
-#include "llvm/ADT/ArrayRef.h"
-
-namespace llvm {
- class StringRef;
-}
namespace lldb_private {
@@ -67,10 +64,10 @@ public:
std::string GetAsString(llvm::StringRef separator = "-") const;
size_t SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16);
-
- // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the
+
+ // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the
// UUID to invalid.
- size_t SetFromOptionalStringRef(llvm::StringRef str,
+ size_t SetFromOptionalStringRef(llvm::StringRef str,
uint32_t num_uuid_bytes = 16);
// Decode as many UUID bytes (up to 16) as possible from the C string "cstr"
@@ -79,14 +76,13 @@ public:
/// Decode as many UUID bytes (up to 16) as possible from the C
/// string \a cstr.
///
- /// \param[in] cstr
- /// A NULL terminate C string that points at a UUID string value
- /// (no leading spaces). The string must contain only hex
- /// characters and optionally can contain the '-' sepearators.
+ /// \param[in] str
+ /// An llvm::StringRef that points at a UUID string value (no leading
+ /// spaces). The string must contain only hex characters and optionally
+ /// can contain the '-' sepearators.
///
/// \param[in] uuid_bytes
- /// A buffer of bytes that will contain a full or patially
- /// decoded UUID.
+ /// A buffer of bytes that will contain a full or partially decoded UUID.
///
/// \return
/// The original string, with all decoded bytes removed.