aboutsummaryrefslogtreecommitdiff
path: root/lldb/include/lldb/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/include/lldb/Utility')
-rw-r--r--lldb/include/lldb/Utility/AnsiTerminal.h8
-rw-r--r--lldb/include/lldb/Utility/ArchSpec.h19
-rw-r--r--lldb/include/lldb/Utility/Args.h30
-rw-r--r--lldb/include/lldb/Utility/Baton.h6
-rw-r--r--lldb/include/lldb/Utility/Broadcaster.h28
-rw-r--r--lldb/include/lldb/Utility/CompletionRequest.h53
-rw-r--r--lldb/include/lldb/Utility/Connection.h11
-rw-r--r--lldb/include/lldb/Utility/ConstString.h24
-rw-r--r--lldb/include/lldb/Utility/DataBuffer.h20
-rw-r--r--lldb/include/lldb/Utility/DataBufferHeap.h6
-rw-r--r--lldb/include/lldb/Utility/DataBufferLLVM.h4
-rw-r--r--lldb/include/lldb/Utility/DataEncoder.h10
-rw-r--r--lldb/include/lldb/Utility/DataExtractor.h52
-rw-r--r--lldb/include/lldb/Utility/Endian.h2
-rw-r--r--lldb/include/lldb/Utility/Environment.h6
-rw-r--r--lldb/include/lldb/Utility/Event.h13
-rw-r--r--lldb/include/lldb/Utility/FileSpec.h21
-rw-r--r--lldb/include/lldb/Utility/Flags.h4
-rw-r--r--lldb/include/lldb/Utility/GDBRemote.h6
-rw-r--r--lldb/include/lldb/Utility/IOObject.h7
-rw-r--r--lldb/include/lldb/Utility/Iterable.h6
-rw-r--r--lldb/include/lldb/Utility/LLDBAssert.h6
-rw-r--r--lldb/include/lldb/Utility/Listener.h3
-rw-r--r--lldb/include/lldb/Utility/Predicate.h9
-rw-r--r--lldb/include/lldb/Utility/ProcessInfo.h90
-rw-r--r--lldb/include/lldb/Utility/RangeMap.h295
-rw-r--r--lldb/include/lldb/Utility/RegisterValue.h10
-rw-r--r--lldb/include/lldb/Utility/RegularExpression.h6
-rw-r--r--lldb/include/lldb/Utility/Reproducer.h116
-rw-r--r--lldb/include/lldb/Utility/ReproducerInstrumentation.h632
-rw-r--r--lldb/include/lldb/Utility/Scalar.h47
-rw-r--r--lldb/include/lldb/Utility/SelectHelper.h6
-rw-r--r--lldb/include/lldb/Utility/SharedCluster.h86
-rw-r--r--lldb/include/lldb/Utility/SharingPtr.h609
-rw-r--r--lldb/include/lldb/Utility/Status.h8
-rw-r--r--lldb/include/lldb/Utility/Stream.h23
-rw-r--r--lldb/include/lldb/Utility/StreamCallback.h6
-rw-r--r--lldb/include/lldb/Utility/StreamString.h6
-rw-r--r--lldb/include/lldb/Utility/StreamTee.h9
-rw-r--r--lldb/include/lldb/Utility/StringExtractor.h8
-rw-r--r--lldb/include/lldb/Utility/StringLexer.h6
-rw-r--r--lldb/include/lldb/Utility/StringList.h6
-rw-r--r--lldb/include/lldb/Utility/StructuredData.h8
-rw-r--r--lldb/include/lldb/Utility/TildeExpressionResolver.h6
-rw-r--r--lldb/include/lldb/Utility/Timeout.h6
-rw-r--r--lldb/include/lldb/Utility/Timer.h12
-rw-r--r--lldb/include/lldb/Utility/TraceOptions.h6
-rw-r--r--lldb/include/lldb/Utility/UUID.h16
-rw-r--r--lldb/include/lldb/Utility/UriParser.h6
-rw-r--r--lldb/include/lldb/Utility/UserID.h6
-rw-r--r--lldb/include/lldb/Utility/UserIDResolver.h2
-rw-r--r--lldb/include/lldb/Utility/VASPrintf.h2
-rw-r--r--lldb/include/lldb/Utility/VMRange.h6
-rw-r--r--lldb/include/lldb/Utility/XcodeSDK.h96
54 files changed, 1165 insertions, 1330 deletions
diff --git a/lldb/include/lldb/Utility/AnsiTerminal.h b/lldb/include/lldb/Utility/AnsiTerminal.h
index 21375e3821ca..c391adb2cf89 100644
--- a/lldb/include/lldb/Utility/AnsiTerminal.h
+++ b/lldb/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.
@@ -111,7 +115,7 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
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.
@@ -138,3 +142,5 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
}
}
} // namespace lldb_private
+
+#endif
diff --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h
index 15e2fdb10c32..5466e573c1a5 100644
--- a/lldb/include/lldb/Utility/ArchSpec.h
+++ b/lldb/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>
@@ -188,6 +189,10 @@ public:
eCore_arc, // little endian ARC
+ eCore_avr,
+
+ eCore_wasm32,
+
kNumCores,
kCore_invalid,
@@ -537,4 +542,16 @@ bool ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str, ArchSpec &arch);
} // 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/lldb/include/lldb/Utility/Args.h b/lldb/include/lldb/Utility/Args.h
index 1308f4038dbd..2cce7d0c697c 100644
--- a/lldb/include/lldb/Utility/Args.h
+++ b/lldb/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,6 +35,9 @@ public:
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;
@@ -283,6 +287,8 @@ public:
char quote_char);
private:
+ friend struct llvm::yaml::MappingTraits<Args>;
+
std::vector<ArgEntry> m_entries;
std::vector<char *> m_argv;
};
@@ -373,4 +379,28 @@ private:
} // 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/lldb/include/lldb/Utility/Baton.h b/lldb/include/lldb/Utility/Baton.h
index c42867489c65..010f8da43868 100644
--- a/lldb/include/lldb/Utility/Baton.h
+++ b/lldb/include/lldb/Utility/Baton.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#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"
@@ -76,4 +76,4 @@ protected:
} // namespace lldb_private
-#endif // lldb_Baton_h_
+#endif // LLDB_UTILITY_BATON_H
diff --git a/lldb/include/lldb/Utility/Broadcaster.h b/lldb/include/lldb/Utility/Broadcaster.h
index ead597d626d7..03995454ecb0 100644
--- a/lldb/include/lldb/Utility/Broadcaster.h
+++ b/lldb/include/lldb/Utility/Broadcaster.h
@@ -259,19 +259,6 @@ public:
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);
}
@@ -308,7 +295,7 @@ public:
/// 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.
///
@@ -347,9 +334,6 @@ public:
/// \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);
}
@@ -367,7 +351,7 @@ public:
/// (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
@@ -389,7 +373,7 @@ public:
/// 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.
@@ -530,7 +514,8 @@ protected:
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;
@@ -549,7 +534,8 @@ private:
/// 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/lldb/include/lldb/Utility/CompletionRequest.h b/lldb/include/lldb/Utility/CompletionRequest.h
index 570f626ac54e..1fbc96944e82 100644
--- a/lldb/include/lldb/Utility/CompletionRequest.h
+++ b/lldb/include/lldb/Utility/CompletionRequest.h
@@ -17,16 +17,21 @@
namespace lldb_private {
enum class CompletionMode {
- // The current token has been completed.
+ /// 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 completed token is still incomplete. Examples
- // for this are file paths, where we want to complete "/bi" to "/bin/", but
- // the file path token is still incomplete after the completion. Clients
- // should not indicate to the user that this is a full completion (e.g. by
- // not inserting the usual trailing space after a successful completion).
+ /// 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.
+ /// The full line has been rewritten by the completion.
+ /// Example: "alias name" -> "other_command full_name".
RewriteLine,
};
@@ -35,7 +40,12 @@ 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;
@@ -53,9 +63,12 @@ public:
};
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:
@@ -102,7 +115,19 @@ public:
CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos,
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; }
@@ -135,8 +160,8 @@ public:
/// the suggested completion is stored, so the given string can be free'd
/// afterwards.
///
- /// \param match The suggested completion.
- /// \param completion 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,
@@ -148,7 +173,7 @@ public:
/// Adds a possible completion string if the completion would complete the
/// current argument.
///
- /// \param match The suggested completion.
+ /// \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>
@@ -178,7 +203,7 @@ public:
/// 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,
diff --git a/lldb/include/lldb/Utility/Connection.h b/lldb/include/lldb/Utility/Connection.h
index 9e66dee1363b..39e6e40191b0 100644
--- a/lldb/include/lldb/Utility/Connection.h
+++ b/lldb/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 @@ public:
/// 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
@@ -175,9 +175,10 @@ public:
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/lldb/include/lldb/Utility/ConstString.h b/lldb/include/lldb/Utility/ConstString.h
index 74750459d16f..1e55b2ebb957 100644
--- a/lldb/include/lldb/Utility/ConstString.h
+++ b/lldb/include/lldb/Utility/ConstString.h
@@ -6,12 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_ConstString_h_
-#define liblldb_ConstString_h_
+#ifndef LLDB_UTILITY_CONSTSTRING_H
+#define LLDB_UTILITY_CONSTSTRING_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/YAMLTraits.h"
#include <stddef.h>
@@ -481,6 +482,21 @@ template <> struct DenseMapInfo<lldb_private::ConstString> {
}
};
/// \}
+
+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 // liblldb_ConstString_h_
+#endif // LLDB_UTILITY_CONSTSTRING_H
diff --git a/lldb/include/lldb/Utility/DataBuffer.h b/lldb/include/lldb/Utility/DataBuffer.h
index 523569301e84..302b13307958 100644
--- a/lldb/include/lldb/Utility/DataBuffer.h
+++ b/lldb/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 @@ public:
}
};
+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/lldb/include/lldb/Utility/DataBufferHeap.h b/lldb/include/lldb/Utility/DataBufferHeap.h
index 2a64694d7f29..ace526bf0a47 100644
--- a/lldb/include/lldb/Utility/DataBufferHeap.h
+++ b/lldb/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 @@ private:
} // namespace lldb_private
-#endif // liblldb_DataBufferHeap_h_
+#endif // LLDB_UTILITY_DATABUFFERHEAP_H
diff --git a/lldb/include/lldb/Utility/DataBufferLLVM.h b/lldb/include/lldb/Utility/DataBufferLLVM.h
index d4c110743068..4dc800c348c5 100644
--- a/lldb/include/lldb/Utility/DataBufferLLVM.h
+++ b/lldb/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/lldb/include/lldb/Utility/DataEncoder.h b/lldb/include/lldb/Utility/DataEncoder.h
index f4964b250b9d..8edec54c36f5 100644
--- a/lldb/include/lldb/Utility/DataEncoder.h
+++ b/lldb/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)
@@ -225,7 +225,6 @@ private:
/// The total number of bytes of data this object refers to.
size_t GetByteSize() const { return m_end - m_start; }
-private:
/// A pointer to the first byte of data.
uint8_t *m_start;
@@ -243,10 +242,11 @@ private:
/// be shared among multiple instances
mutable lldb::DataBufferSP m_data_sp;
- DISALLOW_COPY_AND_ASSIGN(DataEncoder);
+ 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/lldb/include/lldb/Utility/DataExtractor.h b/lldb/include/lldb/Utility/DataExtractor.h
index bf0d1055cf43..0210af5cf6d1 100644
--- a/lldb/include/lldb/Utility/DataExtractor.h
+++ b/lldb/include/lldb/Utility/DataExtractor.h
@@ -9,12 +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>
@@ -535,13 +537,13 @@ public:
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.
///
@@ -573,24 +575,6 @@ public:
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
@@ -997,19 +981,33 @@ public:
}
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/lldb/include/lldb/Utility/Endian.h b/lldb/include/lldb/Utility/Endian.h
index cead5f8603d2..1d1f8fa333b8 100644
--- a/lldb/include/lldb/Utility/Endian.h
+++ b/lldb/include/lldb/Utility/Endian.h
@@ -30,4 +30,4 @@ inline lldb::ByteOrder InlHostByteOrder() {
}
}
-#endif // liblldb_host_endian_h_
+#endif // LLDB_UTILITY_ENDIAN_H
diff --git a/lldb/include/lldb/Utility/Environment.h b/lldb/include/lldb/Utility/Environment.h
index 398b3bae3106..e2af2eb2463d 100644
--- a/lldb/include/lldb/Utility/Environment.h
+++ b/lldb/include/lldb/Utility/Environment.h
@@ -50,6 +50,7 @@ public:
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 @@ public:
}
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 @@ template <> struct format_provider<lldb_private::Environment> {
};
} // namespace llvm
-#endif // #ifndef LLDB_UTILITY_ENVIRONMENT_H
+#endif // LLDB_UTILITY_ENVIRONMENT_H
diff --git a/lldb/include/lldb/Utility/Event.h b/lldb/include/lldb/Utility/Event.h
index dd5d08024cef..06c02629d448 100644
--- a/lldb/include/lldb/Utility/Event.h
+++ b/lldb/include/lldb/Utility/Event.h
@@ -48,7 +48,8 @@ public:
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 @@ public:
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 @@ private:
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 @@ private:
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/lldb/include/lldb/Utility/FileSpec.h b/lldb/include/lldb/Utility/FileSpec.h
index 533426671cc6..f7cbeb247100 100644
--- a/lldb/include/lldb/Utility/FileSpec.h
+++ b/lldb/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>
@@ -397,6 +398,8 @@ public:
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);
@@ -410,6 +413,8 @@ protected:
/// 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 {
@@ -436,6 +441,16 @@ template <> struct format_provider<lldb_private::FileSpec> {
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/lldb/include/lldb/Utility/Flags.h b/lldb/include/lldb/Utility/Flags.h
index 254a5ec443c3..19f750639e94 100644
--- a/lldb/include/lldb/Utility/Flags.h
+++ b/lldb/include/lldb/Utility/Flags.h
@@ -29,7 +29,7 @@ public:
/// 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) {}
@@ -116,4 +116,4 @@ protected:
} // namespace lldb_private
-#endif // liblldb_Flags_h_
+#endif // LLDB_UTILITY_FLAGS_H
diff --git a/lldb/include/lldb/Utility/GDBRemote.h b/lldb/include/lldb/Utility/GDBRemote.h
index 21b2c8cd73cd..f5749b7e6eaf 100644
--- a/lldb/include/lldb/Utility/GDBRemote.h
+++ b/lldb/include/lldb/Utility/GDBRemote.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_GDBRemote_h_
-#define liblldb_GDBRemote_h_
+#ifndef LLDB_UTILITY_GDBREMOTE_H
+#define LLDB_UTILITY_GDBREMOTE_H
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Reproducer.h"
@@ -155,4 +155,4 @@ template <> struct MappingTraits<lldb_private::GDBRemotePacket> {
} // namespace yaml
} // namespace llvm
-#endif // liblldb_GDBRemote_h_
+#endif // LLDB_UTILITY_GDBREMOTE_H
diff --git a/lldb/include/lldb/Utility/IOObject.h b/lldb/include/lldb/Utility/IOObject.h
index 16ed580abf71..9b2b9cfcfec0 100644
--- a/lldb/include/lldb/Utility/IOObject.h
+++ b/lldb/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>
@@ -45,7 +45,8 @@ protected:
FDType m_fd_type;
private:
- DISALLOW_COPY_AND_ASSIGN(IOObject);
+ IOObject(const IOObject &) = delete;
+ const IOObject &operator=(const IOObject &) = delete;
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Utility/Iterable.h b/lldb/include/lldb/Utility/Iterable.h
index d9c61aa958cc..3f9b8b1e4c57 100644
--- a/lldb/include/lldb/Utility/Iterable.h
+++ b/lldb/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>
@@ -194,4 +194,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_Iterable_h_
+#endif // LLDB_UTILITY_ITERABLE_H
diff --git a/lldb/include/lldb/Utility/LLDBAssert.h b/lldb/include/lldb/Utility/LLDBAssert.h
index 7008dd82496d..845af1d4cc2a 100644
--- a/lldb/include/lldb/Utility/LLDBAssert.h
+++ b/lldb/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 @@ void lldb_assert(bool expression, const char *expr_text, const char *func,
const char *file, unsigned int line);
}
-#endif // utility_LLDBAssert_h_
+#endif // LLDB_UTILITY_LLDBASSERT_H
diff --git a/lldb/include/lldb/Utility/Listener.h b/lldb/include/lldb/Utility/Listener.h
index 17fc47880e8f..9d96e36c5abc 100644
--- a/lldb/include/lldb/Utility/Listener.h
+++ b/lldb/include/lldb/Utility/Listener.h
@@ -145,7 +145,8 @@ private:
// 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/lldb/include/lldb/Utility/Predicate.h b/lldb/include/lldb/Utility/Predicate.h
index cbccc3e91a8b..a17ac05f6e56 100644
--- a/lldb/include/lldb/Utility/Predicate.h
+++ b/lldb/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>
@@ -221,9 +221,10 @@ private:
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/lldb/include/lldb/Utility/ProcessInfo.h b/lldb/include/lldb/Utility/ProcessInfo.h
index 9188bf3b7090..ec91060cda54 100644
--- a/lldb/include/lldb/Utility/ProcessInfo.h
+++ b/lldb/include/lldb/Utility/ProcessInfo.h
@@ -9,13 +9,13 @@
#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 "lldb/Utility/Reproducer.h"
+#include "llvm/Support/YAMLTraits.h"
#include <vector>
namespace lldb_private {
@@ -89,6 +89,7 @@ public:
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,46 +151,13 @@ public:
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); }
-
- llvm::StringRef GetProcessNameAtIndex(size_t idx) {
- return ((idx < m_infos.size()) ? m_infos[idx].GetNameAsStringRef() : "");
- }
-
- 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
//
@@ -248,6 +216,52 @@ protected:
bool m_match_all_users;
};
+namespace repro {
+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;
+};
+
+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/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h
index 9e0307351836..fb24c5a43479 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -122,220 +122,13 @@ template <typename B, typename S> struct Range {
}
};
-// 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;
@@ -601,19 +394,31 @@ struct RangeData : public Range<B, S> {
RangeData(B base, S size, DataType d) : Range<B, S>(base, size), data(d) {}
};
+// 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(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)
@@ -625,13 +430,13 @@ public:
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)
@@ -701,26 +506,20 @@ public:
}
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
- // Search the entries until the first entry that has a larger base address
- // than `addr`. As m_entries is sorted by their base address, all following
- // entries can't contain `addr` as their base address is already larger.
- for (const auto &entry : m_entries) {
- if (entry.Contains(addr))
- indexes.push_back(entry.data);
- else if (entry.GetRangeBase() > addr)
- break;
- }
+ if (!m_entries.empty())
+ FindEntryIndexesThatContain(addr, 0, m_entries.size(), indexes);
+
return indexes.size();
}
@@ -806,6 +605,54 @@ public:
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/lldb/include/lldb/Utility/RegisterValue.h b/lldb/include/lldb/Utility/RegisterValue.h
index eeb3ce52a82b..c9f295a8d95a 100644
--- a/lldb/include/lldb/Utility/RegisterValue.h
+++ b/lldb/include/lldb/Utility/RegisterValue.h
@@ -26,7 +26,8 @@ struct RegisterInfo;
class RegisterValue {
public:
- enum { kMaxRegisterByteSize = 64u };
+ // big enough to support up to 256 byte AArch64 SVE
+ enum { kMaxRegisterByteSize = 256u };
enum Type {
eTypeInvalid,
@@ -259,9 +260,10 @@ protected:
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/lldb/include/lldb/Utility/RegularExpression.h b/lldb/include/lldb/Utility/RegularExpression.h
index 6acc203d8e7c..415f1b58b111 100644
--- a/lldb/include/lldb/Utility/RegularExpression.h
+++ b/lldb/include/lldb/Utility/RegularExpression.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef liblldb_RegularExpression_h_
-#define liblldb_RegularExpression_h_
+#ifndef LLDB_UTILITY_REGULAREXPRESSION_H
+#define LLDB_UTILITY_REGULAREXPRESSION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -91,4 +91,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_RegularExpression_h_
+#endif // LLDB_UTILITY_REGULAREXPRESSION_H
diff --git a/lldb/include/lldb/Utility/Reproducer.h b/lldb/include/lldb/Utility/Reproducer.h
index 0d23fe8571ff..ab673e5e0019 100644
--- a/lldb/include/lldb/Utility/Reproducer.h
+++ b/lldb/include/lldb/Utility/Reproducer.h
@@ -27,6 +27,7 @@ class Reproducer;
enum class ReproducerMode {
Capture,
Replay,
+ PassiveReplay,
Off,
};
@@ -98,6 +99,8 @@ public:
return m_collector;
}
+ void recordInterestingDirectory(const llvm::Twine &dir);
+
void Keep() override {
auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file);
// Temporary files that are removed during execution can cause copy errors.
@@ -132,7 +135,7 @@ public:
static char ID;
};
-/// Provider for the LLDB current working directroy.
+/// Provider for the LLDB 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.
@@ -142,8 +145,11 @@ public:
llvm::SmallString<128> cwd;
if (std::error_code EC = llvm::sys::fs::current_path(cwd))
return;
- m_cwd = cwd.str();
+ m_cwd = std::string(cwd.str());
}
+
+ void Update(llvm::StringRef path) { m_cwd = std::string(path); }
+
struct Info {
static const char *name;
static const char *file;
@@ -153,6 +159,9 @@ public:
static char ID;
};
+/// 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)
@@ -175,6 +184,7 @@ protected:
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)
@@ -193,24 +203,88 @@ public:
}
};
-class CommandProvider : public Provider<CommandProvider> {
+/// 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();
+ }
+};
+
+/// 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) : Provider(directory) {}
-
- DataRecorder *GetNewDataRecorder();
-
- void Keep() override;
- void Discard() override;
+ CommandProvider(const FileSpec &directory)
+ : MultiProvider<DataRecorder, CommandProvider>(directory) {}
static char ID;
-
-private:
- std::vector<std::unique_ptr<DataRecorder>> m_data_recorders;
};
/// The generator is responsible for the logic needed to generate a
@@ -231,6 +305,12 @@ public:
/// 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 = std::make_unique<T>(m_root);
@@ -272,11 +352,14 @@ private:
/// Flag to ensure that we never call both keep and discard.
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(FileSpec root);
+ Loader(FileSpec root, bool passive = false);
template <typename T> FileSpec GetFile() {
if (!HasFile(T::file))
@@ -298,12 +381,15 @@ public:
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
@@ -331,7 +417,7 @@ public:
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();
@@ -342,6 +428,8 @@ private:
mutable std::mutex m_mutex;
};
+/// 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(files) {}
diff --git a/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/lldb/include/lldb/Utility/ReproducerInstrumentation.h
index 75d66045758f..5fc33ad1a17b 100644
--- a/lldb/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/lldb/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,7 +16,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
-#include <iostream>
#include <map>
#include <type_traits>
@@ -33,6 +32,11 @@ inline void stringify_append(llvm::raw_string_ostream &ss, const T &t) {
}
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);
}
@@ -43,6 +47,12 @@ inline void stringify_append<char>(llvm::raw_string_ostream &ss,
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>
inline void stringify_helper(llvm::raw_string_ostream &ss, const Head &head) {
stringify_append(ss, head);
@@ -69,120 +79,146 @@ template <typename... Ts> inline std::string stringify_args(const Ts &... ts) {
// #define LLDB_REPRO_INSTR_TRACE
#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(*this, __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(*this, __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, \
- stringify_args(*this)); \
- 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, \
- stringify_args(*this)); \
- 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 sb_recorder(LLVM_PRETTY_FUNCTION);
+ 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.
@@ -205,19 +241,24 @@ public:
}
/// 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.
@@ -238,11 +279,11 @@ struct ReferenceTag {};
struct ValueTag {};
struct FundamentalPointerTag {};
struct FundamentalReferenceTag {};
-struct NotImplementedTag {};
/// Return the deserialization tag for the given type T.
template <class T> struct serializer_tag {
- typedef typename std::conditional<std::is_trivially_copyable<T>::value, ValueTag, NotImplementedTag>::type type;
+ typedef typename std::conditional<std::is_trivially_copyable<T>::value,
+ ValueTag, ReferenceTag>::type type;
};
template <class T> struct serializer_tag<T *> {
typedef
@@ -275,27 +316,37 @@ public:
/// 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;
+ }
+
+ template <typename T> const T &HandleReplayResult(const T &t) {
+ unsigned result = Deserialize<unsigned>();
+ 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> void HandleReplayResult(const T &t) {
+ template <typename T> T &HandleReplayResult(T &t) {
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) {
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;
+ return m_index_to_object.AddObjectForIndex(result, t);
}
/// All returned types are recorded, even when the function returns a void.
@@ -306,12 +357,11 @@ public:
(void)result;
}
-private:
- template <typename T> T Read(NotImplementedTag) {
- m_buffer = m_buffer.drop_front(sizeof(T));
- return T();
+ std::vector<void *> GetAllObjects() const {
+ return m_index_to_object.GetAllObjects();
}
+private:
template <typename T> T Read(ValueTag) {
assert(HasData(sizeof(T)));
T t;
@@ -362,7 +412,11 @@ private:
/// 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
@@ -404,7 +458,11 @@ struct DefaultReplayer<Result(Args...)> : public Replayer {
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));
}
@@ -419,6 +477,10 @@ struct DefaultReplayer<void(Args...)> : public Replayer {
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();
@@ -474,18 +536,25 @@ public:
/// 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;
@@ -494,37 +563,6 @@ private:
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.
///
@@ -561,6 +599,10 @@ private:
/// 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
+ llvm::errs() << "Serializing with " << LLVM_PRETTY_FUNCTION << " -> "
+ << stringify_args(t) << "\n";
+#endif
if (std::is_fundamental<T>::value) {
Serialize(*t);
} else {
@@ -573,7 +615,11 @@ private:
/// 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
+ llvm::errs() << "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);
@@ -581,14 +627,43 @@ private:
}
}
+ 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
+ llvm::errs() << "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.
@@ -596,24 +671,46 @@ private:
/// Mapping of objects to indices.
ObjectToIndex m_tracker;
-};
+}; // namespace repro
class InstrumentationData {
public:
- InstrumentationData() : m_serializer(nullptr), m_registry(nullptr){};
- InstrumentationData(Serializer &serializer, Registry &registry)
- : m_serializer(&serializer), m_registry(&registry){};
-
- 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 &registry);
+ static void Initialize(Deserializer &serializer, Registry &registry);
+ 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 &registry)
+ : m_serializer(&serializer), m_deserializer(nullptr),
+ m_registry(&registry) {}
+ InstrumentationData(Deserializer &deserializer, Registry &registry)
+ : m_serializer(nullptr), m_deserializer(&deserializer),
+ m_registry(&registry) {}
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
@@ -628,7 +725,8 @@ private:
/// 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.
@@ -679,9 +777,26 @@ public:
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 &registry, 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()) {
assert(!m_result_recorded);
m_serializer->SerializeAll(r);
@@ -690,14 +805,41 @@ public:
return std::forward<Result>(r);
}
+ template <typename Result, typename T>
+ Result Replay(Deserializer &deserializer, Registry &registry, uintptr_t addr,
+ bool update_boundary) {
+ 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 &registry, uintptr_t addr) {
+ 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; }
+
private:
+ 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 << " ("
@@ -721,7 +863,197 @@ private:
static bool g_global_boundary;
};
+/// 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 &registry) {
+ 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 &registry) {
+ 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 &registry) {
+ 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 &registry) {
+ 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 &registry) {
+ 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 &registry) {
+ 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 &registry) {
+ 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 &registry, char *str) {
+ 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 &registry, char *str) {
+ 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 &registry, char *str) {
+ 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/lldb/include/lldb/Utility/Scalar.h b/lldb/include/lldb/Utility/Scalar.h
index 69c948ec6222..f215fa71c84c 100644
--- a/lldb/include/lldb/Utility/Scalar.h
+++ b/lldb/include/lldb/Utility/Scalar.h
@@ -83,20 +83,11 @@ public:
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(long double v)
+ : m_type(e_long_double),
+ m_float(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);
m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true);
@@ -115,7 +106,10 @@ public:
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;
@@ -131,7 +125,7 @@ public:
m_integer.clearAllBits();
}
- const char *GetTypeAsCString() const;
+ const char *GetTypeAsCString() const { return GetValueTypeAsCString(m_type); }
void GetValue(Stream *s, bool show_type) const;
@@ -139,8 +133,8 @@ public:
return (m_type >= e_sint) && (m_type <= e_long_double);
}
- /// Convert integer to \p type, limited to \p bits size.
- void TruncOrExtendTo(Scalar::Type type, uint16_t bits);
+ /// Convert to an integer with \p bits and the given signedness.
+ void TruncOrExtendTo(uint16_t bits, bool sign);
bool Promote(Scalar::Type type);
@@ -162,16 +156,6 @@ public:
// 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);
Scalar &operator<<=(const Scalar &rhs); // Shift left
Scalar &operator>>=(const Scalar &rhs); // Shift right (arithmetic)
@@ -204,7 +188,7 @@ public:
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;
@@ -220,7 +204,7 @@ public:
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;
@@ -282,7 +266,8 @@ protected:
Scalar::Type m_type;
llvm::APInt m_integer;
llvm::APFloat m_float;
- bool m_ieee_quad = false;
+
+ template <typename T> T GetAs(T fail_value) const;
private:
friend const Scalar operator+(const Scalar &lhs, const Scalar &rhs);
diff --git a/lldb/include/lldb/Utility/SelectHelper.h b/lldb/include/lldb/Utility/SelectHelper.h
index ec37f194d329..63f1fe6421cf 100644
--- a/lldb/include/lldb/Utility/SelectHelper.h
+++ b/lldb/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 @@ protected:
llvm::Optional<std::chrono::steady_clock::time_point> m_end_time;
};
-#endif // liblldb_SelectHelper_h_
+#endif // LLDB_UTILITY_SELECTHELPER_H
diff --git a/lldb/include/lldb/Utility/SharedCluster.h b/lldb/include/lldb/Utility/SharedCluster.h
index 71bbb334cff3..375c1c131a09 100644
--- a/lldb/include/lldb/Utility/SharedCluster.h
+++ b/lldb/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/SmallPtrSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include <memory>
#include <mutex>
namespace lldb_private {
-namespace imp {
-template <typename T>
-class shared_ptr_refcount : public lldb_private::imp::shared_count {
-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 {
+template <class T>
+class ClusterManager : public std::enable_shared_from_this<ClusterManager<T>> {
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();
- }
-
- friend class imp::shared_ptr_refcount<ClusterManager>;
+ ClusterManager() : m_objects(), m_mutex() {}
- 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/lldb/include/lldb/Utility/SharingPtr.h b/lldb/include/lldb/Utility/SharingPtr.h
deleted file mode 100644
index e4ab3d27a69b..000000000000
--- a/lldb/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/lldb/include/lldb/Utility/Status.h b/lldb/include/lldb/Utility/Status.h
index 36f52922c9bc..9babad18edc0 100644
--- a/lldb/include/lldb/Utility/Status.h
+++ b/lldb/include/lldb/Utility/Status.h
@@ -111,7 +111,7 @@ public:
/// 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
@@ -123,9 +123,9 @@ public:
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
@@ -217,4 +217,4 @@ template <> struct format_provider<lldb_private::Status> {
} \
} while (0);
-#endif // #ifndef LLDB_UTILITY_STATUS_H
+#endif // LLDB_UTILITY_STATUS_H
diff --git a/lldb/include/lldb/Utility/Stream.h b/lldb/include/lldb/Utility/Stream.h
index 18a16a3461c1..e7f065a1fc7b 100644
--- a/lldb/include/lldb/Utility/Stream.h
+++ b/lldb/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"
@@ -56,12 +56,13 @@ public:
///
/// 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; }
@@ -270,10 +271,8 @@ public:
/// 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(unsigned amount = 2);
@@ -405,8 +404,10 @@ protected:
}
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;
};
@@ -461,4 +462,4 @@ void DumpAddressRange(llvm::raw_ostream &s, uint64_t lo_addr, uint64_t hi_addr,
} // namespace lldb_private
-#endif // liblldb_Stream_h_
+#endif // LLDB_UTILITY_STREAM_H
diff --git a/lldb/include/lldb/Utility/StreamCallback.h b/lldb/include/lldb/Utility/StreamCallback.h
index 6dbee67ecca2..d6d74fb84799 100644
--- a/lldb/include/lldb/Utility/StreamCallback.h
+++ b/lldb/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 @@ private:
} // namespace lldb_private
-#endif // liblldb_StreamCallback_h
+#endif // LLDB_UTILITY_STREAMCALLBACK_H
diff --git a/lldb/include/lldb/Utility/StreamString.h b/lldb/include/lldb/Utility/StreamString.h
index 581e102d4e80..b0be0f7dd76a 100644
--- a/lldb/include/lldb/Utility/StreamString.h
+++ b/lldb/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 @@ protected:
} // namespace lldb_private
-#endif // liblldb_StreamString_h_
+#endif // LLDB_UTILITY_STREAMSTRING_H
diff --git a/lldb/include/lldb/Utility/StreamTee.h b/lldb/include/lldb/Utility/StreamTee.h
index 92e94d4494f6..2995bc07f42a 100644
--- a/lldb/include/lldb/Utility/StreamTee.h
+++ b/lldb/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 @@ namespace lldb_private {
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 @@ protected:
} // namespace lldb_private
-#endif // liblldb_StreamTee_h_
+#endif // LLDB_UTILITY_STREAMTEE_H
diff --git a/lldb/include/lldb/Utility/StringExtractor.h b/lldb/include/lldb/Utility/StringExtractor.h
index 293fef2fbe6b..6a5bb24779a4 100644
--- a/lldb/include/lldb/Utility/StringExtractor.h
+++ b/lldb/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 @@ public:
virtual ~StringExtractor();
void Reset(llvm::StringRef str) {
- m_packet = str;
+ m_packet = std::string(str);
m_index = 0;
}
@@ -118,4 +118,4 @@ protected:
uint64_t m_index;
};
-#endif // utility_StringExtractor_h_
+#endif // LLDB_UTILITY_STRINGEXTRACTOR_H
diff --git a/lldb/include/lldb/Utility/StringLexer.h b/lldb/include/lldb/Utility/StringLexer.h
index 533fd4fb896e..52f98e860da2 100644
--- a/lldb/include/lldb/Utility/StringLexer.h
+++ b/lldb/include/lldb/Utility/StringLexer.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef utility_StringLexer_h_
-#define utility_StringLexer_h_
+#ifndef LLDB_UTILITY_STRINGLEXER_H
+#define LLDB_UTILITY_STRINGLEXER_H
#include <initializer_list>
#include <string>
@@ -53,4 +53,4 @@ private:
} // namespace lldb_private
-#endif // #ifndef utility_StringLexer_h_
+#endif // LLDB_UTILITY_STRINGLEXER_H
diff --git a/lldb/include/lldb/Utility/StringList.h b/lldb/include/lldb/Utility/StringList.h
index 0b1d955678b3..591a15861593 100644
--- a/lldb/include/lldb/Utility/StringList.h
+++ b/lldb/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"
@@ -132,4 +132,4 @@ private:
} // namespace lldb_private
-#endif // liblldb_StringList_h_
+#endif // LLDB_UTILITY_STRINGLIST_H
diff --git a/lldb/include/lldb/Utility/StructuredData.h b/lldb/include/lldb/Utility/StructuredData.h
index 01b14fc3d4d3..14c82e669676 100644
--- a/lldb/include/lldb/Utility/StructuredData.h
+++ b/lldb/include/lldb/Utility/StructuredData.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#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"
@@ -339,7 +339,7 @@ public:
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; }
@@ -553,4 +553,4 @@ public:
} // namespace lldb_private
-#endif // liblldb_StructuredData_h_
+#endif // LLDB_UTILITY_STRUCTUREDDATA_H
diff --git a/lldb/include/lldb/Utility/TildeExpressionResolver.h b/lldb/include/lldb/Utility/TildeExpressionResolver.h
index 196fdfcf9ab4..3253767ffd75 100644
--- a/lldb/include/lldb/Utility/TildeExpressionResolver.h
+++ b/lldb/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 @@ public:
};
}
-#endif // #ifndef LLDB_UTILITY_TILDE_EXPRESSION_RESOLVER_H
+#endif // LLDB_UTILITY_TILDEEXPRESSIONRESOLVER_H
diff --git a/lldb/include/lldb/Utility/Timeout.h b/lldb/include/lldb/Utility/Timeout.h
index 202b747fd480..80e201515577 100644
--- a/lldb/include/lldb/Utility/Timeout.h
+++ b/lldb/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 @@ struct format_provider<lldb_private::Timeout<Ratio>, void> {
};
}
-#endif // liblldb_Timeout_h_
+#endif // LLDB_UTILITY_TIMEOUT_H
diff --git a/lldb/include/lldb/Utility/Timer.h b/lldb/include/lldb/Utility/Timer.h
index ad9421a75b15..f97315b2db0f 100644
--- a/lldb/include/lldb/Utility/Timer.h
+++ b/lldb/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"
@@ -34,7 +34,8 @@ public:
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 +67,10 @@ protected:
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_
+#endif // LLDB_UTILITY_TIMER_H
diff --git a/lldb/include/lldb/Utility/TraceOptions.h b/lldb/include/lldb/Utility/TraceOptions.h
index d5e21ccd8ba3..97aad33899be 100644
--- a/lldb/include/lldb/Utility/TraceOptions.h
+++ b/lldb/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"
@@ -57,4 +57,4 @@ private:
};
}
-#endif // liblldb_TraceOptions_h_
+#endif // LLDB_UTILITY_TRACEOPTIONS_H
diff --git a/lldb/include/lldb/Utility/UUID.h b/lldb/include/lldb/Utility/UUID.h
index 0284357be44a..5327719094c0 100644
--- a/lldb/include/lldb/Utility/UUID.h
+++ b/lldb/include/lldb/Utility/UUID.h
@@ -63,18 +63,13 @@ public:
std::string GetAsString(llvm::StringRef separator = "-") const;
- size_t SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes = 16);
+ bool SetFromStringRef(llvm::StringRef str);
// 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);
-
- // 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.
+ bool SetFromOptionalStringRef(llvm::StringRef str);
+
+ /// Decode as many UUID bytes as possible from the C string \a cstr.
///
/// \param[in] str
/// An llvm::StringRef that points at a UUID string value (no leading
@@ -88,8 +83,7 @@ public:
/// 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/lldb/include/lldb/Utility/UriParser.h b/lldb/include/lldb/Utility/UriParser.h
index 4a3f01230e1a..6a64c3d747b5 100644
--- a/lldb/include/lldb/Utility/UriParser.h
+++ b/lldb/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 @@ public:
};
}
-#endif // utility_UriParser_h_
+#endif // LLDB_UTILITY_URIPARSER_H
diff --git a/lldb/include/lldb/Utility/UserID.h b/lldb/include/lldb/Utility/UserID.h
index 2dc5cdb23d0e..9fc6985a5a99 100644
--- a/lldb/include/lldb/Utility/UserID.h
+++ b/lldb/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 @@ Stream &operator<<(Stream &strm, const UserID &uid);
} // namespace lldb_private
-#endif // liblldb_UserID_h_
+#endif // LLDB_UTILITY_USERID_H
diff --git a/lldb/include/lldb/Utility/UserIDResolver.h b/lldb/include/lldb/Utility/UserIDResolver.h
index bca82a11b660..e0f7b69cc075 100644
--- a/lldb/include/lldb/Utility/UserIDResolver.h
+++ b/lldb/include/lldb/Utility/UserIDResolver.h
@@ -53,4 +53,4 @@ private:
} // namespace lldb_private
-#endif // #ifndef LLDB_HOST_USERIDRESOLVER_H
+#endif // LLDB_UTILITY_USERIDRESOLVER_H
diff --git a/lldb/include/lldb/Utility/VASPrintf.h b/lldb/include/lldb/Utility/VASPrintf.h
index 582645fd2292..a4b5f7ddae2c 100644
--- a/lldb/include/lldb/Utility/VASPrintf.h
+++ b/lldb/include/lldb/Utility/VASPrintf.h
@@ -17,4 +17,4 @@ namespace lldb_private {
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/lldb/include/lldb/Utility/VMRange.h b/lldb/include/lldb/Utility/VMRange.h
index 72f859b67582..4b01cd86da2c 100644
--- a/lldb/include/lldb/Utility/VMRange.h
+++ b/lldb/include/lldb/Utility/VMRange.h
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#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"
@@ -101,4 +101,4 @@ bool operator>=(const VMRange &lhs, const VMRange &rhs);
} // namespace lldb_private
-#endif // liblldb_VMRange_h_
+#endif // LLDB_UTILITY_VMRANGE_H
diff --git a/lldb/include/lldb/Utility/XcodeSDK.h b/lldb/include/lldb/Utility/XcodeSDK.h
new file mode 100644
index 000000000000..307fe7f46798
--- /dev/null
+++ b/lldb/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(XcodeSDK other);
+
+ XcodeSDK &operator=(XcodeSDK other);
+ XcodeSDK(const XcodeSDK&) = default;
+ bool operator==(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