diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:26:05 +0000 |
commit | 14f1b3e8826ce43b978db93a62d1166055db5394 (patch) | |
tree | 0a00ad8d3498783fe0193f3b656bca17c4c8697d /include/lldb/Utility | |
parent | 4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff) | |
download | src-14f1b3e8826ce43b978db93a62d1166055db5394.tar.gz src-14f1b3e8826ce43b978db93a62d1166055db5394.zip |
Vendor import of lldb trunk r290819:vendor/lldb/lldb-trunk-r290819
Notes
Notes:
svn path=/vendor/lldb/dist/; revision=311128
svn path=/vendor/lldb/lldb-trunk-r290819/; revision=311129; tag=vendor/lldb/lldb-trunk-r290819
Diffstat (limited to 'include/lldb/Utility')
-rw-r--r-- | include/lldb/Utility/AnsiTerminal.h | 236 | ||||
-rw-r--r-- | include/lldb/Utility/CleanUp.h | 446 | ||||
-rw-r--r-- | include/lldb/Utility/ConvertEnum.h | 3 | ||||
-rw-r--r-- | include/lldb/Utility/Either.h | 240 | ||||
-rw-r--r-- | include/lldb/Utility/Iterable.h | 350 | ||||
-rw-r--r-- | include/lldb/Utility/JSON.h | 589 | ||||
-rw-r--r-- | include/lldb/Utility/LLDBAssert.h | 14 | ||||
-rw-r--r-- | include/lldb/Utility/NameMatches.h | 8 | ||||
-rw-r--r-- | include/lldb/Utility/PriorityPointerPair.h | 176 | ||||
-rw-r--r-- | include/lldb/Utility/ProcessStructReader.h | 152 | ||||
-rw-r--r-- | include/lldb/Utility/PseudoTerminal.h | 444 | ||||
-rw-r--r-- | include/lldb/Utility/Range.h | 108 | ||||
-rw-r--r-- | include/lldb/Utility/RegisterNumber.h | 53 | ||||
-rw-r--r-- | include/lldb/Utility/SafeMachO.h | 170 | ||||
-rw-r--r-- | include/lldb/Utility/SelectHelper.h | 76 | ||||
-rw-r--r-- | include/lldb/Utility/SharedCluster.h | 133 | ||||
-rw-r--r-- | include/lldb/Utility/SharingPtr.h | 1140 | ||||
-rw-r--r-- | include/lldb/Utility/StringExtractor.h | 265 | ||||
-rw-r--r-- | include/lldb/Utility/StringLexer.h | 89 | ||||
-rw-r--r-- | include/lldb/Utility/TaskPool.h | 283 | ||||
-rw-r--r-- | include/lldb/Utility/Timeout.h | 55 |
21 files changed, 2277 insertions, 2753 deletions
diff --git a/include/lldb/Utility/AnsiTerminal.h b/include/lldb/Utility/AnsiTerminal.h index a43dd1ba4325..5eaf2fd0e069 100644 --- a/include/lldb/Utility/AnsiTerminal.h +++ b/include/lldb/Utility/AnsiTerminal.h @@ -7,124 +7,130 @@ // //===----------------------------------------------------------------------===// +#define ANSI_FG_COLOR_BLACK 30 +#define ANSI_FG_COLOR_RED 31 +#define ANSI_FG_COLOR_GREEN 32 +#define ANSI_FG_COLOR_YELLOW 33 +#define ANSI_FG_COLOR_BLUE 34 +#define ANSI_FG_COLOR_PURPLE 35 +#define ANSI_FG_COLOR_CYAN 36 +#define ANSI_FG_COLOR_WHITE 37 + +#define ANSI_BG_COLOR_BLACK 40 +#define ANSI_BG_COLOR_RED 41 +#define ANSI_BG_COLOR_GREEN 42 +#define ANSI_BG_COLOR_YELLOW 43 +#define ANSI_BG_COLOR_BLUE 44 +#define ANSI_BG_COLOR_PURPLE 45 +#define ANSI_BG_COLOR_CYAN 46 +#define ANSI_BG_COLOR_WHITE 47 + +#define ANSI_SPECIAL_FRAMED 51 +#define ANSI_SPECIAL_ENCIRCLED 52 + +#define ANSI_CTRL_NORMAL 0 +#define ANSI_CTRL_BOLD 1 +#define ANSI_CTRL_FAINT 2 +#define ANSI_CTRL_ITALIC 3 +#define ANSI_CTRL_UNDERLINE 4 +#define ANSI_CTRL_SLOW_BLINK 5 +#define ANSI_CTRL_FAST_BLINK 6 +#define ANSI_CTRL_IMAGE_NEGATIVE 7 +#define ANSI_CTRL_CONCEAL 8 +#define ANSI_CTRL_CROSSED_OUT 9 + +#define ANSI_ESC_START "\033[" +#define ANSI_ESC_END "m" + +#define ANSI_STR(s) #s +#define ANSI_DEF_STR(s) ANSI_STR(s) + +#define ANSI_ESCAPE1(s) ANSI_ESC_START ANSI_DEF_STR(s) ANSI_ESC_END + +#define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END +#define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" + +#include <string> +namespace lldb_utility { -#define ANSI_FG_COLOR_BLACK 30 -#define ANSI_FG_COLOR_RED 31 -#define ANSI_FG_COLOR_GREEN 32 -#define ANSI_FG_COLOR_YELLOW 33 -#define ANSI_FG_COLOR_BLUE 34 -#define ANSI_FG_COLOR_PURPLE 35 -#define ANSI_FG_COLOR_CYAN 36 -#define ANSI_FG_COLOR_WHITE 37 - -#define ANSI_BG_COLOR_BLACK 40 -#define ANSI_BG_COLOR_RED 41 -#define ANSI_BG_COLOR_GREEN 42 -#define ANSI_BG_COLOR_YELLOW 43 -#define ANSI_BG_COLOR_BLUE 44 -#define ANSI_BG_COLOR_PURPLE 45 -#define ANSI_BG_COLOR_CYAN 46 -#define ANSI_BG_COLOR_WHITE 47 - -#define ANSI_SPECIAL_FRAMED 51 -#define ANSI_SPECIAL_ENCIRCLED 52 - -#define ANSI_CTRL_NORMAL 0 -#define ANSI_CTRL_BOLD 1 -#define ANSI_CTRL_FAINT 2 -#define ANSI_CTRL_ITALIC 3 -#define ANSI_CTRL_UNDERLINE 4 -#define ANSI_CTRL_SLOW_BLINK 5 -#define ANSI_CTRL_FAST_BLINK 6 -#define ANSI_CTRL_IMAGE_NEGATIVE 7 -#define ANSI_CTRL_CONCEAL 8 -#define ANSI_CTRL_CROSSED_OUT 9 - -#define ANSI_ESC_START "\033[" -#define ANSI_ESC_END "m" - -#define ANSI_STR(s) #s -#define ANSI_DEF_STR(s) ANSI_STR(s) - -#define ANSI_ESCAPE1(s) ANSI_ESC_START ANSI_DEF_STR(s) ANSI_ESC_END - -#define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END -#define ANSI_2_CTRL(ctrl1,ctrl2) "\033["##ctrl1";"##ctrl2 ANSI_ESC_END +namespace ansi { + +inline std::string FormatAnsiTerminalCodes(llvm::StringRef format, + bool do_color = true) { + // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is + // false. + static const struct { + const char *name; + const char *value; + } g_color_tokens[] = { +#define _TO_STR2(_val) #_val +#define _TO_STR(_val) _TO_STR2(_val) + {"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END}, + {"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END}, + {"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END}, + {"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END}, + {"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END}, + {"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END}, + {"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END}, + {"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END}, + {"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END}, + {"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END}, + {"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END}, + {"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END}, + {"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END}, + {"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END}, + {"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END}, + {"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END}, + {"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END}, + {"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END}, + {"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END}, + {"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END}, + {"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END}, + {"slow-blink}", + ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END}, + {"fast-blink}", + ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END}, + {"negative}", + ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END}, + {"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END}, + {"crossed-out}", + ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END}, +#undef _TO_STR +#undef _TO_STR2 + }; + auto codes = llvm::makeArrayRef(g_color_tokens); + + static const char tok_hdr[] = "${ansi."; + + std::string fmt; + while (!format.empty()) { + llvm::StringRef left, right; + std::tie(left, right) = format.split(tok_hdr); + + fmt.append(left); + + if (left == format && right.empty()) { + // The header was not found. Just exit. + break; + } -namespace lldb_utility { + for (const auto &code : codes) { + if (!right.consume_front(code.name)) + continue; - namespace ansi { - - inline std::string - FormatAnsiTerminalCodes(const char *format, bool do_color = true) - { - // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is false. - static const struct - { - const char *name; - const char *value; - } g_color_tokens[] = - { - #define _TO_STR2(_val) #_val - #define _TO_STR(_val) _TO_STR2(_val) - { "fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END }, - { "fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END }, - { "fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END }, - { "fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END }, - { "fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END }, - { "fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END }, - { "fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END }, - { "fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END }, - { "bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END }, - { "bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END }, - { "bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END }, - { "bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END }, - { "bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END }, - { "bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END }, - { "bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END }, - { "bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END }, - { "normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END }, - { "bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END }, - { "faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END }, - { "italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END }, - { "underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END }, - { "slow-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END }, - { "fast-blink}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END }, - { "negative}", ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END }, - { "conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END }, - { "crossed-out}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END }, - #undef _TO_STR - #undef _TO_STR2 - }; - static const char tok_hdr[] = "${ansi."; - - std::string fmt; - for (const char *p = format; *p; ++p) - { - const char *tok_start = strstr (p, tok_hdr); - if (!tok_start) - { - fmt.append (p, strlen(p)); - break; - } - - fmt.append (p, tok_start - p); - p = tok_start; - - const char *tok_str = tok_start + sizeof(tok_hdr) - 1; - for (size_t i = 0; i < sizeof(g_color_tokens) / sizeof(g_color_tokens[0]); ++i) - { - if (!strncmp (tok_str, g_color_tokens[i].name, strlen(g_color_tokens[i].name))) - { - if (do_color) - fmt.append (g_color_tokens[i].value); - p = tok_str + strlen (g_color_tokens[i].name) - 1; - break; - } - } - } - return fmt; - } + if (do_color) + fmt.append(code.value); + format = right; + break; } + + format = format.drop_front(); + } + return fmt; +} +} } diff --git a/include/lldb/Utility/CleanUp.h b/include/lldb/Utility/CleanUp.h index 9ffe5de27df1..0d7bc8d99219 100644 --- a/include/lldb/Utility/CleanUp.h +++ b/include/lldb/Utility/CleanUp.h @@ -17,33 +17,33 @@ namespace lldb_utility { //---------------------------------------------------------------------- // Templated class that guarantees that a cleanup callback function will -// be called. The cleanup function will be called once under the +// be called. The cleanup function will be called once under the // following conditions: // - when the object goes out of scope -// - when the user explicitly calls clean. +// - when the user explicitly calls clean. // - the current value will be cleaned up when a new value is set using // set(T value) as long as the current value hasn't already been cleaned. // // This class is designed to be used with simple types for type T (like -// file descriptors, opaque handles, pointers, etc). If more complex +// file descriptors, opaque handles, pointers, etc). If more complex // type T objects are desired, we need to probably specialize this class -// to take "const T&" for all input T parameters. Yet if a type T is -// complex already it might be better to build the cleanup functionality +// to take "const T&" for all input T parameters. Yet if a type T is +// complex already it might be better to build the cleanup functionality // into T. // -// The cleanup function must take one argument that is of type T. +// The cleanup function must take one argument that is of type T. // The calback function return type is R. The return value is currently // needed for "CallbackType". If there is an easy way to get around the // need for the return value we can change this class. // // The two template parameters are: -// T - The variable type of value that will be stored and used as the +// T - The variable type of value that will be stored and used as the // sole argument for the cleanup callback. // R - The return type for the cleanup function. // // EXAMPLES -// // Use with file handles that get opened where you want to close -// // them. Below we use "int open(const char *path, int oflag, ...)" +// // Use with file handles that get opened where you want to close +// // them. Below we use "int open(const char *path, int oflag, ...)" // // which returns an integer file descriptor. -1 is the invalid file // // descriptor so to make an object that will call "int close(int fd)" // // automatically we can use: @@ -53,269 +53,207 @@ namespace lldb_utility { // // malloc/free example // CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free); //---------------------------------------------------------------------- -template <typename T, typename R = void> -class CleanUp -{ +template <typename T, typename R = void> class CleanUp { public: - typedef T value_type; - typedef std::function<R(value_type)> CallbackType; + typedef T value_type; + typedef std::function<R(value_type)> CallbackType; - //---------------------------------------------------------------------- - // Constructor that sets the current value only. No values are - // considered to be invalid and the cleanup function will be called - // regardless of the value of m_current_value. - //---------------------------------------------------------------------- - CleanUp (value_type value, CallbackType callback) : - m_current_value (value), - m_invalid_value (), - m_callback (callback), - m_callback_called (false), - m_invalid_value_is_valid (false) - { - } + //---------------------------------------------------------------------- + // Constructor that sets the current value only. No values are + // considered to be invalid and the cleanup function will be called + // regardless of the value of m_current_value. + //---------------------------------------------------------------------- + CleanUp(value_type value, CallbackType callback) + : m_current_value(value), m_invalid_value(), m_callback(callback), + m_callback_called(false), m_invalid_value_is_valid(false) {} - //---------------------------------------------------------------------- - // Constructor that sets the current value and also the invalid value. - // The cleanup function will be called on "m_value" as long as it isn't - // equal to "m_invalid_value". - //---------------------------------------------------------------------- - CleanUp (value_type value, value_type invalid, CallbackType callback) : - m_current_value (value), - m_invalid_value (invalid), - m_callback (callback), - m_callback_called (false), - m_invalid_value_is_valid (true) - { - } + //---------------------------------------------------------------------- + // Constructor that sets the current value and also the invalid value. + // The cleanup function will be called on "m_value" as long as it isn't + // equal to "m_invalid_value". + //---------------------------------------------------------------------- + CleanUp(value_type value, value_type invalid, CallbackType callback) + : m_current_value(value), m_invalid_value(invalid), m_callback(callback), + m_callback_called(false), m_invalid_value_is_valid(true) {} - //---------------------------------------------------------------------- - // Automatically cleanup when this object goes out of scope. - //---------------------------------------------------------------------- - ~CleanUp () - { - clean(); - } + //---------------------------------------------------------------------- + // Automatically cleanup when this object goes out of scope. + //---------------------------------------------------------------------- + ~CleanUp() { clean(); } - //---------------------------------------------------------------------- - // Access the value stored in this class - //---------------------------------------------------------------------- - value_type get() - { - return m_current_value; - } + //---------------------------------------------------------------------- + // Access the value stored in this class + //---------------------------------------------------------------------- + value_type get() { return m_current_value; } - //---------------------------------------------------------------------- - // Access the value stored in this class - //---------------------------------------------------------------------- - const value_type - get() const - { - return m_current_value; - } + //---------------------------------------------------------------------- + // Access the value stored in this class + //---------------------------------------------------------------------- + const value_type get() const { return m_current_value; } - //---------------------------------------------------------------------- - // Reset the owned value to "value". If a current value is valid and - // the cleanup callback hasn't been called, the previous value will - // be cleaned up (see void CleanUp::clean()). - //---------------------------------------------------------------------- - void - set (const value_type value) - { - // Cleanup the current value if needed - clean (); - // Now set the new value and mark our callback as not called - m_callback_called = false; - m_current_value = value; - } + //---------------------------------------------------------------------- + // Reset the owned value to "value". If a current value is valid and + // the cleanup callback hasn't been called, the previous value will + // be cleaned up (see void CleanUp::clean()). + //---------------------------------------------------------------------- + void set(const value_type value) { + // Cleanup the current value if needed + clean(); + // Now set the new value and mark our callback as not called + m_callback_called = false; + m_current_value = value; + } - //---------------------------------------------------------------------- - // Checks is "m_current_value" is valid. The value is considered valid - // no invalid value was supplied during construction of this object or - // if an invalid value was supplied and "m_current_value" is not equal - // to "m_invalid_value". - // - // Returns true if "m_current_value" is valid, false otherwise. - //---------------------------------------------------------------------- - bool - is_valid() const - { - if (m_invalid_value_is_valid) - return m_current_value != m_invalid_value; - return true; - } + //---------------------------------------------------------------------- + // Checks is "m_current_value" is valid. The value is considered valid + // no invalid value was supplied during construction of this object or + // if an invalid value was supplied and "m_current_value" is not equal + // to "m_invalid_value". + // + // Returns true if "m_current_value" is valid, false otherwise. + //---------------------------------------------------------------------- + bool is_valid() const { + if (m_invalid_value_is_valid) + return m_current_value != m_invalid_value; + return true; + } - //---------------------------------------------------------------------- - // This function will call the cleanup callback provided in the - // constructor one time if the value is considered valid (See is_valid()). - // This function sets m_callback_called to true so we don't call the - // cleanup callback multiple times on the same value. - //---------------------------------------------------------------------- - void - clean() - { - if (m_callback && !m_callback_called) - { - m_callback_called = true; - if (is_valid()) - m_callback(m_current_value); - } + //---------------------------------------------------------------------- + // This function will call the cleanup callback provided in the + // constructor one time if the value is considered valid (See is_valid()). + // This function sets m_callback_called to true so we don't call the + // cleanup callback multiple times on the same value. + //---------------------------------------------------------------------- + void clean() { + if (m_callback && !m_callback_called) { + m_callback_called = true; + if (is_valid()) + m_callback(m_current_value); } + } - //---------------------------------------------------------------------- - // Cancels the cleanup that would have been called on "m_current_value" - // if it was valid. This function can be used to release the value - // contained in this object so ownership can be transferred to the caller. - //---------------------------------------------------------------------- - value_type - release () - { - m_callback_called = true; - return m_current_value; - } + //---------------------------------------------------------------------- + // Cancels the cleanup that would have been called on "m_current_value" + // if it was valid. This function can be used to release the value + // contained in this object so ownership can be transferred to the caller. + //---------------------------------------------------------------------- + value_type release() { + m_callback_called = true; + return m_current_value; + } private: - value_type m_current_value; - const value_type m_invalid_value; - CallbackType m_callback; - bool m_callback_called; - bool m_invalid_value_is_valid; + value_type m_current_value; + const value_type m_invalid_value; + CallbackType m_callback; + bool m_callback_called; + bool m_invalid_value_is_valid; - // Outlaw default constructor, copy constructor and the assignment operator - DISALLOW_COPY_AND_ASSIGN (CleanUp); + // Outlaw default constructor, copy constructor and the assignment operator + DISALLOW_COPY_AND_ASSIGN(CleanUp); }; - -template <typename T, typename R, typename A0> -class CleanUp2 -{ + +template <typename T, typename R, typename A0> class CleanUp2 { public: - typedef T value_type; - typedef std::function<R(value_type,A0)> CallbackType; - - //---------------------------------------------------------------------- - // Constructor that sets the current value only. No values are - // considered to be invalid and the cleanup function will be called - // regardless of the value of m_current_value. - //---------------------------------------------------------------------- - CleanUp2 (value_type value, CallbackType callback, A0 arg) : - m_current_value (value), - m_invalid_value (), - m_callback (callback), - m_callback_called (false), - m_invalid_value_is_valid (false), - m_argument(arg) - { - } - - //---------------------------------------------------------------------- - // Constructor that sets the current value and also the invalid value. - // The cleanup function will be called on "m_value" as long as it isn't - // equal to "m_invalid_value". - //---------------------------------------------------------------------- - CleanUp2 (value_type value, value_type invalid, CallbackType callback, A0 arg) : - m_current_value (value), - m_invalid_value (invalid), - m_callback (callback), - m_callback_called (false), - m_invalid_value_is_valid (true), - m_argument(arg) - { - } - - //---------------------------------------------------------------------- - // Automatically cleanup when this object goes out of scope. - //---------------------------------------------------------------------- - ~CleanUp2 () - { - clean(); - } - - //---------------------------------------------------------------------- - // Access the value stored in this class - //---------------------------------------------------------------------- - value_type get() - { - return m_current_value; - } - - //---------------------------------------------------------------------- - // Access the value stored in this class - //---------------------------------------------------------------------- - const value_type - get() const - { - return m_current_value; - } - - //---------------------------------------------------------------------- - // Reset the owned value to "value". If a current value is valid and - // the cleanup callback hasn't been called, the previous value will - // be cleaned up (see void CleanUp::clean()). - //---------------------------------------------------------------------- - void - set (const value_type value) - { - // Cleanup the current value if needed - clean (); - // Now set the new value and mark our callback as not called - m_callback_called = false; - m_current_value = value; - } - - //---------------------------------------------------------------------- - // Checks is "m_current_value" is valid. The value is considered valid - // no invalid value was supplied during construction of this object or - // if an invalid value was supplied and "m_current_value" is not equal - // to "m_invalid_value". - // - // Returns true if "m_current_value" is valid, false otherwise. - //---------------------------------------------------------------------- - bool - is_valid() const - { - if (m_invalid_value_is_valid) - return m_current_value != m_invalid_value; - return true; - } - - //---------------------------------------------------------------------- - // This function will call the cleanup callback provided in the - // constructor one time if the value is considered valid (See is_valid()). - // This function sets m_callback_called to true so we don't call the - // cleanup callback multiple times on the same value. - //---------------------------------------------------------------------- - void - clean() - { - if (m_callback && !m_callback_called) - { - m_callback_called = true; - if (is_valid()) - m_callback(m_current_value, m_argument); - } - } - - //---------------------------------------------------------------------- - // Cancels the cleanup that would have been called on "m_current_value" - // if it was valid. This function can be used to release the value - // contained in this object so ownership can be transferred to the caller. - //---------------------------------------------------------------------- - value_type - release () - { - m_callback_called = true; - return m_current_value; + typedef T value_type; + typedef std::function<R(value_type, A0)> CallbackType; + + //---------------------------------------------------------------------- + // Constructor that sets the current value only. No values are + // considered to be invalid and the cleanup function will be called + // regardless of the value of m_current_value. + //---------------------------------------------------------------------- + CleanUp2(value_type value, CallbackType callback, A0 arg) + : m_current_value(value), m_invalid_value(), m_callback(callback), + m_callback_called(false), m_invalid_value_is_valid(false), + m_argument(arg) {} + + //---------------------------------------------------------------------- + // Constructor that sets the current value and also the invalid value. + // The cleanup function will be called on "m_value" as long as it isn't + // equal to "m_invalid_value". + //---------------------------------------------------------------------- + CleanUp2(value_type value, value_type invalid, CallbackType callback, A0 arg) + : m_current_value(value), m_invalid_value(invalid), m_callback(callback), + m_callback_called(false), m_invalid_value_is_valid(true), + m_argument(arg) {} + + //---------------------------------------------------------------------- + // Automatically cleanup when this object goes out of scope. + //---------------------------------------------------------------------- + ~CleanUp2() { clean(); } + + //---------------------------------------------------------------------- + // Access the value stored in this class + //---------------------------------------------------------------------- + value_type get() { return m_current_value; } + + //---------------------------------------------------------------------- + // Access the value stored in this class + //---------------------------------------------------------------------- + const value_type get() const { return m_current_value; } + + //---------------------------------------------------------------------- + // Reset the owned value to "value". If a current value is valid and + // the cleanup callback hasn't been called, the previous value will + // be cleaned up (see void CleanUp::clean()). + //---------------------------------------------------------------------- + void set(const value_type value) { + // Cleanup the current value if needed + clean(); + // Now set the new value and mark our callback as not called + m_callback_called = false; + m_current_value = value; + } + + //---------------------------------------------------------------------- + // Checks is "m_current_value" is valid. The value is considered valid + // no invalid value was supplied during construction of this object or + // if an invalid value was supplied and "m_current_value" is not equal + // to "m_invalid_value". + // + // Returns true if "m_current_value" is valid, false otherwise. + //---------------------------------------------------------------------- + bool is_valid() const { + if (m_invalid_value_is_valid) + return m_current_value != m_invalid_value; + return true; + } + + //---------------------------------------------------------------------- + // This function will call the cleanup callback provided in the + // constructor one time if the value is considered valid (See is_valid()). + // This function sets m_callback_called to true so we don't call the + // cleanup callback multiple times on the same value. + //---------------------------------------------------------------------- + void clean() { + if (m_callback && !m_callback_called) { + m_callback_called = true; + if (is_valid()) + m_callback(m_current_value, m_argument); } - + } + + //---------------------------------------------------------------------- + // Cancels the cleanup that would have been called on "m_current_value" + // if it was valid. This function can be used to release the value + // contained in this object so ownership can be transferred to the caller. + //---------------------------------------------------------------------- + value_type release() { + m_callback_called = true; + return m_current_value; + } + private: - value_type m_current_value; - const value_type m_invalid_value; - CallbackType m_callback; - bool m_callback_called; - bool m_invalid_value_is_valid; - A0 m_argument; - - // Outlaw default constructor, copy constructor and the assignment operator - DISALLOW_COPY_AND_ASSIGN (CleanUp2); + value_type m_current_value; + const value_type m_invalid_value; + CallbackType m_callback; + bool m_callback_called; + bool m_invalid_value_is_valid; + A0 m_argument; + + // Outlaw default constructor, copy constructor and the assignment operator + DISALLOW_COPY_AND_ASSIGN(CleanUp2); }; } // namespace lldb_utility diff --git a/include/lldb/Utility/ConvertEnum.h b/include/lldb/Utility/ConvertEnum.h index 6d37484b0112..239247d6a1da 100644 --- a/include/lldb/Utility/ConvertEnum.h +++ b/include/lldb/Utility/ConvertEnum.h @@ -12,8 +12,7 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private-enumerations.h" -namespace lldb_private -{ +namespace lldb_private { const char *GetVoteAsCString(Vote vote); const char *GetSectionTypeAsCString(lldb::SectionType sect_type); diff --git a/include/lldb/Utility/Either.h b/include/lldb/Utility/Either.h index ae647363512d..0dc340b64e86 100644 --- a/include/lldb/Utility/Either.h +++ b/include/lldb/Utility/Either.h @@ -15,140 +15,112 @@ #include <functional> namespace lldb_utility { - template <typename T1, typename T2> - class Either - { - private: - enum class Selected - { - One, Two - }; - - Selected m_selected; - union - { - T1 m_t1; - T2 m_t2; - }; - - public: - Either (const T1& t1) - { - m_t1 = t1; - m_selected = Selected::One; - } - - Either (const T2& t2) - { - m_t2 = t2; - m_selected = Selected::Two; - } - - Either (const Either<T1,T2>& rhs) - { - switch (rhs.m_selected) - { - case Selected::One: - m_t1 = rhs.GetAs<T1>().getValue(); - m_selected = Selected::One; - break; - case Selected::Two: - m_t2 = rhs.GetAs<T2>().getValue(); - m_selected = Selected::Two; - break; - } - } - - template <class X, typename std::enable_if<std::is_same<T1,X>::value>::type * = nullptr> - llvm::Optional<T1> - GetAs() const - { - switch (m_selected) - { - case Selected::One: - return m_t1; - default: - return llvm::Optional<T1>(); - } - } - - template <class X, typename std::enable_if<std::is_same<T2,X>::value>::type * = nullptr> - llvm::Optional<T2> - GetAs() const - { - switch (m_selected) - { - case Selected::Two: - return m_t2; - default: - return llvm::Optional<T2>(); - } - } - - template <class ResultType> - ResultType - Apply (std::function<ResultType(T1)> if_T1, - std::function<ResultType(T2)> if_T2) const - { - switch (m_selected) - { - case Selected::One: - return if_T1(m_t1); - case Selected::Two: - return if_T2(m_t2); - } - } - - bool - operator == (const Either<T1,T2>& rhs) - { - return (GetAs<T1>() == rhs.GetAs<T1>()) && (GetAs<T2>() == rhs.GetAs<T2>()); - } - - explicit - operator bool () - { - switch (m_selected) - { - case Selected::One: - return (bool)m_t1; - case Selected::Two: - return (bool)m_t2; - } - } - - Either<T1,T2>& - operator = (const Either<T1,T2>& rhs) - { - switch (rhs.m_selected) - { - case Selected::One: - m_t1 = rhs.GetAs<T1>().getValue(); - m_selected = Selected::One; - break; - case Selected::Two: - m_t2 = rhs.GetAs<T2>().getValue(); - m_selected = Selected::Two; - break; - } - return *this; - } - - ~Either () - { - switch (m_selected) - { - case Selected::One: - m_t1.T1::~T1(); - break; - case Selected::Two: - m_t2.T2::~T2(); - break; - } - } - }; - +template <typename T1, typename T2> class Either { +private: + enum class Selected { One, Two }; + + Selected m_selected; + union { + T1 m_t1; + T2 m_t2; + }; + +public: + Either(const T1 &t1) { + m_t1 = t1; + m_selected = Selected::One; + } + + Either(const T2 &t2) { + m_t2 = t2; + m_selected = Selected::Two; + } + + Either(const Either<T1, T2> &rhs) { + switch (rhs.m_selected) { + case Selected::One: + m_t1 = rhs.GetAs<T1>().getValue(); + m_selected = Selected::One; + break; + case Selected::Two: + m_t2 = rhs.GetAs<T2>().getValue(); + m_selected = Selected::Two; + break; + } + } + + template <class X, typename std::enable_if<std::is_same<T1, X>::value>::type + * = nullptr> + llvm::Optional<T1> GetAs() const { + switch (m_selected) { + case Selected::One: + return m_t1; + default: + return llvm::Optional<T1>(); + } + } + + template <class X, typename std::enable_if<std::is_same<T2, X>::value>::type + * = nullptr> + llvm::Optional<T2> GetAs() const { + switch (m_selected) { + case Selected::Two: + return m_t2; + default: + return llvm::Optional<T2>(); + } + } + + template <class ResultType> + ResultType Apply(std::function<ResultType(T1)> if_T1, + std::function<ResultType(T2)> if_T2) const { + switch (m_selected) { + case Selected::One: + return if_T1(m_t1); + case Selected::Two: + return if_T2(m_t2); + } + } + + bool operator==(const Either<T1, T2> &rhs) { + return (GetAs<T1>() == rhs.GetAs<T1>()) && (GetAs<T2>() == rhs.GetAs<T2>()); + } + + explicit operator bool() { + switch (m_selected) { + case Selected::One: + return (bool)m_t1; + case Selected::Two: + return (bool)m_t2; + } + } + + Either<T1, T2> &operator=(const Either<T1, T2> &rhs) { + switch (rhs.m_selected) { + case Selected::One: + m_t1 = rhs.GetAs<T1>().getValue(); + m_selected = Selected::One; + break; + case Selected::Two: + m_t2 = rhs.GetAs<T2>().getValue(); + m_selected = Selected::Two; + break; + } + return *this; + } + + ~Either() { + switch (m_selected) { + case Selected::One: + m_t1.T1::~T1(); + break; + case Selected::Two: + m_t2.T2::~T2(); + break; + } + } +}; + } // namespace lldb_utility #endif // #ifndef liblldb_Either_h_ - diff --git a/include/lldb/Utility/Iterable.h b/include/lldb/Utility/Iterable.h index 0c16a251b7a7..dcb340a05ef1 100644 --- a/include/lldb/Utility/Iterable.h +++ b/include/lldb/Utility/Iterable.h @@ -17,220 +17,184 @@ // Other libraries and framework includes // Project includes -namespace lldb_private -{ - -template <typename I, typename E> E map_adapter(I &iter) -{ - return iter->second; -} - -template <typename I, typename E> E vector_adapter(I &iter) -{ - return *iter; -} - -template <typename I, typename E> E list_adapter(I &iter) -{ - return *iter; +namespace lldb_private { + +template <typename I, typename E> E map_adapter(I &iter) { + return iter->second; } - -template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedConstIterator -{ + +template <typename I, typename E> E vector_adapter(I &iter) { return *iter; } + +template <typename I, typename E> E list_adapter(I &iter) { return *iter; } + +template <typename C, typename E, E (*A)(typename C::const_iterator &)> +class AdaptedConstIterator { public: - typedef typename C::const_iterator BackingIterator; - - // Wrapping constructor - AdaptedConstIterator (BackingIterator backing_iterator) : - m_iter(backing_iterator) - { - } - - // Default-constructible - AdaptedConstIterator () : - m_iter() - { - } - - // Copy-constructible - AdaptedConstIterator (const AdaptedConstIterator &rhs) : - m_iter(rhs.m_iter) - { - } - - // Copy-assignable - AdaptedConstIterator &operator= (const AdaptedConstIterator &rhs) - { - m_iter = rhs.m_iter; - return *this; - } - - // Destructible - ~AdaptedConstIterator() = default; - - // Comparable - bool operator== (const AdaptedConstIterator &rhs) - { - return m_iter == rhs.m_iter; - } - - bool operator!= (const AdaptedConstIterator &rhs) - { - return m_iter != rhs.m_iter; - } - - // Rvalue dereferenceable - E operator* () - { - return (*A)(m_iter); - } - - E operator-> () - { - return (*A)(m_iter); - } - - // Offset dereferenceable - E operator[] (typename BackingIterator::difference_type offset) - { - return AdaptedConstIterator(m_iter + offset); - } - - // Incrementable - AdaptedConstIterator &operator++ () - { - m_iter++; - return *this; - } - - // Decrementable - AdaptedConstIterator &operator-- () - { - m_iter--; - return *this; - } - - // Compound assignment - AdaptedConstIterator &operator+= (typename BackingIterator::difference_type offset) - { - m_iter += offset; - return *this; - } - - AdaptedConstIterator &operator-= (typename BackingIterator::difference_type offset) - { - m_iter -= offset; - return *this; - } - - // Arithmetic - AdaptedConstIterator operator+ (typename BackingIterator::difference_type offset) - { - return AdaptedConstIterator(m_iter + offset); - } - - AdaptedConstIterator operator- (typename BackingIterator::difference_type offset) - { - return AdaptedConstIterator(m_iter - offset); - } - - // Comparable - bool operator< (AdaptedConstIterator &rhs) - { - return m_iter < rhs.m_iter; - } - - bool operator<= (AdaptedConstIterator &rhs) - { - return m_iter <= rhs.m_iter; - } - - bool operator> (AdaptedConstIterator &rhs) - { - return m_iter > rhs.m_iter; - } - - bool operator>= (AdaptedConstIterator &rhs) - { - return m_iter >= rhs.m_iter; - } - - template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> - friend AdaptedConstIterator<C1, E1, A1> operator+(typename C1::const_iterator::difference_type, AdaptedConstIterator<C1, E1, A1> &); - - template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> - friend typename C1::const_iterator::difference_type operator-(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &); - - template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> - friend void swap(AdaptedConstIterator<C1, E1, A1> &, AdaptedConstIterator<C1, E1, A1> &); + typedef typename C::const_iterator BackingIterator; + + // Wrapping constructor + AdaptedConstIterator(BackingIterator backing_iterator) + : m_iter(backing_iterator) {} + + // Default-constructible + AdaptedConstIterator() : m_iter() {} + + // Copy-constructible + AdaptedConstIterator(const AdaptedConstIterator &rhs) : m_iter(rhs.m_iter) {} + + // Copy-assignable + AdaptedConstIterator &operator=(const AdaptedConstIterator &rhs) { + m_iter = rhs.m_iter; + return *this; + } + + // Destructible + ~AdaptedConstIterator() = default; + + // Comparable + bool operator==(const AdaptedConstIterator &rhs) { + return m_iter == rhs.m_iter; + } + + bool operator!=(const AdaptedConstIterator &rhs) { + return m_iter != rhs.m_iter; + } + + // Rvalue dereferenceable + E operator*() { return (*A)(m_iter); } + + E operator->() { return (*A)(m_iter); } + + // Offset dereferenceable + E operator[](typename BackingIterator::difference_type offset) { + return AdaptedConstIterator(m_iter + offset); + } + + // Incrementable + AdaptedConstIterator &operator++() { + m_iter++; + return *this; + } + + // Decrementable + AdaptedConstIterator &operator--() { + m_iter--; + return *this; + } + + // Compound assignment + AdaptedConstIterator & + operator+=(typename BackingIterator::difference_type offset) { + m_iter += offset; + return *this; + } + + AdaptedConstIterator & + operator-=(typename BackingIterator::difference_type offset) { + m_iter -= offset; + return *this; + } + + // Arithmetic + AdaptedConstIterator + operator+(typename BackingIterator::difference_type offset) { + return AdaptedConstIterator(m_iter + offset); + } + + AdaptedConstIterator + operator-(typename BackingIterator::difference_type offset) { + return AdaptedConstIterator(m_iter - offset); + } + + // Comparable + bool operator<(AdaptedConstIterator &rhs) { return m_iter < rhs.m_iter; } + + bool operator<=(AdaptedConstIterator &rhs) { return m_iter <= rhs.m_iter; } + + bool operator>(AdaptedConstIterator &rhs) { return m_iter > rhs.m_iter; } + + bool operator>=(AdaptedConstIterator &rhs) { return m_iter >= rhs.m_iter; } + + template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> + friend AdaptedConstIterator<C1, E1, A1> + operator+(typename C1::const_iterator::difference_type, + AdaptedConstIterator<C1, E1, A1> &); + + template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> + friend typename C1::const_iterator::difference_type + operator-(AdaptedConstIterator<C1, E1, A1> &, + AdaptedConstIterator<C1, E1, A1> &); + + template <typename C1, typename E1, E1 (*A1)(typename C1::const_iterator &)> + friend void swap(AdaptedConstIterator<C1, E1, A1> &, + AdaptedConstIterator<C1, E1, A1> &); private: - BackingIterator m_iter; + BackingIterator m_iter; }; - + template <typename C, typename E, E (*A)(typename C::const_iterator &)> -AdaptedConstIterator<C, E, A> operator+ (typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type offset, AdaptedConstIterator<C, E, A> &rhs) -{ - return rhs.operator+(offset); +AdaptedConstIterator<C, E, A> operator+( + typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type + offset, + AdaptedConstIterator<C, E, A> &rhs) { + return rhs.operator+(offset); } template <typename C, typename E, E (*A)(typename C::const_iterator &)> -typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type operator- (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs) -{ - return(lhs.m_iter - rhs.m_iter); +typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type +operator-(AdaptedConstIterator<C, E, A> &lhs, + AdaptedConstIterator<C, E, A> &rhs) { + return (lhs.m_iter - rhs.m_iter); } template <typename C, typename E, E (*A)(typename C::const_iterator &)> -void swap (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs) -{ - std::swap(lhs.m_iter, rhs.m_iter); +void swap(AdaptedConstIterator<C, E, A> &lhs, + AdaptedConstIterator<C, E, A> &rhs) { + std::swap(lhs.m_iter, rhs.m_iter); } - -template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedIterable -{ + +template <typename C, typename E, E (*A)(typename C::const_iterator &)> +class AdaptedIterable { private: - const C &m_container; + const C &m_container; + public: - AdaptedIterable (const C &container) : - m_container(container) - { - } - - AdaptedConstIterator<C, E, A> begin () - { - return AdaptedConstIterator<C, E, A>(m_container.begin()); - } - - AdaptedConstIterator<C, E, A> end () - { - return AdaptedConstIterator<C, E, A>(m_container.end()); - } + AdaptedIterable(const C &container) : m_container(container) {} + + AdaptedConstIterator<C, E, A> begin() { + return AdaptedConstIterator<C, E, A>(m_container.begin()); + } + + AdaptedConstIterator<C, E, A> end() { + return AdaptedConstIterator<C, E, A>(m_container.end()); + } }; -template <typename C, typename E, E (*A)(typename C::const_iterator &), typename MutexType> -class LockingAdaptedIterable : public AdaptedIterable<C, E, A> -{ +template <typename C, typename E, E (*A)(typename C::const_iterator &), + typename MutexType> +class LockingAdaptedIterable : public AdaptedIterable<C, E, A> { public: - LockingAdaptedIterable(C &container, MutexType &mutex) : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) - { - m_mutex->lock(); - } - - LockingAdaptedIterable(LockingAdaptedIterable &&rhs) : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) - { - rhs.m_mutex = nullptr; - } - - ~LockingAdaptedIterable() - { - if (m_mutex) - m_mutex->unlock(); - } + LockingAdaptedIterable(C &container, MutexType &mutex) + : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) { + m_mutex->lock(); + } + + LockingAdaptedIterable(LockingAdaptedIterable &&rhs) + : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) { + rhs.m_mutex = nullptr; + } + + ~LockingAdaptedIterable() { + if (m_mutex) + m_mutex->unlock(); + } private: - MutexType *m_mutex = nullptr; + MutexType *m_mutex = nullptr; - DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable); + LockingAdaptedIterable(const LockingAdaptedIterable &) = delete; + LockingAdaptedIterable &operator=(const LockingAdaptedIterable &) = delete; }; } // namespace lldb_private diff --git a/include/lldb/Utility/JSON.h b/include/lldb/Utility/JSON.h index e61c5ee85017..145ef4868d2f 100644 --- a/include/lldb/Utility/JSON.h +++ b/include/lldb/Utility/JSON.h @@ -24,338 +24,263 @@ namespace lldb_private { - class JSONValue - { - public: - virtual void - Write (Stream& s) = 0; - - typedef std::shared_ptr<JSONValue> SP; - - enum class Kind - { - String, - Number, - True, - False, - Null, - Object, - Array - }; - - JSONValue (Kind k) : - m_kind(k) - {} - - Kind - GetKind() const - { - return m_kind; - } - - virtual - ~JSONValue () = default; - - private: - const Kind m_kind; - }; - - class JSONString : public JSONValue - { - public: - JSONString (); - JSONString (const char* s); - JSONString (const std::string& s); - - JSONString (const JSONString& s) = delete; - JSONString& - operator = (const JSONString& s) = delete; - - void - Write(Stream& s) override; - - typedef std::shared_ptr<JSONString> SP; - - std::string - GetData () { return m_data; } - - static bool classof(const JSONValue *V) - { - return V->GetKind() == JSONValue::Kind::String; - } - - ~JSONString() override = default; - - private: - - static std::string - json_string_quote_metachars (const std::string&); - - std::string m_data; - }; - - class JSONNumber : public JSONValue - { - public: - typedef std::shared_ptr<JSONNumber> SP; - - // We cretae a constructor for all integer and floating point type with using templates and - // SFINAE to avoid having ambiguous overloads because of the implicit type promotion. If we - // would have constructors only with int64_t, uint64_t and double types then constructing a - // JSONNumber from an int32_t (or any other similar type) would fail to compile. - - template <typename T, - typename std::enable_if<std::is_integral<T>::value && - std::is_unsigned<T>::value>::type* = nullptr> - explicit JSONNumber (T u) : - JSONValue(JSONValue::Kind::Number), - m_data_type(DataType::Unsigned) - { - m_data.m_unsigned = u; - } - - template <typename T, - typename std::enable_if<std::is_integral<T>::value && - std::is_signed<T>::value>::type* = nullptr> - explicit JSONNumber (T s) : - JSONValue(JSONValue::Kind::Number), - m_data_type(DataType::Signed) - { - m_data.m_signed = s; - } - - template <typename T, - typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr> - explicit JSONNumber (T d) : - JSONValue(JSONValue::Kind::Number), - m_data_type(DataType::Double) - { - m_data.m_double = d; - } - - ~JSONNumber() override = default; - - JSONNumber (const JSONNumber& s) = delete; - JSONNumber& - operator = (const JSONNumber& s) = delete; - - void - Write(Stream& s) override; - - uint64_t - GetAsUnsigned() const; - - int64_t - GetAsSigned() const; - - double - GetAsDouble() const; - - static bool classof(const JSONValue *V) - { - return V->GetKind() == JSONValue::Kind::Number; - } - - private: - enum class DataType : uint8_t - { - Unsigned, - Signed, - Double - } m_data_type; - - union - { - uint64_t m_unsigned; - int64_t m_signed; - double m_double; - } m_data; - }; - - class JSONTrue : public JSONValue - { - public: - JSONTrue (); - - JSONTrue (const JSONTrue& s) = delete; - JSONTrue& - operator = (const JSONTrue& s) = delete; - - void - Write(Stream& s) override; - - typedef std::shared_ptr<JSONTrue> SP; - - static bool classof(const JSONValue *V) - { - return V->GetKind() == JSONValue::Kind::True; - } - - ~JSONTrue() override = default; - }; - - class JSONFalse : public JSONValue - { - public: - JSONFalse (); - - JSONFalse (const JSONFalse& s) = delete; - JSONFalse& - operator = (const JSONFalse& s) = delete; - - void - Write(Stream& s) override; - - typedef std::shared_ptr<JSONFalse> SP; - - static bool classof(const JSONValue *V) - { - return V->GetKind() == JSONValue::Kind::False; - } - - ~JSONFalse() override = default; - }; - - class JSONNull : public JSONValue - { - public: - JSONNull (); - - JSONNull (const JSONNull& s) = delete; - JSONNull& - operator = (const JSONNull& s) = delete; - - void - Write(Stream& s) override; - - typedef std::shared_ptr<JSONNull> SP; - - static bool classof(const JSONValue *V) - { - return V->GetKind() == JSONValue::Kind::Null; - } - - ~JSONNull() override = default; - }; - - class JSONObject : public JSONValue - { - public: - JSONObject (); - - JSONObject (const JSONObject& s) = delete; - JSONObject& - operator = (const JSONObject& s) = delete; - - void - Write(Stream& s) override; - - typedef std::shared_ptr<JSONObject> SP; - - static bool classof(const JSONValue *V) - { - return V->GetKind() == JSONValue::Kind::Object; - } - - bool - SetObject (const std::string& key, - JSONValue::SP value); - - JSONValue::SP - GetObject (const std::string& key); - - ~JSONObject() override = default; - - private: - typedef std::map<std::string, JSONValue::SP> Map; - typedef Map::iterator Iterator; - Map m_elements; - }; - - class JSONArray : public JSONValue - { - public: - JSONArray (); - - JSONArray (const JSONArray& s) = delete; - JSONArray& - operator = (const JSONArray& s) = delete; - - void - Write(Stream& s) override; - - typedef std::shared_ptr<JSONArray> SP; - - static bool classof(const JSONValue *V) - { - return V->GetKind() == JSONValue::Kind::Array; - } - - private: - typedef std::vector<JSONValue::SP> Vector; - typedef Vector::iterator Iterator; - typedef Vector::size_type Index; - typedef Vector::size_type Size; - - public: - bool - SetObject (Index i, - JSONValue::SP value); - - bool - AppendObject (JSONValue::SP value); - - JSONValue::SP - GetObject (Index i); - - Size - GetNumElements (); - - ~JSONArray() override = default; - - Vector m_elements; - }; - - class JSONParser : public StringExtractor - { - public: - enum Token - { - Invalid, - Error, - ObjectStart, - ObjectEnd, - ArrayStart, - ArrayEnd, - Comma, - Colon, - String, - Integer, - Float, - True, - False, - Null, - EndOfFile - }; - - JSONParser (const char *cstr); - - int - GetEscapedChar (bool &was_escaped); - - Token - GetToken (std::string &value); - - JSONValue::SP - ParseJSONValue (); - - protected: - JSONValue::SP - ParseJSONObject (); - - JSONValue::SP - ParseJSONArray (); - }; +class JSONValue { +public: + virtual void Write(Stream &s) = 0; + + typedef std::shared_ptr<JSONValue> SP; + + enum class Kind { String, Number, True, False, Null, Object, Array }; + + JSONValue(Kind k) : m_kind(k) {} + + Kind GetKind() const { return m_kind; } + + virtual ~JSONValue() = default; + +private: + const Kind m_kind; +}; + +class JSONString : public JSONValue { +public: + JSONString(); + JSONString(const char *s); + JSONString(const std::string &s); + + JSONString(const JSONString &s) = delete; + JSONString &operator=(const JSONString &s) = delete; + + void Write(Stream &s) override; + + typedef std::shared_ptr<JSONString> SP; + + std::string GetData() { return m_data; } + + static bool classof(const JSONValue *V) { + return V->GetKind() == JSONValue::Kind::String; + } + + ~JSONString() override = default; + +private: + static std::string json_string_quote_metachars(const std::string &); + + std::string m_data; +}; + +class JSONNumber : public JSONValue { +public: + typedef std::shared_ptr<JSONNumber> SP; + + // We cretae a constructor for all integer and floating point type with using + // templates and + // SFINAE to avoid having ambiguous overloads because of the implicit type + // promotion. If we + // would have constructors only with int64_t, uint64_t and double types then + // constructing a + // JSONNumber from an int32_t (or any other similar type) would fail to + // compile. + + template <typename T, typename std::enable_if< + std::is_integral<T>::value && + std::is_unsigned<T>::value>::type * = nullptr> + explicit JSONNumber(T u) + : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) { + m_data.m_unsigned = u; + } + + template <typename T, + typename std::enable_if<std::is_integral<T>::value && + std::is_signed<T>::value>::type * = nullptr> + explicit JSONNumber(T s) + : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) { + m_data.m_signed = s; + } + + template <typename T, typename std::enable_if< + std::is_floating_point<T>::value>::type * = nullptr> + explicit JSONNumber(T d) + : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) { + m_data.m_double = d; + } + + ~JSONNumber() override = default; + + JSONNumber(const JSONNumber &s) = delete; + JSONNumber &operator=(const JSONNumber &s) = delete; + + void Write(Stream &s) override; + + uint64_t GetAsUnsigned() const; + + int64_t GetAsSigned() const; + + double GetAsDouble() const; + + static bool classof(const JSONValue *V) { + return V->GetKind() == JSONValue::Kind::Number; + } + +private: + enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type; + + union { + uint64_t m_unsigned; + int64_t m_signed; + double m_double; + } m_data; +}; + +class JSONTrue : public JSONValue { +public: + JSONTrue(); + + JSONTrue(const JSONTrue &s) = delete; + JSONTrue &operator=(const JSONTrue &s) = delete; + + void Write(Stream &s) override; + + typedef std::shared_ptr<JSONTrue> SP; + + static bool classof(const JSONValue *V) { + return V->GetKind() == JSONValue::Kind::True; + } + + ~JSONTrue() override = default; +}; + +class JSONFalse : public JSONValue { +public: + JSONFalse(); + + JSONFalse(const JSONFalse &s) = delete; + JSONFalse &operator=(const JSONFalse &s) = delete; + + void Write(Stream &s) override; + + typedef std::shared_ptr<JSONFalse> SP; + + static bool classof(const JSONValue *V) { + return V->GetKind() == JSONValue::Kind::False; + } + + ~JSONFalse() override = default; +}; + +class JSONNull : public JSONValue { +public: + JSONNull(); + + JSONNull(const JSONNull &s) = delete; + JSONNull &operator=(const JSONNull &s) = delete; + + void Write(Stream &s) override; + + typedef std::shared_ptr<JSONNull> SP; + + static bool classof(const JSONValue *V) { + return V->GetKind() == JSONValue::Kind::Null; + } + + ~JSONNull() override = default; +}; + +class JSONObject : public JSONValue { +public: + JSONObject(); + + JSONObject(const JSONObject &s) = delete; + JSONObject &operator=(const JSONObject &s) = delete; + + void Write(Stream &s) override; + + typedef std::shared_ptr<JSONObject> SP; + + static bool classof(const JSONValue *V) { + return V->GetKind() == JSONValue::Kind::Object; + } + + bool SetObject(const std::string &key, JSONValue::SP value); + + JSONValue::SP GetObject(const std::string &key); + + ~JSONObject() override = default; + +private: + typedef std::map<std::string, JSONValue::SP> Map; + typedef Map::iterator Iterator; + Map m_elements; +}; + +class JSONArray : public JSONValue { +public: + JSONArray(); + + JSONArray(const JSONArray &s) = delete; + JSONArray &operator=(const JSONArray &s) = delete; + + void Write(Stream &s) override; + + typedef std::shared_ptr<JSONArray> SP; + + static bool classof(const JSONValue *V) { + return V->GetKind() == JSONValue::Kind::Array; + } + +private: + typedef std::vector<JSONValue::SP> Vector; + typedef Vector::iterator Iterator; + typedef Vector::size_type Index; + typedef Vector::size_type Size; + +public: + bool SetObject(Index i, JSONValue::SP value); + + bool AppendObject(JSONValue::SP value); + + JSONValue::SP GetObject(Index i); + + Size GetNumElements(); + + ~JSONArray() override = default; + + Vector m_elements; +}; + +class JSONParser : public StringExtractor { +public: + enum Token { + Invalid, + Error, + ObjectStart, + ObjectEnd, + ArrayStart, + ArrayEnd, + Comma, + Colon, + String, + Integer, + Float, + True, + False, + Null, + EndOfFile + }; + + JSONParser(const char *cstr); + + int GetEscapedChar(bool &was_escaped); + + Token GetToken(std::string &value); + + JSONValue::SP ParseJSONValue(); + +protected: + JSONValue::SP ParseJSONObject(); + + JSONValue::SP ParseJSONArray(); +}; } // namespace lldb_private #endif // utility_JSON_h_ diff --git a/include/lldb/Utility/LLDBAssert.h b/include/lldb/Utility/LLDBAssert.h index 5ca252f20032..328a4d4f9258 100644 --- a/include/lldb/Utility/LLDBAssert.h +++ b/include/lldb/Utility/LLDBAssert.h @@ -1,4 +1,5 @@ -//===----------------- LLDBAssert.h --------------------------------*- C++ -*-===// +//===----------------- LLDBAssert.h --------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -15,16 +16,13 @@ #ifdef LLDB_CONFIGURATION_DEBUG #define lldbassert(x) assert(x) #else -#define lldbassert(x) lldb_private::lldb_assert(x, #x, __FUNCTION__, __FILE__, __LINE__) +#define lldbassert(x) \ + lldb_private::lldb_assert(x, #x, __FUNCTION__, __FILE__, __LINE__) #endif namespace lldb_private { - void - lldb_assert (bool expression, - const char* expr_text, - const char* func, - const char* file, - unsigned int line); +void lldb_assert(bool expression, const char *expr_text, const char *func, + const char *file, unsigned int line); } #endif // utility_LLDBAssert_h_ diff --git a/include/lldb/Utility/NameMatches.h b/include/lldb/Utility/NameMatches.h index 5fe6565d06f9..50ea7ba7f887 100644 --- a/include/lldb/Utility/NameMatches.h +++ b/include/lldb/Utility/NameMatches.h @@ -11,9 +11,11 @@ #include "lldb/lldb-private-enumerations.h" -namespace lldb_private -{ -bool NameMatches(const char *name, NameMatchType match_type, const char *match); +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { +bool NameMatches(llvm::StringRef name, NameMatchType match_type, + llvm::StringRef match); } #endif diff --git a/include/lldb/Utility/PriorityPointerPair.h b/include/lldb/Utility/PriorityPointerPair.h index 49f0765d0f96..2bd369e78a9a 100644 --- a/include/lldb/Utility/PriorityPointerPair.h +++ b/include/lldb/Utility/PriorityPointerPair.h @@ -1,4 +1,5 @@ -//===-- PriorityPointerPair.h ----------------------------------------*- C++ -*-===// +//===-- PriorityPointerPair.h ----------------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -10,8 +11,8 @@ #ifndef liblldb_PriorityPointerPair_h_ #define liblldb_PriorityPointerPair_h_ -#include "lldb/lldb-public.h" #include "lldb/Utility/SharingPtr.h" +#include "lldb/lldb-public.h" namespace lldb_utility { @@ -22,127 +23,62 @@ namespace lldb_utility { // otherwise, low is returned (even if *low == NULL) //---------------------------------------------------------------------- -template<typename T> -class PriorityPointerPair -{ +template <typename T> class PriorityPointerPair { public: - - typedef T& reference_type; - typedef T* pointer_type; - - typedef typename std::shared_ptr<T> T_SP; - - PriorityPointerPair() : - m_high(), - m_low() - {} - - PriorityPointerPair(pointer_type high, - pointer_type low) : - m_high(high), - m_low(low) - {} - - PriorityPointerPair(pointer_type low) : - m_high(), - m_low(low) - {} - - PriorityPointerPair(T_SP& high, - T_SP& low) : - m_high(high), - m_low(low) - {} - - PriorityPointerPair(T_SP& low) : - m_high(), - m_low(low) - {} - - void - SwapLow(pointer_type l) - { - m_low.swap(l); - } - - void - SwapHigh(pointer_type h) - { - m_high.swap(h); - } - - void - SwapLow(T_SP l) - { - m_low.swap(l); - } - - void - SwapHigh(T_SP h) - { - m_high.swap(h); - } - - T_SP - GetLow() - { - return m_low; - } - - T_SP - GetHigh() - { - return m_high; - } - - T_SP - Get() - { - if (m_high.get()) - return m_high; - return m_low; - } - - void - ResetHigh() - { - m_high.reset(); - } - - void - ResetLow() - { - m_low.reset(); - } - - void - Reset() - { - ResetLow(); - ResetHigh(); - } - - reference_type - operator*() const - { - return Get().operator*(); - } - - pointer_type - operator->() const - { - return Get().operator->(); - } - - ~PriorityPointerPair(); - + typedef T &reference_type; + typedef T *pointer_type; + + typedef typename std::shared_ptr<T> T_SP; + + PriorityPointerPair() : m_high(), m_low() {} + + PriorityPointerPair(pointer_type high, pointer_type low) + : m_high(high), m_low(low) {} + + PriorityPointerPair(pointer_type low) : m_high(), m_low(low) {} + + PriorityPointerPair(T_SP &high, T_SP &low) : m_high(high), m_low(low) {} + + PriorityPointerPair(T_SP &low) : m_high(), m_low(low) {} + + void SwapLow(pointer_type l) { m_low.swap(l); } + + void SwapHigh(pointer_type h) { m_high.swap(h); } + + void SwapLow(T_SP l) { m_low.swap(l); } + + void SwapHigh(T_SP h) { m_high.swap(h); } + + T_SP GetLow() { return m_low; } + + T_SP GetHigh() { return m_high; } + + T_SP Get() { + if (m_high.get()) + return m_high; + return m_low; + } + + void ResetHigh() { m_high.reset(); } + + void ResetLow() { m_low.reset(); } + + void Reset() { + ResetLow(); + ResetHigh(); + } + + reference_type operator*() const { return Get().operator*(); } + + pointer_type operator->() const { return Get().operator->(); } + + ~PriorityPointerPair(); + private: + T_SP m_high; + T_SP m_low; - T_SP m_high; - T_SP m_low; - - DISALLOW_COPY_AND_ASSIGN (PriorityPointerPair); - + DISALLOW_COPY_AND_ASSIGN(PriorityPointerPair); }; } // namespace lldb_utility diff --git a/include/lldb/Utility/ProcessStructReader.h b/include/lldb/Utility/ProcessStructReader.h index bbb497cd51cb..eb5126329bc0 100644 --- a/include/lldb/Utility/ProcessStructReader.h +++ b/include/lldb/Utility/ProcessStructReader.h @@ -1,4 +1,5 @@ -//===---------------------ProcessStructReader.h ------------------*- C++ -*-===// +//===---------------------ProcessStructReader.h ------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -24,86 +25,79 @@ #include <string> namespace lldb_private { - class ProcessStructReader - { - protected: - struct FieldImpl - { - CompilerType type; - size_t offset; - size_t size; - }; - - std::map<ConstString, FieldImpl> m_fields; - DataExtractor m_data; - lldb::ByteOrder m_byte_order; - size_t m_addr_byte_size; - - public: - ProcessStructReader (Process *process, lldb::addr_t base_addr, CompilerType struct_type) - { - if (!process) - return; - if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS) - return; - m_byte_order = process->GetByteOrder(); - m_addr_byte_size = process->GetAddressByteSize(); +class ProcessStructReader { +protected: + struct FieldImpl { + CompilerType type; + size_t offset; + size_t size; + }; - for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++) - { - std::string name; - uint64_t bit_offset; - uint32_t bitfield_bit_size; - bool is_bitfield; - CompilerType field_type = struct_type.GetFieldAtIndex(idx,name,&bit_offset,&bitfield_bit_size,&is_bitfield); - // no support for bitfields in here (yet) - if (is_bitfield) - return; - auto size = field_type.GetByteSize(nullptr); - // no support for things larger than a uint64_t (yet) - if (size > 8) - return; - ConstString const_name = ConstString(name.c_str()); - size_t byte_index = static_cast<size_t>(bit_offset / 8); - m_fields[const_name] = FieldImpl{field_type, byte_index, static_cast<size_t>(size)}; - } - size_t total_size = struct_type.GetByteSize(nullptr); - lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size,0)); - Error error; - process->ReadMemoryFromInferior(base_addr, - buffer_sp->GetBytes(), - total_size, - error); - if (error.Fail()) - return; - m_data = DataExtractor(buffer_sp,m_byte_order,m_addr_byte_size); - } - - template<typename RetType> - RetType - GetField (ConstString name, RetType fail_value = RetType()) - { - auto iter = m_fields.find(name), end = m_fields.end(); - if (iter == end) - return fail_value; - auto size = iter->second.size; - if (sizeof(RetType) < size) - return fail_value; - lldb::offset_t offset = iter->second.offset; - if (offset + size > m_data.GetByteSize()) - return fail_value; - return (RetType)(m_data.GetMaxU64(&offset, size)); - } + std::map<ConstString, FieldImpl> m_fields; + DataExtractor m_data; + lldb::ByteOrder m_byte_order; + size_t m_addr_byte_size; - size_t - GetOffsetOf(ConstString name, size_t fail_value = SIZE_MAX) - { - auto iter = m_fields.find(name), end = m_fields.end(); - if (iter == end) - return fail_value; - return iter->second.offset; - } - }; +public: + ProcessStructReader(Process *process, lldb::addr_t base_addr, + CompilerType struct_type) { + if (!process) + return; + if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS) + return; + m_byte_order = process->GetByteOrder(); + m_addr_byte_size = process->GetAddressByteSize(); + + for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++) { + std::string name; + uint64_t bit_offset; + uint32_t bitfield_bit_size; + bool is_bitfield; + CompilerType field_type = struct_type.GetFieldAtIndex( + idx, name, &bit_offset, &bitfield_bit_size, &is_bitfield); + // no support for bitfields in here (yet) + if (is_bitfield) + return; + auto size = field_type.GetByteSize(nullptr); + // no support for things larger than a uint64_t (yet) + if (size > 8) + return; + ConstString const_name = ConstString(name.c_str()); + size_t byte_index = static_cast<size_t>(bit_offset / 8); + m_fields[const_name] = + FieldImpl{field_type, byte_index, static_cast<size_t>(size)}; + } + size_t total_size = struct_type.GetByteSize(nullptr); + lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size, 0)); + Error error; + process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(), + total_size, error); + if (error.Fail()) + return; + m_data = DataExtractor(buffer_sp, m_byte_order, m_addr_byte_size); + } + + template <typename RetType> + RetType GetField(ConstString name, RetType fail_value = RetType()) { + auto iter = m_fields.find(name), end = m_fields.end(); + if (iter == end) + return fail_value; + auto size = iter->second.size; + if (sizeof(RetType) < size) + return fail_value; + lldb::offset_t offset = iter->second.offset; + if (offset + size > m_data.GetByteSize()) + return fail_value; + return (RetType)(m_data.GetMaxU64(&offset, size)); + } + + size_t GetOffsetOf(ConstString name, size_t fail_value = SIZE_MAX) { + auto iter = m_fields.find(name), end = m_fields.end(); + if (iter == end) + return fail_value; + return iter->second.offset; + } +}; } #endif // utility_ProcessStructReader_h_ diff --git a/include/lldb/Utility/PseudoTerminal.h b/include/lldb/Utility/PseudoTerminal.h index d73253497746..fbe93343452e 100644 --- a/include/lldb/Utility/PseudoTerminal.h +++ b/include/lldb/Utility/PseudoTerminal.h @@ -11,7 +11,6 @@ #define liblldb_PseudoTerminal_h_ #if defined(__cplusplus) - #include <fcntl.h> #include <string> @@ -26,241 +25,228 @@ namespace lldb_utility { /// The pseudo terminal class abstracts the use of pseudo terminals on /// the host system. //---------------------------------------------------------------------- -class PseudoTerminal -{ +class PseudoTerminal { public: - enum - { - invalid_fd = -1 ///< Invalid file descriptor value - }; - - //------------------------------------------------------------------ - /// Default constructor - /// - /// Constructs this object with invalid master and slave file - /// descriptors. - //------------------------------------------------------------------ - PseudoTerminal (); - - //------------------------------------------------------------------ - /// Destructor - /// - /// The destructor will close the master and slave file descriptors - /// if they are valid and ownership has not been released using - /// one of: - /// @li PseudoTerminal::ReleaseMasterFileDescriptor() - /// @li PseudoTerminal::ReleaseSaveFileDescriptor() - //------------------------------------------------------------------ - ~PseudoTerminal (); - - //------------------------------------------------------------------ - /// Close the master file descriptor if it is valid. - //------------------------------------------------------------------ - void - CloseMasterFileDescriptor (); - - //------------------------------------------------------------------ - /// Close the slave file descriptor if it is valid. - //------------------------------------------------------------------ - void - CloseSlaveFileDescriptor (); - - //------------------------------------------------------------------ - /// Fork a child process that uses pseudo terminals for its stdio. - /// - /// In the parent process, a call to this function results in a pid - /// being returned. If the pid is valid, the master file descriptor - /// can be used for read/write access to stdio of the child process. - /// - /// In the child process the stdin/stdout/stderr will already be - /// routed to the slave pseudo terminal and the master file - /// descriptor will be closed as it is no longer needed by the child - /// process. - /// - /// This class will close the file descriptors for the master/slave - /// when the destructor is called. The file handles can be released - /// using either: - /// @li PseudoTerminal::ReleaseMasterFileDescriptor() - /// @li PseudoTerminal::ReleaseSaveFileDescriptor() - /// - /// @param[out] error - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// - /// @return - /// @li \b Parent process: a child process ID that is greater - /// than zero, or -1 if the fork fails. - /// @li \b Child process: zero. - //------------------------------------------------------------------ - lldb::pid_t - Fork (char *error_str, size_t error_len); - - //------------------------------------------------------------------ - /// The master file descriptor accessor. - /// - /// This object retains ownership of the master file descriptor when - /// this accessor is used. Users can call the member function - /// PseudoTerminal::ReleaseMasterFileDescriptor() if this - /// object should release ownership of the slave file descriptor. - /// - /// @return - /// The master file descriptor, or PseudoTerminal::invalid_fd - /// if the master file descriptor is not currently valid. - /// - /// @see PseudoTerminal::ReleaseMasterFileDescriptor() - //------------------------------------------------------------------ - int - GetMasterFileDescriptor () const; - - //------------------------------------------------------------------ - /// The slave file descriptor accessor. - /// - /// This object retains ownership of the slave file descriptor when - /// this accessor is used. Users can call the member function - /// PseudoTerminal::ReleaseSlaveFileDescriptor() if this - /// object should release ownership of the slave file descriptor. - /// - /// @return - /// The slave file descriptor, or PseudoTerminal::invalid_fd - /// if the slave file descriptor is not currently valid. - /// - /// @see PseudoTerminal::ReleaseSlaveFileDescriptor() - //------------------------------------------------------------------ - int - GetSlaveFileDescriptor () const; - - //------------------------------------------------------------------ - /// Get the name of the slave pseudo terminal. - /// - /// A master pseudo terminal should already be valid prior to - /// calling this function. - /// - /// @param[out] error - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// - /// @return - /// The name of the slave pseudo terminal as a NULL terminated - /// C. This string that comes from static memory, so a copy of - /// the string should be made as subsequent calls can change - /// this value. NULL is returned if this object doesn't have - /// a valid master pseudo terminal opened or if the call to - /// \c ptsname() fails. - /// - /// @see PseudoTerminal::OpenFirstAvailableMaster() - //------------------------------------------------------------------ - const char* - GetSlaveName (char *error_str, size_t error_len) const; - - //------------------------------------------------------------------ - /// Open the first available pseudo terminal. - /// - /// Opens the first available pseudo terminal with \a oflag as the - /// permissions. The opened master file descriptor is stored in this - /// object and can be accessed by calling the - /// PseudoTerminal::GetMasterFileDescriptor() accessor. Clients - /// can call the PseudoTerminal::ReleaseMasterFileDescriptor() - /// accessor function if they wish to use the master file descriptor - /// beyond the lifespan of this object. - /// - /// If this object still has a valid master file descriptor when its - /// destructor is called, it will close it. - /// - /// @param[in] oflag - /// Flags to use when calling \c posix_openpt(\a oflag). - /// A value of "O_RDWR|O_NOCTTY" is suggested. - /// - /// @param[out] error - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// - /// @return - /// @li \b true when the master files descriptor is - /// successfully opened. - /// @li \b false if anything goes wrong. - /// - /// @see PseudoTerminal::GetMasterFileDescriptor() - /// @see PseudoTerminal::ReleaseMasterFileDescriptor() - //------------------------------------------------------------------ - bool - OpenFirstAvailableMaster (int oflag, char *error_str, size_t error_len); - - //------------------------------------------------------------------ - /// Open the slave for the current master pseudo terminal. - /// - /// A master pseudo terminal should already be valid prior to - /// calling this function. The opened slave file descriptor is - /// stored in this object and can be accessed by calling the - /// PseudoTerminal::GetSlaveFileDescriptor() accessor. Clients - /// can call the PseudoTerminal::ReleaseSlaveFileDescriptor() - /// accessor function if they wish to use the slave file descriptor - /// beyond the lifespan of this object. - /// - /// If this object still has a valid slave file descriptor when its - /// destructor is called, it will close it. - /// - /// @param[in] oflag - /// Flags to use when calling \c open(\a oflag). - /// - /// @param[out] error - /// An pointer to an error that can describe any errors that - /// occur. This can be NULL if no error status is desired. - /// - /// @return - /// @li \b true when the master files descriptor is - /// successfully opened. - /// @li \b false if anything goes wrong. - /// - /// @see PseudoTerminal::OpenFirstAvailableMaster() - /// @see PseudoTerminal::GetSlaveFileDescriptor() - /// @see PseudoTerminal::ReleaseSlaveFileDescriptor() - //------------------------------------------------------------------ - bool - OpenSlave (int oflag, char *error_str, size_t error_len); - - //------------------------------------------------------------------ - /// Release the master file descriptor. - /// - /// Releases ownership of the master pseudo terminal file descriptor - /// without closing it. The destructor for this class will close the - /// master file descriptor if the ownership isn't released using this - /// call and the master file descriptor has been opened. - /// - /// @return - /// The master file descriptor, or PseudoTerminal::invalid_fd - /// if the mast file descriptor is not currently valid. - //------------------------------------------------------------------ - int - ReleaseMasterFileDescriptor (); - - //------------------------------------------------------------------ - /// Release the slave file descriptor. - /// - /// Release ownership of the slave pseudo terminal file descriptor - /// without closing it. The destructor for this class will close the - /// slave file descriptor if the ownership isn't released using this - /// call and the slave file descriptor has been opened. - /// - /// @return - /// The slave file descriptor, or PseudoTerminal::invalid_fd - /// if the slave file descriptor is not currently valid. - //------------------------------------------------------------------ - int - ReleaseSlaveFileDescriptor (); + enum { + invalid_fd = -1 ///< Invalid file descriptor value + }; + + //------------------------------------------------------------------ + /// Default constructor + /// + /// Constructs this object with invalid master and slave file + /// descriptors. + //------------------------------------------------------------------ + PseudoTerminal(); + + //------------------------------------------------------------------ + /// Destructor + /// + /// The destructor will close the master and slave file descriptors + /// if they are valid and ownership has not been released using + /// one of: + /// @li PseudoTerminal::ReleaseMasterFileDescriptor() + /// @li PseudoTerminal::ReleaseSaveFileDescriptor() + //------------------------------------------------------------------ + ~PseudoTerminal(); + + //------------------------------------------------------------------ + /// Close the master file descriptor if it is valid. + //------------------------------------------------------------------ + void CloseMasterFileDescriptor(); + + //------------------------------------------------------------------ + /// Close the slave file descriptor if it is valid. + //------------------------------------------------------------------ + void CloseSlaveFileDescriptor(); + + //------------------------------------------------------------------ + /// Fork a child process that uses pseudo terminals for its stdio. + /// + /// In the parent process, a call to this function results in a pid + /// being returned. If the pid is valid, the master file descriptor + /// can be used for read/write access to stdio of the child process. + /// + /// In the child process the stdin/stdout/stderr will already be + /// routed to the slave pseudo terminal and the master file + /// descriptor will be closed as it is no longer needed by the child + /// process. + /// + /// This class will close the file descriptors for the master/slave + /// when the destructor is called. The file handles can be released + /// using either: + /// @li PseudoTerminal::ReleaseMasterFileDescriptor() + /// @li PseudoTerminal::ReleaseSaveFileDescriptor() + /// + /// @param[out] error + /// An pointer to an error that can describe any errors that + /// occur. This can be NULL if no error status is desired. + /// + /// @return + /// @li \b Parent process: a child process ID that is greater + /// than zero, or -1 if the fork fails. + /// @li \b Child process: zero. + //------------------------------------------------------------------ + lldb::pid_t Fork(char *error_str, size_t error_len); + + //------------------------------------------------------------------ + /// The master file descriptor accessor. + /// + /// This object retains ownership of the master file descriptor when + /// this accessor is used. Users can call the member function + /// PseudoTerminal::ReleaseMasterFileDescriptor() if this + /// object should release ownership of the slave file descriptor. + /// + /// @return + /// The master file descriptor, or PseudoTerminal::invalid_fd + /// if the master file descriptor is not currently valid. + /// + /// @see PseudoTerminal::ReleaseMasterFileDescriptor() + //------------------------------------------------------------------ + int GetMasterFileDescriptor() const; + + //------------------------------------------------------------------ + /// The slave file descriptor accessor. + /// + /// This object retains ownership of the slave file descriptor when + /// this accessor is used. Users can call the member function + /// PseudoTerminal::ReleaseSlaveFileDescriptor() if this + /// object should release ownership of the slave file descriptor. + /// + /// @return + /// The slave file descriptor, or PseudoTerminal::invalid_fd + /// if the slave file descriptor is not currently valid. + /// + /// @see PseudoTerminal::ReleaseSlaveFileDescriptor() + //------------------------------------------------------------------ + int GetSlaveFileDescriptor() const; + + //------------------------------------------------------------------ + /// Get the name of the slave pseudo terminal. + /// + /// A master pseudo terminal should already be valid prior to + /// calling this function. + /// + /// @param[out] error + /// An pointer to an error that can describe any errors that + /// occur. This can be NULL if no error status is desired. + /// + /// @return + /// The name of the slave pseudo terminal as a NULL terminated + /// C. This string that comes from static memory, so a copy of + /// the string should be made as subsequent calls can change + /// this value. NULL is returned if this object doesn't have + /// a valid master pseudo terminal opened or if the call to + /// \c ptsname() fails. + /// + /// @see PseudoTerminal::OpenFirstAvailableMaster() + //------------------------------------------------------------------ + const char *GetSlaveName(char *error_str, size_t error_len) const; + + //------------------------------------------------------------------ + /// Open the first available pseudo terminal. + /// + /// Opens the first available pseudo terminal with \a oflag as the + /// permissions. The opened master file descriptor is stored in this + /// object and can be accessed by calling the + /// PseudoTerminal::GetMasterFileDescriptor() accessor. Clients + /// can call the PseudoTerminal::ReleaseMasterFileDescriptor() + /// accessor function if they wish to use the master file descriptor + /// beyond the lifespan of this object. + /// + /// If this object still has a valid master file descriptor when its + /// destructor is called, it will close it. + /// + /// @param[in] oflag + /// Flags to use when calling \c posix_openpt(\a oflag). + /// A value of "O_RDWR|O_NOCTTY" is suggested. + /// + /// @param[out] error + /// An pointer to an error that can describe any errors that + /// occur. This can be NULL if no error status is desired. + /// + /// @return + /// @li \b true when the master files descriptor is + /// successfully opened. + /// @li \b false if anything goes wrong. + /// + /// @see PseudoTerminal::GetMasterFileDescriptor() + /// @see PseudoTerminal::ReleaseMasterFileDescriptor() + //------------------------------------------------------------------ + bool OpenFirstAvailableMaster(int oflag, char *error_str, size_t error_len); + + //------------------------------------------------------------------ + /// Open the slave for the current master pseudo terminal. + /// + /// A master pseudo terminal should already be valid prior to + /// calling this function. The opened slave file descriptor is + /// stored in this object and can be accessed by calling the + /// PseudoTerminal::GetSlaveFileDescriptor() accessor. Clients + /// can call the PseudoTerminal::ReleaseSlaveFileDescriptor() + /// accessor function if they wish to use the slave file descriptor + /// beyond the lifespan of this object. + /// + /// If this object still has a valid slave file descriptor when its + /// destructor is called, it will close it. + /// + /// @param[in] oflag + /// Flags to use when calling \c open(\a oflag). + /// + /// @param[out] error + /// An pointer to an error that can describe any errors that + /// occur. This can be NULL if no error status is desired. + /// + /// @return + /// @li \b true when the master files descriptor is + /// successfully opened. + /// @li \b false if anything goes wrong. + /// + /// @see PseudoTerminal::OpenFirstAvailableMaster() + /// @see PseudoTerminal::GetSlaveFileDescriptor() + /// @see PseudoTerminal::ReleaseSlaveFileDescriptor() + //------------------------------------------------------------------ + bool OpenSlave(int oflag, char *error_str, size_t error_len); + + //------------------------------------------------------------------ + /// Release the master file descriptor. + /// + /// Releases ownership of the master pseudo terminal file descriptor + /// without closing it. The destructor for this class will close the + /// master file descriptor if the ownership isn't released using this + /// call and the master file descriptor has been opened. + /// + /// @return + /// The master file descriptor, or PseudoTerminal::invalid_fd + /// if the mast file descriptor is not currently valid. + //------------------------------------------------------------------ + int ReleaseMasterFileDescriptor(); + + //------------------------------------------------------------------ + /// Release the slave file descriptor. + /// + /// Release ownership of the slave pseudo terminal file descriptor + /// without closing it. The destructor for this class will close the + /// slave file descriptor if the ownership isn't released using this + /// call and the slave file descriptor has been opened. + /// + /// @return + /// The slave file descriptor, or PseudoTerminal::invalid_fd + /// if the slave file descriptor is not currently valid. + //------------------------------------------------------------------ + int ReleaseSlaveFileDescriptor(); protected: - //------------------------------------------------------------------ - // Member variables - //------------------------------------------------------------------ - int m_master_fd; ///< The file descriptor for the master. - int m_slave_fd; ///< The file descriptor for the slave. + //------------------------------------------------------------------ + // Member variables + //------------------------------------------------------------------ + int m_master_fd; ///< The file descriptor for the master. + int m_slave_fd; ///< The file descriptor for the slave. private: - DISALLOW_COPY_AND_ASSIGN (PseudoTerminal); - + DISALLOW_COPY_AND_ASSIGN(PseudoTerminal); }; } // namespace lldb_utility -#endif // #if defined(__cplusplus) +#endif // #if defined(__cplusplus) #endif // #ifndef liblldb_PseudoTerminal_h_ diff --git a/include/lldb/Utility/Range.h b/include/lldb/Utility/Range.h index 1257adb719a1..c13bc0d08bd6 100644 --- a/include/lldb/Utility/Range.h +++ b/include/lldb/Utility/Range.h @@ -10,80 +10,52 @@ #ifndef utility_Range_h_ #define utility_Range_h_ -#include <stdint.h> #include <algorithm> +#include <stdint.h> namespace lldb_utility { - -class Range -{ + +class Range { public: - - typedef uint64_t ValueType; - - static const ValueType OPEN_END = UINT64_MAX; - - Range (const Range& rng); - - Range (ValueType low = 0, - ValueType high = OPEN_END); - - Range& - operator = (const Range& rhs); - - ValueType - GetLow () - { - return m_low; - } - - ValueType - GetHigh () - { - return m_high; - } - - void - SetLow (ValueType low) - { - m_low = low; - } - - void - SetHigh (ValueType high) - { - m_high = high; - } - - void - Flip (); - - void - Intersection (const Range& other); - - void - Union (const Range& other); - - typedef bool (*RangeCallback)(ValueType index); - - void - Iterate (RangeCallback callback); - - ValueType - GetSize (); - - bool - IsEmpty (); - + typedef uint64_t ValueType; + + static const ValueType OPEN_END = UINT64_MAX; + + Range(const Range &rng); + + Range(ValueType low = 0, ValueType high = OPEN_END); + + Range &operator=(const Range &rhs); + + ValueType GetLow() { return m_low; } + + ValueType GetHigh() { return m_high; } + + void SetLow(ValueType low) { m_low = low; } + + void SetHigh(ValueType high) { m_high = high; } + + void Flip(); + + void Intersection(const Range &other); + + void Union(const Range &other); + + typedef bool (*RangeCallback)(ValueType index); + + void Iterate(RangeCallback callback); + + ValueType GetSize(); + + bool IsEmpty(); + private: - - void - InitRange (); - - ValueType m_low; - ValueType m_high; + void InitRange(); + + ValueType m_low; + ValueType m_high; }; - + } // namespace lldb_private #endif // #ifndef utility_Range_h_ diff --git a/include/lldb/Utility/RegisterNumber.h b/include/lldb/Utility/RegisterNumber.h index 89d52fd4a967..b3845ac0d46b 100644 --- a/include/lldb/Utility/RegisterNumber.h +++ b/include/lldb/Utility/RegisterNumber.h @@ -21,49 +21,42 @@ class RegisterNumber { public: - RegisterNumber (lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num); + RegisterNumber(lldb_private::Thread &thread, lldb::RegisterKind kind, + uint32_t num); - // This constructor plus the init() method below allow for the placeholder - // creation of an invalid object initially, possibly to be filled in. It - // would be more consistent to have three Set* methods to set the three - // data that the object needs. - RegisterNumber (); + // This constructor plus the init() method below allow for the placeholder + // creation of an invalid object initially, possibly to be filled in. It + // would be more consistent to have three Set* methods to set the three + // data that the object needs. + RegisterNumber(); - void - init (lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num); + void init(lldb_private::Thread &thread, lldb::RegisterKind kind, + uint32_t num); - const RegisterNumber & - operator = (const RegisterNumber &rhs); + const RegisterNumber &operator=(const RegisterNumber &rhs); - bool - operator == (RegisterNumber &rhs); + bool operator==(RegisterNumber &rhs); - bool - operator != (RegisterNumber &rhs); + bool operator!=(RegisterNumber &rhs); - bool - IsValid () const; + bool IsValid() const; - uint32_t - GetAsKind (lldb::RegisterKind kind); + uint32_t GetAsKind(lldb::RegisterKind kind); - uint32_t - GetRegisterNumber () const; + uint32_t GetRegisterNumber() const; - lldb::RegisterKind - GetRegisterKind () const; + lldb::RegisterKind GetRegisterKind() const; - const char * - GetName (); + const char *GetName(); private: - typedef std::map<lldb::RegisterKind, uint32_t> Collection; + typedef std::map<lldb::RegisterKind, uint32_t> Collection; - lldb::RegisterContextSP m_reg_ctx_sp; - uint32_t m_regnum; - lldb::RegisterKind m_kind; - Collection m_kind_regnum_map; - const char *m_name; + lldb::RegisterContextSP m_reg_ctx_sp; + uint32_t m_regnum; + lldb::RegisterKind m_kind; + Collection m_kind_regnum_map; + const char *m_name; }; #endif // liblldb_RegisterNumber_h diff --git a/include/lldb/Utility/SafeMachO.h b/include/lldb/Utility/SafeMachO.h index 2a831ed89b80..5da03c15da94 100644 --- a/include/lldb/Utility/SafeMachO.h +++ b/include/lldb/Utility/SafeMachO.h @@ -9,104 +9,110 @@ #ifndef liblldb_SafeMachO_h_ #define liblldb_SafeMachO_h_ -// This header file is required to work around collisions between the defines in mach/machine.h, and enum members -// of the same name in llvm's MachO.h. If you want to use llvm/Support/MachO.h, use this file instead. +// This header file is required to work around collisions between the defines in +// mach/machine.h, and enum members +// of the same name in llvm's MachO.h. If you want to use llvm/Support/MachO.h, +// use this file instead. // The caveats are: -// 1) You can only use the MachO.h enums, you can't use the defines. That won't make a difference since the values +// 1) You can only use the MachO.h enums, you can't use the defines. That won't +// make a difference since the values // are the same. -// 2) If you need any header file that relies on mach/machine.h, you must include that first. -// 3) This isn't a total solution, it doesn't undef every define that MachO.h has borrowed from various system headers, -// only the ones that come from mach/machine.h because that is the one we ended up pulling in from various places. +// 2) If you need any header file that relies on mach/machine.h, you must +// include that first. +// 3) This isn't a total solution, it doesn't undef every define that MachO.h +// has borrowed from various system headers, +// only the ones that come from mach/machine.h because that is the one we +// ended up pulling in from various places. // #undef CPU_ARCH_MASK -#undef CPU_ARCH_ABI64 - -#undef CPU_TYPE_ANY -#undef CPU_TYPE_X86 -#undef CPU_TYPE_I386 -#undef CPU_TYPE_X86_64 -#undef CPU_TYPE_MC98000 -#undef CPU_TYPE_ARM -#undef CPU_TYPE_ARM64 -#undef CPU_TYPE_SPARC -#undef CPU_TYPE_POWERPC -#undef CPU_TYPE_POWERPC64 - -#undef CPU_SUB_TYPE_MASK -#undef CPU_SUB_TYPE_LIB64 - -#undef CPU_SUBTYPE_MULTIPLE - -#undef CPU_SUBTYPE_I386_ALL -#undef CPU_SUBTYPE_386 -#undef CPU_SUBTYPE_486 -#undef CPU_SUBTYPE_486SX -#undef CPU_SUBTYPE_586 -#undef CPU_SUBTYPE_PENT -#undef CPU_SUBTYPE_PENTPRO -#undef CPU_SUBTYPE_PENTII_M3 -#undef CPU_SUBTYPE_PENTII_M5 -#undef CPU_SUBTYPE_CELERON -#undef CPU_SUBTYPE_CELERON_MOBILE -#undef CPU_SUBTYPE_PENTIUM_3 -#undef CPU_SUBTYPE_PENTIUM_3_M -#undef CPU_SUBTYPE_PENTIUM_3_XEON -#undef CPU_SUBTYPE_PENTIUM_M -#undef CPU_SUBTYPE_PENTIUM_4 -#undef CPU_SUBTYPE_PENTIUM_4_M -#undef CPU_SUBTYPE_ITANIUM -#undef CPU_SUBTYPE_ITANIUM_2 -#undef CPU_SUBTYPE_XEON -#undef CPU_SUBTYPE_XEON_MP - -#undef CPU_SUBTYPE_X86_ALL -#undef CPU_SUBTYPE_X86_64_ALL -#undef CPU_SUBTYPE_X86_ARCH1 -#undef CPU_SUBTYPE_X86_64_H +#undef CPU_ARCH_ABI64 + +#undef CPU_TYPE_ANY +#undef CPU_TYPE_X86 +#undef CPU_TYPE_I386 +#undef CPU_TYPE_X86_64 +#undef CPU_TYPE_MC98000 +#undef CPU_TYPE_ARM +#undef CPU_TYPE_ARM64 +#undef CPU_TYPE_SPARC +#undef CPU_TYPE_POWERPC +#undef CPU_TYPE_POWERPC64 + +#undef CPU_SUB_TYPE_MASK +#undef CPU_SUB_TYPE_LIB64 + +#undef CPU_SUBTYPE_MULTIPLE + +#undef CPU_SUBTYPE_I386_ALL +#undef CPU_SUBTYPE_386 +#undef CPU_SUBTYPE_486 +#undef CPU_SUBTYPE_486SX +#undef CPU_SUBTYPE_586 +#undef CPU_SUBTYPE_PENT +#undef CPU_SUBTYPE_PENTPRO +#undef CPU_SUBTYPE_PENTII_M3 +#undef CPU_SUBTYPE_PENTII_M5 +#undef CPU_SUBTYPE_CELERON +#undef CPU_SUBTYPE_CELERON_MOBILE +#undef CPU_SUBTYPE_PENTIUM_3 +#undef CPU_SUBTYPE_PENTIUM_3_M +#undef CPU_SUBTYPE_PENTIUM_3_XEON +#undef CPU_SUBTYPE_PENTIUM_M +#undef CPU_SUBTYPE_PENTIUM_4 +#undef CPU_SUBTYPE_PENTIUM_4_M +#undef CPU_SUBTYPE_ITANIUM +#undef CPU_SUBTYPE_ITANIUM_2 +#undef CPU_SUBTYPE_XEON +#undef CPU_SUBTYPE_XEON_MP + +#undef CPU_SUBTYPE_X86_ALL +#undef CPU_SUBTYPE_X86_64_ALL +#undef CPU_SUBTYPE_X86_ARCH1 +#undef CPU_SUBTYPE_X86_64_H #undef CPU_SUBTYPE_INTEL #undef CPU_SUBTYPE_INTEL_FAMILY #undef CPU_SUBTYPE_INTEL_FAMILY_MAX -#undef CPU_SUBTYPE_INTEL_MODEL -#undef CPU_SUBTYPE_INTEL_MODEL_ALL +#undef CPU_SUBTYPE_INTEL_MODEL +#undef CPU_SUBTYPE_INTEL_MODEL_ALL #undef CPU_SUBTYPE_ARM -#undef CPU_SUBTYPE_ARM_ALL -#undef CPU_SUBTYPE_ARM_V4T -#undef CPU_SUBTYPE_ARM_V6 -#undef CPU_SUBTYPE_ARM_V5 -#undef CPU_SUBTYPE_ARM_V5TEJ -#undef CPU_SUBTYPE_ARM_XSCALE -#undef CPU_SUBTYPE_ARM_V7 +#undef CPU_SUBTYPE_ARM_ALL +#undef CPU_SUBTYPE_ARM_V4T +#undef CPU_SUBTYPE_ARM_V6 +#undef CPU_SUBTYPE_ARM_V5 +#undef CPU_SUBTYPE_ARM_V5TEJ +#undef CPU_SUBTYPE_ARM_XSCALE +#undef CPU_SUBTYPE_ARM_V7 -#undef CPU_SUBTYPE_ARM_V7S -#undef CPU_SUBTYPE_ARM_V7K -#undef CPU_SUBTYPE_ARM_V6M -#undef CPU_SUBTYPE_ARM_V7M -#undef CPU_SUBTYPE_ARM_V7EM +#undef CPU_SUBTYPE_ARM_V7S +#undef CPU_SUBTYPE_ARM_V7K +#undef CPU_SUBTYPE_ARM_V6M +#undef CPU_SUBTYPE_ARM_V7M +#undef CPU_SUBTYPE_ARM_V7EM -#undef CPU_SUBTYPE_ARM64_ALL +#undef CPU_SUBTYPE_ARM64_ALL -#undef CPU_SUBTYPE_SPARC_ALL +#undef CPU_SUBTYPE_SPARC_ALL #undef CPU_SUBTYPE_POWERPC -#undef CPU_SUBTYPE_POWERPC_ALL -#undef CPU_SUBTYPE_POWERPC_601 -#undef CPU_SUBTYPE_POWERPC_602 -#undef CPU_SUBTYPE_POWERPC_603 -#undef CPU_SUBTYPE_POWERPC_603e -#undef CPU_SUBTYPE_POWERPC_603ev -#undef CPU_SUBTYPE_POWERPC_604 -#undef CPU_SUBTYPE_POWERPC_604e -#undef CPU_SUBTYPE_POWERPC_620 -#undef CPU_SUBTYPE_POWERPC_750 -#undef CPU_SUBTYPE_POWERPC_7400 -#undef CPU_SUBTYPE_POWERPC_7450 -#undef CPU_SUBTYPE_POWERPC_970 - -#undef CPU_SUBTYPE_MC980000_ALL -#undef CPU_SUBTYPE_MC98601 +#undef CPU_SUBTYPE_POWERPC_ALL +#undef CPU_SUBTYPE_POWERPC_601 +#undef CPU_SUBTYPE_POWERPC_602 +#undef CPU_SUBTYPE_POWERPC_603 +#undef CPU_SUBTYPE_POWERPC_603e +#undef CPU_SUBTYPE_POWERPC_603ev +#undef CPU_SUBTYPE_POWERPC_604 +#undef CPU_SUBTYPE_POWERPC_604e +#undef CPU_SUBTYPE_POWERPC_620 +#undef CPU_SUBTYPE_POWERPC_750 +#undef CPU_SUBTYPE_POWERPC_7400 +#undef CPU_SUBTYPE_POWERPC_7450 +#undef CPU_SUBTYPE_POWERPC_970 + +#undef CPU_SUBTYPE_MC980000_ALL +#undef CPU_SUBTYPE_MC98601 #include "llvm/Support/MachO.h" diff --git a/include/lldb/Utility/SelectHelper.h b/include/lldb/Utility/SelectHelper.h new file mode 100644 index 000000000000..0251c8e72cde --- /dev/null +++ b/include/lldb/Utility/SelectHelper.h @@ -0,0 +1,76 @@ +//===-- SelectHelper.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_SelectHelper_h_ +#define liblldb_SelectHelper_h_ + +// C Includes +// C++ Includes +#include <chrono> + +// Other libraries and framework includes +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" + +// Project includes +#include "lldb/lldb-forward.h" + +class SelectHelper { +public: + // Defaults to infinite wait for select unless you call SetTimeout() + SelectHelper(); + + // Call SetTimeout() before calling SelectHelper::Select() to set the + // timeout based on the current time + the timeout. This allows multiple + // calls to SelectHelper::Select() without having to worry about the + // absolute timeout as this class manages to set the relative timeout + // correctly. + void SetTimeout(const std::chrono::microseconds &timeout); + + // Call the FDSet*() functions before calling SelectHelper::Select() to + // set the file descriptors that we will watch for when calling + // select. This will cause FD_SET() to be called prior to calling select + // using the "fd" provided. + void FDSetRead(lldb::socket_t fd); + void FDSetWrite(lldb::socket_t fd); + void FDSetError(lldb::socket_t fd); + + // Call the FDIsSet*() functions after calling SelectHelper::Select() + // to check which file descriptors are ready for read/write/error. This + // will contain the result of FD_ISSET after calling select for a given + // file descriptor. + bool FDIsSetRead(lldb::socket_t fd) const; + bool FDIsSetWrite(lldb::socket_t fd) const; + bool FDIsSetError(lldb::socket_t fd) const; + + // Call the system's select() to wait for descriptors using + // timeout provided in a call the SelectHelper::SetTimeout(), + // or infinite wait if no timeout was set. + lldb_private::Error Select(); + +protected: + struct FDInfo { + FDInfo() + : read_set(false), write_set(false), error_set(false), + read_is_set(false), write_is_set(false), error_is_set(false) {} + + void PrepareForSelect() { + read_is_set = false; + write_is_set = false; + error_is_set = false; + } + + bool read_set : 1, write_set : 1, error_set : 1, read_is_set : 1, + write_is_set : 1, error_is_set : 1; + }; + llvm::DenseMap<lldb::socket_t, FDInfo> m_fd_map; + llvm::Optional<std::chrono::steady_clock::time_point> m_end_time; +}; + +#endif // liblldb_SelectHelper_h_ diff --git a/include/lldb/Utility/SharedCluster.h b/include/lldb/Utility/SharedCluster.h index dfcc119e14bf..b01f702c2787 100644 --- a/include/lldb/Utility/SharedCluster.h +++ b/include/lldb/Utility/SharedCluster.h @@ -17,91 +17,76 @@ 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 <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: - ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {} - - ~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(); + ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {} + + ~ClusterManager() { + for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), + end = m_objects.end(); + pos != end; ++pos) { + T *object = *pos; + delete object; } - void - ManageObject(T *new_object) - { - std::lock_guard<std::mutex> guard(m_mutex); - m_objects.insert(new_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(); + } - 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; - } - } - return typename lldb_private::SharingPtr<T>(desired_object, new imp::shared_ptr_refcount<ClusterManager>(this)); - } + void ManageObject(T *new_object) { + std::lock_guard<std::mutex> guard(m_mutex); + m_objects.insert(new_object); + } -private: - void - DecrementRefCount() + typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) { { - m_mutex.lock(); - m_external_ref--; - if (m_external_ref == 0) - delete this; - else - m_mutex.unlock(); + 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; + } } + return typename lldb_private::SharingPtr<T>( + desired_object, new imp::shared_ptr_refcount<ClusterManager>(this)); + } - friend class imp::shared_ptr_refcount<ClusterManager>; - - llvm::SmallPtrSet<T *, 16> m_objects; - int m_external_ref; - std::mutex m_mutex; +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>; + + llvm::SmallPtrSet<T *, 16> m_objects; + int m_external_ref; + std::mutex m_mutex; }; } // namespace lldb_private diff --git a/include/lldb/Utility/SharingPtr.h b/include/lldb/Utility/SharingPtr.h index 29538bc7dc03..4e91222b3c31 100644 --- a/include/lldb/Utility/SharingPtr.h +++ b/include/lldb/Utility/SharingPtr.h @@ -28,813 +28,595 @@ // Project includes //#define ENABLE_SP_LOGGING 1 // DON'T CHECK THIS LINE IN UNLESS COMMENTED OUT -#if defined (ENABLE_SP_LOGGING) +#if defined(ENABLE_SP_LOGGING) -extern "C" void track_sp (void *sp_this, void *ptr, long count); +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&); - shared_count& operator=(const shared_count&); + +class shared_count { + shared_count(const shared_count &); + shared_count &operator=(const shared_count &); public: - explicit shared_count(long refs = 0) - : shared_owners_(refs) {} + explicit shared_count(long refs = 0) : shared_owners_(refs) {} + + void add_shared(); + void release_shared(); + long use_count() const { return shared_owners_ + 1; } - void add_shared(); - void release_shared(); - long use_count() const {return shared_owners_ + 1;} protected: #ifdef _MSC_VER - long shared_owners_; + long shared_owners_; #else - std::atomic<long> shared_owners_; + std::atomic<long> shared_owners_; #endif - virtual ~shared_count(); + virtual ~shared_count(); private: - virtual void on_zero_shared() = 0; + virtual void on_zero_shared() = 0; }; -template <class T> -class shared_ptr_pointer - : public shared_count -{ - T data_; +template <class T> class shared_ptr_pointer : public shared_count { + T data_; + public: - shared_ptr_pointer(T p) - : data_(p) {} + shared_ptr_pointer(T p) : data_(p) {} private: - void on_zero_shared() override; + void on_zero_shared() override; - // Outlaw copy constructor and assignment operator to keep effective C++ - // warnings down to a minimum - shared_ptr_pointer (const shared_ptr_pointer &); - shared_ptr_pointer & operator=(const shared_ptr_pointer &); + // Outlaw copy constructor and assignment operator to keep effective C++ + // warnings down to a minimum + shared_ptr_pointer(const shared_ptr_pointer &); + shared_ptr_pointer &operator=(const shared_ptr_pointer &); }; -template <class T> -void -shared_ptr_pointer<T>::on_zero_shared() -{ - delete data_; +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: +template <class T> class shared_ptr_emplace : public shared_count { + T data_; - shared_ptr_emplace() - : data_() {} +public: + shared_ptr_emplace() : data_() {} - template <class A0> - shared_ptr_emplace(A0& a0) - : data_(a0) {} + 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> + 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> + 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> + 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) {} + 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; + void on_zero_shared() override; public: - T* get() {return &data_;} + T *get() { return &data_; } }; -template <class T> -void -shared_ptr_emplace<T>::on_zero_shared() -{ -} +template <class T> void shared_ptr_emplace<T>::on_zero_shared() {} } // namespace imp -template<class T> -class SharingPtr -{ -public: - typedef T element_type; +template <class T> class SharingPtr { +public: + typedef T element_type; private: - element_type* ptr_; - imp::shared_count* cntrl_; + element_type *ptr_; + imp::shared_count *cntrl_; - struct nat {int for_bool_;}; + 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(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(); - SharingPtr& operator=(const SharingPtr& r); - template<class Y> SharingPtr& operator=(const SharingPtr<Y>& r); + 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); + 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();} + 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(); + static SharingPtr<T> make_shared(); - template<class A0> - static SharingPtr<T> make_shared(A0&); + 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> 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> + 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> + 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&); + 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 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> +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> -inline -SharingPtr<T>& -SharingPtr<T>::operator=(const SharingPtr<Y>& r) -{ - SharingPtr(r).swap(*this); - return *this; +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> -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> SharingPtr<T>::~SharingPtr() { + if (cntrl_) + cntrl_->release_shared(); } -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> +inline SharingPtr<T> &SharingPtr<T>::operator=(const SharingPtr &r) { + SharingPtr(r).swap(*this); + return *this; } template <class T> -class LoggingSharingPtr - : public SharingPtr<T> -{ - typedef SharingPtr<T> base; +template <class Y> +inline SharingPtr<T> &SharingPtr<T>::operator=(const SharingPtr<Y> &r) { + SharingPtr(r).swap(*this); + return *this; +} -public: - typedef void (*Callback)(void*, const LoggingSharingPtr&, bool action); - // action: false means increment just happened - // true means decrement is about to happen +template <class T> inline void SharingPtr<T>::swap(SharingPtr &r) { + std::swap(ptr_, r.ptr_); + std::swap(cntrl_, r.cntrl_); +} - LoggingSharingPtr() : cb_(0), baton_(nullptr) {} +template <class T> inline void SharingPtr<T>::reset() { + SharingPtr().swap(*this); +} - LoggingSharingPtr(Callback cb, void* baton) - : cb_(cb), baton_(baton) - { - if (cb_) - cb_(baton_, *this, false); - } +template <class T> inline void SharingPtr<T>::reset(std::nullptr_t p) { + reset(); +} - template <class Y> - LoggingSharingPtr(Y* p) - : base(p), cb_(0), baton_(nullptr) {} +template <class T> template <class Y> inline void SharingPtr<T>::reset(Y *p) { + SharingPtr(p).swap(*this); +} - template <class Y> - LoggingSharingPtr(Y* p, Callback cb, void* baton) - : base(p), cb_(cb), baton_(baton) - { - if (cb_) - cb_(baton_, *this, false); - } +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; +} - ~LoggingSharingPtr() - { - if (cb_) - cb_(baton_, *this, true); - } +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; +} - LoggingSharingPtr(const LoggingSharingPtr& p) - : base(p), cb_(p.cb_), baton_(p.baton_) - { - if (cb_) - cb_(baton_, *this, false); - } +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; +} - 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; - } +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; +} - void reset() - { - if (cb_) - cb_(baton_, *this, true); - base::reset(); - } +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 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; - } +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; +} - void ClearCallback() - { - cb_ = 0; - baton_ = 0; - } +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_; + Callback cb_; + void *baton_; }; -template <class T> -class IntrusiveSharingPtr; +template <class T> class IntrusiveSharingPtr; -template <class T> -class ReferenceCountedBase -{ +template <class T> class ReferenceCountedBase { public: - explicit ReferenceCountedBase() - : shared_owners_(-1) - { - } - - void - add_shared(); + explicit ReferenceCountedBase() : shared_owners_(-1) {} - void - release_shared(); + void add_shared(); + + void release_shared(); + + long use_count() const { return shared_owners_ + 1; } - long - use_count() const - { - return shared_owners_ + 1; - } - protected: - long shared_owners_; - - friend class IntrusiveSharingPtr<T>; - + long shared_owners_; + + friend class IntrusiveSharingPtr<T>; + private: - ReferenceCountedBase(const ReferenceCountedBase&); - ReferenceCountedBase& operator=(const ReferenceCountedBase&); + ReferenceCountedBase(const ReferenceCountedBase &); + ReferenceCountedBase &operator=(const ReferenceCountedBase &); }; - template <class T> - void - lldb_private::ReferenceCountedBase<T>::add_shared() - { +template <class T> void lldb_private::ReferenceCountedBase<T>::add_shared() { #ifdef _MSC_VER - _InterlockedIncrement(&shared_owners_); + _InterlockedIncrement(&shared_owners_); #else - ++shared_owners_; + ++shared_owners_; #endif - } - - template <class T> - void - lldb_private::ReferenceCountedBase<T>::release_shared() - { +} + +template <class T> +void lldb_private::ReferenceCountedBase<T>::release_shared() { #ifdef _MSC_VER - if (_InterlockedDecrement(&shared_owners_) == -1) + if (_InterlockedDecrement(&shared_owners_) == -1) #else - if (--shared_owners_ == -1) + if (--shared_owners_ == -1) #endif - delete static_cast<T*>(this); - } + delete static_cast<T *>(this); +} - template <class T> -class ReferenceCountedBaseVirtual : public imp::shared_count -{ +class ReferenceCountedBaseVirtual : public imp::shared_count { public: - explicit ReferenceCountedBaseVirtual () : - imp::shared_count(-1) - { - } + explicit ReferenceCountedBaseVirtual() : imp::shared_count(-1) {} - ~ReferenceCountedBaseVirtual() override = default; + ~ReferenceCountedBaseVirtual() override = default; - void on_zero_shared() override; + void on_zero_shared() override; }; -template <class T> -void -ReferenceCountedBaseVirtual<T>::on_zero_shared() -{ -} +template <class T> void ReferenceCountedBaseVirtual<T>::on_zero_shared() {} -template <typename T> -class IntrusiveSharingPtr -{ +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(); -#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) - // NULL out the pointer in objects which can help with leaks detection. - // We don't enable this for LLDB_CONFIGURATION_BUILD_AND_INTEGRATION or - // when none of the LLDB_CONFIGURATION_XXX macros are defined since - // those would be builds for release. But for debug and release builds - // that are for development, we NULL out the pointers to catch potential - // issues. - ptr_ = nullptr; -#endif // #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) - } - - 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()); + 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(); +#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE) + // NULL out the pointer in objects which can help with leaks detection. + // We don't enable this for LLDB_CONFIGURATION_BUILD_AND_INTEGRATION or + // when none of the LLDB_CONFIGURATION_XXX macros are defined since + // those would be builds for release. But for debug and release builds + // that are for development, we NULL out the pointers to catch potential + // issues. + ptr_ = nullptr; +#endif // #if defined (LLDB_CONFIGURATION_DEBUG) || defined + // (LLDB_CONFIGURATION_RELEASE) + } + + 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); - } + 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; - } + 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()); + 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); + } + void release_shared() { + if (ptr_) { +#if defined(ENABLE_SP_LOGGING) + track_sp(this, nullptr, ptr_->use_count() - 1); #endif - ptr_->release_shared(); - } + 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, 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!= (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(); } -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 diff --git a/include/lldb/Utility/StringExtractor.h b/include/lldb/Utility/StringExtractor.h index db1b83b07694..624d1ef3edfd 100644 --- a/include/lldb/Utility/StringExtractor.h +++ b/include/lldb/Utility/StringExtractor.h @@ -12,168 +12,125 @@ // C Includes // C++ Includes -#include <string> #include <stdint.h> +#include <string> // Other libraries and framework includes // Project includes +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" -class StringExtractor -{ +class StringExtractor { public: + enum { BigEndian = 0, LittleEndian = 1 }; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + StringExtractor(); + StringExtractor(llvm::StringRef packet_str); + StringExtractor(const char *packet_cstr); + StringExtractor(const StringExtractor &rhs); + virtual ~StringExtractor(); + + //------------------------------------------------------------------ + // Operators + //------------------------------------------------------------------ + const StringExtractor &operator=(const StringExtractor &rhs); + + void Reset(llvm::StringRef str) { + m_packet = str; + m_index = 0; + } + + // Returns true if the file position is still valid for the data + // contained in this string extractor object. + bool IsGood() const { return m_index != UINT64_MAX; } + + uint64_t GetFilePos() const { return m_index; } + + void SetFilePos(uint32_t idx) { m_index = idx; } + + void Clear() { + m_packet.clear(); + m_index = 0; + } + + void SkipSpaces(); + + std::string &GetStringRef() { return m_packet; } + + const std::string &GetStringRef() const { return m_packet; } + + bool Empty() { return m_packet.empty(); } + + size_t GetBytesLeft() { + if (m_index < m_packet.size()) + return m_packet.size() - m_index; + return 0; + } + + char GetChar(char fail_value = '\0'); + + char PeekChar(char fail_value = '\0') { + const char *cstr = Peek(); + if (cstr) + return cstr[0]; + return fail_value; + } + + int DecodeHexU8(); + + uint8_t GetHexU8(uint8_t fail_value = 0, bool set_eof_on_fail = true); + + bool GetHexU8Ex(uint8_t &ch, bool set_eof_on_fail = true); + + bool GetNameColonValue(llvm::StringRef &name, llvm::StringRef &value); + + int32_t GetS32(int32_t fail_value, int base = 0); + + uint32_t GetU32(uint32_t fail_value, int base = 0); + + int64_t GetS64(int64_t fail_value, int base = 0); + + uint64_t GetU64(uint64_t fail_value, int base = 0); + + uint32_t GetHexMaxU32(bool little_endian, uint32_t fail_value); + + uint64_t GetHexMaxU64(bool little_endian, uint64_t fail_value); + + size_t GetHexBytes(llvm::MutableArrayRef<uint8_t> dest, + uint8_t fail_fill_value); + + size_t GetHexBytesAvail(llvm::MutableArrayRef<uint8_t> dest); + + uint64_t GetHexWithFixedSize(uint32_t byte_size, bool little_endian, + uint64_t fail_value); + + size_t GetHexByteString(std::string &str); + + size_t GetHexByteStringFixedLength(std::string &str, uint32_t nibble_length); + + size_t GetHexByteStringTerminatedBy(std::string &str, char terminator); - enum { - BigEndian = 0, - LittleEndian = 1 - }; - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - StringExtractor(); - StringExtractor(const char *packet_cstr); - StringExtractor(const StringExtractor& rhs); - virtual ~StringExtractor(); - - //------------------------------------------------------------------ - // Operators - //------------------------------------------------------------------ - const StringExtractor& - operator=(const StringExtractor& rhs); - - // Returns true if the file position is still valid for the data - // contained in this string extractor object. - bool - IsGood() const - { - return m_index != UINT64_MAX; - } - - uint64_t - GetFilePos () const - { - return m_index; - } - - void - SetFilePos (uint32_t idx) - { - m_index = idx; - } - - void - Clear () - { - m_packet.clear(); - m_index = 0; - } - - void - SkipSpaces (); - - std::string & - GetStringRef () - { - return m_packet; - } - - const std::string & - GetStringRef () const - { - return m_packet; - } - - bool - Empty() - { - return m_packet.empty(); - } - - size_t - GetBytesLeft () - { - if (m_index < m_packet.size()) - return m_packet.size() - m_index; - return 0; - } - - char - GetChar (char fail_value = '\0'); - - char - PeekChar (char fail_value = '\0') - { - const char *cstr = Peek(); - if (cstr) - return cstr[0]; - return fail_value; - } - - int - DecodeHexU8(); - - uint8_t - GetHexU8 (uint8_t fail_value = 0, bool set_eof_on_fail = true); - - bool - GetHexU8Ex (uint8_t& ch, bool set_eof_on_fail = true); - - bool - GetNameColonValue (std::string &name, std::string &value); - - int32_t - GetS32 (int32_t fail_value, int base = 0); - - uint32_t - GetU32 (uint32_t fail_value, int base = 0); - - int64_t - GetS64 (int64_t fail_value, int base = 0); - - uint64_t - GetU64 (uint64_t fail_value, int base = 0); - - uint32_t - GetHexMaxU32 (bool little_endian, uint32_t fail_value); - - uint64_t - GetHexMaxU64 (bool little_endian, uint64_t fail_value); - - size_t - GetHexBytes (void *dst, size_t dst_len, uint8_t fail_fill_value); - - size_t - GetHexBytesAvail (void *dst, size_t dst_len); - - uint64_t - GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value); - - size_t - GetHexByteString (std::string &str); - - size_t - GetHexByteStringFixedLength (std::string &str, uint32_t nibble_length); - - size_t - GetHexByteStringTerminatedBy (std::string &str, - char terminator); - - const char * - Peek () - { - if (m_index < m_packet.size()) - return m_packet.c_str() + m_index; - return nullptr; - } + const char *Peek() { + if (m_index < m_packet.size()) + return m_packet.c_str() + m_index; + return nullptr; + } protected: - //------------------------------------------------------------------ - // For StringExtractor only - //------------------------------------------------------------------ - std::string m_packet; // The string in which to extract data. - uint64_t m_index; // When extracting data from a packet, this index - // will march along as things get extracted. If set - // to UINT64_MAX the end of the packet data was - // reached when decoding information + bool fail() { + m_index = UINT64_MAX; + return false; + } + //------------------------------------------------------------------ + // For StringExtractor only + //------------------------------------------------------------------ + std::string m_packet; // The string in which to extract data. + uint64_t m_index; // When extracting data from a packet, this index + // will march along as things get extracted. If set + // to UINT64_MAX the end of the packet data was + // reached when decoding information }; -#endif // utility_StringExtractor_h_ +#endif // utility_StringExtractor_h_ diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h index ae6b393b0eb6..3a399dfd7812 100644 --- a/include/lldb/Utility/StringLexer.h +++ b/include/lldb/Utility/StringLexer.h @@ -1,4 +1,5 @@ -//===--------------------- StringLexer.h -------------------------*- C++ -*-===// +//===--------------------- StringLexer.h -------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -15,57 +16,45 @@ #include <string> namespace lldb_utility { - -class StringLexer -{ + +class StringLexer { public: - typedef std::string::size_type Position; - typedef std::string::size_type Size; - - typedef std::string::value_type Character; - - StringLexer (std::string s); - - StringLexer (const StringLexer& rhs); - - // These APIs are not bounds-checked. Use HasAtLeast() if you're not sure. - Character - Peek (); - - bool - NextIf (Character c); - - std::pair<bool, Character> - NextIf (std::initializer_list<Character> cs); - - bool - AdvanceIf (const std::string& token); - - Character - Next (); - - bool - HasAtLeast (Size s); - - bool - HasAny (Character c); - - std::string - GetUnlexed (); - - // This will assert if there are less than s characters preceding the cursor. - void - PutBack (Size s); - - StringLexer& - operator = (const StringLexer& rhs); - + typedef std::string::size_type Position; + typedef std::string::size_type Size; + + typedef std::string::value_type Character; + + StringLexer(std::string s); + + StringLexer(const StringLexer &rhs); + + // These APIs are not bounds-checked. Use HasAtLeast() if you're not sure. + Character Peek(); + + bool NextIf(Character c); + + std::pair<bool, Character> NextIf(std::initializer_list<Character> cs); + + bool AdvanceIf(const std::string &token); + + Character Next(); + + bool HasAtLeast(Size s); + + bool HasAny(Character c); + + std::string GetUnlexed(); + + // This will assert if there are less than s characters preceding the cursor. + void PutBack(Size s); + + StringLexer &operator=(const StringLexer &rhs); + private: - std::string m_data; - Position m_position; - - void - Consume(); + std::string m_data; + Position m_position; + + void Consume(); }; } // namespace lldb_private diff --git a/include/lldb/Utility/TaskPool.h b/include/lldb/Utility/TaskPool.h index 443e2a5853e2..db15b208171b 100644 --- a/include/lldb/Utility/TaskPool.h +++ b/include/lldb/Utility/TaskPool.h @@ -23,7 +23,7 @@ // warnings in the Concurrency Runtime. This can be removed when we switch to // MSVC 2015 #pragma warning(push) -#pragma warning(disable:4062) +#pragma warning(disable : 4062) #endif #include <cassert> @@ -34,185 +34,174 @@ #include <thread> #include <vector> -// Global TaskPool class for running tasks in parallel on a set of worker thread created the first -// time the task pool is used. The TaskPool provide no gurantee about the order the task will be run -// and about what tasks will run in parrallel. None of the task added to the task pool should block -// on something (mutex, future, condition variable) what will be set only by the completion of an +// Global TaskPool class for running tasks in parallel on a set of worker thread +// created the first +// time the task pool is used. The TaskPool provide no guarantee about the order +// the task will be run +// and about what tasks will run in parallel. None of the task added to the task +// pool should block +// on something (mutex, future, condition variable) what will be set only by the +// completion of an // other task on the task pool as they may run on the same thread sequentally. -class TaskPool -{ +class TaskPool { public: - // Add a new task to the task pool and return a std::future belonging to the newly created task. - // The caller of this function has to wait on the future for this task to complete. - template<typename F, typename... Args> - static std::future<typename std::result_of<F(Args...)>::type> - AddTask(F&& f, Args&&... args); - - // Run all of the specified tasks on the task pool and wait until all of them are finished - // before returning. This method is intended to be used for small number tasks where listing - // them as function arguments is acceptable. For running large number of tasks you should use - // AddTask for each task and then call wait() on each returned future. - template<typename... T> - static void - RunTasks(T&&... tasks); + // Add a new task to the task pool and return a std::future belonging to the + // newly created task. + // The caller of this function has to wait on the future for this task to + // complete. + template <typename F, typename... Args> + static std::future<typename std::result_of<F(Args...)>::type> + AddTask(F &&f, Args &&... args); + + // Run all of the specified tasks on the task pool and wait until all of them + // are finished + // before returning. This method is intended to be used for small number tasks + // where listing + // them as function arguments is acceptable. For running large number of tasks + // you should use + // AddTask for each task and then call wait() on each returned future. + template <typename... T> static void RunTasks(T &&... tasks); private: - TaskPool() = delete; + TaskPool() = delete; - template<typename... T> - struct RunTaskImpl; + template <typename... T> struct RunTaskImpl; - static void - AddTaskImpl(std::function<void()>&& task_fn); + static void AddTaskImpl(std::function<void()> &&task_fn); }; -// Wrapper class around the global TaskPool implementation to make it possible to create a set of -// tasks and then wait for the tasks to be completed by the WaitForNextCompletedTask call. This -// class should be used when WaitForNextCompletedTask is needed because this class add no other -// extra functionality to the TaskPool class and it have a very minor performance overhead. -template <typename T> // The return type of the tasks what will be added to this task runner -class TaskRunner -{ +// Wrapper class around the global TaskPool implementation to make it possible +// to create a set of +// tasks and then wait for the tasks to be completed by the +// WaitForNextCompletedTask call. This +// class should be used when WaitForNextCompletedTask is needed because this +// class add no other +// extra functionality to the TaskPool class and it have a very minor +// performance overhead. +template <typename T> // The return type of the tasks what will be added to this + // task runner + class TaskRunner { public: - // Add a task to the task runner what will also add the task to the global TaskPool. The - // function doesn't return the std::future for the task because it will be supplied by the - // WaitForNextCompletedTask after the task is completed. - template<typename F, typename... Args> - void - AddTask(F&& f, Args&&... args); - - // Wait for the next task in this task runner to finish and then return the std::future what - // belongs to the finished task. If there is no task in this task runner (neither pending nor - // comleted) then this function will return an invalid future. Usually this function should be - // called in a loop processing the results of the tasks until it returns an invalid std::future - // what means that all task in this task runner is completed. - std::future<T> - WaitForNextCompletedTask(); - - // Convenience method to wait for all task in this TaskRunner to finish. Do NOT use this class - // just because of this method. Use TaskPool instead and wait for each std::future returned by - // AddTask in a loop. - void - WaitForAllTasks(); + // Add a task to the task runner what will also add the task to the global + // TaskPool. The + // function doesn't return the std::future for the task because it will be + // supplied by the + // WaitForNextCompletedTask after the task is completed. + template <typename F, typename... Args> void AddTask(F &&f, Args &&... args); + + // Wait for the next task in this task runner to finish and then return the + // std::future what + // belongs to the finished task. If there is no task in this task runner + // (neither pending nor + // comleted) then this function will return an invalid future. Usually this + // function should be + // called in a loop processing the results of the tasks until it returns an + // invalid std::future + // what means that all task in this task runner is completed. + std::future<T> WaitForNextCompletedTask(); + + // Convenience method to wait for all task in this TaskRunner to finish. Do + // NOT use this class + // just because of this method. Use TaskPool instead and wait for each + // std::future returned by + // AddTask in a loop. + void WaitForAllTasks(); private: - std::list<std::future<T>> m_ready; - std::list<std::future<T>> m_pending; - std::mutex m_mutex; - std::condition_variable m_cv; + std::list<std::future<T>> m_ready; + std::list<std::future<T>> m_pending; + std::mutex m_mutex; + std::condition_variable m_cv; }; -template<typename F, typename... Args> +template <typename F, typename... Args> std::future<typename std::result_of<F(Args...)>::type> -TaskPool::AddTask(F&& f, Args&&... args) -{ - auto task_sp = std::make_shared<std::packaged_task<typename std::result_of<F(Args...)>::type()>>( - std::bind(std::forward<F>(f), std::forward<Args>(args)...)); +TaskPool::AddTask(F &&f, Args &&... args) { + auto task_sp = std::make_shared< + std::packaged_task<typename std::result_of<F(Args...)>::type()>>( + std::bind(std::forward<F>(f), std::forward<Args>(args)...)); - AddTaskImpl([task_sp]() { (*task_sp)(); }); + AddTaskImpl([task_sp]() { (*task_sp)(); }); - return task_sp->get_future(); + return task_sp->get_future(); } -template<typename... T> -void -TaskPool::RunTasks(T&&... tasks) -{ - RunTaskImpl<T...>::Run(std::forward<T>(tasks)...); +template <typename... T> void TaskPool::RunTasks(T &&... tasks) { + RunTaskImpl<T...>::Run(std::forward<T>(tasks)...); } -template<typename Head, typename... Tail> -struct TaskPool::RunTaskImpl<Head, Tail...> -{ - static void - Run(Head&& h, Tail&&... t) - { - auto f = AddTask(std::forward<Head>(h)); - RunTaskImpl<Tail...>::Run(std::forward<Tail>(t)...); - f.wait(); - } +template <typename Head, typename... Tail> +struct TaskPool::RunTaskImpl<Head, Tail...> { + static void Run(Head &&h, Tail &&... t) { + auto f = AddTask(std::forward<Head>(h)); + RunTaskImpl<Tail...>::Run(std::forward<Tail>(t)...); + f.wait(); + } }; -template<> -struct TaskPool::RunTaskImpl<> -{ - static void - Run() {} +template <> struct TaskPool::RunTaskImpl<> { + static void Run() {} }; template <typename T> -template<typename F, typename... Args> -void -TaskRunner<T>::AddTask(F&& f, Args&&... args) -{ - std::unique_lock<std::mutex> lock(m_mutex); - auto it = m_pending.emplace(m_pending.end()); - *it = std::move(TaskPool::AddTask( - [this, it](F f, Args... args) - { - T&& r = f(std::forward<Args>(args)...); - - std::unique_lock<std::mutex> lock(this->m_mutex); - this->m_ready.splice(this->m_ready.end(), this->m_pending, it); - lock.unlock(); - - this->m_cv.notify_one(); - return r; - }, - std::forward<F>(f), - std::forward<Args>(args)...)); +template <typename F, typename... Args> +void TaskRunner<T>::AddTask(F &&f, Args &&... args) { + std::unique_lock<std::mutex> lock(m_mutex); + auto it = m_pending.emplace(m_pending.end()); + *it = std::move(TaskPool::AddTask( + [this, it](F f, Args... args) { + T &&r = f(std::forward<Args>(args)...); + + std::unique_lock<std::mutex> lock(this->m_mutex); + this->m_ready.splice(this->m_ready.end(), this->m_pending, it); + lock.unlock(); + + this->m_cv.notify_one(); + return r; + }, + std::forward<F>(f), std::forward<Args>(args)...)); } template <> -template<typename F, typename... Args> -void -TaskRunner<void>::AddTask(F&& f, Args&&... args) -{ - std::unique_lock<std::mutex> lock(m_mutex); - auto it = m_pending.emplace(m_pending.end()); - *it = std::move(TaskPool::AddTask( - [this, it](F f, Args... args) - { - f(std::forward<Args>(args)...); - - std::unique_lock<std::mutex> lock(this->m_mutex); - this->m_ready.emplace_back(std::move(*it)); - this->m_pending.erase(it); - lock.unlock(); - - this->m_cv.notify_one(); - }, - std::forward<F>(f), - std::forward<Args>(args)...)); +template <typename F, typename... Args> +void TaskRunner<void>::AddTask(F &&f, Args &&... args) { + std::unique_lock<std::mutex> lock(m_mutex); + auto it = m_pending.emplace(m_pending.end()); + *it = std::move(TaskPool::AddTask( + [this, it](F f, Args... args) { + f(std::forward<Args>(args)...); + + std::unique_lock<std::mutex> lock(this->m_mutex); + this->m_ready.emplace_back(std::move(*it)); + this->m_pending.erase(it); + lock.unlock(); + + this->m_cv.notify_one(); + }, + std::forward<F>(f), std::forward<Args>(args)...)); } -template <typename T> -std::future<T> -TaskRunner<T>::WaitForNextCompletedTask() -{ - std::unique_lock<std::mutex> lock(m_mutex); - if (m_ready.empty() && m_pending.empty()) - return std::future<T>(); // No more tasks - - if (m_ready.empty()) - m_cv.wait(lock, [this](){ return !this->m_ready.empty(); }); - - std::future<T> res = std::move(m_ready.front()); - m_ready.pop_front(); - - lock.unlock(); - res.wait(); - - return std::move(res); -} +template <typename T> std::future<T> TaskRunner<T>::WaitForNextCompletedTask() { + std::unique_lock<std::mutex> lock(m_mutex); + if (m_ready.empty() && m_pending.empty()) + return std::future<T>(); // No more tasks -template <typename T> -void -TaskRunner<T>::WaitForAllTasks() -{ - while (WaitForNextCompletedTask().valid()); + if (m_ready.empty()) + m_cv.wait(lock, [this]() { return !this->m_ready.empty(); }); + + std::future<T> res = std::move(m_ready.front()); + m_ready.pop_front(); + + lock.unlock(); + res.wait(); + + return std::move(res); } +template <typename T> void TaskRunner<T>::WaitForAllTasks() { + while (WaitForNextCompletedTask().valid()) + ; +} #if defined(_MSC_VER) #pragma warning(pop) diff --git a/include/lldb/Utility/Timeout.h b/include/lldb/Utility/Timeout.h new file mode 100644 index 000000000000..6c6fd009acb0 --- /dev/null +++ b/include/lldb/Utility/Timeout.h @@ -0,0 +1,55 @@ +//===-- Timeout.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_Timeout_h_ +#define liblldb_Timeout_h_ + +#include "llvm/ADT/Optional.h" +#include <chrono> + +namespace lldb_private { + +// A general purpose class for representing timeouts for various APIs. It's +// basically an llvm::Optional<std::chrono::duration<int64_t, Ratio>>, but we +// customize it a bit to enable the standard chrono implicit conversions (e.g. +// from Timeout<std::milli> to Timeout<std::micro>. +// +// The intended meaning of the values is: +// - llvm::None - no timeout, the call should wait forever +// - 0 - poll, only complete the call if it will not block +// - >0 - wait for a given number of units for the result +template <typename Ratio> +class Timeout : public llvm::Optional<std::chrono::duration<int64_t, Ratio>> { +private: + template <typename Ratio2> using Dur = std::chrono::duration<int64_t, Ratio2>; + template <typename Rep2, typename Ratio2> + using EnableIf = std::enable_if< + std::is_convertible<std::chrono::duration<Rep2, Ratio2>, + std::chrono::duration<int64_t, Ratio>>::value>; + + using Base = llvm::Optional<Dur<Ratio>>; + +public: + Timeout(llvm::NoneType none) : Base(none) {} + Timeout(const Timeout &other) = default; + + template <typename Ratio2, + typename = typename EnableIf<int64_t, Ratio2>::type> + Timeout(const Timeout<Ratio2> &other) + : Base(other ? Base(Dur<Ratio>(*other)) : llvm::None) {} + + template <typename Rep2, typename Ratio2, + typename = typename EnableIf<Rep2, Ratio2>::type> + Timeout(const std::chrono::duration<Rep2, Ratio2> &other) + : Base(Dur<Ratio>(other)) {} +}; + +} // namespace lldb_private + +#endif // liblldb_Timeout_h_ |