summaryrefslogtreecommitdiff
path: root/include/lldb/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Utility')
-rw-r--r--include/lldb/Utility/Connection.h212
-rw-r--r--include/lldb/Utility/IOObject.h56
-rw-r--r--include/lldb/Utility/JSON.h2
-rw-r--r--include/lldb/Utility/StructuredData.h556
-rw-r--r--include/lldb/Utility/Timer.h79
-rw-r--r--include/lldb/Utility/TraceOptions.h61
6 files changed, 965 insertions, 1 deletions
diff --git a/include/lldb/Utility/Connection.h b/include/lldb/Utility/Connection.h
new file mode 100644
index 0000000000000..be5641d5fa632
--- /dev/null
+++ b/include/lldb/Utility/Connection.h
@@ -0,0 +1,212 @@
+//===-- Connection.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Connection_h_
+#define liblldb_Connection_h_
+
+#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
+#include "lldb/lldb-enumerations.h" // for ConnectionStatus
+#include "lldb/lldb-forward.h" // for IOObjectSP
+
+#include "llvm/ADT/StringRef.h" // for StringRef
+
+#include <ratio> // for micro
+#include <string>
+
+#include <stddef.h> // for size_t
+
+namespace lldb_private {
+class Status;
+}
+namespace lldb_private {
+template <typename Ratio> class Timeout;
+}
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Connection Connection.h "lldb/Utility/Connection.h"
+/// @brief A communication connection class.
+///
+/// A class that implements that actual communication functions for
+/// connecting/disconnecting, reading/writing, and waiting for bytes
+/// to become available from a two way communication connection.
+///
+/// This class is designed to only do very simple communication
+/// functions. Instances can be instantiated and given to a
+/// Communication class to perform communications where clients can
+/// listen for broadcasts, and perform other higher level communications.
+//----------------------------------------------------------------------
+class Connection {
+public:
+ //------------------------------------------------------------------
+ /// Default constructor
+ //------------------------------------------------------------------
+ Connection() = default;
+
+ //------------------------------------------------------------------
+ /// Virtual destructor since this class gets subclassed and handed
+ /// to a Communication object.
+ //------------------------------------------------------------------
+ virtual ~Connection();
+
+ //------------------------------------------------------------------
+ /// Connect using the connect string \a url.
+ ///
+ /// @param[in] url
+ /// A string that contains all information needed by the
+ /// subclass to connect to another client.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// appropriate error value if this method returns false. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// \b True if the connect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// @see Status& Communication::GetError ();
+ //------------------------------------------------------------------
+ virtual lldb::ConnectionStatus Connect(llvm::StringRef url,
+ Status *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// Disconnect the communications connection if one is currently
+ /// connected.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// appropriate error value if this method returns false. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// \b True if the disconnect succeeded, \b false otherwise. The
+ /// internal error object should be filled in with an
+ /// appropriate value based on the result of this function.
+ ///
+ /// @see Status& Communication::GetError ();
+ //------------------------------------------------------------------
+ virtual lldb::ConnectionStatus Disconnect(Status *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// Check if the connection is valid.
+ ///
+ /// @return
+ /// \b True if this object is currently connected, \b false
+ /// otherwise.
+ //------------------------------------------------------------------
+ virtual bool IsConnected() const = 0;
+
+ //------------------------------------------------------------------
+ /// The read function that attempts to read from the connection.
+ ///
+ /// @param[in] dst
+ /// A destination buffer that must be at least \a dst_len bytes
+ /// long.
+ ///
+ /// @param[in] dst_len
+ /// The number of bytes to attempt to read, and also the max
+ /// number of bytes that can be placed into \a dst.
+ ///
+ /// @param[in] timeout
+ /// The number of microseconds to wait for the data.
+ ///
+ /// @param[out] status
+ /// On return, indicates whether the call was successful or terminated
+ /// due to some error condition.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// appropriate error value if this method returns zero. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// The number of bytes actually read.
+ ///
+ /// @see size_t Communication::Read (void *, size_t, uint32_t);
+ //------------------------------------------------------------------
+ virtual size_t Read(void *dst, size_t dst_len,
+ const Timeout<std::micro> &timeout,
+ lldb::ConnectionStatus &status, Status *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// The actual write function that attempts to write to the
+ /// communications protocol.
+ ///
+ /// Subclasses must override this function.
+ ///
+ /// @param[in] dst
+ /// A desination buffer that must be at least \a dst_len bytes
+ /// long.
+ ///
+ /// @param[in] dst_len
+ /// The number of bytes to attempt to write, and also the
+ /// number of bytes are currently available in \a dst.
+ ///
+ /// @param[out] error_ptr
+ /// A pointer to an error object that should be given an
+ /// appropriate error value if this method returns zero. This
+ /// value can be NULL if the error value should be ignored.
+ ///
+ /// @return
+ /// The number of bytes actually Written.
+ //------------------------------------------------------------------
+ virtual size_t Write(const void *dst, size_t dst_len,
+ lldb::ConnectionStatus &status, Status *error_ptr) = 0;
+
+ //------------------------------------------------------------------
+ /// Returns a URI that describes this connection object
+ ///
+ /// Subclasses may override this function.
+ ///
+ /// @return
+ /// Returns URI or an empty string if disconnecteds
+ //------------------------------------------------------------------
+ virtual std::string GetURI() = 0;
+
+ //------------------------------------------------------------------
+ /// Interrupts an ongoing Read() operation.
+ ///
+ /// If there is an ongoing read operation in another thread, this operation
+ /// return with status == eConnectionStatusInterrupted. Note that if there
+ /// data waiting to be read and an interrupt request is issued, the Read()
+ /// function will return the data immediately without processing the
+ /// interrupt request (which will remain queued for the next Read()
+ /// operation).
+ ///
+ /// @return
+ /// Returns true is the interrupt request was successful.
+ //------------------------------------------------------------------
+ virtual bool InterruptRead() = 0;
+
+ //------------------------------------------------------------------
+ /// Returns the underlying IOObject used by the Connection.
+ ///
+ /// The IOObject can be used to wait for data to become available
+ /// on the connection. If the Connection does not use IOObjects (and
+ /// hence does not support waiting) this function should return a
+ /// null pointer.
+ ///
+ /// @return
+ /// The underlying IOObject used for reading.
+ //------------------------------------------------------------------
+ virtual lldb::IOObjectSP GetReadObject() { return lldb::IOObjectSP(); }
+
+private:
+ //------------------------------------------------------------------
+ // For Connection only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN(Connection);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Connection_h_
diff --git a/include/lldb/Utility/IOObject.h b/include/lldb/Utility/IOObject.h
new file mode 100644
index 0000000000000..61f288183850b
--- /dev/null
+++ b/include/lldb/Utility/IOObject.h
@@ -0,0 +1,56 @@
+//===-- IOObject.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Host_Common_IOObject_h_
+#define liblldb_Host_Common_IOObject_h_
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+class IOObject {
+public:
+ typedef enum {
+ eFDTypeFile, // Other FD requiring read/write
+ eFDTypeSocket, // Socket requiring send/recv
+ } FDType;
+
+ // TODO: On Windows this should be a HANDLE, and wait should use
+ // WaitForMultipleObjects
+ typedef int WaitableHandle;
+ static const WaitableHandle kInvalidHandleValue;
+
+ IOObject(FDType type, bool should_close)
+ : m_fd_type(type), m_should_close_fd(should_close) {}
+ virtual ~IOObject();
+
+ virtual Status Read(void *buf, size_t &num_bytes) = 0;
+ virtual Status Write(const void *buf, size_t &num_bytes) = 0;
+ virtual bool IsValid() const = 0;
+ virtual Status Close() = 0;
+
+ FDType GetFdType() const { return m_fd_type; }
+
+ virtual WaitableHandle GetWaitableHandle() = 0;
+
+protected:
+ FDType m_fd_type;
+ bool m_should_close_fd; // True if this class should close the file descriptor
+ // when it goes away.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(IOObject);
+};
+} // namespace lldb_private
+
+#endif
diff --git a/include/lldb/Utility/JSON.h b/include/lldb/Utility/JSON.h
index bf8ed9afc008d..8bf9c4b37b023 100644
--- a/include/lldb/Utility/JSON.h
+++ b/include/lldb/Utility/JSON.h
@@ -269,7 +269,7 @@ public:
EndOfFile
};
- JSONParser(const char *cstr);
+ JSONParser(llvm::StringRef data);
int GetEscapedChar(bool &was_escaped);
diff --git a/include/lldb/Utility/StructuredData.h b/include/lldb/Utility/StructuredData.h
new file mode 100644
index 0000000000000..2ea5fb98e0555
--- /dev/null
+++ b/include/lldb/Utility/StructuredData.h
@@ -0,0 +1,556 @@
+//===-- StructuredData.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StructuredData_h_
+#define liblldb_StructuredData_h_
+
+#include "llvm/ADT/StringRef.h"
+
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/FileSpec.h" // for FileSpec
+#include "lldb/lldb-enumerations.h" // for StructuredDataType
+
+#include <cassert> // for assert
+#include <cstddef> // for size_t
+#include <cstdint> // for uint64_t
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <type_traits> // for move
+#include <utility>
+#include <vector>
+
+namespace lldb_private {
+class Status;
+}
+namespace lldb_private {
+class Stream;
+}
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class StructuredData StructuredData.h "lldb/Utility/StructuredData.h"
+/// @brief A class which can hold structured data
+///
+/// The StructuredData class is designed to hold the data from a JSON
+/// or plist style file -- a serialized data structure with dictionaries
+/// (maps, hashes), arrays, and concrete values like integers, floating
+/// point numbers, strings, booleans.
+///
+/// StructuredData does not presuppose any knowledge of the schema for
+/// the data it is holding; it can parse JSON data, for instance, and
+/// other parts of lldb can iterate through the parsed data set to find
+/// keys and values that may be present.
+//----------------------------------------------------------------------
+
+class StructuredData {
+public:
+ class Object;
+ class Array;
+ class Integer;
+ class Float;
+ class Boolean;
+ class String;
+ class Dictionary;
+ class Generic;
+
+ typedef std::shared_ptr<Object> ObjectSP;
+ typedef std::shared_ptr<Array> ArraySP;
+ typedef std::shared_ptr<Integer> IntegerSP;
+ typedef std::shared_ptr<Float> FloatSP;
+ typedef std::shared_ptr<Boolean> BooleanSP;
+ typedef std::shared_ptr<String> StringSP;
+ typedef std::shared_ptr<Dictionary> DictionarySP;
+ typedef std::shared_ptr<Generic> GenericSP;
+
+ class Object : public std::enable_shared_from_this<Object> {
+ public:
+ Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
+ : m_type(t) {}
+
+ virtual ~Object() = default;
+
+ virtual bool IsValid() const { return true; }
+
+ virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; }
+
+ lldb::StructuredDataType GetType() const { return m_type; }
+
+ void SetType(lldb::StructuredDataType t) { m_type = t; }
+
+ Array *GetAsArray() {
+ return ((m_type == lldb::eStructuredDataTypeArray)
+ ? static_cast<Array *>(this)
+ : nullptr);
+ }
+
+ Dictionary *GetAsDictionary() {
+ return ((m_type == lldb::eStructuredDataTypeDictionary)
+ ? static_cast<Dictionary *>(this)
+ : nullptr);
+ }
+
+ Integer *GetAsInteger() {
+ return ((m_type == lldb::eStructuredDataTypeInteger)
+ ? static_cast<Integer *>(this)
+ : nullptr);
+ }
+
+ uint64_t GetIntegerValue(uint64_t fail_value = 0) {
+ Integer *integer = GetAsInteger();
+ return ((integer != nullptr) ? integer->GetValue() : fail_value);
+ }
+
+ Float *GetAsFloat() {
+ return ((m_type == lldb::eStructuredDataTypeFloat)
+ ? static_cast<Float *>(this)
+ : nullptr);
+ }
+
+ double GetFloatValue(double fail_value = 0.0) {
+ Float *f = GetAsFloat();
+ return ((f != nullptr) ? f->GetValue() : fail_value);
+ }
+
+ Boolean *GetAsBoolean() {
+ return ((m_type == lldb::eStructuredDataTypeBoolean)
+ ? static_cast<Boolean *>(this)
+ : nullptr);
+ }
+
+ bool GetBooleanValue(bool fail_value = false) {
+ Boolean *b = GetAsBoolean();
+ return ((b != nullptr) ? b->GetValue() : fail_value);
+ }
+
+ String *GetAsString() {
+ return ((m_type == lldb::eStructuredDataTypeString)
+ ? static_cast<String *>(this)
+ : nullptr);
+ }
+
+ llvm::StringRef GetStringValue(const char *fail_value = nullptr) {
+ String *s = GetAsString();
+ if (s)
+ return s->GetValue();
+
+ return fail_value;
+ }
+
+ Generic *GetAsGeneric() {
+ return ((m_type == lldb::eStructuredDataTypeGeneric)
+ ? static_cast<Generic *>(this)
+ : nullptr);
+ }
+
+ ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path);
+
+ void DumpToStdout(bool pretty_print = true) const;
+
+ virtual void Dump(Stream &s, bool pretty_print = true) const = 0;
+
+ private:
+ lldb::StructuredDataType m_type;
+ };
+
+ class Array : public Object {
+ public:
+ Array() : Object(lldb::eStructuredDataTypeArray) {}
+
+ ~Array() override = default;
+
+ bool
+ ForEach(std::function<bool(Object *object)> const &foreach_callback) const {
+ for (const auto &object_sp : m_items) {
+ if (foreach_callback(object_sp.get()) == false)
+ return false;
+ }
+ return true;
+ }
+
+ size_t GetSize() const { return m_items.size(); }
+
+ ObjectSP operator[](size_t idx) {
+ if (idx < m_items.size())
+ return m_items[idx];
+ return ObjectSP();
+ }
+
+ ObjectSP GetItemAtIndex(size_t idx) const {
+ assert(idx < GetSize());
+ if (idx < m_items.size())
+ return m_items[idx];
+ return ObjectSP();
+ }
+
+ template <class IntType>
+ bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
+ ObjectSP value_sp = GetItemAtIndex(idx);
+ if (value_sp.get()) {
+ if (auto int_value = value_sp->GetAsInteger()) {
+ result = static_cast<IntType>(int_value->GetValue());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <class IntType>
+ bool GetItemAtIndexAsInteger(size_t idx, IntType &result,
+ IntType default_val) const {
+ bool success = GetItemAtIndexAsInteger(idx, result);
+ if (!success)
+ result = default_val;
+ return success;
+ }
+
+ bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const {
+ ObjectSP value_sp = GetItemAtIndex(idx);
+ if (value_sp.get()) {
+ if (auto string_value = value_sp->GetAsString()) {
+ result = string_value->GetValue();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result,
+ llvm::StringRef default_val) const {
+ bool success = GetItemAtIndexAsString(idx, result);
+ if (!success)
+ result = default_val;
+ return success;
+ }
+
+ bool GetItemAtIndexAsString(size_t idx, ConstString &result) const {
+ ObjectSP value_sp = GetItemAtIndex(idx);
+ if (value_sp.get()) {
+ if (auto string_value = value_sp->GetAsString()) {
+ result = ConstString(string_value->GetValue());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool GetItemAtIndexAsString(size_t idx, ConstString &result,
+ const char *default_val) const {
+ bool success = GetItemAtIndexAsString(idx, result);
+ if (!success)
+ result.SetCString(default_val);
+ return success;
+ }
+
+ bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const {
+ result = nullptr;
+ ObjectSP value_sp = GetItemAtIndex(idx);
+ if (value_sp.get()) {
+ result = value_sp->GetAsDictionary();
+ return (result != nullptr);
+ }
+ return false;
+ }
+
+ bool GetItemAtIndexAsArray(size_t idx, Array *&result) const {
+ result = nullptr;
+ ObjectSP value_sp = GetItemAtIndex(idx);
+ if (value_sp.get()) {
+ result = value_sp->GetAsArray();
+ return (result != nullptr);
+ }
+ return false;
+ }
+
+ void Push(ObjectSP item) { m_items.push_back(item); }
+
+ void AddItem(ObjectSP item) { m_items.push_back(item); }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+
+ protected:
+ typedef std::vector<ObjectSP> collection;
+ collection m_items;
+ };
+
+ class Integer : public Object {
+ public:
+ Integer(uint64_t i = 0)
+ : Object(lldb::eStructuredDataTypeInteger), m_value(i) {}
+
+ ~Integer() override = default;
+
+ void SetValue(uint64_t value) { m_value = value; }
+
+ uint64_t GetValue() { return m_value; }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+
+ protected:
+ uint64_t m_value;
+ };
+
+ class Float : public Object {
+ public:
+ Float(double d = 0.0)
+ : Object(lldb::eStructuredDataTypeFloat), m_value(d) {}
+
+ ~Float() override = default;
+
+ void SetValue(double value) { m_value = value; }
+
+ double GetValue() { return m_value; }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+
+ protected:
+ double m_value;
+ };
+
+ class Boolean : public Object {
+ public:
+ Boolean(bool b = false)
+ : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {}
+
+ ~Boolean() override = default;
+
+ void SetValue(bool value) { m_value = value; }
+
+ bool GetValue() { return m_value; }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+
+ protected:
+ bool m_value;
+ };
+
+ class String : public Object {
+ public:
+ String() : Object(lldb::eStructuredDataTypeString) {}
+ explicit String(llvm::StringRef S)
+ : Object(lldb::eStructuredDataTypeString), m_value(S) {}
+
+ void SetValue(llvm::StringRef S) { m_value = S; }
+
+ llvm::StringRef GetValue() { return m_value; }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+
+ protected:
+ std::string m_value;
+ };
+
+ class Dictionary : public Object {
+ public:
+ Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {}
+
+ ~Dictionary() override = default;
+
+ size_t GetSize() const { return m_dict.size(); }
+
+ void ForEach(std::function<bool(ConstString key, Object *object)> const
+ &callback) const {
+ for (const auto &pair : m_dict) {
+ if (callback(pair.first, pair.second.get()) == false)
+ break;
+ }
+ }
+
+ ObjectSP GetKeys() const {
+ auto object_sp = std::make_shared<Array>();
+ collection::const_iterator iter;
+ for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) {
+ auto key_object_sp = std::make_shared<String>();
+ key_object_sp->SetValue(iter->first.AsCString());
+ object_sp->Push(key_object_sp);
+ }
+ return object_sp;
+ }
+
+ ObjectSP GetValueForKey(llvm::StringRef key) const {
+ ObjectSP value_sp;
+ if (!key.empty()) {
+ ConstString key_cs(key);
+ collection::const_iterator iter = m_dict.find(key_cs);
+ if (iter != m_dict.end())
+ value_sp = iter->second;
+ }
+ return value_sp;
+ }
+
+ bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {
+ bool success = false;
+ ObjectSP value_sp = GetValueForKey(key);
+ if (value_sp.get()) {
+ Boolean *result_ptr = value_sp->GetAsBoolean();
+ if (result_ptr) {
+ result = result_ptr->GetValue();
+ success = true;
+ }
+ }
+ return success;
+ }
+ template <class IntType>
+ bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
+ ObjectSP value_sp = GetValueForKey(key);
+ if (value_sp) {
+ if (auto int_value = value_sp->GetAsInteger()) {
+ result = static_cast<IntType>(int_value->GetValue());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <class IntType>
+ bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result,
+ IntType default_val) const {
+ bool success = GetValueForKeyAsInteger<IntType>(key, result);
+ if (!success)
+ result = default_val;
+ return success;
+ }
+
+ bool GetValueForKeyAsString(llvm::StringRef key,
+ llvm::StringRef &result) const {
+ ObjectSP value_sp = GetValueForKey(key);
+ if (value_sp.get()) {
+ if (auto string_value = value_sp->GetAsString()) {
+ result = string_value->GetValue();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result,
+ const char *default_val) const {
+ bool success = GetValueForKeyAsString(key, result);
+ if (!success) {
+ if (default_val)
+ result = default_val;
+ else
+ result = llvm::StringRef();
+ }
+ return success;
+ }
+
+ bool GetValueForKeyAsString(llvm::StringRef key,
+ ConstString &result) const {
+ ObjectSP value_sp = GetValueForKey(key);
+ if (value_sp.get()) {
+ if (auto string_value = value_sp->GetAsString()) {
+ result = ConstString(string_value->GetValue());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result,
+ const char *default_val) const {
+ bool success = GetValueForKeyAsString(key, result);
+ if (!success)
+ result.SetCString(default_val);
+ return success;
+ }
+
+ bool GetValueForKeyAsDictionary(llvm::StringRef key,
+ Dictionary *&result) const {
+ result = nullptr;
+ ObjectSP value_sp = GetValueForKey(key);
+ if (value_sp.get()) {
+ result = value_sp->GetAsDictionary();
+ return (result != nullptr);
+ }
+ return false;
+ }
+
+ bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const {
+ result = nullptr;
+ ObjectSP value_sp = GetValueForKey(key);
+ if (value_sp.get()) {
+ result = value_sp->GetAsArray();
+ return (result != nullptr);
+ }
+ return false;
+ }
+
+ bool HasKey(llvm::StringRef key) const {
+ ConstString key_cs(key);
+ collection::const_iterator search = m_dict.find(key_cs);
+ return search != m_dict.end();
+ }
+
+ void AddItem(llvm::StringRef key, ObjectSP value_sp) {
+ ConstString key_cs(key);
+ m_dict[key_cs] = value_sp;
+ }
+
+ void AddIntegerItem(llvm::StringRef key, uint64_t value) {
+ AddItem(key, std::make_shared<Integer>(value));
+ }
+
+ void AddFloatItem(llvm::StringRef key, double value) {
+ AddItem(key, std::make_shared<Float>(value));
+ }
+
+ void AddStringItem(llvm::StringRef key, llvm::StringRef value) {
+ AddItem(key, std::make_shared<String>(std::move(value)));
+ }
+
+ void AddBooleanItem(llvm::StringRef key, bool value) {
+ AddItem(key, std::make_shared<Boolean>(value));
+ }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+
+ protected:
+ typedef std::map<ConstString, ObjectSP> collection;
+ collection m_dict;
+ };
+
+ class Null : public Object {
+ public:
+ Null() : Object(lldb::eStructuredDataTypeNull) {}
+
+ ~Null() override = default;
+
+ bool IsValid() const override { return false; }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+ };
+
+ class Generic : public Object {
+ public:
+ explicit Generic(void *object = nullptr)
+ : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {}
+
+ void SetValue(void *value) { m_object = value; }
+
+ void *GetValue() const { return m_object; }
+
+ bool IsValid() const override { return m_object != nullptr; }
+
+ void Dump(Stream &s, bool pretty_print = true) const override;
+
+ private:
+ void *m_object;
+ };
+
+ static ObjectSP ParseJSON(std::string json_text);
+
+ static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_StructuredData_h_
diff --git a/include/lldb/Utility/Timer.h b/include/lldb/Utility/Timer.h
new file mode 100644
index 0000000000000..c06ac17d344de
--- /dev/null
+++ b/include/lldb/Utility/Timer.h
@@ -0,0 +1,79 @@
+//===-- Timer.h -------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Timer_h_
+#define liblldb_Timer_h_
+
+#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
+#include "llvm/Support/Chrono.h"
+#include <atomic>
+#include <stdint.h> // for uint32_t
+
+namespace lldb_private {
+class Stream;
+
+//----------------------------------------------------------------------
+/// @class Timer Timer.h "lldb/Utility/Timer.h"
+/// @brief A timer class that simplifies common timing metrics.
+//----------------------------------------------------------------------
+
+class Timer {
+public:
+ class Category {
+ public:
+ explicit Category(const char *category_name);
+
+ private:
+ friend class Timer;
+ const char *m_name;
+ std::atomic<uint64_t> m_nanos;
+ std::atomic<Category *> m_next;
+
+ DISALLOW_COPY_AND_ASSIGN(Category);
+ };
+
+ //--------------------------------------------------------------
+ /// Default constructor.
+ //--------------------------------------------------------------
+ Timer(Category &category, const char *format, ...)
+ __attribute__((format(printf, 3, 4)));
+
+ //--------------------------------------------------------------
+ /// Destructor
+ //--------------------------------------------------------------
+ ~Timer();
+
+ void Dump();
+
+ static void SetDisplayDepth(uint32_t depth);
+
+ static void SetQuiet(bool value);
+
+ static void DumpCategoryTimes(Stream *s);
+
+ static void ResetCategoryTimes();
+
+protected:
+ using TimePoint = std::chrono::steady_clock::time_point;
+ void ChildDuration(TimePoint::duration dur) { m_child_duration += dur; }
+
+ Category &m_category;
+ TimePoint m_total_start;
+ TimePoint::duration m_child_duration{0};
+
+ static std::atomic<bool> g_quiet;
+ static std::atomic<unsigned> g_display_depth;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(Timer);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Timer_h_
diff --git a/include/lldb/Utility/TraceOptions.h b/include/lldb/Utility/TraceOptions.h
new file mode 100644
index 0000000000000..325ff74e6f556
--- /dev/null
+++ b/include/lldb/Utility/TraceOptions.h
@@ -0,0 +1,61 @@
+//===-- TraceOptions.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TraceOptions_h_
+#define liblldb_TraceOptions_h_
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Utility/StructuredData.h"
+
+namespace lldb_private {
+class TraceOptions {
+public:
+ TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {}
+
+ const StructuredData::DictionarySP &getTraceParams() const {
+ return m_trace_params;
+ }
+
+ lldb::TraceType getType() const { return m_type; }
+
+ uint64_t getTraceBufferSize() const { return m_trace_buffer_size; }
+
+ uint64_t getMetaDataBufferSize() const { return m_meta_data_buffer_size; }
+
+ void setTraceParams(const StructuredData::DictionarySP &dict_obj) {
+ m_trace_params = dict_obj;
+ }
+
+ void setType(lldb::TraceType type) { m_type = type; }
+
+ void setTraceBufferSize(uint64_t size) { m_trace_buffer_size = size; }
+
+ void setMetaDataBufferSize(uint64_t size) { m_meta_data_buffer_size = size; }
+
+ void setThreadID(lldb::tid_t thread_id) { m_thread_id = thread_id; }
+
+ lldb::tid_t getThreadID() const { return m_thread_id; }
+
+private:
+ lldb::TraceType m_type;
+ uint64_t m_trace_buffer_size;
+ uint64_t m_meta_data_buffer_size;
+ lldb::tid_t m_thread_id;
+
+ /// m_trace_params is meant to hold any custom parameters
+ /// apart from meta buffer size and trace size.
+ /// The interpretation of such parameters is left to
+ /// the lldb-server.
+ StructuredData::DictionarySP m_trace_params;
+};
+}
+
+#endif // liblldb_TraceOptions_h_