Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/lldb/Utility/AnsiTerminal.h b/linux-x64/clang/include/lldb/Utility/AnsiTerminal.h
index 1473c60..c391adb 100644
--- a/linux-x64/clang/include/lldb/Utility/AnsiTerminal.h
+++ b/linux-x64/clang/include/lldb/Utility/AnsiTerminal.h
@@ -1,3 +1,7 @@
+#ifndef LLDB_UTILITY_ANSITERMINAL_H
+
+#define LLDB_UTILITY_ANSITERMINAL_H
+
//===---------------------AnsiTerminal.h ------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -55,7 +59,7 @@
#include <string>
-namespace lldb_utility {
+namespace lldb_private {
namespace ansi {
@@ -111,7 +115,7 @@
llvm::StringRef left, right;
std::tie(left, right) = format.split(tok_hdr);
- fmt.append(left);
+ fmt += left;
if (left == format && right.empty()) {
// The header was not found. Just exit.
@@ -137,4 +141,6 @@
return fmt;
}
}
-}
+} // namespace lldb_private
+
+#endif
diff --git a/linux-x64/clang/include/lldb/Utility/ArchSpec.h b/linux-x64/clang/include/lldb/Utility/ArchSpec.h
index 7a32556..b35766d 100644
--- a/linux-x64/clang/include/lldb/Utility/ArchSpec.h
+++ b/linux-x64/clang/include/lldb/Utility/ArchSpec.h
@@ -16,6 +16,7 @@
#include "lldb/lldb-private-enumerations.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Support/YAMLTraits.h"
#include <cstddef>
#include <cstdint>
#include <string>
@@ -91,6 +92,12 @@
eARM_abi_hard_float = 0x00000400
};
+ enum RISCVSubType {
+ eRISCVSubType_unknown,
+ eRISCVSubType_riscv32,
+ eRISCVSubType_riscv64,
+ };
+
enum Core {
eCore_arm_generic,
eCore_arm_armv4,
@@ -101,6 +108,7 @@
eCore_arm_armv6,
eCore_arm_armv6m,
eCore_arm_armv7,
+ eCore_arm_armv7l,
eCore_arm_armv7f,
eCore_arm_armv7s,
eCore_arm_armv7k,
@@ -122,6 +130,8 @@
eCore_thumbv7em,
eCore_arm_arm64,
eCore_arm_armv8,
+ eCore_arm_armv8l,
+ eCore_arm_arm64_32,
eCore_arm_aarch64,
eCore_mips32,
@@ -180,9 +190,18 @@
eCore_hexagon_hexagonv4,
eCore_hexagon_hexagonv5,
+ eCore_riscv32,
+ eCore_riscv64,
+
eCore_uknownMach32,
eCore_uknownMach64,
+ eCore_arc, // little endian ARC
+
+ eCore_avr,
+
+ eCore_wasm32,
+
kNumCores,
kCore_invalid,
@@ -255,20 +274,13 @@
/// Destructor.
~ArchSpec();
- /// Assignment operator.
- ///
- /// \param[in] rhs another ArchSpec object to copy.
- ///
- /// \return A const reference to this object.
- const ArchSpec &operator=(const ArchSpec &rhs);
-
/// Returns true if the OS, vendor and environment fields of the triple are
/// unset. The triple is expected to be normalized
/// (llvm::Triple::normalize).
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.
///
@@ -435,7 +447,7 @@
/// \return A triple describing this ArchSpec.
const llvm::Triple &GetTriple() const { return m_triple; }
- void DumpTriple(Stream &s) const;
+ void DumpTriple(llvm::raw_ostream &s) const;
/// Architecture triple setter.
///
@@ -502,7 +514,7 @@
void SetFlags(uint32_t flags) { m_flags = flags; }
- void SetFlags(std::string elf_abi);
+ void SetFlags(const std::string &elf_abi);
protected:
bool IsEqualTo(const ArchSpec &rhs, bool exact_match) const;
@@ -539,4 +551,16 @@
} // namespace lldb_private
-#endif // #ifndef LLDB_UTILITY_ARCHSPEC_H
+namespace llvm {
+namespace yaml {
+template <> struct ScalarTraits<lldb_private::ArchSpec> {
+ static void output(const lldb_private::ArchSpec &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, lldb_private::ArchSpec &);
+ static QuotingType mustQuote(StringRef S) { return QuotingType::Double; }
+};
+} // namespace yaml
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ArchSpec)
+
+#endif // LLDB_UTILITY_ARCHSPEC_H
diff --git a/linux-x64/clang/include/lldb/Utility/Args.h b/linux-x64/clang/include/lldb/Utility/Args.h
index 6f25849..b93677b 100644
--- a/linux-x64/clang/include/lldb/Utility/Args.h
+++ b/linux-x64/clang/include/lldb/Utility/Args.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/YAMLTraits.h"
#include <string>
#include <utility>
#include <vector>
@@ -34,7 +35,11 @@
struct ArgEntry {
private:
friend class Args;
+ friend struct llvm::yaml::MappingTraits<Args>;
+ friend struct llvm::yaml::MappingTraits<Args::ArgEntry>;
+
std::unique_ptr<char[]> ptr;
+ char quote;
char *data() { return ptr.get(); }
@@ -42,12 +47,12 @@
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.
@@ -61,6 +66,7 @@
Args(const Args &rhs);
explicit Args(const StringList &list);
+ explicit Args(llvm::ArrayRef<llvm::StringRef> args);
Args &operator=(const Args &rhs);
@@ -121,7 +127,6 @@
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 +173,8 @@
/// 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 +184,27 @@
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 +240,12 @@
/// \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,48 +257,14 @@
// 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)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const uint64_t max = (static_cast<uint64_t>(1)
- << static_cast<uint64_t>(total_byte_size * 8)) -
- 1;
- return uval64 <= max;
- }
-
- static bool SInt64ValueIsValidForByteSize(int64_t sval64,
- size_t total_byte_size) {
- if (total_byte_size > 8)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const int64_t max = (static_cast<int64_t>(1)
- << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
- 1;
- const int64_t min = ~(max);
- return min <= sval64 && sval64 <= max;
- }
-
static lldb::Encoding
StringToEncoding(llvm::StringRef s,
lldb::Encoding fail_value = lldb::eEncodingInvalid);
static uint32_t StringToGenericRegister(llvm::StringRef s);
- static const char *GetShellSafeArgument(const FileSpec &shell,
- const char *unsafe_arg,
- std::string &safe_arg);
+ static std::string GetShellSafeArgument(const FileSpec &shell,
+ llvm::StringRef unsafe_arg);
// EncodeEscapeSequences will change the textual representation of common
// escape sequences like "\n" (two characters) into a single '\n'. It does
@@ -319,6 +287,8 @@
char quote_char);
private:
+ friend struct llvm::yaml::MappingTraits<Args>;
+
std::vector<ArgEntry> m_entries;
std::vector<char *> m_argv;
};
@@ -409,4 +379,28 @@
} // namespace lldb_private
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<lldb_private::Args::ArgEntry> {
+ class NormalizedArgEntry {
+ public:
+ NormalizedArgEntry(IO &) {}
+ NormalizedArgEntry(IO &, lldb_private::Args::ArgEntry &entry)
+ : value(entry.ref()), quote(entry.quote) {}
+ lldb_private::Args::ArgEntry denormalize(IO &) {
+ return lldb_private::Args::ArgEntry(value, quote);
+ }
+ StringRef value;
+ uint8_t quote;
+ };
+ static void mapping(IO &io, lldb_private::Args::ArgEntry &v);
+};
+template <> struct MappingTraits<lldb_private::Args> {
+ static void mapping(IO &io, lldb_private::Args &v);
+};
+} // namespace yaml
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::Args::ArgEntry)
+
#endif // LLDB_UTILITY_ARGS_H
diff --git a/linux-x64/clang/include/lldb/Utility/Baton.h b/linux-x64/clang/include/lldb/Utility/Baton.h
index 4050f2a..010f8da 100644
--- a/linux-x64/clang/include/lldb/Utility/Baton.h
+++ b/linux-x64/clang/include/lldb/Utility/Baton.h
@@ -6,12 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef lldb_Baton_h_
-#define lldb_Baton_h_
+#ifndef LLDB_UTILITY_BATON_H
+#define LLDB_UTILITY_BATON_H
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"
+#include "llvm/Support/raw_ostream.h"
+
#include <memory>
namespace lldb_private {
@@ -37,8 +39,9 @@
virtual void *data() = 0;
- virtual void GetDescription(Stream *s,
- lldb::DescriptionLevel level) const = 0;
+ virtual void GetDescription(llvm::raw_ostream &s,
+ lldb::DescriptionLevel level,
+ unsigned indentation) const = 0;
};
class UntypedBaton : public Baton {
@@ -50,7 +53,8 @@
}
void *data() override { return m_data; }
- void GetDescription(Stream *s, lldb::DescriptionLevel level) const override;
+ void GetDescription(llvm::raw_ostream &s, lldb::DescriptionLevel level,
+ unsigned indentation) const override;
void *m_data; // Leave baton public for easy access
};
@@ -63,7 +67,8 @@
const T *getItem() const { return Item.get(); }
void *data() override { return Item.get(); }
- void GetDescription(Stream *s, lldb::DescriptionLevel level) const override {}
+ void GetDescription(llvm::raw_ostream &s, lldb::DescriptionLevel level,
+ unsigned indentation) const override {}
protected:
std::unique_ptr<T> Item;
@@ -71,4 +76,4 @@
} // namespace lldb_private
-#endif // lldb_Baton_h_
+#endif // LLDB_UTILITY_BATON_H
diff --git a/linux-x64/clang/include/lldb/Utility/Broadcaster.h b/linux-x64/clang/include/lldb/Utility/Broadcaster.h
index fe4d1ca..9c025a7 100644
--- a/linux-x64/clang/include/lldb/Utility/Broadcaster.h
+++ b/linux-x64/clang/include/lldb/Utility/Broadcaster.h
@@ -39,7 +39,7 @@
/// Debugger maintains a list of BroadcastEventSpec's and when it is made
class BroadcastEventSpec {
public:
- BroadcastEventSpec(ConstString broadcaster_class, uint32_t event_bits)
+ BroadcastEventSpec(const ConstString &broadcaster_class, uint32_t event_bits)
: m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}
~BroadcastEventSpec() = default;
@@ -65,7 +65,6 @@
}
bool operator<(const BroadcastEventSpec &rhs) const;
- BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs);
private:
ConstString m_broadcaster_class;
@@ -118,7 +117,7 @@
class BroadcasterClassMatches {
public:
- BroadcasterClassMatches(ConstString broadcaster_class)
+ BroadcasterClassMatches(const ConstString &broadcaster_class)
: m_broadcaster_class(broadcaster_class) {}
~BroadcasterClassMatches() = default;
@@ -260,19 +259,6 @@
void CheckInWithManager();
/// Broadcast an event which has no associated data.
- ///
- /// \param[in] event_type
- /// The element from the enum defining this broadcaster's events
- /// that is being broadcast.
- ///
- /// \param[in] event_data
- /// User event data that will be owned by the lldb::Event that
- /// is created internally.
- ///
- /// \param[in] unique
- /// If true, then only add an event of this type if there isn't
- /// one already in the queue.
- ///
void BroadcastEvent(lldb::EventSP &event_sp) {
m_broadcaster_sp->BroadcastEvent(event_sp);
}
@@ -309,7 +295,7 @@
/// different from what is requested in \a event_mask, and to track this the
/// actual event bits that are acquired get returned.
///
- /// \param[in] listener
+ /// \param[in] listener_sp
/// The Listener object that wants to monitor the events that
/// get broadcast by this object.
///
@@ -348,9 +334,6 @@
/// \param[in] event_mask
/// A bit mask that indicates which events the listener is
/// asking to monitor.
- ///
- /// \return
- /// The NULL terminated C string name of this Broadcaster.
void SetEventName(uint32_t event_mask, const char *name) {
m_broadcaster_sp->SetEventName(event_mask, name);
}
@@ -368,7 +351,7 @@
/// (assuming \a listener was listening to this object) for other listener
/// objects to use.
///
- /// \param[in] listener
+ /// \param[in] listener_sp
/// A Listener object that previously called AddListener.
///
/// \param[in] event_mask
@@ -390,7 +373,7 @@
/// now go to the hijacking listener. Only one hijack can occur at a time.
/// If we need more than this we will have to implement a Listener stack.
///
- /// \param[in] listener
+ /// \param[in] listener_sp
/// A Listener object. You do not need to call StartListeningForEvents
/// for this broadcaster (that would fail anyway since the event bits
/// would most likely be taken by the listener(s) you are usurping.
@@ -531,7 +514,8 @@
std::vector<uint32_t> m_hijacking_masks;
private:
- DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl);
+ BroadcasterImpl(const BroadcasterImpl &) = delete;
+ const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete;
};
typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
@@ -550,7 +534,8 @@
/// The name of this broadcaster object.
const ConstString m_broadcaster_name;
- DISALLOW_COPY_AND_ASSIGN(Broadcaster);
+ Broadcaster(const Broadcaster &) = delete;
+ const Broadcaster &operator=(const Broadcaster &) = delete;
};
} // namespace lldb_private
diff --git a/linux-x64/clang/include/lldb/Utility/CleanUp.h b/linux-x64/clang/include/lldb/Utility/CleanUp.h
deleted file mode 100644
index 6cd5f33..0000000
--- a/linux-x64/clang/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/linux-x64/clang/include/lldb/Utility/CompletionRequest.h b/linux-x64/clang/include/lldb/Utility/CompletionRequest.h
index f5ccb01..1fbc969 100644
--- a/linux-x64/clang/include/lldb/Utility/CompletionRequest.h
+++ b/linux-x64/clang/include/lldb/Utility/CompletionRequest.h
@@ -16,25 +16,66 @@
#include "llvm/ADT/StringSet.h"
namespace lldb_private {
-class CompletionResult {
- /// A single completion and all associated data.
- struct Completion {
- Completion(llvm::StringRef completion, llvm::StringRef description)
- : m_completion(completion.str()), m_descripton(description.str()) {}
+enum class CompletionMode {
+ /// The current token has been completed. The client should indicate this
+ /// to the user (usually this is done by adding a trailing space behind the
+ /// token).
+ /// Example: "command sub" -> "command subcommand " (note the trailing space).
+ Normal,
+ /// The current token has been partially completed. This means that we found
+ /// a completion, but that the 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).
+ /// Example: "file /us" -> "file /usr/" (note the missing trailing space).
+ Partial,
+ /// The full line has been rewritten by the completion.
+ /// Example: "alias name" -> "other_command full_name".
+ RewriteLine,
+};
+class CompletionResult {
+public:
+ /// A single completion and all associated data.
+ class Completion {
+
+ /// The actual text that should be completed. The meaning of this text
+ /// is defined by the CompletionMode.
+ /// \see m_mode
std::string m_completion;
+ /// The description that should be displayed to the user alongside the
+ /// completion text.
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:
+ /// List of found completions.
std::vector<Completion> m_results;
- /// List of added completions so far. Used to filter out duplicates.
+ /// A set of the unique keys of all found completions so far. Used to filter
+ /// out duplicates.
+ /// \see CompletionResult::Completion::GetUniqueKey
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,21 +109,25 @@
/// 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; }
+ /// Returns the raw user input used to create this CompletionRequest cut off
+ /// at the cursor position. The cursor will be at the end of the raw line.
+ llvm::StringRef GetRawLine() const {
+ return m_command.substr(0, GetRawCursorPos());
+ }
+
+ /// Returns the full raw user input used to create this CompletionRequest.
+ /// This string is not cut off at the cursor position and will include
+ /// characters behind the cursor position.
+ ///
+ /// You should most likely *not* use this function unless the characters
+ /// behind the cursor position influence the completion.
+ llvm::StringRef GetRawLineWithUnusedSuffix() const { return m_command; }
unsigned GetRawCursorPos() const { return m_raw_cursor_pos; }
@@ -90,33 +135,57 @@
Args &GetParsedLine() { return m_parsed_line; }
- const Args &GetPartialParsedLine() const { return m_partial_parsed_line; }
+ const Args::ArgEntry &GetParsedArg() {
+ return GetParsedLine()[GetCursorIndex()];
+ }
- void SetCursorIndex(int i) { m_cursor_index = i; }
- int GetCursorIndex() const { return m_cursor_index; }
+ /// Drops the first argument from the argument list.
+ void ShiftArguments() {
+ m_cursor_index--;
+ m_parsed_line.Shift();
+ }
- void SetCursorCharPosition(int pos) { m_cursor_char_position = pos; }
- int GetCursorCharPosition() const { return m_cursor_char_position; }
+ /// 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;
+ }
- int GetMatchStartPoint() const { return m_match_start_point; }
-
- int GetMaxReturnElements() const { return m_max_return_elements; }
-
- bool GetWordComplete() { return m_word_complete; }
-
- 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
/// the suggested completion is stored, so the given string can be free'd
/// afterwards.
///
- /// \param match The suggested completion.
- /// \param match An optional description of the completion string. The
+ /// \param completion The suggested completion.
+ /// \param description 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 completion 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 +194,8 @@
///
/// \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.
@@ -134,7 +203,7 @@
/// The number of completions and descriptions must be identical.
///
/// \param completions The list of completions.
- /// \param completions The list of descriptions.
+ /// \param descriptions The list of descriptions.
///
/// \see AddCompletion
void AddCompletions(const StringList &completions,
@@ -145,16 +214,8 @@
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 +225,10 @@
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/linux-x64/clang/include/lldb/Utility/Connection.h b/linux-x64/clang/include/lldb/Utility/Connection.h
index 77f3ef4..39e6e40 100644
--- a/linux-x64/clang/include/lldb/Utility/Connection.h
+++ b/linux-x64/clang/include/lldb/Utility/Connection.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Connection_h_
-#define liblldb_Connection_h_
+#ifndef LLDB_UTILITY_CONNECTION_H
+#define LLDB_UTILITY_CONNECTION_H
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
@@ -125,7 +125,7 @@
/// Subclasses must override this function.
///
/// \param[in] dst
- /// A desination buffer that must be at least \a dst_len bytes
+ /// A destination buffer that must be at least \a dst_len bytes
/// long.
///
/// \param[in] dst_len
@@ -171,13 +171,14 @@
///
/// \return
/// The underlying IOObject used for reading.
- virtual lldb::IOObjectSP GetReadObject() { return lldb::IOObjectSP(); }
+ virtual lldb::IOObjectSP GetReadObject() { return lldb::IOObjectSP(); };
private:
// For Connection only
- DISALLOW_COPY_AND_ASSIGN(Connection);
+ Connection(const Connection &) = delete;
+ const Connection &operator=(const Connection &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_Connection_h_
+#endif // LLDB_UTILITY_CONNECTION_H
diff --git a/linux-x64/clang/include/lldb/Utility/ConstString.h b/linux-x64/clang/include/lldb/Utility/ConstString.h
index 8576c18..8a67faf 100644
--- a/linux-x64/clang/include/lldb/Utility/ConstString.h
+++ b/linux-x64/clang/include/lldb/Utility/ConstString.h
@@ -6,11 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ConstString_h_
-#define liblldb_ConstString_h_
+#ifndef LLDB_UTILITY_CONSTSTRING_H
+#define LLDB_UTILITY_CONSTSTRING_H
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/YAMLTraits.h"
#include <stddef.h>
@@ -40,15 +42,7 @@
/// Default constructor
///
/// Initializes the string to an empty string.
- ConstString() : m_string(nullptr) {}
-
- /// Copy constructor
- ///
- /// Copies the string value in \a rhs into this object.
- ///
- /// \param[in] rhs
- /// Another string object to copy.
- ConstString(const ConstString &rhs) : m_string(rhs.m_string) {}
+ ConstString() = default;
explicit ConstString(const llvm::StringRef &s);
@@ -84,12 +78,6 @@
/// from \a cstr.
explicit ConstString(const char *cstr, size_t max_cstr_len);
- /// Destructor
- ///
- /// Since constant string values are currently not reference counted, there
- /// isn't much to do here.
- ~ConstString() = default;
-
/// C string equality binary predicate function object for ConstString
/// objects.
struct StringIsEqual {
@@ -122,20 +110,6 @@
/// false otherwise.
explicit operator bool() const { return !IsEmpty(); }
- /// Assignment operator
- ///
- /// Assigns the string in this object with the value from \a rhs.
- ///
- /// \param[in] rhs
- /// Another string object to copy into this object.
- ///
- /// \return
- /// A const reference to this object.
- ConstString operator=(ConstString rhs) {
- m_string = rhs.m_string;
- return *this;
- }
-
/// Equal to operator
///
/// Returns true if this string is equal to the string in \a rhs. This
@@ -146,8 +120,8 @@
/// Another string object to compare this object to.
///
/// \return
- /// \li \b true if this object is equal to \a rhs.
- /// \li \b false if this object is not equal to \a rhs.
+ /// true if this object is equal to \a rhs.
+ /// false if this object is not equal to \a rhs.
bool operator==(ConstString rhs) const {
// We can do a pointer compare to compare these strings since they must
// come from the same pool in order to be equal.
@@ -165,8 +139,8 @@
/// Another string object to compare this object to.
///
/// \return
- /// \li \b true if this object is equal to \a rhs.
- /// \li \b false if this object is not equal to \a rhs.
+ /// \b true if this object is equal to \a rhs.
+ /// \b false if this object is not equal to \a rhs.
bool operator==(const char *rhs) const {
// ConstString differentiates between empty strings and nullptr strings, but
// StringRef doesn't. Therefore we have to do this check manually now.
@@ -188,11 +162,9 @@
/// 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.
- bool operator!=(ConstString rhs) const {
- return m_string != rhs.m_string;
- }
+ /// \b true if this object is not equal to \a rhs.
+ /// \b false if this object is equal to \a rhs.
+ bool operator!=(ConstString rhs) const { return m_string != rhs.m_string; }
/// Not equal to operator against a non-ConstString value.
///
@@ -204,9 +176,7 @@
/// \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 +188,7 @@
///
/// 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 +238,7 @@
/// 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 +248,7 @@
/// 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 +272,7 @@
/// 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);
@@ -335,15 +299,15 @@
/// Test for empty string.
///
/// \return
- /// \li \b true if the contained string is empty.
- /// \li \b false if the contained string is not empty.
+ /// \b true if the contained string is empty.
+ /// \b false if the contained string is not empty.
bool IsEmpty() const { return m_string == nullptr || m_string[0] == '\0'; }
/// Test for null string.
///
/// \return
- /// \li \b true if there is no string associated with this instance.
- /// \li \b false if there is a string associated with this instance.
+ /// \b true if there is no string associated with this instance.
+ /// \b false if there is a string associated with this instance.
bool IsNull() const { return m_string == nullptr; }
/// Set the C string value.
@@ -445,8 +409,15 @@
static size_t StaticMemorySize();
protected:
- // Member variables
- const char *m_string;
+ 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;
+ };
+
+ const char *m_string = nullptr;
};
/// Stream the string value \a str to the stream \a s
@@ -459,6 +430,42 @@
static void format(const lldb_private::ConstString &CS, llvm::raw_ostream &OS,
llvm::StringRef Options);
};
-}
-#endif // liblldb_ConstString_h_
+/// 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;
+ }
+};
+/// \}
+
+namespace yaml {
+template <> struct ScalarTraits<lldb_private::ConstString> {
+ static void output(const lldb_private::ConstString &, void *, raw_ostream &);
+ static StringRef input(StringRef, void *, lldb_private::ConstString &);
+ static QuotingType mustQuote(StringRef S) { return QuotingType::Double; }
+};
+} // namespace yaml
+
+inline raw_ostream &operator<<(raw_ostream &os, lldb_private::ConstString s) {
+ os << s.GetStringRef();
+ return os;
+}
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ConstString)
+
+#endif // LLDB_UTILITY_CONSTSTRING_H
diff --git a/linux-x64/clang/include/lldb/Utility/DataBuffer.h b/linux-x64/clang/include/lldb/Utility/DataBuffer.h
index 5235693..302b133 100644
--- a/linux-x64/clang/include/lldb/Utility/DataBuffer.h
+++ b/linux-x64/clang/include/lldb/Utility/DataBuffer.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DataBuffer_h_
-#define liblldb_DataBuffer_h_
+#ifndef LLDB_UTILITY_DATABUFFER_H
+#define LLDB_UTILITY_DATABUFFER_H
#if defined(__cplusplus)
#include <stdint.h>
@@ -79,7 +79,21 @@
}
};
+class DataBufferUnowned : public DataBuffer {
+public:
+ DataBufferUnowned(uint8_t *bytes, lldb::offset_t size)
+ : m_bytes(bytes), m_size(size) {}
+
+ uint8_t *GetBytes() override { return m_bytes; }
+ const uint8_t *GetBytes() const override { return m_bytes; }
+ lldb::offset_t GetByteSize() const override { return m_size; }
+
+private:
+ uint8_t *m_bytes;
+ lldb::offset_t m_size;
+};
+
} // namespace lldb_private
#endif /// #if defined(__cplusplus)
-#endif /// lldb_DataBuffer_h_
+#endif // LLDB_UTILITY_DATABUFFER_H
diff --git a/linux-x64/clang/include/lldb/Utility/DataBufferHeap.h b/linux-x64/clang/include/lldb/Utility/DataBufferHeap.h
index 2a64694..ace526b 100644
--- a/linux-x64/clang/include/lldb/Utility/DataBufferHeap.h
+++ b/linux-x64/clang/include/lldb/Utility/DataBufferHeap.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DataBufferHeap_h_
-#define liblldb_DataBufferHeap_h_
+#ifndef LLDB_UTILITY_DATABUFFERHEAP_H
+#define LLDB_UTILITY_DATABUFFERHEAP_H
#include "lldb/Utility/DataBuffer.h"
#include "lldb/lldb-types.h"
@@ -109,4 +109,4 @@
} // namespace lldb_private
-#endif // liblldb_DataBufferHeap_h_
+#endif // LLDB_UTILITY_DATABUFFERHEAP_H
diff --git a/linux-x64/clang/include/lldb/Utility/DataBufferLLVM.h b/linux-x64/clang/include/lldb/Utility/DataBufferLLVM.h
index d4c1107..4dc800c 100644
--- a/linux-x64/clang/include/lldb/Utility/DataBufferLLVM.h
+++ b/linux-x64/clang/include/lldb/Utility/DataBufferLLVM.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_CORE_DATABUFFERLLVM_H
-#define LLDB_CORE_DATABUFFERLLVM_H
+#ifndef LLDB_UTILITY_DATABUFFERLLVM_H
+#define LLDB_UTILITY_DATABUFFERLLVM_H
#include "lldb/Utility/DataBuffer.h"
#include "lldb/lldb-types.h"
diff --git a/linux-x64/clang/include/lldb/Utility/DataEncoder.h b/linux-x64/clang/include/lldb/Utility/DataEncoder.h
index 19b7cef..8edec54 100644
--- a/linux-x64/clang/include/lldb/Utility/DataEncoder.h
+++ b/linux-x64/clang/include/lldb/Utility/DataEncoder.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_DataEncoder_h_
-#define liblldb_DataEncoder_h_
+#ifndef LLDB_UTILITY_DATAENCODER_H
+#define LLDB_UTILITY_DATAENCODER_H
#if defined(__cplusplus)
@@ -21,8 +21,9 @@
namespace lldb_private {
-/// \class DataEncoder DataEncoder.h "lldb/Core/DataEncoder.h" An binary data
-/// encoding class.
+/// \class DataEncoder
+///
+/// An binary data encoding class.
///
/// DataEncoder is a class that can encode binary data (swapping if needed) to
/// a data buffer. The data buffer can be caller owned, or can be shared data
@@ -86,74 +87,6 @@
/// any references to shared data that this object may contain.
void Clear();
- /// Get the current address size.
- ///
- /// Return the size in bytes of any address values this object will extract.
- ///
- /// \return
- /// The size in bytes of address values that will be extracted.
- uint8_t GetAddressByteSize() const { return m_addr_size; }
-
- /// Get the number of bytes contained in this object.
- ///
- /// \return
- /// The total number of bytes of data this object refers to.
- size_t GetByteSize() const { return m_end - m_start; }
-
- /// Get the data end pointer.
- ///
- /// \return
- /// Returns a pointer to the next byte contained in this
- /// object's data, or NULL of there is no data in this object.
- uint8_t *GetDataEnd() { return m_end; }
-
- const uint8_t *GetDataEnd() const { return m_end; }
-
- /// Get the shared data offset.
- ///
- /// Get the offset of the first byte of data in the shared data (if any).
- ///
- /// \return
- /// If this object contains shared data, this function returns
- /// the offset in bytes into that shared data, zero otherwise.
- size_t GetSharedDataOffset() const;
-
- /// Get the current byte order value.
- ///
- /// \return
- /// The current byte order value from this object's internal
- /// state.
- lldb::ByteOrder GetByteOrder() const { return m_byte_order; }
-
- /// Get the data start pointer.
- ///
- /// \return
- /// Returns a pointer to the first byte contained in this
- /// object's data, or NULL of there is no data in this object.
- uint8_t *GetDataStart() { return m_start; }
-
- const uint8_t *GetDataStart() const { return m_start; }
-
- /// Encode unsigned integer values into the data at \a offset.
- ///
- /// \param[in] offset
- /// The offset within the contained data at which to put the
- /// data.
- ///
- /// \param[in] value
- /// The value to encode into the data.
- ///
- /// \return
- /// The next offset in the bytes of this data if the data
- /// was successfully encoded, UINT32_MAX if the encoding failed.
- uint32_t PutU8(uint32_t offset, uint8_t value);
-
- uint32_t PutU16(uint32_t offset, uint16_t value);
-
- uint32_t PutU32(uint32_t offset, uint32_t value);
-
- uint32_t PutU64(uint32_t offset, uint64_t value);
-
/// Encode an unsigned integer of size \a byte_size to \a offset.
///
/// Encode a single integer value at \a offset and return the offset that
@@ -176,7 +109,7 @@
/// \return
/// The next offset in the bytes of this data if the integer
/// was successfully encoded, UINT32_MAX if the encoding failed.
- uint32_t PutMaxU64(uint32_t offset, uint32_t byte_size, uint64_t value);
+ uint32_t PutUnsigned(uint32_t offset, uint32_t byte_size, uint64_t value);
/// Encode an arbitrary number of bytes.
///
@@ -204,12 +137,11 @@
/// 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,50 +152,40 @@
///
/// 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; }
+private:
+ uint32_t PutU8(uint32_t offset, uint8_t value);
+ uint32_t PutU16(uint32_t offset, uint16_t value);
+ uint32_t PutU32(uint32_t offset, uint32_t value);
+ uint32_t PutU64(uint32_t offset, uint64_t value);
- /// Set the address byte size.
- ///
- /// Set the size in bytes that will be used when extracting any address and
- /// pointer values from data contained in this object.
- ///
- /// \param[in] addr_size
- /// The size in bytes to use when extracting addresses.
- void SetAddressByteSize(uint8_t addr_size) { m_addr_size = addr_size; }
+ uint32_t BytesLeft(uint32_t offset) const {
+ const uint32_t size = GetByteSize();
+ if (size > offset)
+ return size - offset;
+ return 0;
+ }
- /// Set data with a buffer that is caller owned.
- ///
- /// Use data that is owned by the caller when extracting values. The data
- /// must stay around as long as this object, or any object that copies a
- /// subset of this object's data, is valid. If \a bytes is NULL, or \a
- /// length is zero, this object will contain no data.
- ///
- /// \param[in] bytes
- /// A pointer to caller owned data.
- ///
- /// \param[in] length
- /// The length in bytes of \a bytes.
- ///
- /// \param[in] byte_order
- /// A byte order of the data that we are extracting from.
+ /// Test the availability of \a length bytes of data from \a offset.
///
/// \return
- /// The number of bytes that this object now contains.
- uint32_t SetData(void *bytes, uint32_t length, lldb::ByteOrder byte_order);
+ /// \b true if \a offset is a valid offset and there are \a
+ /// length bytes available at that offset, \b false otherwise.
+ bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
+ return length <= BytesLeft(offset);
+ }
/// Adopt a subset of shared data in \a data_sp.
///
@@ -290,15 +212,6 @@
uint32_t SetData(const lldb::DataBufferSP &data_sp, uint32_t offset = 0,
uint32_t length = UINT32_MAX);
- /// Set the byte_order value.
- ///
- /// Sets the byte order of the data to extract. Extracted values will be
- /// swapped if necessary when decoding.
- ///
- /// \param[in] byte_order
- /// The byte order value to use when extracting data.
- void SetByteOrder(lldb::ByteOrder byte_order) { m_byte_order = byte_order; }
-
/// Test the validity of \a offset.
///
/// \return
@@ -306,38 +219,34 @@
/// object, \b false otherwise.
bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
- /// Test the availability of \a length bytes of data from \a offset.
+ /// Get the number of bytes contained in this object.
///
/// \return
- /// \b true if \a offset is a valid offset and there are \a
- /// length bytes available at that offset, \b false otherwise.
- bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
- return length <= BytesLeft(offset);
- }
+ /// The total number of bytes of data this object refers to.
+ size_t GetByteSize() const { return m_end - m_start; }
- uint32_t BytesLeft(uint32_t offset) const {
- const uint32_t size = GetByteSize();
- if (size > offset)
- return size - offset;
- return 0;
- }
+ /// A pointer to the first byte of data.
+ uint8_t *m_start;
-protected:
- // Member variables
- uint8_t *m_start; ///< A pointer to the first byte of data.
- uint8_t *m_end; ///< A pointer to the byte that is past the end of the data.
- lldb::ByteOrder
- m_byte_order; ///< The byte order of the data we are extracting from.
- uint8_t m_addr_size; ///< The address size to use when extracting pointers or
- /// addresses
- mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can
- /// be shared among multiple instances
+ /// A pointer to the byte that is past the end of the data.
+ uint8_t *m_end;
-private:
- DISALLOW_COPY_AND_ASSIGN(DataEncoder);
+ /// The byte order of the data we are extracting from.
+ lldb::ByteOrder m_byte_order;
+
+ /// The address size to use when extracting pointers or
+ /// addresses
+ uint8_t m_addr_size;
+
+ /// The shared pointer to data that can
+ /// be shared among multiple instances
+ mutable lldb::DataBufferSP m_data_sp;
+
+ DataEncoder(const DataEncoder &) = delete;
+ const DataEncoder &operator=(const DataEncoder &) = delete;
};
} // namespace lldb_private
#endif // #if defined (__cplusplus)
-#endif // #ifndef liblldb_DataEncoder_h_
+#endif // LLDB_UTILITY_DATAENCODER_H
diff --git a/linux-x64/clang/include/lldb/Utility/DataExtractor.h b/linux-x64/clang/include/lldb/Utility/DataExtractor.h
index 74174b3..0210af5 100644
--- a/linux-x64/clang/include/lldb/Utility/DataExtractor.h
+++ b/linux-x64/clang/include/lldb/Utility/DataExtractor.h
@@ -9,11 +9,14 @@
#ifndef LLDB_UTILITY_DATAEXTRACTOR_H
#define LLDB_UTILITY_DATAEXTRACTOR_H
+#include "lldb/Utility/Endian.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/SwapByteOrder.h"
#include <cassert>
#include <stdint.h>
@@ -167,9 +170,8 @@
/// 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.
@@ -188,16 +190,11 @@
/// The type of objects to use when dumping data from this
/// object. See DataExtractor::Type.
///
- /// \param[in] type_format
- /// The optional format to use for the \a type objects. If this
- /// is nullptr, the default format for the \a type will be used.
- ///
/// \return
/// The offset at which dumping ended.
lldb::offset_t PutToLog(Log *log, lldb::offset_t offset,
lldb::offset_t length, uint64_t base_addr,
- uint32_t num_per_line, Type type,
- const char *type_format = nullptr) const;
+ uint32_t num_per_line, Type type) const;
/// Extract an arbitrary number of bytes in the specified byte order.
///
@@ -362,30 +359,29 @@
/// 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 +516,7 @@
/// 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
@@ -541,13 +537,13 @@
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset) const;
- /// Extract an signed integer of size \a byte_size from \a *offset_ptr, then
- /// extract and signe extend the bitfield from this value if \a
+ /// Extract an signed integer of size \a size from \a *offset_ptr, then
+ /// extract and sign-extend the bitfield from this value if \a
/// bitfield_bit_size is non-zero.
///
- /// Extract a single signed integer value (sign extending if required) and
+ /// Extract a single signed integer value (sign-extending if required) and
/// update the offset pointed to by \a offset_ptr. The size of the extracted
- /// integer is specified by the \a byte_size argument. \a byte_size must
+ /// integer is specified by the \a size argument. \a size must
/// have a value greater than or equal to one and less than or equal to
/// eight since the return value is 64 bits wide.
///
@@ -558,7 +554,7 @@
/// 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
@@ -579,24 +575,6 @@
uint32_t bitfield_bit_size,
uint32_t bitfield_bit_offset) const;
- /// Extract an pointer from \a *offset_ptr.
- ///
- /// Extract a single pointer from the data and update the offset pointed to
- /// by \a offset_ptr. The size of the extracted pointer comes from the \a
- /// m_addr_size member variable and should be set correctly prior to
- /// extracting any pointer 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.
- ///
- /// \return
- /// The extracted pointer value as a 64 integer.
- uint64_t GetPointer(lldb::offset_t *offset_ptr) const;
-
/// Get the current byte order value.
///
/// \return
@@ -956,14 +934,14 @@
/// 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 +949,8 @@
/// 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,20 +975,39 @@
return {GetDataStart(), size_t(GetByteSize())};
}
+ llvm::DataExtractor GetAsLLVM() const {
+ return {GetData(), GetByteOrder() == lldb::eByteOrderLittle,
+ uint8_t(GetAddressByteSize())};
+ }
+
protected:
+ template <typename T> T Get(lldb::offset_t *offset_ptr, T fail_value) const {
+ constexpr size_t src_size = sizeof(T);
+ T val = fail_value;
+
+ const T *src = static_cast<const T *>(GetData(offset_ptr, src_size));
+ if (!src)
+ return val;
+
+ memcpy(&val, src, src_size);
+ if (m_byte_order != endian::InlHostByteOrder())
+ llvm::sys::swapByteOrder(val);
+
+ return val;
+ }
+
// Member variables
const uint8_t *m_start; ///< A pointer to the first byte of data.
const uint8_t
*m_end; ///< A pointer to the byte that is past the end of the data.
lldb::ByteOrder
m_byte_order; ///< The byte order of the data we are extracting from.
- uint32_t m_addr_size; ///< The address size to use when extracting pointers or
- /// addresses
- mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can
- /// be shared among multiple instances
+ uint32_t m_addr_size; ///< The address size to use when extracting addresses.
+ /// The shared pointer to data that can be shared among multiple instances
+ lldb::DataBufferSP m_data_sp;
const uint32_t m_target_byte_size;
};
} // namespace lldb_private
-#endif // liblldb_DataExtractor_h_
+#endif // LLDB_UTILITY_DATAEXTRACTOR_H
diff --git a/linux-x64/clang/include/lldb/Utility/Endian.h b/linux-x64/clang/include/lldb/Utility/Endian.h
index cead5f8..1d1f8fa 100644
--- a/linux-x64/clang/include/lldb/Utility/Endian.h
+++ b/linux-x64/clang/include/lldb/Utility/Endian.h
@@ -30,4 +30,4 @@
}
}
-#endif // liblldb_host_endian_h_
+#endif // LLDB_UTILITY_ENDIAN_H
diff --git a/linux-x64/clang/include/lldb/Utility/Environment.h b/linux-x64/clang/include/lldb/Utility/Environment.h
index 398b3ba..e2af2eb 100644
--- a/linux-x64/clang/include/lldb/Utility/Environment.h
+++ b/linux-x64/clang/include/lldb/Utility/Environment.h
@@ -50,6 +50,7 @@
using Base::erase;
using Base::find;
using Base::insert;
+ using Base::insert_or_assign;
using Base::lookup;
using Base::size;
using Base::try_emplace;
@@ -68,7 +69,8 @@
}
std::pair<iterator, bool> insert(llvm::StringRef KeyEqValue) {
- return insert(KeyEqValue.split('='));
+ auto Split = KeyEqValue.split('=');
+ return insert(std::make_pair(Split.first, std::string(Split.second)));
}
void insert(const_iterator first, const_iterator last);
@@ -92,4 +94,4 @@
};
} // namespace llvm
-#endif // #ifndef LLDB_UTILITY_ENVIRONMENT_H
+#endif // LLDB_UTILITY_ENVIRONMENT_H
diff --git a/linux-x64/clang/include/lldb/Utility/Event.h b/linux-x64/clang/include/lldb/Utility/Event.h
index dd5d080..06c0262 100644
--- a/linux-x64/clang/include/lldb/Utility/Event.h
+++ b/linux-x64/clang/include/lldb/Utility/Event.h
@@ -48,7 +48,8 @@
private:
virtual void DoOnRemoval(Event *event_ptr) {}
- DISALLOW_COPY_AND_ASSIGN(EventData);
+ EventData(const EventData &) = delete;
+ const EventData &operator=(const EventData &) = delete;
};
// lldb::EventDataBytes
@@ -92,7 +93,8 @@
private:
std::string m_bytes;
- DISALLOW_COPY_AND_ASSIGN(EventDataBytes);
+ EventDataBytes(const EventDataBytes &) = delete;
+ const EventDataBytes &operator=(const EventDataBytes &) = delete;
};
class EventDataReceipt : public EventData {
@@ -169,7 +171,9 @@
StructuredData::ObjectSP m_object_sp;
lldb::StructuredDataPluginSP m_plugin_sp;
- DISALLOW_COPY_AND_ASSIGN(EventDataStructuredData);
+ EventDataStructuredData(const EventDataStructuredData &) = delete;
+ const EventDataStructuredData &
+ operator=(const EventDataStructuredData &) = delete;
};
// lldb::Event
@@ -242,7 +246,8 @@
uint32_t m_type; // The bit describing this event
lldb::EventDataSP m_data_sp; // User specific data for this event
- DISALLOW_COPY_AND_ASSIGN(Event);
+ Event(const Event &) = delete;
+ const Event &operator=(const Event &) = delete;
Event() = delete;
};
diff --git a/linux-x64/clang/include/lldb/Utility/FileCollector.h b/linux-x64/clang/include/lldb/Utility/FileCollector.h
deleted file mode 100644
index a892067..0000000
--- a/linux-x64/clang/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/linux-x64/clang/include/lldb/Utility/FileSpec.h b/linux-x64/clang/include/lldb/Utility/FileSpec.h
index f0bc5c8..f7cbeb2 100644
--- a/linux-x64/clang/include/lldb/Utility/FileSpec.h
+++ b/linux-x64/clang/include/lldb/Utility/FileSpec.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_FileSpec_h_
-#define liblldb_FileSpec_h_
+#ifndef LLDB_UTILITY_FILESPEC_H
+#define LLDB_UTILITY_FILESPEC_H
#include <functional>
#include <string>
@@ -18,6 +18,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLTraits.h"
#include <stddef.h>
#include <stdint.h>
@@ -73,35 +74,12 @@
/// \see FileSpec::SetFile (const char *path)
explicit FileSpec(llvm::StringRef path, Style style = Style::native);
- explicit FileSpec(llvm::StringRef path, const llvm::Triple &Triple);
-
- /// Copy constructor
- ///
- /// Makes a copy of the uniqued directory and filename strings from \a rhs
- /// if it is not nullptr.
- ///
- /// \param[in] rhs
- /// A const FileSpec object pointer to copy if non-nullptr.
- FileSpec(const FileSpec *rhs);
-
- /// Destructor.
- ~FileSpec();
+ explicit FileSpec(llvm::StringRef path, const llvm::Triple &triple);
bool DirectoryEquals(const FileSpec &other) const;
bool FileEquals(const FileSpec &other) const;
- /// Assignment operator.
- ///
- /// Makes a copy of the uniqued directory and filename strings from \a rhs.
- ///
- /// \param[in] rhs
- /// A const FileSpec object reference to assign to this object.
- ///
- /// \return
- /// A const reference to this object.
- const FileSpec &operator=(const FileSpec &rhs);
-
/// Equal to operator
///
/// Tests if this object is equal to \a rhs.
@@ -200,14 +178,18 @@
/// 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);
+ /// Match FileSpec \a pattern against FileSpec \a file. If \a pattern has a
+ /// directory component, then the \a file must have the same directory
+ /// component. Otherwise, just it matches just the filename. An empty \a
+ /// pattern matches everything.
+ static bool Match(const FileSpec &pattern, const FileSpec &file);
+
/// Attempt to guess path style for a given path string. It returns a style,
/// if it was able to make a reasonable guess, or None if it wasn't. The guess
/// will be correct if the input path was a valid absolute path on the system
@@ -230,7 +212,7 @@
///
/// \param[in] s
/// The stream to which to dump the object description.
- void Dump(Stream *s) const;
+ void Dump(llvm::raw_ostream &s) const;
Style GetPathStyle() const;
@@ -322,10 +304,6 @@
/// 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 +314,7 @@
/// 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 +323,7 @@
/// 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 +347,22 @@
/// \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; }
@@ -413,6 +398,8 @@
ConstString GetLastPathComponent() const;
protected:
+ friend struct llvm::yaml::MappingTraits<FileSpec>;
+
// Convenience method for setting the file without changing the style.
void SetFile(llvm::StringRef path);
@@ -426,6 +413,8 @@
/// Dump a FileSpec object to a stream
Stream &operator<<(Stream &s, const FileSpec &f);
+/// Prevent ODR violations with traits for llvm::sys::path::Style.
+LLVM_YAML_STRONG_TYPEDEF(FileSpec::Style, FileSpecStyle)
} // namespace lldb_private
namespace llvm {
@@ -452,6 +441,16 @@
static void format(const lldb_private::FileSpec &F, llvm::raw_ostream &Stream,
StringRef Style);
};
+
+namespace yaml {
+template <> struct ScalarEnumerationTraits<lldb_private::FileSpecStyle> {
+ static void enumeration(IO &io, lldb_private::FileSpecStyle &style);
+};
+
+template <> struct MappingTraits<lldb_private::FileSpec> {
+ static void mapping(IO &io, lldb_private::FileSpec &f);
+};
+} // namespace yaml
} // namespace llvm
-#endif // liblldb_FileSpec_h_
+#endif // LLDB_UTILITY_FILESPEC_H
diff --git a/linux-x64/clang/include/lldb/Utility/Flags.h b/linux-x64/clang/include/lldb/Utility/Flags.h
index 48b14e7..19f7506 100644
--- a/linux-x64/clang/include/lldb/Utility/Flags.h
+++ b/linux-x64/clang/include/lldb/Utility/Flags.h
@@ -29,21 +29,10 @@
/// Constructs this object with \a mask as the initial value for all of the
/// flags.
///
- /// \param[in] mask
+ /// \param[in] flags
/// The initial value for all flags.
Flags(ValueType flags = 0) : m_flags(flags) {}
- /// Copy constructor.
- ///
- /// Construct and copy the flags from \a rhs.
- ///
- /// \param[in] rhs
- /// A const Flags object reference to copy.
- Flags(const Flags &rhs) : m_flags(rhs.m_flags) {}
-
- /// Destructor.
- ~Flags() {}
-
/// Get accessor for all flags.
///
/// \return
@@ -121,36 +110,10 @@
/// \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.
};
} // namespace lldb_private
-#endif // liblldb_Flags_h_
+#endif // LLDB_UTILITY_FLAGS_H
diff --git a/linux-x64/clang/include/lldb/Utility/GDBRemote.h b/linux-x64/clang/include/lldb/Utility/GDBRemote.h
new file mode 100644
index 0000000..2ee706e
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Utility/GDBRemote.h
@@ -0,0 +1,158 @@
+//===-- 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 LLDB_UTILITY_GDBREMOTE_H
+#define LLDB_UTILITY_GDBREMOTE_H
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/ReproducerProvider.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 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 repro {
+class PacketRecorder : public AbstractRecorder {
+public:
+ PacketRecorder(const FileSpec &filename, std::error_code &ec)
+ : AbstractRecorder(filename, ec) {}
+
+ static llvm::Expected<std::unique_ptr<PacketRecorder>>
+ Create(const FileSpec &filename);
+
+ void Record(const GDBRemotePacket &packet);
+};
+
+class GDBRemoteProvider : public repro::Provider<GDBRemoteProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ GDBRemoteProvider(const FileSpec &directory) : Provider(directory) {}
+
+ llvm::raw_ostream *GetHistoryStream();
+ PacketRecorder *GetNewPacketRecorder();
+
+ void SetCallback(std::function<void()> callback) {
+ m_callback = std::move(callback);
+ }
+
+ void Keep() override;
+ void Discard() override;
+
+ static char ID;
+
+private:
+ std::function<void()> m_callback;
+ std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
+ std::vector<std::unique_ptr<PacketRecorder>> m_packet_recorders;
+};
+
+} // namespace repro
+} // 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 // LLDB_UTILITY_GDBREMOTE_H
diff --git a/linux-x64/clang/include/lldb/Utility/IOObject.h b/linux-x64/clang/include/lldb/Utility/IOObject.h
index 1640200..9b2b9cf 100644
--- a/linux-x64/clang/include/lldb/Utility/IOObject.h
+++ b/linux-x64/clang/include/lldb/Utility/IOObject.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Host_Common_IOObject_h_
-#define liblldb_Host_Common_IOObject_h_
+#ifndef LLDB_UTILITY_IOOBJECT_H
+#define LLDB_UTILITY_IOOBJECT_H
#include <stdarg.h>
#include <stdio.h>
@@ -29,8 +29,7 @@
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,11 +43,10 @@
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);
+ IOObject(const IOObject &) = delete;
+ const IOObject &operator=(const IOObject &) = delete;
};
} // namespace lldb_private
diff --git a/linux-x64/clang/include/lldb/Utility/Iterable.h b/linux-x64/clang/include/lldb/Utility/Iterable.h
index d9c61aa..5c38e46 100644
--- a/linux-x64/clang/include/lldb/Utility/Iterable.h
+++ b/linux-x64/clang/include/lldb/Utility/Iterable.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Iterable_h_
-#define liblldb_Iterable_h_
+#ifndef LLDB_UTILITY_ITERABLE_H
+#define LLDB_UTILITY_ITERABLE_H
#include <utility>
@@ -170,7 +170,7 @@
typename MutexType>
class LockingAdaptedIterable : public AdaptedIterable<C, E, A> {
public:
- LockingAdaptedIterable(C &container, MutexType &mutex)
+ LockingAdaptedIterable(const C &container, MutexType &mutex)
: AdaptedIterable<C, E, A>(container), m_mutex(&mutex) {
m_mutex->lock();
}
@@ -194,4 +194,4 @@
} // namespace lldb_private
-#endif // liblldb_Iterable_h_
+#endif // LLDB_UTILITY_ITERABLE_H
diff --git a/linux-x64/clang/include/lldb/Utility/JSON.h b/linux-x64/clang/include/lldb/Utility/JSON.h
deleted file mode 100644
index 172f77a..0000000
--- a/linux-x64/clang/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/linux-x64/clang/include/lldb/Utility/LLDBAssert.h b/linux-x64/clang/include/lldb/Utility/LLDBAssert.h
index 7008dd8..845af1d 100644
--- a/linux-x64/clang/include/lldb/Utility/LLDBAssert.h
+++ b/linux-x64/clang/include/lldb/Utility/LLDBAssert.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef utility_LLDBAssert_h_
-#define utility_LLDBAssert_h_
+#ifndef LLDB_UTILITY_LLDBASSERT_H
+#define LLDB_UTILITY_LLDBASSERT_H
#ifdef LLDB_CONFIGURATION_DEBUG
#define lldbassert(x) assert(x)
@@ -22,4 +22,4 @@
const char *file, unsigned int line);
}
-#endif // utility_LLDBAssert_h_
+#endif // LLDB_UTILITY_LLDBASSERT_H
diff --git a/linux-x64/clang/include/lldb/Utility/Listener.h b/linux-x64/clang/include/lldb/Utility/Listener.h
index 17fc478..9d96e36 100644
--- a/linux-x64/clang/include/lldb/Utility/Listener.h
+++ b/linux-x64/clang/include/lldb/Utility/Listener.h
@@ -145,7 +145,8 @@
// bool exact);
// For Listener only
- DISALLOW_COPY_AND_ASSIGN(Listener);
+ Listener(const Listener &) = delete;
+ const Listener &operator=(const Listener &) = delete;
};
} // namespace lldb_private
diff --git a/linux-x64/clang/include/lldb/Utility/Log.h b/linux-x64/clang/include/lldb/Utility/Log.h
index 949de69..01edec0 100644
--- a/linux-x64/clang/include/lldb/Utility/Log.h
+++ b/linux-x64/clang/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 @@
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 @@
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)));
@@ -160,6 +166,9 @@
bool GetVerbose() const;
+ void VAPrintf(const char *format, va_list args);
+ void VAError(const char *format, va_list args);
+
private:
Channel &m_channel;
@@ -193,6 +202,10 @@
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 @@
} // 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 @@
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/linux-x64/clang/include/lldb/Utility/Logging.h b/linux-x64/clang/include/lldb/Utility/Logging.h
index 41086fe..1a8a102 100644
--- a/linux-x64/clang/include/lldb/Utility/Logging.h
+++ b/linux-x64/clang/include/lldb/Utility/Logging.h
@@ -54,8 +54,6 @@
class Log;
-void LogIfAnyCategoriesSet(uint32_t mask, const char *format, ...);
-
Log *GetLogIfAllCategoriesSet(uint32_t mask);
Log *GetLogIfAnyCategoriesSet(uint32_t mask);
diff --git a/linux-x64/clang/include/lldb/Utility/OptionDefinition.h b/linux-x64/clang/include/lldb/Utility/OptionDefinition.h
new file mode 100644
index 0000000..725e090
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Utility/OptionDefinition.h
@@ -0,0 +1,55 @@
+//===-- OptionDefinition.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_OPTIONDEFINITION_H
+#define LLDB_UTILITY_OPTIONDEFINITION_H
+
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private-types.h"
+#include "llvm/ADT/StringExtras.h"
+#include <cstdint>
+
+namespace lldb_private {
+struct OptionDefinition {
+ /// Used to mark options that can be used together. If
+ /// `(1 << n & usage_mask) != 0` then this option belongs to option set n.
+ uint32_t usage_mask;
+ /// This option is required (in the current usage level).
+ bool required;
+ /// Full name for this option.
+ const char *long_option;
+ /// Single character for this option. If the option doesn't use a short
+ /// option character, this has to be a integer value that is not a printable
+ /// ASCII code point and also unique in the used set of options.
+ /// @see OptionDefinition::HasShortOption
+ int short_option;
+ /// no_argument, required_argument or optional_argument
+ int option_has_arg;
+ /// If non-NULL, option is valid iff |validator->IsValid()|, otherwise
+ /// always valid.
+ OptionValidator *validator;
+ /// If not empty, an array of enum values.
+ OptionEnumValues enum_values;
+ /// The kind of completion for this option.
+ /// Contains values of the CommandCompletions::CommonCompletionTypes enum.
+ uint32_t completion_type;
+ /// Type of argument this option takes.
+ lldb::CommandArgumentType argument_type;
+ /// Full text explaining what this options does and what (if any) argument to
+ /// pass it.
+ const char *usage_text;
+
+ /// Whether this has a short option character.
+ bool HasShortOption() const {
+ // See the short_option documentation for more.
+ return llvm::isPrint(short_option);
+ }
+};
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_OPTIONDEFINITION_H
diff --git a/linux-x64/clang/include/lldb/Utility/Predicate.h b/linux-x64/clang/include/lldb/Utility/Predicate.h
index f1539b5..a17ac05 100644
--- a/linux-x64/clang/include/lldb/Utility/Predicate.h
+++ b/linux-x64/clang/include/lldb/Utility/Predicate.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Predicate_h_
-#define liblldb_Predicate_h_
+#ifndef LLDB_UTILITY_PREDICATE_H
+#define LLDB_UTILITY_PREDICATE_H
#include <stdint.h>
#include <time.h>
@@ -117,8 +117,7 @@
/// 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 @@
/// 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 @@
/// 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) {
@@ -223,9 +221,10 @@
m_condition.notify_all();
}
- DISALLOW_COPY_AND_ASSIGN(Predicate);
+ Predicate(const Predicate &) = delete;
+ const Predicate &operator=(const Predicate &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_Predicate_h_
+#endif // LLDB_UTILITY_PREDICATE_H
diff --git a/linux-x64/clang/include/lldb/Utility/ProcessInfo.h b/linux-x64/clang/include/lldb/Utility/ProcessInfo.h
index a25c06c..8f5a5f6 100644
--- a/linux-x64/clang/include/lldb/Utility/ProcessInfo.h
+++ b/linux-x64/clang/include/lldb/Utility/ProcessInfo.h
@@ -9,13 +9,12 @@
#ifndef LLDB_UTILITY_PROCESSINFO_H
#define LLDB_UTILITY_PROCESSINFO_H
-// LLDB headers
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Environment.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/NameMatches.h"
-
+#include "llvm/Support/YAMLTraits.h"
#include <vector>
namespace lldb_private {
@@ -38,7 +37,7 @@
const char *GetName() const;
- size_t GetNameLength() const;
+ llvm::StringRef GetNameAsStringRef() const;
FileSpec &GetExecutableFile() { return m_executable; }
@@ -89,6 +88,7 @@
const Environment &GetEnvironment() const { return m_environment; }
protected:
+ template <class T> friend struct llvm::yaml::MappingTraits;
FileSpec m_executable;
std::string m_arg0; // argv[0] if supported. If empty, then use m_executable.
// Not all process plug-ins support specifying an argv[0] that differs from
@@ -150,50 +150,13 @@
bool verbose) const;
protected:
+ friend struct llvm::yaml::MappingTraits<ProcessInstanceInfo>;
uint32_t m_euid;
uint32_t m_egid;
lldb::pid_t m_parent_pid;
};
-class ProcessInstanceInfoList {
-public:
- ProcessInstanceInfoList() = default;
-
- void Clear() { m_infos.clear(); }
-
- size_t GetSize() { return m_infos.size(); }
-
- 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);
- }
-
- lldb::pid_t GetProcessIDAtIndex(size_t idx) {
- return ((idx < m_infos.size()) ? m_infos[idx].GetProcessID() : 0);
- }
-
- bool GetInfoAtIndex(size_t idx, ProcessInstanceInfo &info) {
- if (idx < m_infos.size()) {
- info = m_infos[idx];
- return true;
- }
- return false;
- }
-
- // You must ensure "idx" is valid before calling this function
- const ProcessInstanceInfo &GetProcessInfoAtIndex(size_t idx) const {
- assert(idx < m_infos.size());
- return m_infos[idx];
- }
-
-protected:
- std::vector<ProcessInstanceInfo> m_infos;
-};
+typedef std::vector<ProcessInstanceInfo> ProcessInstanceInfoList;
// ProcessInstanceInfoMatch
//
@@ -227,8 +190,20 @@
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;
@@ -240,6 +215,19 @@
bool m_match_all_users;
};
+namespace repro {
+llvm::Optional<ProcessInstanceInfoList> GetReplayProcessInstanceInfoList();
+} // namespace repro
} // namespace lldb_private
-#endif // #ifndef LLDB_UTILITY_PROCESSINFO_H
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ProcessInstanceInfo)
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<lldb_private::ProcessInstanceInfo> {
+ static void mapping(IO &io, lldb_private::ProcessInstanceInfo &PII);
+};
+} // namespace yaml
+} // namespace llvm
+
+#endif // LLDB_UTILITY_PROCESSINFO_H
diff --git a/linux-x64/clang/include/lldb/Utility/RangeMap.h b/linux-x64/clang/include/lldb/Utility/RangeMap.h
index 36401f5..118fdfd 100644
--- a/linux-x64/clang/include/lldb/Utility/RangeMap.h
+++ b/linux-x64/clang/include/lldb/Utility/RangeMap.h
@@ -122,220 +122,13 @@
}
};
-// A range array class where you get to define the type of the ranges
-// that the collection contains.
-
-template <typename B, typename S, unsigned N> class RangeArray {
+template <typename B, typename S, unsigned N = 0> class RangeVector {
public:
typedef B BaseType;
typedef S SizeType;
typedef Range<B, S> Entry;
typedef llvm::SmallVector<Entry, N> Collection;
- RangeArray() = default;
-
- ~RangeArray() = default;
-
- void Append(const Entry &entry) { m_entries.push_back(entry); }
-
- void Append(B base, S size) { m_entries.emplace_back(base, size); }
-
- bool RemoveEntrtAtIndex(uint32_t idx) {
- if (idx < m_entries.size()) {
- m_entries.erase(m_entries.begin() + idx);
- return true;
- }
- return false;
- }
-
- void Sort() {
- if (m_entries.size() > 1)
- std::stable_sort(m_entries.begin(), m_entries.end());
- }
-
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- bool IsSorted() const {
- typename Collection::const_iterator pos, end, prev;
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end;
- prev = pos++) {
- if (prev != end && *pos < *prev)
- return false;
- }
- return true;
- }
-#endif
-
- void CombineConsecutiveRanges() {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert(IsSorted());
-#endif
- // Can't combine if ranges if we have zero or one range
- if (m_entries.size() > 1) {
- // The list should be sorted prior to calling this function
- typename Collection::iterator pos;
- typename Collection::iterator end;
- typename Collection::iterator prev;
- bool can_combine = false;
- // First we determine if we can combine any of the Entry objects so we
- // don't end up allocating and making a new collection for no reason
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
- pos != end; prev = pos++) {
- if (prev != end && prev->DoesAdjoinOrIntersect(*pos)) {
- can_combine = true;
- break;
- }
- }
-
- // We we can combine at least one entry, then we make a new collection
- // and populate it accordingly, and then swap it into place.
- if (can_combine) {
- Collection minimal_ranges;
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
- pos != end; prev = pos++) {
- if (prev != end && prev->DoesAdjoinOrIntersect(*pos))
- minimal_ranges.back().SetRangeEnd(
- std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
- else
- minimal_ranges.push_back(*pos);
- }
- // Use the swap technique in case our new vector is much smaller. We
- // must swap when using the STL because std::vector objects never
- // release or reduce the memory once it has been allocated/reserved.
- m_entries.swap(minimal_ranges);
- }
- }
- }
-
- BaseType GetMinRangeBase(BaseType fail_value) const {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert(IsSorted());
-#endif
- if (m_entries.empty())
- return fail_value;
- // m_entries must be sorted, so if we aren't empty, we grab the first
- // range's base
- return m_entries.front().GetRangeBase();
- }
-
- BaseType GetMaxRangeEnd(BaseType fail_value) const {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert(IsSorted());
-#endif
- if (m_entries.empty())
- return fail_value;
- // m_entries must be sorted, so if we aren't empty, we grab the last
- // range's end
- return m_entries.back().GetRangeEnd();
- }
-
- void Slide(BaseType slide) {
- typename Collection::iterator pos, end;
- for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
- pos->Slide(slide);
- }
-
- void Clear() { m_entries.clear(); }
-
- bool IsEmpty() const { return m_entries.empty(); }
-
- size_t GetSize() const { return m_entries.size(); }
-
- const Entry *GetEntryAtIndex(size_t i) const {
- return ((i < m_entries.size()) ? &m_entries[i] : nullptr);
- }
-
- // Clients must ensure that "i" is a valid index prior to calling this
- // function
- const Entry &GetEntryRef(size_t i) const { return m_entries[i]; }
-
- Entry *Back() { return (m_entries.empty() ? nullptr : &m_entries.back()); }
-
- const Entry *Back() const {
- return (m_entries.empty() ? nullptr : &m_entries.back());
- }
-
- static bool BaseLessThan(const Entry &lhs, const Entry &rhs) {
- return lhs.GetRangeBase() < rhs.GetRangeBase();
- }
-
- uint32_t FindEntryIndexThatContains(B addr) const {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert(IsSorted());
-#endif
- if (!m_entries.empty()) {
- Entry entry(addr, 1);
- typename Collection::const_iterator begin = m_entries.begin();
- typename Collection::const_iterator end = m_entries.end();
- typename Collection::const_iterator pos =
- std::lower_bound(begin, end, entry, BaseLessThan);
-
- if (pos != end && pos->Contains(addr)) {
- return std::distance(begin, pos);
- } else if (pos != begin) {
- --pos;
- if (pos->Contains(addr))
- return std::distance(begin, pos);
- }
- }
- return UINT32_MAX;
- }
-
- const Entry *FindEntryThatContains(B addr) const {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert(IsSorted());
-#endif
- if (!m_entries.empty()) {
- Entry entry(addr, 1);
- typename Collection::const_iterator begin = m_entries.begin();
- typename Collection::const_iterator end = m_entries.end();
- typename Collection::const_iterator pos =
- std::lower_bound(begin, end, entry, BaseLessThan);
-
- if (pos != end && pos->Contains(addr)) {
- return &(*pos);
- } else if (pos != begin) {
- --pos;
- if (pos->Contains(addr)) {
- return &(*pos);
- }
- }
- }
- return nullptr;
- }
-
- const Entry *FindEntryThatContains(const Entry &range) const {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert(IsSorted());
-#endif
- if (!m_entries.empty()) {
- typename Collection::const_iterator begin = m_entries.begin();
- typename Collection::const_iterator end = m_entries.end();
- typename Collection::const_iterator pos =
- std::lower_bound(begin, end, range, BaseLessThan);
-
- if (pos != end && pos->Contains(range)) {
- return &(*pos);
- } else if (pos != begin) {
- --pos;
- if (pos->Contains(range)) {
- return &(*pos);
- }
- }
- }
- return nullptr;
- }
-
-protected:
- Collection m_entries;
-};
-
-template <typename B, typename S> class RangeVector {
-public:
- typedef B BaseType;
- typedef S SizeType;
- typedef Range<B, S> Entry;
- typedef std::vector<Entry> Collection;
-
RangeVector() = default;
~RangeVector() = default;
@@ -401,41 +194,25 @@
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert(IsSorted());
#endif
- // Can't combine if ranges if we have zero or one range
- if (m_entries.size() > 1) {
- // The list should be sorted prior to calling this function
- typename Collection::iterator pos;
- typename Collection::iterator end;
- typename Collection::iterator prev;
- bool can_combine = false;
- // First we determine if we can combine any of the Entry objects so we
- // don't end up allocating and making a new collection for no reason
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
- pos != end; prev = pos++) {
- if (prev != end && prev->DoesAdjoinOrIntersect(*pos)) {
- can_combine = true;
- break;
- }
- }
+ auto first_intersect = std::adjacent_find(
+ m_entries.begin(), m_entries.end(), [](const Entry &a, const Entry &b) {
+ return a.DoesAdjoinOrIntersect(b);
+ });
+ if (first_intersect == m_entries.end())
+ return;
- // We we can combine at least one entry, then we make a new collection
- // and populate it accordingly, and then swap it into place.
- if (can_combine) {
- Collection minimal_ranges;
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
- pos != end; prev = pos++) {
- if (prev != end && prev->DoesAdjoinOrIntersect(*pos))
- minimal_ranges.back().SetRangeEnd(
- std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
- else
- minimal_ranges.push_back(*pos);
- }
- // Use the swap technique in case our new vector is much smaller. We
- // must swap when using the STL because std::vector objects never
- // release or reduce the memory once it has been allocated/reserved.
- m_entries.swap(minimal_ranges);
- }
+ // We we can combine at least one entry, then we make a new collection and
+ // populate it accordingly, and then swap it into place.
+ auto pos = std::next(first_intersect);
+ Collection minimal_ranges(m_entries.begin(), pos);
+ for (; pos != m_entries.end(); ++pos) {
+ Entry &back = minimal_ranges.back();
+ if (back.DoesAdjoinOrIntersect(*pos))
+ back.SetRangeEnd(std::max(back.GetRangeEnd(), pos->GetRangeEnd()));
+ else
+ minimal_ranges.push_back(*pos);
}
+ m_entries.swap(minimal_ranges);
}
BaseType GetMinRangeBase(BaseType fail_value) const {
@@ -560,6 +337,10 @@
return nullptr;
}
+ using const_iterator = typename Collection::const_iterator;
+ const_iterator begin() const { return m_entries.begin(); }
+ const_iterator end() const { return m_entries.end(); }
+
protected:
void CombinePrevAndNext(typename Collection::iterator pos) {
// Check if the prev or next entries in case they need to be unioned with
@@ -599,51 +380,51 @@
RangeData(B base, S size) : Range<B, S>(base, size), data() {}
RangeData(B base, S size, DataType d) : Range<B, S>(base, size), data(d) {}
-
- bool operator<(const RangeData &rhs) const {
- if (this->base == rhs.base) {
- if (this->size == rhs.size)
- return this->data < rhs.data;
- else
- return this->size < rhs.size;
- }
- return this->base < rhs.base;
- }
-
- bool operator==(const RangeData &rhs) const {
- return this->GetRangeBase() == rhs.GetRangeBase() &&
- this->GetByteSize() == rhs.GetByteSize() && this->data == rhs.data;
- }
-
- bool operator!=(const RangeData &rhs) const {
- return this->GetRangeBase() != rhs.GetRangeBase() ||
- this->GetByteSize() != rhs.GetByteSize() || this->data != rhs.data;
- }
};
-template <typename B, typename S, typename T, unsigned N = 0>
+// We can treat the vector as a flattened Binary Search Tree, augmenting it
+// with upper bounds (max of range endpoints) for every index allows us to
+// query for range containment quicker.
+template <typename B, typename S, typename T>
+struct AugmentedRangeData : public RangeData<B, S, T> {
+ B upper_bound;
+
+ AugmentedRangeData(const RangeData<B, S, T> &rd)
+ : RangeData<B, S, T>(rd), upper_bound() {}
+};
+
+template <typename B, typename S, typename T, unsigned N = 0,
+ class Compare = std::less<T>>
class RangeDataVector {
public:
typedef lldb_private::Range<B, S> Range;
typedef RangeData<B, S, T> Entry;
- typedef llvm::SmallVector<Entry, N> Collection;
+ typedef AugmentedRangeData<B, S, T> AugmentedEntry;
+ typedef llvm::SmallVector<AugmentedEntry, N> Collection;
- RangeDataVector() = default;
+ RangeDataVector(Compare compare = Compare()) : m_compare(compare) {}
~RangeDataVector() = default;
- void Append(const Entry &entry) { m_entries.push_back(entry); }
+ void Append(const Entry &entry) { m_entries.emplace_back(entry); }
void Sort() {
if (m_entries.size() > 1)
- std::stable_sort(m_entries.begin(), m_entries.end());
+ std::stable_sort(m_entries.begin(), m_entries.end(),
+ [&compare = m_compare](const Entry &a, const Entry &b) {
+ if (a.base != b.base)
+ return a.base < b.base;
+ if (a.size != b.size)
+ return a.size < b.size;
+ return compare(a.data, b.data);
+ });
+ if (!m_entries.empty())
+ ComputeUpperBounds(0, m_entries.size());
}
#ifdef ASSERT_RANGEMAP_ARE_SORTED
bool IsSorted() const {
typename Collection::const_iterator pos, end, prev;
- // First we determine if we can combine any of the Entry objects so we
- // don't end up allocating and making a new collection for no reason
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end;
prev = pos++) {
if (prev != end && *pos < *prev)
@@ -713,24 +494,20 @@
}
uint32_t FindEntryIndexThatContains(B addr) const {
- const Entry *entry = FindEntryThatContains(addr);
+ const AugmentedEntry *entry =
+ static_cast<const AugmentedEntry *>(FindEntryThatContains(addr));
if (entry)
return std::distance(m_entries.begin(), entry);
return UINT32_MAX;
}
- uint32_t FindEntryIndexesThatContain(B addr,
- std::vector<uint32_t> &indexes) const {
+ uint32_t FindEntryIndexesThatContain(B addr, std::vector<uint32_t> &indexes) {
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert(IsSorted());
#endif
+ if (!m_entries.empty())
+ FindEntryIndexesThatContain(addr, 0, m_entries.size(), indexes);
- if (!m_entries.empty()) {
- for (const auto &entry : m_entries) {
- if (entry.Contains(addr))
- indexes.push_back(entry.data);
- }
- }
return indexes.size();
}
@@ -815,6 +592,55 @@
protected:
Collection m_entries;
+ Compare m_compare;
+
+private:
+ // Compute extra information needed for search
+ B ComputeUpperBounds(size_t lo, size_t hi) {
+ size_t mid = (lo + hi) / 2;
+ AugmentedEntry &entry = m_entries[mid];
+
+ entry.upper_bound = entry.base + entry.size;
+
+ if (lo < mid)
+ entry.upper_bound =
+ std::max(entry.upper_bound, ComputeUpperBounds(lo, mid));
+
+ if (mid + 1 < hi)
+ entry.upper_bound =
+ std::max(entry.upper_bound, ComputeUpperBounds(mid + 1, hi));
+
+ return entry.upper_bound;
+ }
+
+ // This is based on the augmented tree implementation found at
+ // https://en.wikipedia.org/wiki/Interval_tree#Augmented_tree
+ void FindEntryIndexesThatContain(B addr, size_t lo, size_t hi,
+ std::vector<uint32_t> &indexes) {
+ size_t mid = (lo + hi) / 2;
+ const AugmentedEntry &entry = m_entries[mid];
+
+ // addr is greater than the rightmost point of any interval below mid
+ // so there are cannot be any matches.
+ if (addr > entry.upper_bound)
+ return;
+
+ // Recursively search left subtree
+ if (lo < mid)
+ FindEntryIndexesThatContain(addr, lo, mid, indexes);
+
+ // If addr is smaller than the start of the current interval it
+ // cannot contain it nor can any of its right subtree.
+ if (addr < entry.base)
+ return;
+
+ if (entry.Contains(addr))
+ indexes.push_back(entry.data);
+
+ // Recursively search right subtree
+ if (mid + 1 < hi)
+ FindEntryIndexesThatContain(addr, mid + 1, hi, indexes);
+ }
};
// A simple range with data class where you get to define the type of
diff --git a/linux-x64/clang/include/lldb/Utility/RegisterValue.h b/linux-x64/clang/include/lldb/Utility/RegisterValue.h
index eeb3ce5..4211b0a 100644
--- a/linux-x64/clang/include/lldb/Utility/RegisterValue.h
+++ b/linux-x64/clang/include/lldb/Utility/RegisterValue.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include <cstdint>
#include <cstring>
+#include <utility>
namespace lldb_private {
class DataExtractor;
@@ -26,7 +27,8 @@
class RegisterValue {
public:
- enum { kMaxRegisterByteSize = 64u };
+ // big enough to support up to 256 byte AArch64 SVE
+ enum { kMaxRegisterByteSize = 256u };
enum Type {
eTypeInvalid,
@@ -59,7 +61,7 @@
}
explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUInt128) {
- m_scalar = llvm::APInt(inst);
+ m_scalar = llvm::APInt(std::move(inst));
}
explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; }
@@ -72,9 +74,9 @@
m_scalar = value;
}
- explicit RegisterValue(uint8_t *bytes, size_t length,
+ explicit RegisterValue(llvm::ArrayRef<uint8_t> bytes,
lldb::ByteOrder byte_order) {
- SetBytes(bytes, length, byte_order);
+ SetBytes(bytes.data(), bytes.size(), byte_order);
}
RegisterValue::Type GetType() const { return m_type; }
@@ -168,7 +170,7 @@
void operator=(llvm::APInt uint) {
m_type = eTypeUInt128;
- m_scalar = llvm::APInt(uint);
+ m_scalar = llvm::APInt(std::move(uint));
}
void operator=(float f) {
@@ -208,7 +210,7 @@
void SetUInt128(llvm::APInt uint) {
m_type = eTypeUInt128;
- m_scalar = uint;
+ m_scalar = std::move(uint);
}
bool SetUInt(uint64_t uint, uint32_t byte_size);
@@ -259,9 +261,10 @@
Scalar m_scalar;
struct {
- uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any
- // register for any supported target.
- uint8_t length;
+ mutable uint8_t
+ bytes[kMaxRegisterByteSize]; // This must be big enough to hold any
+ // register for any supported target.
+ uint16_t length;
lldb::ByteOrder byte_order;
} buffer;
};
diff --git a/linux-x64/clang/include/lldb/Utility/RegularExpression.h b/linux-x64/clang/include/lldb/Utility/RegularExpression.h
index 54f3dd8..415f1b5 100644
--- a/linux-x64/clang/include/lldb/Utility/RegularExpression.h
+++ b/linux-x64/clang/include/lldb/Utility/RegularExpression.h
@@ -6,194 +6,89 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegularExpression_h_
-#define liblldb_RegularExpression_h_
+#ifndef LLDB_UTILITY_REGULAREXPRESSION_H
+#define LLDB_UTILITY_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);
- /// Executes a regular expression.
- ///
+ ~RegularExpression() = default;
+
+ RegularExpression(const RegularExpression &rhs);
+ RegularExpression(RegularExpression &&rhs) = default;
+
+ RegularExpression &operator=(RegularExpression &&rhs) = default;
+ RegularExpression &operator=(const RegularExpression &rhs) = default;
+
/// 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;
+ /// 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 {
+ return GetText() == rhs.GetText();
}
- int GetErrorCode() const { return m_comp_err; }
-
- bool operator<(const RegularExpression &rhs) const;
-
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
-#endif // liblldb_RegularExpression_h_
+#endif // LLDB_UTILITY_REGULAREXPRESSION_H
diff --git a/linux-x64/clang/include/lldb/Utility/Reproducer.h b/linux-x64/clang/include/lldb/Utility/Reproducer.h
index 670041d..4659254 100644
--- a/linux-x64/clang/include/lldb/Utility/Reproducer.h
+++ b/linux-x64/clang/include/lldb/Utility/Reproducer.h
@@ -9,18 +9,20 @@
#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/ADT/StringRef.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/YAMLTraits.h"
#include <mutex>
#include <string>
+#include <utility>
#include <vector>
namespace lldb_private {
+class UUID;
namespace repro {
class Reproducer;
@@ -28,6 +30,7 @@
enum class ReproducerMode {
Capture,
Replay,
+ PassiveReplay,
Off,
};
@@ -82,111 +85,13 @@
using ProviderBase::ProviderBase; // Inherit constructor.
};
-class FileProvider : public Provider<FileProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- FileProvider(const FileSpec &directory)
- : Provider(directory),
- m_collector(directory.CopyByAppendingPathComponent("root"), directory) {
- }
-
- 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))
- return;
- m_collector.WriteMapping(mapping);
- }
-
- static char ID;
-
-private:
- FileCollector m_collector;
-};
-
-/// Provider for the LLDB version number.
-///
-/// When the reproducer is kept, it writes the lldb version to a file named
-/// version.txt in the reproducer root.
-class VersionProvider : public Provider<VersionProvider> {
-public:
- VersionProvider(const FileSpec &directory) : Provider(directory) {}
- struct Info {
- static const char *name;
- static const char *file;
- };
- void SetVersion(std::string version) {
- assert(m_version.empty());
- m_version = std::move(version);
- }
- void Keep() override;
- std::string m_version;
- 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) {}
-
- static llvm::Expected<std::unique_ptr<DataRecorder>>
- Create(const FileSpec &filename);
-
- template <typename T> void Record(const T &t, bool newline = false) {
- if (!m_record)
- return;
- m_os << t;
- if (newline)
- m_os << '\n';
- m_os.flush();
- }
-
- const FileSpec &GetFilename() { return m_filename; }
-
- void Stop() {
- assert(m_record);
- m_record = false;
- }
-
-private:
- FileSpec m_filename;
- llvm::raw_fd_ostream m_os;
- bool m_record;
-};
-
-class CommandProvider : public Provider<CommandProvider> {
-public:
- struct Info {
- static const char *name;
- static const char *file;
- };
-
- CommandProvider(const FileSpec &directory) : Provider(directory) {}
-
- DataRecorder *GetNewDataRecorder();
-
- void Keep() override;
- void Discard() override;
-
- static char ID;
-
-private:
- std::vector<std::unique_ptr<DataRecorder>> m_data_recorders;
-};
-
/// 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
@@ -198,9 +103,15 @@
/// might need to clean up files already written to disk.
void Discard();
+ /// Enable or disable auto generate.
+ void SetAutoGenerate(bool b);
+
+ /// Return whether auto generate is enabled.
+ bool IsAutoGenerate() const;
+
/// 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)));
}
@@ -238,12 +149,15 @@
FileSpec m_root;
/// Flag to ensure that we never call both keep and discard.
- bool m_done;
+ bool m_done = false;
+
+ /// Flag to auto generate a reproducer when it would otherwise be discarded.
+ bool m_auto_generate = false;
};
class Loader final {
public:
- Loader(const FileSpec &root);
+ Loader(FileSpec root, bool passive = false);
template <typename T> FileSpec GetFile() {
if (!HasFile(T::file))
@@ -252,16 +166,28 @@
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; }
+ bool IsPassiveReplay() const { return m_passive_replay; }
+
private:
bool HasFile(llvm::StringRef file);
FileSpec m_root;
std::vector<std::string> m_files;
bool m_loaded;
+ bool m_passive_replay;
};
/// The reproducer enables clients to obtain access to the Generator and
@@ -271,6 +197,7 @@
static Reproducer &Instance();
static llvm::Error Initialize(ReproducerMode mode,
llvm::Optional<FileSpec> root);
+ static void Initialize();
static bool Initialized();
static void Terminate();
@@ -284,9 +211,12 @@
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);
+ llvm::Error SetReplay(llvm::Optional<FileSpec> root, bool passive = false);
private:
static llvm::Optional<Reproducer> &InstanceImpl();
@@ -297,6 +227,25 @@
mutable std::mutex m_mutex;
};
+class Verifier {
+public:
+ Verifier(Loader *loader) : m_loader(loader) {}
+ void Verify(llvm::function_ref<void(llvm::StringRef)> error_callback,
+ llvm::function_ref<void(llvm::StringRef)> warning_callback,
+ llvm::function_ref<void(llvm::StringRef)> note_callback) const;
+
+private:
+ Loader *m_loader;
+};
+
+struct ReplayOptions {
+ bool verify = true;
+ bool check_version = true;
+};
+
+llvm::Error Finalize(Loader *loader);
+llvm::Error Finalize(const FileSpec &root);
+
} // namespace repro
} // namespace lldb_private
diff --git a/linux-x64/clang/include/lldb/Utility/ReproducerInstrumentation.h b/linux-x64/clang/include/lldb/Utility/ReproducerInstrumentation.h
index f90ce4b..c8a98ad 100644
--- a/linux-x64/clang/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/linux-x64/clang/include/lldb/Utility/ReproducerInstrumentation.h
@@ -5,8 +5,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_UTILITY_REPRODUCER_INSTRUMENTATION_H
-#define LLDB_UTILITY_REPRODUCER_INSTRUMENTATION_H
+#ifndef LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H
+#define LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
@@ -16,8 +16,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
-#include <iostream>
#include <map>
+#include <thread>
#include <type_traits>
template <typename T,
@@ -33,6 +33,11 @@
}
template <typename T>
+inline void stringify_append(llvm::raw_string_ostream &ss, T *t) {
+ ss << reinterpret_cast<void *>(t);
+}
+
+template <typename T>
inline void stringify_append(llvm::raw_string_ostream &ss, const T *t) {
ss << reinterpret_cast<const void *>(t);
}
@@ -40,7 +45,13 @@
template <>
inline void stringify_append<char>(llvm::raw_string_ostream &ss,
const char *t) {
- ss << t;
+ ss << '\"' << t << '\"';
+}
+
+template <>
+inline void stringify_append<std::nullptr_t>(llvm::raw_string_ostream &ss,
+ const std::nullptr_t &t) {
+ ss << "\"nullptr\"";
}
template <typename Head>
@@ -68,117 +79,154 @@
// is initialized or enabled.
// #define LLDB_REPRO_INSTR_TRACE
+#ifdef LLDB_REPRO_INSTR_TRACE
+inline llvm::raw_ostream &this_thread_id() {
+ size_t tid = std::hash<std::thread::id>{}(std::this_thread::get_id());
+ return llvm::errs().write_hex(tid) << " :: ";
+}
+#endif
+
#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature) \
- R.Register<Class * Signature>(&construct<Class Signature>::doit, "", #Class, \
- #Class, #Signature)
+ R.Register<Class * Signature>(&construct<Class Signature>::record, "", \
+ #Class, #Class, #Signature)
+
#define LLDB_REGISTER_METHOD(Result, Class, Method, Signature) \
R.Register( \
- &invoke<Result(Class::*) Signature>::method<(&Class::Method)>::doit, \
+ &invoke<Result(Class::*) Signature>::method<(&Class::Method)>::record, \
#Result, #Class, #Method, #Signature)
+
#define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature) \
- R.Register(&invoke<Result(Class::*) Signature const>::method_const<( \
- &Class::Method)>::doit, \
+ R.Register(&invoke<Result(Class::*) \
+ Signature const>::method<(&Class::Method)>::record, \
#Result, #Class, #Method, #Signature)
+
#define LLDB_REGISTER_STATIC_METHOD(Result, Class, Method, Signature) \
- R.Register<Result Signature>( \
- static_cast<Result(*) Signature>(&Class::Method), #Result, #Class, \
- #Method, #Signature)
+ R.Register(&invoke<Result(*) Signature>::method<(&Class::Method)>::record, \
+ #Result, #Class, #Method, #Signature)
+
+#define LLDB_REGISTER_CHAR_PTR_METHOD_STATIC(Result, Class, Method) \
+ R.Register( \
+ &invoke<Result (*)(char *, size_t)>::method<(&Class::Method)>::record, \
+ &invoke_char_ptr<Result (*)(char *, \
+ size_t)>::method<(&Class::Method)>::record, \
+ #Result, #Class, #Method, "(char*, size_t");
+
+#define LLDB_REGISTER_CHAR_PTR_METHOD(Result, Class, Method) \
+ R.Register(&invoke<Result (Class::*)(char *, size_t)>::method<( \
+ &Class::Method)>::record, \
+ &invoke_char_ptr<Result (Class::*)(char *, size_t)>::method<( \
+ &Class::Method)>::record, \
+ #Result, #Class, #Method, "(char*, size_t");
+
+#define LLDB_REGISTER_CHAR_PTR_METHOD_CONST(Result, Class, Method) \
+ R.Register(&invoke<Result (Class::*)(char *, size_t) \
+ const>::method<(&Class::Method)>::record, \
+ &invoke_char_ptr<Result (Class::*)(char *, size_t) \
+ const>::method<(&Class::Method)>::record, \
+ #Result, #Class, #Method, "(char*, size_t");
+
+#define LLDB_CONSTRUCT_(T, Class, ...) \
+ lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION); \
+ lldb_private::repro::construct<T>::handle(LLDB_GET_INSTRUMENTATION_DATA(), \
+ _recorder, Class, __VA_ARGS__);
#define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
- if (lldb_private::repro::InstrumentationData data = \
- LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \
- &lldb_private::repro::construct<Class Signature>::doit, \
- __VA_ARGS__); \
- sb_recorder.RecordResult(this); \
- }
+ LLDB_CONSTRUCT_(Class Signature, this, __VA_ARGS__)
#define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
- if (lldb_private::repro::InstrumentationData data = \
+ LLDB_CONSTRUCT_(Class(), this, lldb_private::repro::EmptyArg())
+
+#define LLDB_RECORD_(T1, T2, ...) \
+ lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \
+ stringify_args(__VA_ARGS__)); \
+ if (lldb_private::repro::InstrumentationData _data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \
- &lldb_private::repro::construct<Class()>::doit); \
- sb_recorder.RecordResult(this); \
+ if (lldb_private::repro::Serializer *_serializer = \
+ _data.GetSerializer()) { \
+ _recorder.Record(*_serializer, _data.GetRegistry(), \
+ &lldb_private::repro::invoke<T1>::method<T2>::record, \
+ __VA_ARGS__); \
+ } else if (lldb_private::repro::Deserializer *_deserializer = \
+ _data.GetDeserializer()) { \
+ if (_recorder.ShouldCapture()) { \
+ return lldb_private::repro::invoke<T1>::method<T2>::replay( \
+ _recorder, *_deserializer, _data.GetRegistry()); \
+ } \
+ } \
}
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
- if (lldb_private::repro::InstrumentationData data = \
- LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record( \
- data.GetSerializer(), data.GetRegistry(), \
- &lldb_private::repro::invoke<Result(Class::*) Signature>::method<( \
- &Class::Method)>::doit, \
- this, __VA_ARGS__); \
- }
+ LLDB_RECORD_(Result(Class::*) Signature, (&Class::Method), this, __VA_ARGS__)
#define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
- if (lldb_private::repro::InstrumentationData data = \
- LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record( \
- data.GetSerializer(), data.GetRegistry(), \
- &lldb_private::repro::invoke<Result( \
- Class::*) Signature const>::method_const<(&Class::Method)>::doit, \
- this, __VA_ARGS__); \
- }
+ LLDB_RECORD_(Result(Class::*) Signature const, (&Class::Method), this, \
+ __VA_ARGS__)
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
- if (lldb_private::repro::InstrumentationData data = \
- LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \
- &lldb_private::repro::invoke<Result ( \
- Class::*)()>::method<(&Class::Method)>::doit, \
- this); \
- }
+ LLDB_RECORD_(Result (Class::*)(), (&Class::Method), this)
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
- if (lldb_private::repro::InstrumentationData data = \
- LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record( \
- data.GetSerializer(), data.GetRegistry(), \
- &lldb_private::repro::invoke<Result ( \
- Class::*)() const>::method_const<(&Class::Method)>::doit, \
- this); \
- }
+ LLDB_RECORD_(Result (Class::*)() const, (&Class::Method), this)
#define LLDB_RECORD_STATIC_METHOD(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__)); \
- if (lldb_private::repro::InstrumentationData data = \
- LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \
- static_cast<Result(*) Signature>(&Class::Method), \
- __VA_ARGS__); \
- }
+ LLDB_RECORD_(Result(*) Signature, (&Class::Method), __VA_ARGS__)
#define LLDB_RECORD_STATIC_METHOD_NO_ARGS(Result, Class, Method) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION); \
- if (lldb_private::repro::InstrumentationData data = \
+ LLDB_RECORD_(Result (*)(), (&Class::Method), lldb_private::repro::EmptyArg())
+
+#define LLDB_RECORD_CHAR_PTR_(T1, T2, StrOut, ...) \
+ lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \
+ stringify_args(__VA_ARGS__)); \
+ if (lldb_private::repro::InstrumentationData _data = \
LLDB_GET_INSTRUMENTATION_DATA()) { \
- sb_recorder.Record(data.GetSerializer(), data.GetRegistry(), \
- static_cast<Result (*)()>(&Class::Method)); \
+ if (lldb_private::repro::Serializer *_serializer = \
+ _data.GetSerializer()) { \
+ _recorder.Record(*_serializer, _data.GetRegistry(), \
+ &lldb_private::repro::invoke<T1>::method<(T2)>::record, \
+ __VA_ARGS__); \
+ } else if (lldb_private::repro::Deserializer *_deserializer = \
+ _data.GetDeserializer()) { \
+ if (_recorder.ShouldCapture()) { \
+ return lldb_private::repro::invoke_char_ptr<T1>::method<T2>::replay( \
+ _recorder, *_deserializer, _data.GetRegistry(), StrOut); \
+ } \
+ } \
}
-#define LLDB_RECORD_RESULT(Result) sb_recorder.RecordResult(Result);
+#define LLDB_RECORD_CHAR_PTR_METHOD(Result, Class, Method, Signature, StrOut, \
+ ...) \
+ LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature, (&Class::Method), StrOut, \
+ this, __VA_ARGS__)
+
+#define LLDB_RECORD_CHAR_PTR_METHOD_CONST(Result, Class, Method, Signature, \
+ StrOut, ...) \
+ LLDB_RECORD_CHAR_PTR_(Result(Class::*) Signature const, (&Class::Method), \
+ StrOut, this, __VA_ARGS__)
+
+#define LLDB_RECORD_CHAR_PTR_STATIC_METHOD(Result, Class, Method, Signature, \
+ StrOut, ...) \
+ LLDB_RECORD_CHAR_PTR_(Result(*) Signature, (&Class::Method), StrOut, \
+ __VA_ARGS__)
+
+#define LLDB_RECORD_RESULT(Result) _recorder.RecordResult(Result, true);
/// The LLDB_RECORD_DUMMY macro is special because it doesn't actually record
/// anything. It's used to track API boundaries when we cannot record for
/// technical reasons.
#define LLDB_RECORD_DUMMY(Result, Class, Method, Signature, ...) \
- lldb_private::repro::Recorder sb_recorder(LLVM_PRETTY_FUNCTION, \
- stringify_args(__VA_ARGS__));
+ lldb_private::repro::Recorder _recorder;
+
+#define LLDB_RECORD_DUMMY_NO_ARGS(Result, Class, Method) \
+ lldb_private::repro::Recorder _recorder;
namespace lldb_private {
namespace repro {
+template <class T>
+struct is_trivially_serializable
+ : std::integral_constant<bool, std::is_fundamental<T>::value ||
+ std::is_enum<T>::value> {};
+
/// Mapping between serialized indices and their corresponding objects.
///
/// This class is used during replay to map indices back to in-memory objects.
@@ -201,19 +249,24 @@
}
/// Adds a pointer to an object to the mapping for the given index.
- template <typename T> void AddObjectForIndex(unsigned idx, T *object) {
+ template <typename T> T *AddObjectForIndex(unsigned idx, T *object) {
AddObjectForIndexImpl(
idx, static_cast<void *>(
const_cast<typename std::remove_const<T>::type *>(object)));
+ return object;
}
/// Adds a reference to an object to the mapping for the given index.
- template <typename T> void AddObjectForIndex(unsigned idx, T &object) {
+ template <typename T> T &AddObjectForIndex(unsigned idx, T &object) {
AddObjectForIndexImpl(
idx, static_cast<void *>(
const_cast<typename std::remove_const<T>::type *>(&object)));
+ return object;
}
+ /// Get all objects sorted by their index.
+ std::vector<void *> GetAllObjects() const;
+
private:
/// Helper method that does the actual lookup. The void* result is later cast
/// by the caller.
@@ -236,7 +289,10 @@
struct FundamentalReferenceTag {};
/// 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, ReferenceTag>::type type;
+};
template <class T> struct serializer_tag<T *> {
typedef
typename std::conditional<std::is_fundamental<T>::value,
@@ -268,37 +324,59 @@
/// Deserialize and interpret value as T.
template <typename T> T Deserialize() {
+ T t = Read<T>(typename serializer_tag<T>::type());
#ifdef LLDB_REPRO_INSTR_TRACE
- llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << "\n";
+ llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
#endif
- return Read<T>(typename serializer_tag<T>::type());
+ return t;
}
- /// Store the returned value in the index-to-object mapping.
- template <typename T> void HandleReplayResult(const T &t) {
+ template <typename T> const T &HandleReplayResult(const T &t) {
+ CheckSequence(Deserialize<unsigned>());
unsigned result = Deserialize<unsigned>();
- if (std::is_fundamental<T>::value)
- return;
+ if (is_trivially_serializable<T>::value)
+ return t;
// We need to make a copy as the original object might go out of scope.
- m_index_to_object.AddObjectForIndex(result, new T(t));
+ return *m_index_to_object.AddObjectForIndex(result, new T(t));
}
/// Store the returned value in the index-to-object mapping.
- template <typename T> void HandleReplayResult(T *t) {
+ template <typename T> T &HandleReplayResult(T &t) {
+ CheckSequence(Deserialize<unsigned>());
unsigned result = Deserialize<unsigned>();
- if (std::is_fundamental<T>::value)
- return;
- m_index_to_object.AddObjectForIndex(result, t);
+ if (is_trivially_serializable<T>::value)
+ return t;
+ // We need to make a copy as the original object might go out of scope.
+ return *m_index_to_object.AddObjectForIndex(result, new T(t));
+ }
+
+ /// Store the returned value in the index-to-object mapping.
+ template <typename T> T *HandleReplayResult(T *t) {
+ CheckSequence(Deserialize<unsigned>());
+ unsigned result = Deserialize<unsigned>();
+ if (is_trivially_serializable<T>::value)
+ return t;
+ return m_index_to_object.AddObjectForIndex(result, t);
}
/// All returned types are recorded, even when the function returns a void.
/// The latter requires special handling.
void HandleReplayResultVoid() {
+ CheckSequence(Deserialize<unsigned>());
unsigned result = Deserialize<unsigned>();
assert(result == 0);
(void)result;
}
+ std::vector<void *> GetAllObjects() const {
+ return m_index_to_object.GetAllObjects();
+ }
+
+ void SetExpectedSequence(unsigned sequence) {
+ m_expected_sequence = sequence;
+ }
+
private:
template <typename T> T Read(ValueTag) {
assert(HasData(sizeof(T)));
@@ -340,17 +418,27 @@
return *(new UnderlyingT(Deserialize<UnderlyingT>()));
}
+ /// Verify that the given sequence number matches what we expect.
+ void CheckSequence(unsigned sequence);
+
/// Mapping of indices to objects.
IndexToObject m_index_to_object;
/// Buffer containing the serialized data.
llvm::StringRef m_buffer;
+
+ /// The result's expected sequence number.
+ llvm::Optional<unsigned> m_expected_sequence;
};
/// Partial specialization for C-style strings. We read the string value
/// instead of treating it as pointer.
template <> const char *Deserializer::Deserialize<const char *>();
+template <> const char **Deserializer::Deserialize<const char **>();
+template <> const uint8_t *Deserializer::Deserialize<const uint8_t *>();
+template <> const void *Deserializer::Deserialize<const void *>();
template <> char *Deserializer::Deserialize<char *>();
+template <> void *Deserializer::Deserialize<void *>();
/// Helpers to auto-synthesize function replay code. It deserializes the replay
/// function's arguments one by one and finally calls the corresponding
@@ -392,7 +480,11 @@
DefaultReplayer(Result (*f)(Args...)) : Replayer(), f(f) {}
void operator()(Deserializer &deserializer) const override {
- deserializer.HandleReplayResult(
+ Replay(deserializer);
+ }
+
+ Result Replay(Deserializer &deserializer) const {
+ return deserializer.HandleReplayResult(
DeserializationHelper<Args...>::template deserialized<Result>::doit(
deserializer, f));
}
@@ -407,6 +499,10 @@
DefaultReplayer(void (*f)(Args...)) : Replayer(), f(f) {}
void operator()(Deserializer &deserializer) const override {
+ Replay(deserializer);
+ }
+
+ void Replay(Deserializer &deserializer) const {
DeserializationHelper<Args...>::template deserialized<void>::doit(
deserializer, f);
deserializer.HandleReplayResultVoid();
@@ -442,7 +538,7 @@
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 +548,7 @@
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));
}
@@ -462,18 +558,25 @@
/// Replay functions from a buffer.
bool Replay(llvm::StringRef buffer);
+ /// Replay functions from a deserializer.
+ bool Replay(Deserializer &deserializer);
+
/// Returns the ID for a given function address.
unsigned GetID(uintptr_t addr);
+ /// Get the replayer matching the given ID.
+ Replayer *GetReplayer(unsigned id);
+
+ std::string GetSignature(unsigned id);
+
+ void CheckID(unsigned expected, unsigned actual);
+
protected:
/// Register the given replayer for a function (and the ID mapping).
void DoRegister(uintptr_t RunID, std::unique_ptr<Replayer> replayer,
SignatureStr signature);
private:
- std::string GetSignature(unsigned id);
- Replayer *GetReplayer(unsigned id);
-
/// Mapping of function addresses to replayers and their ID.
std::map<uintptr_t, std::pair<std::unique_ptr<Replayer>, unsigned>>
m_replayers;
@@ -482,37 +585,6 @@
std::map<unsigned, std::pair<Replayer *, SignatureStr>> m_ids;
};
-/// To be used as the "Runtime ID" of a constructor. It also invokes the
-/// constructor when called.
-template <typename Signature> struct construct;
-template <typename Class, typename... Args> struct construct<Class(Args...)> {
- static Class *doit(Args... args) { return new Class(args...); }
-};
-
-/// To be used as the "Runtime ID" of a member function. It also invokes the
-/// member function when called.
-template <typename Signature> struct invoke;
-template <typename Result, typename Class, typename... Args>
-struct invoke<Result (Class::*)(Args...)> {
- template <Result (Class::*m)(Args...)> struct method {
- static Result doit(Class *c, Args... args) { return (c->*m)(args...); }
- };
-};
-
-template <typename Result, typename Class, typename... Args>
-struct invoke<Result (Class::*)(Args...) const> {
- template <Result (Class::*m)(Args...) const> struct method_const {
- static Result doit(Class *c, Args... args) { return (c->*m)(args...); }
- };
-};
-
-template <typename Class, typename... Args>
-struct invoke<void (Class::*)(Args...)> {
- template <void (Class::*m)(Args...)> struct method {
- static void doit(Class *c, Args... args) { (c->*m)(args...); }
- };
-};
-
/// Maps an object to an index for serialization. Indices are unique and
/// incremented for every new object.
///
@@ -542,15 +614,17 @@
SerializeAll(tail...);
}
- void SerializeAll() {
- m_stream.flush();
- }
+ void SerializeAll() { m_stream.flush(); }
private:
/// Serialize pointers. We need to differentiate between pointers to
/// fundamental types (in which case we serialize its value) and pointer to
/// objects (in which case we serialize their index).
template <typename T> void Serialize(T *t) {
+#ifdef LLDB_REPRO_INSTR_TRACE
+ this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
+#endif
if (std::is_fundamental<T>::value) {
Serialize(*t);
} else {
@@ -563,7 +637,11 @@
/// fundamental types (in which case we serialize its value) and references
/// to objects (in which case we serialize their index).
template <typename T> void Serialize(T &t) {
- if (std::is_fundamental<T>::value) {
+#ifdef LLDB_REPRO_INSTR_TRACE
+ this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
+#endif
+ if (is_trivially_serializable<T>::value) {
m_stream.write(reinterpret_cast<const char *>(&t), sizeof(T));
} else {
unsigned idx = m_tracker.GetIndexForObject(&t);
@@ -571,14 +649,43 @@
}
}
+ void Serialize(const void *v) {
+ // FIXME: Support void*
+ }
+
void Serialize(void *v) {
// FIXME: Support void*
- llvm_unreachable("void* is currently unsupported.");
}
void Serialize(const char *t) {
- m_stream << t;
- m_stream.write(0x0);
+#ifdef LLDB_REPRO_INSTR_TRACE
+ this_thread_id() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
+#endif
+ const size_t size = t ? strlen(t) : std::numeric_limits<size_t>::max();
+ Serialize(size);
+ if (t) {
+ m_stream << t;
+ m_stream.write(0x0);
+ }
+ }
+
+ void Serialize(const char **t) {
+ size_t size = 0;
+ if (!t) {
+ Serialize(size);
+ return;
+ }
+
+ // Compute the size of the array.
+ const char *const *temp = t;
+ while (*temp++)
+ size++;
+ Serialize(size);
+
+ // Serialize the content of the array.
+ while (*t)
+ Serialize(*t++);
}
/// Serialization stream.
@@ -586,24 +693,46 @@
/// Mapping of objects to indices.
ObjectToIndex m_tracker;
-};
+}; // namespace repro
class InstrumentationData {
public:
- InstrumentationData() : m_serializer(nullptr), m_registry(nullptr){};
- InstrumentationData(Serializer &serializer, Registry ®istry)
- : m_serializer(&serializer), m_registry(®istry){};
-
- Serializer &GetSerializer() { return *m_serializer; }
+ Serializer *GetSerializer() { return m_serializer; }
+ Deserializer *GetDeserializer() { return m_deserializer; }
Registry &GetRegistry() { return *m_registry; }
- operator bool() { return m_serializer != nullptr && m_registry != nullptr; }
+ operator bool() {
+ return (m_serializer != nullptr || m_deserializer != nullptr) &&
+ m_registry != nullptr;
+ }
+
+ static void Initialize(Serializer &serializer, Registry ®istry);
+ static void Initialize(Deserializer &serializer, Registry ®istry);
+ static InstrumentationData &Instance();
+
+protected:
+ friend llvm::optional_detail::OptionalStorage<InstrumentationData, true>;
+ friend llvm::Optional<InstrumentationData>;
+
+ InstrumentationData()
+ : m_serializer(nullptr), m_deserializer(nullptr), m_registry(nullptr) {}
+ InstrumentationData(Serializer &serializer, Registry ®istry)
+ : m_serializer(&serializer), m_deserializer(nullptr),
+ m_registry(®istry) {}
+ InstrumentationData(Deserializer &deserializer, Registry ®istry)
+ : m_serializer(nullptr), m_deserializer(&deserializer),
+ m_registry(®istry) {}
private:
+ static llvm::Optional<InstrumentationData> &InstanceImpl();
+
Serializer *m_serializer;
+ Deserializer *m_deserializer;
Registry *m_registry;
};
+struct EmptyArg {};
+
/// RAII object that records function invocations and their return value.
///
/// API calls are only captured when the API boundary is crossed. Once we're in
@@ -618,7 +747,8 @@
/// this class is also used for logging.
class Recorder {
public:
- Recorder(llvm::StringRef pretty_func = {}, std::string &&pretty_args = {});
+ Recorder();
+ Recorder(llvm::StringRef pretty_func, std::string &&pretty_args = {});
~Recorder();
/// Records a single function call.
@@ -629,12 +759,15 @@
if (!ShouldCapture())
return;
+ std::lock_guard<std::mutex> lock(g_mutex);
+ unsigned sequence = GetSequenceNumber();
unsigned id = registry.GetID(uintptr_t(f));
#ifdef LLDB_REPRO_INSTR_TRACE
Log(id);
#endif
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(id);
serializer.SerializeAll(args...);
@@ -642,6 +775,7 @@
typename std::remove_reference<Result>::type>::type>::value) {
m_result_recorded = false;
} else {
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(0);
m_result_recorded = true;
}
@@ -655,43 +789,102 @@
if (!ShouldCapture())
return;
+ std::lock_guard<std::mutex> lock(g_mutex);
+ unsigned sequence = GetSequenceNumber();
unsigned id = registry.GetID(uintptr_t(f));
#ifdef LLDB_REPRO_INSTR_TRACE
Log(id);
#endif
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(id);
serializer.SerializeAll(args...);
// Record result.
+ serializer.SerializeAll(sequence);
serializer.SerializeAll(0);
m_result_recorded = true;
}
+ /// Specializations for the no-argument methods. These are passed an empty
+ /// dummy argument so the same variadic macro can be used. These methods
+ /// strip the arguments before forwarding them.
+ template <typename Result>
+ void Record(Serializer &serializer, Registry ®istry, Result (*f)(),
+ const EmptyArg &arg) {
+ Record(serializer, registry, f);
+ }
+
/// Record the result of a function call.
- template <typename Result> Result RecordResult(Result &&r) {
- UpdateBoundary();
+ template <typename Result>
+ Result RecordResult(Result &&r, bool update_boundary) {
+ // When recording the result from the LLDB_RECORD_RESULT macro, we need to
+ // update the boundary so we capture the copy constructor. However, when
+ // called to record the this pointer of the (copy) constructor, the
+ // boundary should not be toggled, because it is called from the
+ // LLDB_RECORD_CONSTRUCTOR macro, which might be followed by other API
+ // calls.
+ if (update_boundary)
+ UpdateBoundary();
if (m_serializer && ShouldCapture()) {
+ std::lock_guard<std::mutex> lock(g_mutex);
assert(!m_result_recorded);
+ m_serializer->SerializeAll(GetSequenceNumber());
m_serializer->SerializeAll(r);
m_result_recorded = true;
}
return std::forward<Result>(r);
}
+ template <typename Result, typename T>
+ Result Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr,
+ bool update_boundary) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
+ unsigned actual_id = registry.GetID(addr);
+ unsigned id = deserializer.Deserialize<unsigned>();
+ registry.CheckID(id, actual_id);
+ return ReplayResult<Result>(
+ static_cast<DefaultReplayer<T> *>(registry.GetReplayer(id))
+ ->Replay(deserializer),
+ update_boundary);
+ }
+
+ void Replay(Deserializer &deserializer, Registry ®istry, uintptr_t addr) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
+ unsigned actual_id = registry.GetID(addr);
+ unsigned id = deserializer.Deserialize<unsigned>();
+ registry.CheckID(id, actual_id);
+ registry.GetReplayer(id)->operator()(deserializer);
+ }
+
+ template <typename Result>
+ Result ReplayResult(Result &&r, bool update_boundary) {
+ if (update_boundary)
+ UpdateBoundary();
+ return std::forward<Result>(r);
+ }
+
+ bool ShouldCapture() { return m_local_boundary; }
+
+ /// Mark the current thread as a private thread and pretend that everything
+ /// on this thread is behind happening behind the API boundary.
+ static void PrivateThread() { g_global_boundary = true; }
+
private:
+ static unsigned GetNextSequenceNumber() { return g_sequence++; }
+ unsigned GetSequenceNumber() const;
+
+ template <typename T> friend struct replay;
void UpdateBoundary() {
if (m_local_boundary)
g_global_boundary = false;
}
- bool ShouldCapture() { return m_local_boundary; }
-
#ifdef LLDB_REPRO_INSTR_TRACE
void Log(unsigned id) {
- llvm::errs() << "Recording " << id << ": " << m_pretty_func << " ("
- << m_pretty_args << ")\n";
+ this_thread_id() << "Recording " << id << ": " << m_pretty_func << " ("
+ << m_pretty_args << ")\n";
}
#endif
@@ -707,11 +900,213 @@
/// Whether the return value was recorded explicitly.
bool m_result_recorded;
+ /// The sequence number for this pair of function and result.
+ unsigned m_sequence;
+
/// Whether we're currently across the API boundary.
- static bool g_global_boundary;
+ static thread_local bool g_global_boundary;
+
+ /// Global mutex to protect concurrent access.
+ static std::mutex g_mutex;
+
+ /// Unique, monotonically increasing sequence number.
+ static std::atomic<unsigned> g_sequence;
};
+/// To be used as the "Runtime ID" of a constructor. It also invokes the
+/// constructor when called.
+template <typename Signature> struct construct;
+template <typename Class, typename... Args> struct construct<Class(Args...)> {
+ static Class *handle(lldb_private::repro::InstrumentationData data,
+ lldb_private::repro::Recorder &recorder, Class *c,
+ const EmptyArg &) {
+ return handle(data, recorder, c);
+ }
+
+ static Class *handle(lldb_private::repro::InstrumentationData data,
+ lldb_private::repro::Recorder &recorder, Class *c,
+ Args... args) {
+ if (!data)
+ return nullptr;
+
+ if (Serializer *serializer = data.GetSerializer()) {
+ recorder.Record(*serializer, data.GetRegistry(), &record, args...);
+ recorder.RecordResult(c, false);
+ } else if (Deserializer *deserializer = data.GetDeserializer()) {
+ if (recorder.ShouldCapture()) {
+ replay(recorder, *deserializer, data.GetRegistry());
+ }
+ }
+
+ return nullptr;
+ }
+
+ static Class *record(Args... args) { return new Class(args...); }
+
+ static Class *replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry) {
+ return recorder.Replay<Class *, Class *(Args...)>(
+ deserializer, registry, uintptr_t(&record), false);
+ }
+};
+
+/// To be used as the "Runtime ID" of a member function. It also invokes the
+/// member function when called.
+template <typename Signature> struct invoke;
+template <typename Result, typename Class, typename... Args>
+struct invoke<Result (Class::*)(Args...)> {
+ template <Result (Class::*m)(Args...)> struct method {
+ static Result record(Class *c, Args... args) { return (c->*m)(args...); }
+
+ static Result replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry) {
+ return recorder.Replay<Result, Result(Class *, Args...)>(
+ deserializer, registry, uintptr_t(&record), true);
+ }
+ };
+};
+
+template <typename Class, typename... Args>
+struct invoke<void (Class::*)(Args...)> {
+ template <void (Class::*m)(Args...)> struct method {
+ static void record(Class *c, Args... args) { (c->*m)(args...); }
+ static void replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry) {
+ recorder.Replay(deserializer, registry, uintptr_t(&record));
+ }
+ };
+};
+
+template <typename Result, typename Class, typename... Args>
+struct invoke<Result (Class::*)(Args...) const> {
+ template <Result (Class::*m)(Args...) const> struct method {
+ static Result record(Class *c, Args... args) { return (c->*m)(args...); }
+ static Result replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry) {
+ return recorder.Replay<Result, Result(Class *, Args...)>(
+ deserializer, registry, uintptr_t(&record), true);
+ }
+ };
+};
+
+template <typename Class, typename... Args>
+struct invoke<void (Class::*)(Args...) const> {
+ template <void (Class::*m)(Args...) const> struct method {
+ static void record(Class *c, Args... args) { return (c->*m)(args...); }
+ static void replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry) {
+ recorder.Replay(deserializer, registry, uintptr_t(&record));
+ }
+ };
+};
+
+template <typename Signature> struct replay;
+
+template <typename Result, typename Class, typename... Args>
+struct replay<Result (Class::*)(Args...)> {
+ template <Result (Class::*m)(Args...)> struct method {};
+};
+
+template <typename Result, typename... Args>
+struct invoke<Result (*)(Args...)> {
+ template <Result (*m)(Args...)> struct method {
+ static Result record(Args... args) { return (*m)(args...); }
+ static Result replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry) {
+ return recorder.Replay<Result, Result(Args...)>(deserializer, registry,
+ uintptr_t(&record), true);
+ }
+ };
+};
+
+template <typename... Args> struct invoke<void (*)(Args...)> {
+ template <void (*m)(Args...)> struct method {
+ static void record(Args... args) { return (*m)(args...); }
+ static void replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry) {
+ recorder.Replay(deserializer, registry, uintptr_t(&record));
+ }
+ };
+};
+
+/// Special handling for functions returning strings as (char*, size_t).
+/// {
+
+/// For inline replay, we ignore the arguments and use the ones from the
+/// serializer instead. This doesn't work for methods that use a char* and a
+/// size to return a string. For one these functions have a custom replayer to
+/// prevent override the input buffer. Furthermore, the template-generated
+/// deserialization is not easy to hook into.
+///
+/// The specializations below hand-implement the serialization logic for the
+/// inline replay. Instead of using the function from the registry, it uses the
+/// one passed into the macro.
+template <typename Signature> struct invoke_char_ptr;
+template <typename Result, typename Class, typename... Args>
+struct invoke_char_ptr<Result (Class::*)(Args...) const> {
+ template <Result (Class::*m)(Args...) const> struct method {
+ static Result record(Class *c, char *s, size_t l) {
+ char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
+ return (c->*m)(buffer, l);
+ }
+
+ static Result replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry, char *str) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
+ deserializer.Deserialize<unsigned>();
+ Class *c = deserializer.Deserialize<Class *>();
+ deserializer.Deserialize<const char *>();
+ size_t l = deserializer.Deserialize<size_t>();
+ return recorder.ReplayResult(
+ std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true);
+ }
+ };
+};
+
+template <typename Signature> struct invoke_char_ptr;
+template <typename Result, typename Class, typename... Args>
+struct invoke_char_ptr<Result (Class::*)(Args...)> {
+ template <Result (Class::*m)(Args...)> struct method {
+ static Result record(Class *c, char *s, size_t l) {
+ char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
+ return (c->*m)(buffer, l);
+ }
+
+ static Result replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry, char *str) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
+ deserializer.Deserialize<unsigned>();
+ Class *c = deserializer.Deserialize<Class *>();
+ deserializer.Deserialize<const char *>();
+ size_t l = deserializer.Deserialize<size_t>();
+ return recorder.ReplayResult(
+ std::move(deserializer.HandleReplayResult((c->*m)(str, l))), true);
+ }
+ };
+};
+
+template <typename Result, typename... Args>
+struct invoke_char_ptr<Result (*)(Args...)> {
+ template <Result (*m)(Args...)> struct method {
+ static Result record(char *s, size_t l) {
+ char *buffer = reinterpret_cast<char *>(calloc(l, sizeof(char)));
+ return (*m)(buffer, l);
+ }
+
+ static Result replay(Recorder &recorder, Deserializer &deserializer,
+ Registry ®istry, char *str) {
+ deserializer.SetExpectedSequence(deserializer.Deserialize<unsigned>());
+ deserializer.Deserialize<unsigned>();
+ deserializer.Deserialize<const char *>();
+ size_t l = deserializer.Deserialize<size_t>();
+ return recorder.ReplayResult(
+ std::move(deserializer.HandleReplayResult((*m)(str, l))), true);
+ }
+ };
+};
+/// }
+
} // namespace repro
} // namespace lldb_private
-#endif // LLDB_UTILITY_REPRODUCER_INSTRUMENTATION_H
+#endif // LLDB_UTILITY_REPRODUCERINSTRUMENTATION_H
diff --git a/linux-x64/clang/include/lldb/Utility/ReproducerProvider.h b/linux-x64/clang/include/lldb/Utility/ReproducerProvider.h
new file mode 100644
index 0000000..221c0eb
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Utility/ReproducerProvider.h
@@ -0,0 +1,434 @@
+//===-- Reproducer.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_REPRODUCER_PROVIDER_H
+#define LLDB_UTILITY_REPRODUCER_PROVIDER_H
+
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/ProcessInfo.h"
+#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/UUID.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileCollector.h"
+#include "llvm/Support/YAMLTraits.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace lldb_private {
+namespace repro {
+
+/// The recorder is a small object handed out by a provider to record data. It
+/// is commonly used in combination with a MultiProvider which is meant to
+/// record information for multiple instances of the same source of data.
+class AbstractRecorder {
+protected:
+ AbstractRecorder(const FileSpec &filename, std::error_code &ec)
+ : m_filename(filename.GetFilename().GetStringRef()),
+ m_os(filename.GetPath(), ec, llvm::sys::fs::OF_Text), m_record(true) {}
+
+public:
+ const FileSpec &GetFilename() { return m_filename; }
+
+ void Stop() {
+ assert(m_record);
+ m_record = false;
+ }
+
+private:
+ FileSpec m_filename;
+
+protected:
+ llvm::raw_fd_ostream m_os;
+ bool m_record;
+};
+
+/// Recorder that records its data as text to a file.
+class DataRecorder : public AbstractRecorder {
+public:
+ DataRecorder(const FileSpec &filename, std::error_code &ec)
+ : AbstractRecorder(filename, ec) {}
+
+ static llvm::Expected<std::unique_ptr<DataRecorder>>
+ Create(const FileSpec &filename);
+
+ template <typename T> void Record(const T &t, bool newline = false) {
+ if (!m_record)
+ return;
+ m_os << t;
+ if (newline)
+ m_os << '\n';
+ m_os.flush();
+ }
+};
+
+/// Recorder that records its data as YAML to a file.
+class YamlRecorder : public AbstractRecorder {
+public:
+ YamlRecorder(const FileSpec &filename, std::error_code &ec)
+ : AbstractRecorder(filename, ec) {}
+
+ static llvm::Expected<std::unique_ptr<YamlRecorder>>
+ Create(const FileSpec &filename);
+
+ template <typename T> void Record(const T &t) {
+ if (!m_record)
+ return;
+ llvm::yaml::Output yout(m_os);
+ // The YAML traits are defined as non-const because they are used for
+ // serialization and deserialization. The cast is safe because
+ // serialization doesn't modify the object.
+ yout << const_cast<T &>(t);
+ m_os.flush();
+ }
+};
+
+class FlushingFileCollector : public llvm::FileCollectorBase {
+public:
+ FlushingFileCollector(llvm::StringRef files_path, llvm::StringRef dirs_path,
+ std::error_code &ec);
+
+protected:
+ void addFileImpl(llvm::StringRef file) override;
+
+ llvm::vfs::directory_iterator
+ addDirectoryImpl(const llvm::Twine &dir,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs,
+ std::error_code &dir_ec) override;
+
+ llvm::Optional<llvm::raw_fd_ostream> m_files_os;
+ llvm::Optional<llvm::raw_fd_ostream> m_dirs_os;
+};
+
+class FileProvider : public Provider<FileProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ FileProvider(const FileSpec &directory) : Provider(directory) {
+ std::error_code ec;
+ m_collector = std::make_shared<FlushingFileCollector>(
+ directory.CopyByAppendingPathComponent("files.txt").GetPath(),
+ directory.CopyByAppendingPathComponent("dirs.txt").GetPath(), ec);
+ if (ec)
+ m_collector.reset();
+ }
+
+ std::shared_ptr<llvm::FileCollectorBase> GetFileCollector() {
+ return m_collector;
+ }
+
+ void RecordInterestingDirectory(const llvm::Twine &dir);
+ void RecordInterestingDirectoryRecursive(const llvm::Twine &dir);
+
+ static char ID;
+
+private:
+ std::shared_ptr<FlushingFileCollector> m_collector;
+};
+
+/// Provider for the LLDB version number.
+///
+/// When the reproducer is kept, it writes the lldb version to a file named
+/// version.txt in the reproducer root.
+class VersionProvider : public Provider<VersionProvider> {
+public:
+ VersionProvider(const FileSpec &directory) : Provider(directory) {}
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ void SetVersion(std::string version) {
+ assert(m_version.empty());
+ m_version = std::move(version);
+ }
+ void Keep() override;
+ std::string m_version;
+ static char ID;
+};
+
+/// Abstract provider to storing directory paths.
+template <typename T> class DirectoryProvider : public repro::Provider<T> {
+public:
+ DirectoryProvider(const FileSpec &root) : Provider<T>(root) {}
+ void SetDirectory(std::string directory) {
+ m_directory = std::move(directory);
+ }
+ llvm::StringRef GetDirectory() { return m_directory; }
+
+ void Keep() override {
+ FileSpec file = this->GetRoot().CopyByAppendingPathComponent(T::Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ os << m_directory << "\n";
+ }
+
+protected:
+ std::string m_directory;
+};
+
+/// Provider for the current working directory.
+///
+/// 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 DirectoryProvider<WorkingDirectoryProvider> {
+public:
+ WorkingDirectoryProvider(const FileSpec &directory)
+ : DirectoryProvider(directory) {
+ llvm::SmallString<128> cwd;
+ if (std::error_code EC = llvm::sys::fs::current_path(cwd))
+ return;
+ SetDirectory(std::string(cwd));
+ }
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ static char ID;
+};
+
+/// Provider for the home directory.
+///
+/// When the reproducer is kept, it writes the user's home directory to a file
+/// a file named home.txt in the reproducer root.
+class HomeDirectoryProvider : public DirectoryProvider<HomeDirectoryProvider> {
+public:
+ HomeDirectoryProvider(const FileSpec &directory)
+ : DirectoryProvider(directory) {
+ llvm::SmallString<128> home_dir;
+ llvm::sys::path::home_directory(home_dir);
+ SetDirectory(std::string(home_dir));
+ }
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ static char ID;
+};
+
+/// Provider for mapping UUIDs to symbol and executable files.
+class SymbolFileProvider : public Provider<SymbolFileProvider> {
+public:
+ SymbolFileProvider(const FileSpec &directory)
+ : Provider(directory), m_symbol_files() {}
+
+ void AddSymbolFile(const UUID *uuid, const FileSpec &module_path,
+ const FileSpec &symbol_path);
+ void Keep() override;
+
+ struct Entry {
+ Entry() = default;
+ Entry(std::string uuid) : uuid(std::move(uuid)) {}
+ Entry(std::string uuid, std::string module_path, std::string symbol_path)
+ : uuid(std::move(uuid)), module_path(std::move(module_path)),
+ symbol_path(std::move(symbol_path)) {}
+
+ bool operator==(const Entry &rhs) const { return uuid == rhs.uuid; }
+ bool operator<(const Entry &rhs) const { return uuid < rhs.uuid; }
+
+ std::string uuid;
+ std::string module_path;
+ std::string symbol_path;
+ };
+
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+ static char ID;
+
+private:
+ std::vector<Entry> m_symbol_files;
+};
+
+/// The MultiProvider is a provider that hands out recorder which can be used
+/// to capture data for different instances of the same object. The recorders
+/// can be passed around or stored as an instance member.
+///
+/// The Info::file for the MultiProvider contains an index of files for every
+/// recorder. Use the MultiLoader to read the index and get the individual
+/// files.
+template <typename T, typename V>
+class MultiProvider : public repro::Provider<V> {
+public:
+ MultiProvider(const FileSpec &directory) : Provider<V>(directory) {}
+
+ T *GetNewRecorder() {
+ std::size_t i = m_recorders.size() + 1;
+ std::string filename = (llvm::Twine(V::Info::name) + llvm::Twine("-") +
+ llvm::Twine(i) + llvm::Twine(".yaml"))
+ .str();
+ auto recorder_or_error =
+ T::Create(this->GetRoot().CopyByAppendingPathComponent(filename));
+ if (!recorder_or_error) {
+ llvm::consumeError(recorder_or_error.takeError());
+ return nullptr;
+ }
+
+ m_recorders.push_back(std::move(*recorder_or_error));
+ return m_recorders.back().get();
+ }
+
+ void Keep() override {
+ std::vector<std::string> files;
+ for (auto &recorder : m_recorders) {
+ recorder->Stop();
+ files.push_back(recorder->GetFilename().GetPath());
+ }
+
+ FileSpec file = this->GetRoot().CopyByAppendingPathComponent(V::Info::file);
+ std::error_code ec;
+ llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
+ if (ec)
+ return;
+ llvm::yaml::Output yout(os);
+ yout << files;
+ }
+
+ void Discard() override { m_recorders.clear(); }
+
+private:
+ std::vector<std::unique_ptr<T>> m_recorders;
+};
+
+class CommandProvider : public MultiProvider<DataRecorder, CommandProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ CommandProvider(const FileSpec &directory)
+ : MultiProvider<DataRecorder, CommandProvider>(directory) {}
+
+ static char ID;
+};
+
+class ProcessInfoRecorder : public AbstractRecorder {
+public:
+ ProcessInfoRecorder(const FileSpec &filename, std::error_code &ec)
+ : AbstractRecorder(filename, ec) {}
+
+ static llvm::Expected<std::unique_ptr<ProcessInfoRecorder>>
+ Create(const FileSpec &filename);
+
+ void Record(const ProcessInstanceInfoList &process_infos);
+};
+
+class ProcessInfoProvider : public repro::Provider<ProcessInfoProvider> {
+public:
+ struct Info {
+ static const char *name;
+ static const char *file;
+ };
+
+ ProcessInfoProvider(const FileSpec &directory) : Provider(directory) {}
+
+ ProcessInfoRecorder *GetNewProcessInfoRecorder();
+
+ void Keep() override;
+ void Discard() override;
+
+ static char ID;
+
+private:
+ std::unique_ptr<llvm::raw_fd_ostream> m_stream_up;
+ std::vector<std::unique_ptr<ProcessInfoRecorder>> m_process_info_recorders;
+};
+
+/// Loader for data captured with the MultiProvider. It will read the index and
+/// return the path to the files in the index.
+template <typename T> class MultiLoader {
+public:
+ MultiLoader(std::vector<std::string> files) : m_files(std::move(files)) {}
+
+ static std::unique_ptr<MultiLoader> Create(Loader *loader) {
+ if (!loader)
+ return {};
+
+ FileSpec file = loader->GetFile<typename T::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<MultiLoader<T>>(std::move(files));
+ }
+
+ llvm::Optional<std::string> GetNextFile() {
+ if (m_index >= m_files.size())
+ return {};
+ return m_files[m_index++];
+ }
+
+private:
+ std::vector<std::string> m_files;
+ unsigned m_index = 0;
+};
+
+class SymbolFileLoader {
+public:
+ SymbolFileLoader(Loader *loader);
+ std::pair<FileSpec, FileSpec> GetPaths(const UUID *uuid) const;
+
+private:
+ // Sorted list of UUID to path mappings.
+ std::vector<SymbolFileProvider::Entry> m_symbol_files;
+};
+
+/// Helper to read directories written by the DirectoryProvider.
+template <typename T>
+llvm::Expected<std::string> GetDirectoryFrom(repro::Loader *loader) {
+ llvm::Expected<std::string> dir = loader->LoadBuffer<T>();
+ if (!dir)
+ return dir.takeError();
+ return std::string(llvm::StringRef(*dir).rtrim());
+}
+
+} // namespace repro
+} // namespace lldb_private
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::repro::SymbolFileProvider::Entry)
+
+namespace llvm {
+namespace yaml {
+template <>
+struct MappingTraits<lldb_private::repro::SymbolFileProvider::Entry> {
+ static void mapping(IO &io,
+ lldb_private::repro::SymbolFileProvider::Entry &entry) {
+ io.mapRequired("uuid", entry.uuid);
+ io.mapRequired("module-path", entry.module_path);
+ io.mapRequired("symbol-path", entry.symbol_path);
+ }
+};
+} // namespace yaml
+} // namespace llvm
+
+#endif // LLDB_UTILITY_REPRODUCER_PROVIDER_H
diff --git a/linux-x64/clang/include/lldb/Utility/Scalar.h b/linux-x64/clang/include/lldb/Utility/Scalar.h
index 62ee9f6..f797aaf 100644
--- a/linux-x64/clang/include/lldb/Utility/Scalar.h
+++ b/linux-x64/clang/include/lldb/Utility/Scalar.h
@@ -9,118 +9,68 @@
#ifndef LLDB_UTILITY_SCALAR_H
#define LLDB_UTILITY_SCALAR_H
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-types.h"
-#include "lldb/Utility/LLDBAssert.h"
#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
#include <cstddef>
#include <cstdint>
+#include <utility>
namespace lldb_private {
+
class DataExtractor;
class Stream;
-} // namespace lldb_private
#define NUM_OF_WORDS_INT128 2
#define BITWIDTH_INT128 128
-#define NUM_OF_WORDS_INT256 4
-#define BITWIDTH_INT256 256
-#define NUM_OF_WORDS_INT512 8
-#define BITWIDTH_INT512 512
-
-namespace lldb_private {
// A class designed to hold onto values and their corresponding types.
// Operators are defined and Scalar objects will correctly promote their types
// and values before performing these operations. Type promotion currently
// follows the ANSI C type promotion rules.
class Scalar {
+ template<typename T>
+ static llvm::APSInt MakeAPSInt(T v) {
+ static_assert(std::is_integral<T>::value, "");
+ static_assert(sizeof(T) <= sizeof(uint64_t), "Conversion loses precision!");
+ return llvm::APSInt(
+ llvm::APInt(sizeof(T) * 8, uint64_t(v), std::is_signed<T>::value),
+ std::is_unsigned<T>::value);
+ }
+
public:
enum Type {
e_void = 0,
- e_sint,
- e_uint,
- e_slong,
- e_ulong,
- e_slonglong,
- e_ulonglong,
- e_sint128,
- e_uint128,
- e_sint256,
- e_uint256,
- e_sint512,
- e_uint512,
+ e_int,
e_float,
- e_double,
- e_long_double
};
// Constructors and Destructors
- Scalar();
- Scalar(int v) : m_type(e_sint), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(int) * 8, v, true);
- }
- Scalar(unsigned int v) : m_type(e_uint), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(int) * 8, v);
- }
- Scalar(long v) : m_type(e_slong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long) * 8, v, true);
- }
- Scalar(unsigned long v) : m_type(e_ulong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long) * 8, v);
- }
- Scalar(long long v) : m_type(e_slonglong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long long) * 8, v, true);
- }
+ Scalar() : m_type(e_void), m_float(0.0f) {}
+ Scalar(int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(unsigned int v)
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(long v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(unsigned long v)
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(long long v)
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
Scalar(unsigned long long v)
- : m_type(e_ulonglong), m_float(static_cast<float>(0)) {
- m_integer = llvm::APInt(sizeof(long long) * 8, v);
+ : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+ Scalar(float v) : m_type(e_float), m_float(v) {}
+ Scalar(double v) : m_type(e_float), m_float(v) {}
+ Scalar(long double v) : m_type(e_float), m_float(double(v)) {
+ bool ignore;
+ m_float.convert(llvm::APFloat::x87DoubleExtended(),
+ llvm::APFloat::rmNearestTiesToEven, &ignore);
}
- Scalar(float v) : m_type(e_float), m_float(v) { m_float = llvm::APFloat(v); }
- Scalar(double v) : m_type(e_double), m_float(v) {
- m_float = llvm::APFloat(v);
- }
- Scalar(long double v, bool ieee_quad)
- : m_type(e_long_double), m_float(static_cast<float>(0)),
- m_ieee_quad(ieee_quad) {
- if (ieee_quad)
- m_float =
- llvm::APFloat(llvm::APFloat::IEEEquad(),
- llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
- (reinterpret_cast<type128 *>(&v))->x));
- else
- m_float =
- llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
- llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
- (reinterpret_cast<type128 *>(&v))->x));
- }
- 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");
- }
- // Scalar(const RegisterValue& reg_value);
- virtual ~Scalar();
+ Scalar(llvm::APInt v)
+ : m_type(e_int), m_integer(std::move(v), false), m_float(0.0f) {}
+ Scalar(llvm::APSInt v)
+ : m_type(e_int), m_integer(std::move(v)), m_float(0.0f) {}
bool SignExtend(uint32_t bit_pos);
@@ -130,7 +80,10 @@
bool ClearBit(uint32_t bit);
- const void *GetBytes() const;
+ /// Store the binary representation of this value into the given storage.
+ /// Exactly GetByteSize() bytes will be stored, and the buffer must be large
+ /// enough to hold this data.
+ void GetBytes(llvm::MutableArrayRef<uint8_t> storage) const;
size_t GetByteSize() const;
@@ -146,46 +99,30 @@
m_integer.clearAllBits();
}
- const char *GetTypeAsCString() const;
+ const char *GetTypeAsCString() const { return GetValueTypeAsCString(m_type); }
void GetValue(Stream *s, bool show_type) const;
- bool IsValid() const {
- return (m_type >= e_sint) && (m_type <= e_long_double);
- }
+ bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); }
- bool Promote(Scalar::Type type);
+ /// Convert to an integer with \p bits and the given signedness.
+ void TruncOrExtendTo(uint16_t bits, bool sign);
+ bool IntegralPromote(uint16_t bits, bool sign);
+ bool FloatPromote(const llvm::fltSemantics &semantics);
+
+ bool IsSigned() const;
bool MakeSigned();
bool MakeUnsigned();
static const char *GetValueTypeAsCString(Scalar::Type value_type);
- static Scalar::Type
- GetValueTypeForSignedIntegerWithByteSize(size_t byte_size);
-
- static Scalar::Type
- GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size);
-
- static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size);
-
// All operators can benefits from the implicit conversions that will happen
// automagically by the compiler, so no temporary objects will need to be
// created. As a result, we currently don't need a variety of overloaded set
// value accessors.
- Scalar &operator=(const int i);
- Scalar &operator=(unsigned int v);
- Scalar &operator=(long v);
- Scalar &operator=(unsigned long v);
- Scalar &operator=(long long v);
- Scalar &operator=(unsigned long long v);
- Scalar &operator=(float v);
- Scalar &operator=(double v);
- Scalar &operator=(long double v);
- Scalar &operator=(llvm::APInt v);
- Scalar &operator=(const Scalar &rhs); // Assignment operator
- Scalar &operator+=(const Scalar &rhs);
+ Scalar &operator+=(Scalar rhs);
Scalar &operator<<=(const Scalar &rhs); // Shift left
Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic)
Scalar &operator&=(const Scalar &rhs);
@@ -217,7 +154,7 @@
unsigned char UChar(unsigned char fail_value = 0) const;
- signed char SChar(char fail_value = 0) const;
+ signed char SChar(signed char fail_value = 0) const;
unsigned short UShort(unsigned short fail_value = 0) const;
@@ -233,7 +170,7 @@
unsigned long long ULongLong(unsigned long long fail_value = 0) const;
- llvm::APInt SInt128(llvm::APInt &fail_value) const;
+ llvm::APInt SInt128(const llvm::APInt &fail_value) const;
llvm::APInt UInt128(const llvm::APInt &fail_value) const;
@@ -246,71 +183,37 @@
Status SetValueFromCString(const char *s, lldb::Encoding encoding,
size_t byte_size);
- Status SetValueFromData(DataExtractor &data, lldb::Encoding encoding,
+ Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding,
size_t byte_size);
- static bool UIntValueIsValidForSize(uint64_t uval64, size_t total_byte_size) {
- if (total_byte_size > 8)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const uint64_t max = (static_cast<uint64_t>(1)
- << static_cast<uint64_t>(total_byte_size * 8)) -
- 1;
- return uval64 <= max;
- }
-
- static bool SIntValueIsValidForSize(int64_t sval64, size_t total_byte_size) {
- if (total_byte_size > 8)
- return false;
-
- if (total_byte_size == 8)
- return true;
-
- const int64_t max = (static_cast<int64_t>(1)
- << static_cast<uint64_t>(total_byte_size * 8 - 1)) -
- 1;
- const int64_t min = ~(max);
- return min <= sval64 && sval64 <= max;
- }
-
protected:
- typedef char schar_t;
- typedef unsigned char uchar_t;
- typedef short sshort_t;
- typedef unsigned short ushort_t;
- typedef int sint_t;
- typedef unsigned int uint_t;
- typedef long slong_t;
- typedef unsigned long ulong_t;
- typedef long long slonglong_t;
- typedef unsigned long long ulonglong_t;
- typedef float float_t;
- typedef double double_t;
- typedef long double long_double_t;
-
- // Classes that inherit from Scalar can see and modify these
Scalar::Type m_type;
- llvm::APInt m_integer;
+ llvm::APSInt m_integer;
llvm::APFloat m_float;
- bool m_ieee_quad = false;
+
+ template <typename T> T GetAs(T fail_value) const;
+
+ static Type PromoteToMaxType(Scalar &lhs, Scalar &rhs);
+
+ using PromotionKey = std::tuple<Type, unsigned, bool>;
+ PromotionKey GetPromoKey() const;
+
+ static PromotionKey GetFloatPromoKey(const llvm::fltSemantics &semantics);
private:
friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator-(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator/(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator*(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator&(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator|(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator%(const Scalar &lhs, const Scalar &rhs);
- friend const Scalar operator^(const Scalar &lhs, const Scalar &rhs);
+ friend const Scalar operator-(Scalar lhs, Scalar rhs);
+ friend const Scalar operator/(Scalar lhs, Scalar rhs);
+ friend const Scalar operator*(Scalar lhs, Scalar rhs);
+ friend const Scalar operator&(Scalar lhs, Scalar rhs);
+ friend const Scalar operator|(Scalar lhs, Scalar rhs);
+ friend const Scalar operator%(Scalar lhs, Scalar rhs);
+ friend const Scalar operator^(Scalar lhs, Scalar rhs);
friend const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
friend const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
- friend bool operator==(const Scalar &lhs, const Scalar &rhs);
+ friend bool operator==(Scalar lhs, Scalar rhs);
friend bool operator!=(const Scalar &lhs, const Scalar &rhs);
- friend bool operator<(const Scalar &lhs, const Scalar &rhs);
+ friend bool operator<(Scalar lhs, Scalar rhs);
friend bool operator<=(const Scalar &lhs, const Scalar &rhs);
friend bool operator>(const Scalar &lhs, const Scalar &rhs);
friend bool operator>=(const Scalar &lhs, const Scalar &rhs);
@@ -330,18 +233,18 @@
// Differentiate among members functions, non-member functions, and
// friend functions
const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator-(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator/(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator*(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator&(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator|(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator%(const Scalar &lhs, const Scalar &rhs);
-const Scalar operator^(const Scalar &lhs, const Scalar &rhs);
+const Scalar operator-(Scalar lhs, Scalar rhs);
+const Scalar operator/(Scalar lhs, Scalar rhs);
+const Scalar operator*(Scalar lhs, Scalar rhs);
+const Scalar operator&(Scalar lhs, Scalar rhs);
+const Scalar operator|(Scalar lhs, Scalar rhs);
+const Scalar operator%(Scalar lhs, Scalar rhs);
+const Scalar operator^(Scalar lhs, Scalar rhs);
const Scalar operator<<(const Scalar &lhs, const Scalar &rhs);
const Scalar operator>>(const Scalar &lhs, const Scalar &rhs);
-bool operator==(const Scalar &lhs, const Scalar &rhs);
+bool operator==(Scalar lhs, Scalar rhs);
bool operator!=(const Scalar &lhs, const Scalar &rhs);
-bool operator<(const Scalar &lhs, const Scalar &rhs);
+bool operator<(Scalar lhs, Scalar rhs);
bool operator<=(const Scalar &lhs, const Scalar &rhs);
bool operator>(const Scalar &lhs, const Scalar &rhs);
bool operator>=(const Scalar &lhs, const Scalar &rhs);
diff --git a/linux-x64/clang/include/lldb/Utility/SelectHelper.h b/linux-x64/clang/include/lldb/Utility/SelectHelper.h
index ec37f19..63f1fe6 100644
--- a/linux-x64/clang/include/lldb/Utility/SelectHelper.h
+++ b/linux-x64/clang/include/lldb/Utility/SelectHelper.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_SelectHelper_h_
-#define liblldb_SelectHelper_h_
+#ifndef LLDB_UTILITY_SELECTHELPER_H
+#define LLDB_UTILITY_SELECTHELPER_H
#include "lldb/Utility/Status.h"
#include "lldb/lldb-types.h"
@@ -68,4 +68,4 @@
llvm::Optional<std::chrono::steady_clock::time_point> m_end_time;
};
-#endif // liblldb_SelectHelper_h_
+#endif // LLDB_UTILITY_SELECTHELPER_H
diff --git a/linux-x64/clang/include/lldb/Utility/SharedCluster.h b/linux-x64/clang/include/lldb/Utility/SharedCluster.h
index 71bbb33..375c1c1 100644
--- a/linux-x64/clang/include/lldb/Utility/SharedCluster.h
+++ b/linux-x64/clang/include/lldb/Utility/SharedCluster.h
@@ -6,90 +6,54 @@
//
//===----------------------------------------------------------------------===//
-#ifndef utility_SharedCluster_h_
-#define utility_SharedCluster_h_
+#ifndef LLDB_UTILITY_SHAREDCLUSTER_H
+#define LLDB_UTILITY_SHAREDCLUSTER_H
#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/SharingPtr.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-
+#include <memory>
#include <mutex>
namespace lldb_private {
-namespace imp {
-template <typename T>
-class shared_ptr_refcount : public lldb_private::imp::shared_count {
+template <class T>
+class ClusterManager : public std::enable_shared_from_this<ClusterManager<T>> {
public:
- template <class Y>
- shared_ptr_refcount(Y *in) : shared_count(0), manager(in) {}
-
- shared_ptr_refcount() : shared_count(0) {}
-
- ~shared_ptr_refcount() override {}
-
- void on_zero_shared() override { manager->DecrementRefCount(); }
-
-private:
- T *manager;
-};
-
-} // namespace imp
-
-template <class T> class ClusterManager {
-public:
- ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {}
+ static std::shared_ptr<ClusterManager> Create() {
+ return std::shared_ptr<ClusterManager>(new ClusterManager());
+ }
~ClusterManager() {
- for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(),
- end = m_objects.end();
- pos != end; ++pos) {
- T *object = *pos;
- delete object;
- }
-
- // Decrement refcount should have been called on this ClusterManager, and
- // it should have locked the mutex, now we will unlock it before we destroy
- // it...
- m_mutex.unlock();
+ for (T *obj : m_objects)
+ delete obj;
}
void ManageObject(T *new_object) {
std::lock_guard<std::mutex> guard(m_mutex);
- m_objects.insert(new_object);
+ assert(!llvm::is_contained(m_objects, new_object) &&
+ "ManageObject called twice for the same object?");
+ m_objects.push_back(new_object);
}
- typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) {
- {
- std::lock_guard<std::mutex> guard(m_mutex);
- m_external_ref++;
- if (0 == m_objects.count(desired_object)) {
- lldbassert(false && "object not found in shared cluster when expected");
- desired_object = nullptr;
- }
+ std::shared_ptr<T> GetSharedPointer(T *desired_object) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ auto this_sp = this->shared_from_this();
+ if (!llvm::is_contained(m_objects, desired_object)) {
+ lldbassert(false && "object not found in shared cluster when expected");
+ desired_object = nullptr;
}
- return typename lldb_private::SharingPtr<T>(
- desired_object, new imp::shared_ptr_refcount<ClusterManager>(this));
+ return {std::move(this_sp), desired_object};
}
private:
- void DecrementRefCount() {
- m_mutex.lock();
- m_external_ref--;
- if (m_external_ref == 0)
- delete this;
- else
- m_mutex.unlock();
- }
+ ClusterManager() : m_objects(), m_mutex() {}
- friend class imp::shared_ptr_refcount<ClusterManager>;
-
- llvm::SmallPtrSet<T *, 16> m_objects;
- int m_external_ref;
+ llvm::SmallVector<T *, 16> m_objects;
std::mutex m_mutex;
};
} // namespace lldb_private
-#endif // utility_SharedCluster_h_
+#endif // LLDB_UTILITY_SHAREDCLUSTER_H
diff --git a/linux-x64/clang/include/lldb/Utility/SharingPtr.h b/linux-x64/clang/include/lldb/Utility/SharingPtr.h
deleted file mode 100644
index e4ab3d2..0000000
--- a/linux-x64/clang/include/lldb/Utility/SharingPtr.h
+++ /dev/null
@@ -1,609 +0,0 @@
-//===---------------------SharingPtr.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_SharingPtr_h_
-#define utility_SharingPtr_h_
-
-#include <memory>
-
-// Microsoft Visual C++ currently does not enable std::atomic to work in CLR
-// mode - as such we need to "hack around it" for MSVC++ builds only using
-// Windows specific intrinsics instead of the C++11 atomic support
-#ifdef _MSC_VER
-#include <intrin.h>
-#else
-#include <atomic>
-#endif
-
-#include <stddef.h>
-
-
-//#define ENABLE_SP_LOGGING 1 // DON'T CHECK THIS LINE IN UNLESS COMMENTED OUT
-#if defined(ENABLE_SP_LOGGING)
-
-extern "C" void track_sp(void *sp_this, void *ptr, long count);
-
-#endif
-
-namespace lldb_private {
-
-namespace imp {
-
-class shared_count {
- shared_count(const shared_count &) = delete;
- shared_count &operator=(const shared_count &) = delete;
-
-public:
- explicit shared_count(long refs = 0) : shared_owners_(refs) {}
-
- void add_shared();
- void release_shared();
- long use_count() const { return shared_owners_ + 1; }
-
-protected:
-#ifdef _MSC_VER
- long shared_owners_;
-#else
- std::atomic<long> shared_owners_;
-#endif
- virtual ~shared_count();
-
-private:
- virtual void on_zero_shared() = 0;
-};
-
-template <class T> class shared_ptr_pointer : public shared_count {
- T data_;
-
-public:
- shared_ptr_pointer(T p) : data_(p) {}
-
-private:
- void on_zero_shared() override;
-
- shared_ptr_pointer(const shared_ptr_pointer &) = delete;
- shared_ptr_pointer &operator=(const shared_ptr_pointer &) = delete;
-};
-
-template <class T> void shared_ptr_pointer<T>::on_zero_shared() {
- delete data_;
-}
-
-template <class T> class shared_ptr_emplace : public shared_count {
- T data_;
-
-public:
- shared_ptr_emplace() : data_() {}
-
- template <class A0> shared_ptr_emplace(A0 &a0) : data_(a0) {}
-
- template <class A0, class A1>
- shared_ptr_emplace(A0 &a0, A1 &a1) : data_(a0, a1) {}
-
- template <class A0, class A1, class A2>
- shared_ptr_emplace(A0 &a0, A1 &a1, A2 &a2) : data_(a0, a1, a2) {}
-
- template <class A0, class A1, class A2, class A3>
- shared_ptr_emplace(A0 &a0, A1 &a1, A2 &a2, A3 &a3) : data_(a0, a1, a2, a3) {}
-
- template <class A0, class A1, class A2, class A3, class A4>
- shared_ptr_emplace(A0 &a0, A1 &a1, A2 &a2, A3 &a3, A4 &a4)
- : data_(a0, a1, a2, a3, a4) {}
-
-private:
- void on_zero_shared() override;
-
-public:
- T *get() { return &data_; }
-};
-
-template <class T> void shared_ptr_emplace<T>::on_zero_shared() {}
-
-} // namespace imp
-
-template <class T> class SharingPtr {
-public:
- typedef T element_type;
-
-private:
- element_type *ptr_;
- imp::shared_count *cntrl_;
-
- struct nat {
- int for_bool_;
- };
-
-public:
- SharingPtr();
- SharingPtr(std::nullptr_t);
- template <class Y> explicit SharingPtr(Y *p);
- template <class Y> explicit SharingPtr(Y *p, imp::shared_count *ctrl_block);
- template <class Y> SharingPtr(const SharingPtr<Y> &r, element_type *p);
- SharingPtr(const SharingPtr &r);
- template <class Y> SharingPtr(const SharingPtr<Y> &r);
-
- ~SharingPtr();
-
- SharingPtr &operator=(const SharingPtr &r);
- template <class Y> SharingPtr &operator=(const SharingPtr<Y> &r);
-
- void swap(SharingPtr &r);
- void reset();
- template <class Y> void reset(Y *p);
- void reset(std::nullptr_t);
-
- element_type *get() const { return ptr_; }
- element_type &operator*() const { return *ptr_; }
- element_type *operator->() const { return ptr_; }
- long use_count() const { return cntrl_ ? cntrl_->use_count() : 0; }
- bool unique() const { return use_count() == 1; }
- bool empty() const { return cntrl_ == nullptr; }
- operator nat *() const { return (nat *)get(); }
-
- static SharingPtr<T> make_shared();
-
- template <class A0> static SharingPtr<T> make_shared(A0 &);
-
- template <class A0, class A1> static SharingPtr<T> make_shared(A0 &, A1 &);
-
- template <class A0, class A1, class A2>
- static SharingPtr<T> make_shared(A0 &, A1 &, A2 &);
-
- template <class A0, class A1, class A2, class A3>
- static SharingPtr<T> make_shared(A0 &, A1 &, A2 &, A3 &);
-
- template <class A0, class A1, class A2, class A3, class A4>
- static SharingPtr<T> make_shared(A0 &, A1 &, A2 &, A3 &, A4 &);
-
-private:
- template <class U> friend class SharingPtr;
-};
-
-template <class T>
-inline SharingPtr<T>::SharingPtr() : ptr_(nullptr), cntrl_(nullptr) {}
-
-template <class T>
-inline SharingPtr<T>::SharingPtr(std::nullptr_t)
- : ptr_(nullptr), cntrl_(nullptr) {}
-
-template <class T>
-template <class Y>
-SharingPtr<T>::SharingPtr(Y *p) : ptr_(p), cntrl_(nullptr) {
- std::unique_ptr<Y> hold(p);
- typedef imp::shared_ptr_pointer<Y *> _CntrlBlk;
- cntrl_ = new _CntrlBlk(p);
- hold.release();
-}
-
-template <class T>
-template <class Y>
-SharingPtr<T>::SharingPtr(Y *p, imp::shared_count *cntrl_block)
- : ptr_(p), cntrl_(cntrl_block) {}
-
-template <class T>
-template <class Y>
-inline SharingPtr<T>::SharingPtr(const SharingPtr<Y> &r, element_type *p)
- : ptr_(p), cntrl_(r.cntrl_) {
- if (cntrl_)
- cntrl_->add_shared();
-}
-
-template <class T>
-inline SharingPtr<T>::SharingPtr(const SharingPtr &r)
- : ptr_(r.ptr_), cntrl_(r.cntrl_) {
- if (cntrl_)
- cntrl_->add_shared();
-}
-
-template <class T>
-template <class Y>
-inline SharingPtr<T>::SharingPtr(const SharingPtr<Y> &r)
- : ptr_(r.ptr_), cntrl_(r.cntrl_) {
- if (cntrl_)
- cntrl_->add_shared();
-}
-
-template <class T> SharingPtr<T>::~SharingPtr() {
- if (cntrl_)
- cntrl_->release_shared();
-}
-
-template <class T>
-inline SharingPtr<T> &SharingPtr<T>::operator=(const SharingPtr &r) {
- SharingPtr(r).swap(*this);
- return *this;
-}
-
-template <class T>
-template <class Y>
-inline SharingPtr<T> &SharingPtr<T>::operator=(const SharingPtr<Y> &r) {
- SharingPtr(r).swap(*this);
- return *this;
-}
-
-template <class T> inline void SharingPtr<T>::swap(SharingPtr &r) {
- std::swap(ptr_, r.ptr_);
- std::swap(cntrl_, r.cntrl_);
-}
-
-template <class T> inline void SharingPtr<T>::reset() {
- SharingPtr().swap(*this);
-}
-
-template <class T> inline void SharingPtr<T>::reset(std::nullptr_t p) {
- reset();
-}
-
-template <class T> template <class Y> inline void SharingPtr<T>::reset(Y *p) {
- SharingPtr(p).swap(*this);
-}
-
-template <class T> SharingPtr<T> SharingPtr<T>::make_shared() {
- typedef imp::shared_ptr_emplace<T> CntrlBlk;
- SharingPtr<T> r;
- r.cntrl_ = new CntrlBlk();
- r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get();
- return r;
-}
-
-template <class T>
-template <class A0>
-SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0) {
- typedef imp::shared_ptr_emplace<T> CntrlBlk;
- SharingPtr<T> r;
- r.cntrl_ = new CntrlBlk(a0);
- r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get();
- return r;
-}
-
-template <class T>
-template <class A0, class A1>
-SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1) {
- typedef imp::shared_ptr_emplace<T> CntrlBlk;
- SharingPtr<T> r;
- r.cntrl_ = new CntrlBlk(a0, a1);
- r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get();
- return r;
-}
-
-template <class T>
-template <class A0, class A1, class A2>
-SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1, A2 &a2) {
- typedef imp::shared_ptr_emplace<T> CntrlBlk;
- SharingPtr<T> r;
- r.cntrl_ = new CntrlBlk(a0, a1, a2);
- r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get();
- return r;
-}
-
-template <class T>
-template <class A0, class A1, class A2, class A3>
-SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3) {
- typedef imp::shared_ptr_emplace<T> CntrlBlk;
- SharingPtr<T> r;
- r.cntrl_ = new CntrlBlk(a0, a1, a2, a3);
- r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get();
- return r;
-}
-
-template <class T>
-template <class A0, class A1, class A2, class A3, class A4>
-SharingPtr<T> SharingPtr<T>::make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3,
- A4 &a4) {
- typedef imp::shared_ptr_emplace<T> CntrlBlk;
- SharingPtr<T> r;
- r.cntrl_ = new CntrlBlk(a0, a1, a2, a3, a4);
- r.ptr_ = static_cast<CntrlBlk *>(r.cntrl_)->get();
- return r;
-}
-
-template <class T> inline SharingPtr<T> make_shared() {
- return SharingPtr<T>::make_shared();
-}
-
-template <class T, class A0> inline SharingPtr<T> make_shared(A0 &a0) {
- return SharingPtr<T>::make_shared(a0);
-}
-
-template <class T, class A0, class A1>
-inline SharingPtr<T> make_shared(A0 &a0, A1 &a1) {
- return SharingPtr<T>::make_shared(a0, a1);
-}
-
-template <class T, class A0, class A1, class A2>
-inline SharingPtr<T> make_shared(A0 &a0, A1 &a1, A2 &a2) {
- return SharingPtr<T>::make_shared(a0, a1, a2);
-}
-
-template <class T, class A0, class A1, class A2, class A3>
-inline SharingPtr<T> make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3) {
- return SharingPtr<T>::make_shared(a0, a1, a2, a3);
-}
-
-template <class T, class A0, class A1, class A2, class A3, class A4>
-inline SharingPtr<T> make_shared(A0 &a0, A1 &a1, A2 &a2, A3 &a3, A4 &a4) {
- return SharingPtr<T>::make_shared(a0, a1, a2, a3, a4);
-}
-
-template <class T, class U>
-inline bool operator==(const SharingPtr<T> &__x, const SharingPtr<U> &__y) {
- return __x.get() == __y.get();
-}
-
-template <class T, class U>
-inline bool operator!=(const SharingPtr<T> &__x, const SharingPtr<U> &__y) {
- return !(__x == __y);
-}
-
-template <class T, class U>
-inline bool operator<(const SharingPtr<T> &__x, const SharingPtr<U> &__y) {
- return __x.get() < __y.get();
-}
-
-template <class T> inline void swap(SharingPtr<T> &__x, SharingPtr<T> &__y) {
- __x.swap(__y);
-}
-
-template <class T, class U>
-inline SharingPtr<T> static_pointer_cast(const SharingPtr<U> &r) {
- return SharingPtr<T>(r, static_cast<T *>(r.get()));
-}
-
-template <class T, class U>
-SharingPtr<T> const_pointer_cast(const SharingPtr<U> &r) {
- return SharingPtr<T>(r, const_cast<T *>(r.get()));
-}
-
-template <class T> class LoggingSharingPtr : public SharingPtr<T> {
- typedef SharingPtr<T> base;
-
-public:
- typedef void (*Callback)(void *, const LoggingSharingPtr &, bool action);
- // action: false means increment just happened
- // true means decrement is about to happen
-
- LoggingSharingPtr() : cb_(0), baton_(nullptr) {}
-
- LoggingSharingPtr(Callback cb, void *baton) : cb_(cb), baton_(baton) {
- if (cb_)
- cb_(baton_, *this, false);
- }
-
- template <class Y>
- LoggingSharingPtr(Y *p) : base(p), cb_(0), baton_(nullptr) {}
-
- template <class Y>
- LoggingSharingPtr(Y *p, Callback cb, void *baton)
- : base(p), cb_(cb), baton_(baton) {
- if (cb_)
- cb_(baton_, *this, false);
- }
-
- ~LoggingSharingPtr() {
- if (cb_)
- cb_(baton_, *this, true);
- }
-
- LoggingSharingPtr(const LoggingSharingPtr &p)
- : base(p), cb_(p.cb_), baton_(p.baton_) {
- if (cb_)
- cb_(baton_, *this, false);
- }
-
- LoggingSharingPtr &operator=(const LoggingSharingPtr &p) {
- if (cb_)
- cb_(baton_, *this, true);
- base::operator=(p);
- cb_ = p.cb_;
- baton_ = p.baton_;
- if (cb_)
- cb_(baton_, *this, false);
- return *this;
- }
-
- void reset() {
- if (cb_)
- cb_(baton_, *this, true);
- base::reset();
- }
-
- template <class Y> void reset(Y *p) {
- if (cb_)
- cb_(baton_, *this, true);
- base::reset(p);
- if (cb_)
- cb_(baton_, *this, false);
- }
-
- void SetCallback(Callback cb, void *baton) {
- cb_ = cb;
- baton_ = baton;
- }
-
- void ClearCallback() {
- cb_ = 0;
- baton_ = 0;
- }
-
-private:
- Callback cb_;
- void *baton_;
-};
-
-template <class T> class IntrusiveSharingPtr;
-
-template <class T> class ReferenceCountedBase {
-public:
- explicit ReferenceCountedBase() : shared_owners_(-1) {}
-
- void add_shared();
-
- void release_shared();
-
- long use_count() const { return shared_owners_ + 1; }
-
-protected:
- long shared_owners_;
-
- friend class IntrusiveSharingPtr<T>;
-
-private:
- ReferenceCountedBase(const ReferenceCountedBase &) = delete;
- ReferenceCountedBase &operator=(const ReferenceCountedBase &) = delete;
-};
-
-template <class T> void lldb_private::ReferenceCountedBase<T>::add_shared() {
-#ifdef _MSC_VER
- _InterlockedIncrement(&shared_owners_);
-#else
- ++shared_owners_;
-#endif
-}
-
-template <class T>
-void lldb_private::ReferenceCountedBase<T>::release_shared() {
-#ifdef _MSC_VER
- if (_InterlockedDecrement(&shared_owners_) == -1)
-#else
- if (--shared_owners_ == -1)
-#endif
- delete static_cast<T *>(this);
-}
-
-template <class T>
-class ReferenceCountedBaseVirtual : public imp::shared_count {
-public:
- explicit ReferenceCountedBaseVirtual() : imp::shared_count(-1) {}
-
- ~ReferenceCountedBaseVirtual() override = default;
-
- void on_zero_shared() override;
-};
-
-template <class T> void ReferenceCountedBaseVirtual<T>::on_zero_shared() {}
-
-template <typename T> class IntrusiveSharingPtr {
-public:
- typedef T element_type;
-
- explicit IntrusiveSharingPtr() : ptr_(0) {}
-
- explicit IntrusiveSharingPtr(T *ptr) : ptr_(ptr) { add_shared(); }
-
- IntrusiveSharingPtr(const IntrusiveSharingPtr &rhs) : ptr_(rhs.ptr_) {
- add_shared();
- }
-
- template <class X>
- IntrusiveSharingPtr(const IntrusiveSharingPtr<X> &rhs) : ptr_(rhs.get()) {
- add_shared();
- }
-
- IntrusiveSharingPtr &operator=(const IntrusiveSharingPtr &rhs) {
- reset(rhs.get());
- return *this;
- }
-
- template <class X>
- IntrusiveSharingPtr &operator=(const IntrusiveSharingPtr<X> &rhs) {
- reset(rhs.get());
- return *this;
- }
-
- IntrusiveSharingPtr &operator=(T *ptr) {
- reset(ptr);
- return *this;
- }
-
- ~IntrusiveSharingPtr() {
- release_shared();
- ptr_ = nullptr;
- }
-
- T &operator*() const { return *ptr_; }
-
- T *operator->() const { return ptr_; }
-
- T *get() const { return ptr_; }
-
- explicit operator bool() const { return ptr_ != 0; }
-
- void swap(IntrusiveSharingPtr &rhs) {
- std::swap(ptr_, rhs.ptr_);
-#if defined(ENABLE_SP_LOGGING)
- track_sp(this, ptr_, use_count());
- track_sp(&rhs, rhs.ptr_, rhs.use_count());
-#endif
- }
-
- void reset(T *ptr = nullptr) { IntrusiveSharingPtr(ptr).swap(*this); }
-
- long use_count() const {
- if (ptr_)
- return ptr_->use_count();
- return 0;
- }
-
- bool unique() const { return use_count() == 1; }
-
-private:
- element_type *ptr_;
-
- void add_shared() {
- if (ptr_) {
- ptr_->add_shared();
-#if defined(ENABLE_SP_LOGGING)
- track_sp(this, ptr_, ptr_->use_count());
-#endif
- }
- }
- void release_shared() {
- if (ptr_) {
-#if defined(ENABLE_SP_LOGGING)
- track_sp(this, nullptr, ptr_->use_count() - 1);
-#endif
- ptr_->release_shared();
- }
- }
-};
-
-template <class T, class U>
-inline bool operator==(const IntrusiveSharingPtr<T> &lhs,
- const IntrusiveSharingPtr<U> &rhs) {
- return lhs.get() == rhs.get();
-}
-
-template <class T, class U>
-inline bool operator!=(const IntrusiveSharingPtr<T> &lhs,
- const IntrusiveSharingPtr<U> &rhs) {
- return lhs.get() != rhs.get();
-}
-
-template <class T, class U>
-inline bool operator==(const IntrusiveSharingPtr<T> &lhs, U *rhs) {
- return lhs.get() == rhs;
-}
-
-template <class T, class U>
-inline bool operator!=(const IntrusiveSharingPtr<T> &lhs, U *rhs) {
- return lhs.get() != rhs;
-}
-
-template <class T, class U>
-inline bool operator==(T *lhs, const IntrusiveSharingPtr<U> &rhs) {
- return lhs == rhs.get();
-}
-
-template <class T, class U>
-inline bool operator!=(T *lhs, const IntrusiveSharingPtr<U> &rhs) {
- return lhs != rhs.get();
-}
-
-} // namespace lldb_private
-
-#endif // utility_SharingPtr_h_
diff --git a/linux-x64/clang/include/lldb/Utility/Status.h b/linux-x64/clang/include/lldb/Utility/Status.h
index ae730b9..9babad1 100644
--- a/linux-x64/clang/include/lldb/Utility/Status.h
+++ b/linux-x64/clang/include/lldb/Utility/Status.h
@@ -47,8 +47,8 @@
/// into ValueType.
typedef uint32_t ValueType;
- /// Default constructor.
- ///
+ Status();
+
/// Initialize the error object with a generic success value.
///
/// \param[in] err
@@ -56,25 +56,14 @@
///
/// \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();
// llvm::Error support
@@ -122,7 +111,7 @@
/// Set accessor from a kern_return_t.
///
- /// Set accesssor for the error value to \a err and the error type to \c
+ /// Set accessor for the error value to \a err and the error type to \c
/// MachKernel.
///
/// \param[in] err
@@ -134,9 +123,9 @@
int SetExpressionErrorWithFormat(lldb::ExpressionResults, const char *format,
...) __attribute__((format(printf, 3, 4)));
- /// Set accesssor with an error value and type.
+ /// Set accessor with an error value and type.
///
- /// Set accesssor for the error value to \a err and the error type to \a
+ /// Set accessor for the error value to \a err and the error type to \a
/// type.
///
/// \param[in] err
@@ -221,4 +210,11 @@
};
}
-#endif // #ifndef LLDB_UTILITY_STATUS_H
+#define LLDB_ERRORF(status, fmt, ...) \
+ do { \
+ if (status) { \
+ (status)->SetErrorStringWithFormat((fmt), __VA_ARGS__); \
+ } \
+ } while (0);
+
+#endif // LLDB_UTILITY_STATUS_H
diff --git a/linux-x64/clang/include/lldb/Utility/Stream.h b/linux-x64/clang/include/lldb/Utility/Stream.h
index b24d4e4..e7f065a 100644
--- a/linux-x64/clang/include/lldb/Utility/Stream.h
+++ b/linux-x64/clang/include/lldb/Utility/Stream.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Stream_h_
-#define liblldb_Stream_h_
+#ifndef LLDB_UTILITY_STREAM_H
+#define LLDB_UTILITY_STREAM_H
#include "lldb/Utility/Flags.h"
#include "lldb/lldb-defines.h"
@@ -35,11 +35,11 @@
/// 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.
@@ -56,12 +56,13 @@
///
/// Construct with dump flags \a flags and the default address size. \a
/// flags can be any of the above enumeration logical OR'ed together.
- Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order);
+ Stream(uint32_t flags, uint32_t addr_size, lldb::ByteOrder byte_order,
+ bool colors = false);
/// Construct a default Stream, not binary, host byte order and host addr
/// size.
///
- Stream();
+ Stream(bool colors = false);
// FIXME: Streams should not be copyable.
Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; }
@@ -213,126 +214,14 @@
/// in one statement.
Stream &operator<<(char ch);
- /// Output a uint8_t \a uval to the stream \a s.
- ///
- /// \param[in] uval
- /// A uint8_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(uint8_t uval);
-
- /// Output a uint16_t \a uval to the stream \a s.
- ///
- /// \param[in] uval
- /// A uint16_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(uint16_t uval);
-
- /// Output a uint32_t \a uval to the stream \a s.
- ///
- /// \param[in] uval
- /// A uint32_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(uint32_t uval);
-
- /// Output a uint64_t \a uval to the stream \a s.
- ///
- /// \param[in] uval
- /// A uint64_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(uint64_t uval);
-
- /// Output a int8_t \a sval to the stream \a s.
- ///
- /// \param[in] sval
- /// A int8_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(int8_t sval);
-
- /// Output a int16_t \a sval to the stream \a s.
- ///
- /// \param[in] sval
- /// A int16_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(int16_t sval);
-
- /// Output a int32_t \a sval to the stream \a s.
- ///
- /// \param[in] sval
- /// A int32_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(int32_t sval);
-
- /// Output a int64_t \a sval to the stream \a s.
- ///
- /// \param[in] sval
- /// A int64_t value.
- ///
- /// \return
- /// A reference to this class so multiple things can be streamed
- /// in one statement.
- Stream &operator<<(int64_t sval);
-
- /// Output an address value to this stream.
- ///
- /// Put an address \a addr out to the stream with optional \a prefix and \a
- /// suffix strings.
- ///
- /// \param[in] addr
- /// An address value.
- ///
- /// \param[in] addr_size
- /// Size in bytes of the address, used for formatting.
- ///
- /// \param[in] prefix
- /// A prefix C string. If nullptr, no prefix will be output.
- ///
- /// \param[in] suffix
- /// A suffix C string. If nullptr, no suffix will be output.
- void Address(uint64_t addr, uint32_t addr_size, const char *prefix = nullptr,
- const char *suffix = nullptr);
-
- /// Output an address range to this stream.
- ///
- /// Put an address range \a lo_addr - \a hi_addr out to the stream with
- /// optional \a prefix and \a suffix strings.
- ///
- /// \param[in] lo_addr
- /// The start address of the address range.
- ///
- /// \param[in] hi_addr
- /// The end address of the address range.
- ///
- /// \param[in] addr_size
- /// Size in bytes of the address, used for formatting.
- ///
- /// \param[in] prefix
- /// A prefix C string. If nullptr, no prefix will be output.
- ///
- /// \param[in] suffix
- /// A suffix C string. If nullptr, no suffix will be output.
- void AddressRange(uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size,
- const char *prefix = nullptr, const char *suffix = nullptr);
+ Stream &operator<<(uint8_t uval) = delete;
+ Stream &operator<<(uint16_t uval) = delete;
+ Stream &operator<<(uint32_t uval) = delete;
+ Stream &operator<<(uint64_t uval) = delete;
+ Stream &operator<<(int8_t sval) = delete;
+ Stream &operator<<(int16_t sval) = delete;
+ Stream &operator<<(int32_t sval) = delete;
+ Stream &operator<<(int64_t sval) = delete;
/// Output a C string to the stream.
///
@@ -373,8 +262,8 @@
/// Get the current indentation level.
///
/// \return
- /// The current indentation level as an integer.
- int GetIndentLevel() const;
+ /// The current indentation level.
+ unsigned GetIndentLevel() const;
/// Indent the current line in the stream.
///
@@ -382,16 +271,14 @@
/// optional string following the indentation spaces.
///
/// \param[in] s
- /// A C string to print following the indentation. If nullptr, just
- /// output the indentation characters.
- size_t Indent(const char *s = nullptr);
- size_t Indent(llvm::StringRef s);
+ /// A string to print following the indentation.
+ size_t Indent(llvm::StringRef s = "");
/// Decrement the current indentation level.
- void IndentLess(int amount = 2);
+ void IndentLess(unsigned amount = 2);
/// Increment the current indentation level.
- void IndentMore(int amount = 2);
+ void IndentMore(unsigned amount = 2);
/// Output an offset value.
///
@@ -446,7 +333,7 @@
///
/// \param[in] level
/// The new indentation level.
- void SetIndentLevel(int level);
+ void SetIndentLevel(unsigned level);
/// Output a SLEB128 number to the stream.
///
@@ -477,7 +364,7 @@
uint32_t m_addr_size; ///< Size of an address in bytes.
lldb::ByteOrder
m_byte_order; ///< Byte order to use when encoding scalar types.
- int m_indent_level; ///< Indention level.
+ unsigned m_indent_level; ///< Indention level.
std::size_t m_bytes_written = 0; ///< Number of bytes written so far.
void _PutHex8(uint8_t uvalue, bool add_prefix);
@@ -517,12 +404,62 @@
}
public:
- RawOstreamForward(Stream &target)
- : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {}
+ RawOstreamForward(Stream &target, bool colors = false)
+ : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {
+ enable_colors(colors);
+ }
};
RawOstreamForward m_forwarder;
};
+/// Output an address value to this stream.
+///
+/// Put an address \a addr out to the stream with optional \a prefix and \a
+/// suffix strings.
+///
+/// \param[in] s
+/// The output stream.
+///
+/// \param[in] addr
+/// An address value.
+///
+/// \param[in] addr_size
+/// Size in bytes of the address, used for formatting.
+///
+/// \param[in] prefix
+/// A prefix C string. If nullptr, no prefix will be output.
+///
+/// \param[in] suffix
+/// A suffix C string. If nullptr, no suffix will be output.
+void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size,
+ const char *prefix = nullptr, const char *suffix = nullptr);
+
+/// Output an address range to this stream.
+///
+/// Put an address range \a lo_addr - \a hi_addr out to the stream with
+/// optional \a prefix and \a suffix strings.
+///
+/// \param[in] s
+/// The output stream.
+///
+/// \param[in] lo_addr
+/// The start address of the address range.
+///
+/// \param[in] hi_addr
+/// The end address of the address range.
+///
+/// \param[in] addr_size
+/// Size in bytes of the address, used for formatting.
+///
+/// \param[in] prefix
+/// A prefix C string. If nullptr, no prefix will be output.
+///
+/// \param[in] suffix
+/// A suffix C string. If nullptr, no suffix will be output.
+void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr,
+ uint32_t addr_size, const char *prefix = nullptr,
+ const char *suffix = nullptr);
+
} // namespace lldb_private
-#endif // liblldb_Stream_h_
+#endif // LLDB_UTILITY_STREAM_H
diff --git a/linux-x64/clang/include/lldb/Utility/StreamCallback.h b/linux-x64/clang/include/lldb/Utility/StreamCallback.h
index 6dbee67..d6d74fb 100644
--- a/linux-x64/clang/include/lldb/Utility/StreamCallback.h
+++ b/linux-x64/clang/include/lldb/Utility/StreamCallback.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_StreamCallback_h_
-#define liblldb_StreamCallback_h_
+#ifndef LLDB_UTILITY_STREAMCALLBACK_H
+#define LLDB_UTILITY_STREAMCALLBACK_H
#include "lldb/lldb-types.h"
#include "llvm/Support/raw_ostream.h"
@@ -32,4 +32,4 @@
} // namespace lldb_private
-#endif // liblldb_StreamCallback_h
+#endif // LLDB_UTILITY_STREAMCALLBACK_H
diff --git a/linux-x64/clang/include/lldb/Utility/StreamGDBRemote.h b/linux-x64/clang/include/lldb/Utility/StreamGDBRemote.h
deleted file mode 100644
index dd0ea31..0000000
--- a/linux-x64/clang/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/linux-x64/clang/include/lldb/Utility/StreamString.h b/linux-x64/clang/include/lldb/Utility/StreamString.h
index 581e102..b0be0f7 100644
--- a/linux-x64/clang/include/lldb/Utility/StreamString.h
+++ b/linux-x64/clang/include/lldb/Utility/StreamString.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_StreamString_h_
-#define liblldb_StreamString_h_
+#ifndef LLDB_UTILITY_STREAMSTRING_H
+#define LLDB_UTILITY_STREAMSTRING_H
#include "lldb/Utility/Stream.h"
#include "lldb/lldb-enumerations.h"
@@ -51,4 +51,4 @@
} // namespace lldb_private
-#endif // liblldb_StreamString_h_
+#endif // LLDB_UTILITY_STREAMSTRING_H
diff --git a/linux-x64/clang/include/lldb/Utility/StreamTee.h b/linux-x64/clang/include/lldb/Utility/StreamTee.h
index 92e94d4..2995bc0 100644
--- a/linux-x64/clang/include/lldb/Utility/StreamTee.h
+++ b/linux-x64/clang/include/lldb/Utility/StreamTee.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_StreamTee_h_
-#define liblldb_StreamTee_h_
+#ifndef LLDB_UTILITY_STREAMTEE_H
+#define LLDB_UTILITY_STREAMTEE_H
#include <limits.h>
@@ -19,7 +19,8 @@
class StreamTee : public Stream {
public:
- StreamTee() : Stream(), m_streams_mutex(), m_streams() {}
+ StreamTee(bool colors = false)
+ : Stream(colors), m_streams_mutex(), m_streams() {}
StreamTee(lldb::StreamSP &stream_sp)
: Stream(), m_streams_mutex(), m_streams() {
@@ -137,4 +138,4 @@
} // namespace lldb_private
-#endif // liblldb_StreamTee_h_
+#endif // LLDB_UTILITY_STREAMTEE_H
diff --git a/linux-x64/clang/include/lldb/Utility/StringExtractor.h b/linux-x64/clang/include/lldb/Utility/StringExtractor.h
index f20ec92..6a5bb24 100644
--- a/linux-x64/clang/include/lldb/Utility/StringExtractor.h
+++ b/linux-x64/clang/include/lldb/Utility/StringExtractor.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef utility_StringExtractor_h_
-#define utility_StringExtractor_h_
+#ifndef LLDB_UTILITY_STRINGEXTRACTOR_H
+#define LLDB_UTILITY_STRINGEXTRACTOR_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
@@ -26,7 +26,7 @@
virtual ~StringExtractor();
void Reset(llvm::StringRef str) {
- m_packet = str;
+ m_packet = std::string(str);
m_index = 0;
}
@@ -45,9 +45,7 @@
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 @@
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 @@
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_
+#endif // LLDB_UTILITY_STRINGEXTRACTOR_H
diff --git a/linux-x64/clang/include/lldb/Utility/StringExtractorGDBRemote.h b/linux-x64/clang/include/lldb/Utility/StringExtractorGDBRemote.h
index cbf6e0c..3b6ed80 100644
--- a/linux-x64/clang/include/lldb/Utility/StringExtractorGDBRemote.h
+++ b/linux-x64/clang/include/lldb/Utility/StringExtractorGDBRemote.h
@@ -31,11 +31,6 @@
StringExtractorGDBRemote(const char *cstr)
: StringExtractor(cstr), m_validator(nullptr) {}
- StringExtractorGDBRemote(const StringExtractorGDBRemote &rhs)
- : StringExtractor(rhs), m_validator(rhs.m_validator) {}
-
- ~StringExtractorGDBRemote() override {}
-
bool ValidateResponse() const;
void CopyResponseValidator(const StringExtractorGDBRemote &rhs);
@@ -81,6 +76,7 @@
eServerPacketType_QSetSTDERR,
eServerPacketType_QSetWorkingDir,
eServerPacketType_QStartNoAckMode,
+ eServerPacketType_qPathComplete,
eServerPacketType_qPlatform_shell,
eServerPacketType_qPlatform_mkdir,
eServerPacketType_qPlatform_chmod,
@@ -166,11 +162,13 @@
eServerPacketType__m,
eServerPacketType_notify, // '%' notification
- eServerPacketType_jTraceStart,
- eServerPacketType_jTraceBufferRead,
- eServerPacketType_jTraceMetaRead,
- eServerPacketType_jTraceStop,
- eServerPacketType_jTraceConfigRead,
+ eServerPacketType_jTraceStart, // deprecated
+ eServerPacketType_jTraceBufferRead, // deprecated
+ eServerPacketType_jTraceMetaRead, // deprecated
+ eServerPacketType_jTraceStop, // deprecated
+ eServerPacketType_jTraceConfigRead, // deprecated
+
+ eServerPacketType_jLLDBTraceSupportedType,
};
ServerPacketType GetServerPacketType() const;
diff --git a/linux-x64/clang/include/lldb/Utility/StringLexer.h b/linux-x64/clang/include/lldb/Utility/StringLexer.h
index d9806c1..52f98e8 100644
--- a/linux-x64/clang/include/lldb/Utility/StringLexer.h
+++ b/linux-x64/clang/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.
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef utility_StringLexer_h_
-#define utility_StringLexer_h_
+#ifndef LLDB_UTILITY_STRINGLEXER_H
+#define LLDB_UTILITY_STRINGLEXER_H
#include <initializer_list>
#include <string>
#include <utility>
-namespace lldb_utility {
+namespace lldb_private {
class StringLexer {
public:
@@ -53,4 +53,4 @@
} // namespace lldb_private
-#endif // #ifndef utility_StringLexer_h_
+#endif // LLDB_UTILITY_STRINGLEXER_H
diff --git a/linux-x64/clang/include/lldb/Utility/StringList.h b/linux-x64/clang/include/lldb/Utility/StringList.h
index 68c1f87..34930ab 100644
--- a/linux-x64/clang/include/lldb/Utility/StringList.h
+++ b/linux-x64/clang/include/lldb/Utility/StringList.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_StringList_h_
-#define liblldb_StringList_h_
+#ifndef LLDB_UTILITY_STRINGLIST_H
+#define LLDB_UTILITY_STRINGLIST_H
#include "llvm/ADT/StringRef.h"
@@ -23,6 +23,8 @@
namespace lldb_private {
class StringList {
+ typedef std::vector<std::string> collection;
+
public:
StringList();
@@ -52,6 +54,14 @@
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 @@
void Clear();
- void LongestCommonPrefix(std::string &common_prefix);
+ std::string LongestCommonPrefix();
void InsertStringAtIndex(size_t idx, const std::string &str);
@@ -92,19 +102,11 @@
StringList &operator<<(const std::string &s);
- StringList &operator<<(StringList strings);
+ StringList &operator<<(const StringList &strings);
// 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,9 +127,9 @@
}
private:
- std::vector<std::string> m_strings;
+ collection m_strings;
};
} // namespace lldb_private
-#endif // liblldb_StringList_h_
+#endif // LLDB_UTILITY_STRINGLIST_H
diff --git a/linux-x64/clang/include/lldb/Utility/StructuredData.h b/linux-x64/clang/include/lldb/Utility/StructuredData.h
index 75eb2f7..4d03af1 100644
--- a/linux-x64/clang/include/lldb/Utility/StructuredData.h
+++ b/linux-x64/clang/include/lldb/Utility/StructuredData.h
@@ -6,13 +6,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_StructuredData_h_
-#define liblldb_StructuredData_h_
+#ifndef LLDB_UTILITY_STRUCTUREDDATA_H
+#define LLDB_UTILITY_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 @@
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;
@@ -265,11 +271,11 @@
return false;
}
- void Push(ObjectSP item) { m_items.push_back(item); }
+ void Push(const ObjectSP &item) { m_items.push_back(item); }
- void AddItem(ObjectSP item) { m_items.push_back(item); }
+ void AddItem(const 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 @@
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 @@
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 @@
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;
@@ -333,11 +339,11 @@
explicit String(llvm::StringRef S)
: Object(lldb::eStructuredDataTypeString), m_value(S) {}
- void SetValue(llvm::StringRef S) { m_value = S; }
+ void SetValue(llvm::StringRef S) { m_value = std::string(S); }
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;
@@ -487,7 +493,7 @@
void AddItem(llvm::StringRef key, ObjectSP value_sp) {
ConstString key_cs(key);
- m_dict[key_cs] = value_sp;
+ m_dict[key_cs] = std::move(value_sp);
}
void AddIntegerItem(llvm::StringRef key, uint64_t value) {
@@ -506,7 +512,7 @@
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 @@
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,17 +541,16 @@
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 ParseJSON(const std::string &json_text);
static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
};
} // namespace lldb_private
-#endif // liblldb_StructuredData_h_
+#endif // LLDB_UTILITY_STRUCTUREDDATA_H
diff --git a/linux-x64/clang/include/lldb/Utility/TildeExpressionResolver.h b/linux-x64/clang/include/lldb/Utility/TildeExpressionResolver.h
index 196fdfc..3253767 100644
--- a/linux-x64/clang/include/lldb/Utility/TildeExpressionResolver.h
+++ b/linux-x64/clang/include/lldb/Utility/TildeExpressionResolver.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H
-#define LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H
+#ifndef LLDB_UTILITY_TILDEEXPRESSIONRESOLVER_H
+#define LLDB_UTILITY_TILDEEXPRESSIONRESOLVER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
@@ -61,4 +61,4 @@
};
}
-#endif // #ifndef LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H
+#endif // LLDB_UTILITY_TILDEEXPRESSIONRESOLVER_H
diff --git a/linux-x64/clang/include/lldb/Utility/Timeout.h b/linux-x64/clang/include/lldb/Utility/Timeout.h
index 202b747..80e2015 100644
--- a/linux-x64/clang/include/lldb/Utility/Timeout.h
+++ b/linux-x64/clang/include/lldb/Utility/Timeout.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Timeout_h_
-#define liblldb_Timeout_h_
+#ifndef LLDB_UTILITY_TIMEOUT_H
+#define LLDB_UTILITY_TIMEOUT_H
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Chrono.h"
@@ -67,4 +67,4 @@
};
}
-#endif // liblldb_Timeout_h_
+#endif // LLDB_UTILITY_TIMEOUT_H
diff --git a/linux-x64/clang/include/lldb/Utility/Timer.h b/linux-x64/clang/include/lldb/Utility/Timer.h
index ad9421a..edc064b 100644
--- a/linux-x64/clang/include/lldb/Utility/Timer.h
+++ b/linux-x64/clang/include/lldb/Utility/Timer.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_Timer_h_
-#define liblldb_Timer_h_
+#ifndef LLDB_UTILITY_TIMER_H
+#define LLDB_UTILITY_TIMER_H
#include "lldb/lldb-defines.h"
#include "llvm/Support/Chrono.h"
@@ -25,6 +25,7 @@
class Category {
public:
explicit Category(const char *category_name);
+ llvm::StringRef GetName() { return m_name; }
private:
friend class Timer;
@@ -34,7 +35,8 @@
std::atomic<uint64_t> m_count;
std::atomic<Category *> m_next;
- DISALLOW_COPY_AND_ASSIGN(Category);
+ Category(const Category &) = delete;
+ const Category &operator=(const Category &) = delete;
};
/// Default constructor.
@@ -66,9 +68,17 @@
static std::atomic<unsigned> g_display_depth;
private:
- DISALLOW_COPY_AND_ASSIGN(Timer);
+ Timer(const Timer &) = delete;
+ const Timer &operator=(const Timer &) = delete;
};
} // namespace lldb_private
-#endif // liblldb_Timer_h_
+#define LLDB_SCOPED_TIMER() \
+ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \
+ ::lldb_private::Timer _scoped_timer(_cat, LLVM_PRETTY_FUNCTION)
+#define LLDB_SCOPED_TIMERF(...) \
+ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \
+ ::lldb_private::Timer _scoped_timer(_cat, __VA_ARGS__)
+
+#endif // LLDB_UTILITY_TIMER_H
diff --git a/linux-x64/clang/include/lldb/Utility/TraceOptions.h b/linux-x64/clang/include/lldb/Utility/TraceOptions.h
index d5e21cc..c9a8d12 100644
--- a/linux-x64/clang/include/lldb/Utility/TraceOptions.h
+++ b/linux-x64/clang/include/lldb/Utility/TraceOptions.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_TraceOptions_h_
-#define liblldb_TraceOptions_h_
+#ifndef LLDB_UTILITY_TRACEOPTIONS_H
+#define LLDB_UTILITY_TRACEOPTIONS_H
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
@@ -15,6 +15,19 @@
#include "lldb/Utility/StructuredData.h"
namespace lldb_private {
+
+/// This struct represents a tracing technology.
+struct TraceTypeInfo {
+ /// The name of the technology, e.g. intel-pt or arm-coresight.
+ ///
+ /// In order for a Trace plug-in (see \a lldb_private::Trace.h) to support the
+ /// trace technology given by this struct, it should match its name with this
+ /// field.
+ std::string name;
+ /// A description for the technology.
+ std::string description;
+};
+
class TraceOptions {
public:
TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {}
@@ -57,4 +70,12 @@
};
}
-#endif // liblldb_TraceOptions_h_
+namespace llvm {
+namespace json {
+
+bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info, Path path);
+
+} // namespace json
+} // namespace llvm
+
+#endif // LLDB_UTILITY_TRACEOPTIONS_H
diff --git a/linux-x64/clang/include/lldb/Utility/UUID.h b/linux-x64/clang/include/lldb/Utility/UUID.h
index dbeb9db..f2107d9 100644
--- a/linux-x64/clang/include/lldb/Utility/UUID.h
+++ b/linux-x64/clang/include/lldb/Utility/UUID.h
@@ -9,14 +9,12 @@
#ifndef LLDB_UTILITY_UUID_H
#define LLDB_UTILITY_UUID_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Endian.h"
#include <stddef.h>
#include <stdint.h>
#include <string>
-#include "llvm/ADT/ArrayRef.h"
-
-namespace llvm {
- class StringRef;
-}
namespace lldb_private {
@@ -26,6 +24,22 @@
public:
UUID() = default;
+ // Reference:
+ // https://crashpad.chromium.org/doxygen/structcrashpad_1_1CodeViewRecordPDB70.html
+ struct CvRecordPdb70 {
+ struct {
+ llvm::support::ulittle32_t Data1;
+ llvm::support::ulittle16_t Data2;
+ llvm::support::ulittle16_t Data3;
+ uint8_t Data4[8];
+ } Uuid;
+ llvm::support::ulittle32_t Age;
+ // char PDBFileName[];
+ };
+
+ /// Create a UUID from CvRecordPdb70.
+ static UUID fromCvRecord(CvRecordPdb70 debug_info);
+
/// Creates a UUID from the data pointed to by the bytes argument. No special
/// significance is attached to any of the values.
static UUID fromData(const void *bytes, uint32_t num_bytes) {
@@ -66,34 +80,27 @@
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
- // UUID to invalid.
- size_t SetFromOptionalStringRef(llvm::StringRef str,
- uint32_t num_uuid_bytes = 16);
+ bool SetFromStringRef(llvm::StringRef str);
- // Decode as many UUID bytes (up to 16) as possible from the C string "cstr"
- // This is used for auto completion where a partial UUID might have been
- // typed in. It
- /// Decode as many UUID bytes (up to 16) as possible from the C
- /// string \a cstr.
+ // Same as SetFromStringRef, but if the resultant UUID is all 0 bytes, set the
+ // UUID to invalid.
+ bool SetFromOptionalStringRef(llvm::StringRef str);
+
+ /// Decode as many UUID bytes 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.
static llvm::StringRef
DecodeUUIDBytesFromString(llvm::StringRef str,
- llvm::SmallVectorImpl<uint8_t> &uuid_bytes,
- uint32_t num_uuid_bytes = 16);
+ llvm::SmallVectorImpl<uint8_t> &uuid_bytes);
private:
UUID(llvm::ArrayRef<uint8_t> bytes) : m_bytes(bytes.begin(), bytes.end()) {}
diff --git a/linux-x64/clang/include/lldb/Utility/UnimplementedError.h b/linux-x64/clang/include/lldb/Utility/UnimplementedError.h
new file mode 100644
index 0000000..c6fab0a
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Utility/UnimplementedError.h
@@ -0,0 +1,28 @@
+//===-- UnimplementedError.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_UNIMPLEMENTEDERROR_H
+#define LLDB_UTILITY_UNIMPLEMENTEDERROR_H
+
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+
+namespace lldb_private {
+class UnimplementedError : public llvm::ErrorInfo<UnimplementedError> {
+public:
+ static char ID;
+
+ void log(llvm::raw_ostream &OS) const override { OS << "Not implemented"; }
+
+ std::error_code convertToErrorCode() const override {
+ return llvm::errc::not_supported;
+ };
+};
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_UNIMPLEMENTEDERROR_H
diff --git a/linux-x64/clang/include/lldb/Utility/UriParser.h b/linux-x64/clang/include/lldb/Utility/UriParser.h
index 4a3f012..6a64c3d 100644
--- a/linux-x64/clang/include/lldb/Utility/UriParser.h
+++ b/linux-x64/clang/include/lldb/Utility/UriParser.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef utility_UriParser_h_
-#define utility_UriParser_h_
+#ifndef LLDB_UTILITY_URIPARSER_H
+#define LLDB_UTILITY_URIPARSER_H
#include "llvm/ADT/StringRef.h"
@@ -28,4 +28,4 @@
};
}
-#endif // utility_UriParser_h_
+#endif // LLDB_UTILITY_URIPARSER_H
diff --git a/linux-x64/clang/include/lldb/Utility/UserID.h b/linux-x64/clang/include/lldb/Utility/UserID.h
index 2dc5cdb..9fc6985 100644
--- a/linux-x64/clang/include/lldb/Utility/UserID.h
+++ b/linux-x64/clang/include/lldb/Utility/UserID.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_UserID_h_
-#define liblldb_UserID_h_
+#ifndef LLDB_UTILITY_USERID_H
+#define LLDB_UTILITY_USERID_H
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
@@ -90,4 +90,4 @@
} // namespace lldb_private
-#endif // liblldb_UserID_h_
+#endif // LLDB_UTILITY_USERID_H
diff --git a/linux-x64/clang/include/lldb/Utility/UserIDResolver.h b/linux-x64/clang/include/lldb/Utility/UserIDResolver.h
index bca82a1..e0f7b69 100644
--- a/linux-x64/clang/include/lldb/Utility/UserIDResolver.h
+++ b/linux-x64/clang/include/lldb/Utility/UserIDResolver.h
@@ -53,4 +53,4 @@
} // namespace lldb_private
-#endif // #ifndef LLDB_HOST_USERIDRESOLVER_H
+#endif // LLDB_UTILITY_USERIDRESOLVER_H
diff --git a/linux-x64/clang/include/lldb/Utility/VASPrintf.h b/linux-x64/clang/include/lldb/Utility/VASPrintf.h
index 582645f..a4b5f7d 100644
--- a/linux-x64/clang/include/lldb/Utility/VASPrintf.h
+++ b/linux-x64/clang/include/lldb/Utility/VASPrintf.h
@@ -17,4 +17,4 @@
bool VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt, va_list args);
}
-#endif // #ifdef LLDB_UTILITY_VASPRINTF_H
+#endif // LLDB_UTILITY_VASPRINTF_H
diff --git a/linux-x64/clang/include/lldb/Utility/VMRange.h b/linux-x64/clang/include/lldb/Utility/VMRange.h
index 9c2f9d0..4b01cd8 100644
--- a/linux-x64/clang/include/lldb/Utility/VMRange.h
+++ b/linux-x64/clang/include/lldb/Utility/VMRange.h
@@ -6,20 +6,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_VMRange_h_
-#define liblldb_VMRange_h_
+#ifndef LLDB_UTILITY_VMRANGE_H
+#define LLDB_UTILITY_VMRANGE_H
#include "lldb/lldb-types.h"
+#include "llvm/Support/raw_ostream.h"
#include <stddef.h>
#include <stdint.h>
#include <vector>
namespace lldb_private {
-class Stream;
-}
-
-namespace lldb_private {
// A vm address range. These can represent offsets ranges or actual
// addresses.
@@ -81,7 +78,7 @@
return false;
}
- void Dump(Stream *s, lldb::addr_t base_addr = 0,
+ void Dump(llvm::raw_ostream &s, lldb::addr_t base_addr = 0,
uint32_t addr_width = 8) const;
static bool ContainsValue(const VMRange::collection &coll,
@@ -104,4 +101,4 @@
} // namespace lldb_private
-#endif // liblldb_VMRange_h_
+#endif // LLDB_UTILITY_VMRANGE_H
diff --git a/linux-x64/clang/include/lldb/Utility/XcodeSDK.h b/linux-x64/clang/include/lldb/Utility/XcodeSDK.h
new file mode 100644
index 0000000..878b131
--- /dev/null
+++ b/linux-x64/clang/include/lldb/Utility/XcodeSDK.h
@@ -0,0 +1,96 @@
+//===-- XcodeSDK.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_SDK_H
+#define LLDB_UTILITY_SDK_H
+
+#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/VersionTuple.h"
+#include <tuple>
+
+namespace llvm {
+class Triple;
+}
+
+namespace lldb_private {
+
+/// An abstraction for Xcode-style SDKs that works like \ref ArchSpec.
+class XcodeSDK {
+ std::string m_name;
+
+public:
+ /// Different types of Xcode SDKs.
+ enum Type : int {
+ MacOSX = 0,
+ iPhoneSimulator,
+ iPhoneOS,
+ AppleTVSimulator,
+ AppleTVOS,
+ WatchSimulator,
+ watchOS,
+ bridgeOS,
+ Linux,
+ unknown = -1
+ };
+ static constexpr int numSDKTypes = Linux + 1;
+
+ /// A parsed SDK directory name.
+ struct Info {
+ Type type = unknown;
+ llvm::VersionTuple version;
+ bool internal = false;
+
+ Info() = default;
+ bool operator<(const Info &other) const;
+ bool operator==(const Info &other) const;
+ };
+
+
+ /// Default constructor, constructs an empty string.
+ XcodeSDK() = default;
+ /// Construct an XcodeSDK object from a specification.
+ XcodeSDK(Info info);
+ /// Initialize an XcodeSDK object with an SDK name. The SDK name is the last
+ /// directory component of a path one would pass to clang's -isysroot
+ /// parameter. For example, "MacOSX.10.14.sdk".
+ XcodeSDK(std::string &&name) : m_name(std::move(name)) {}
+ static XcodeSDK GetAnyMacOS() { return XcodeSDK("MacOSX.sdk"); }
+
+ /// The merge function follows a strict order to maintain monotonicity:
+ /// 1. SDK with the higher SDKType wins.
+ /// 2. The newer SDK wins.
+ void Merge(const XcodeSDK &other);
+
+ XcodeSDK &operator=(const XcodeSDK &other);
+ XcodeSDK(const XcodeSDK&) = default;
+ bool operator==(const XcodeSDK &other);
+
+ /// Return parsed SDK type and version number.
+ Info Parse() const;
+ bool IsAppleInternalSDK() const;
+ llvm::VersionTuple GetVersion() const;
+ Type GetType() const;
+ llvm::StringRef GetString() const;
+ /// Whether this Xcode SDK supports Swift.
+ bool SupportsSwift() const;
+
+ /// Whether LLDB feels confident importing Clang modules from this SDK.
+ static bool SDKSupportsModules(Type type, llvm::VersionTuple version);
+ static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path);
+ /// Return the canonical SDK name, such as "macosx" for the macOS SDK.
+ static std::string GetCanonicalName(Info info);
+ /// Return the best-matching SDK type for a specific triple.
+ static XcodeSDK::Type GetSDKTypeForTriple(const llvm::Triple &triple);
+
+ static std::string FindXcodeContentsDirectoryInPath(llvm::StringRef path);
+};
+
+} // namespace lldb_private
+
+#endif