diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -48,7 +48,6 @@ const lldb::BreakpointLocationSP& bp_loc_sp ) { - lldb::SBFrame sb_frame (frame_sp); lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp); @@ -83,7 +82,6 @@ const lldb::WatchpointSP& wp_sp ) { - lldb::SBFrame sb_frame (frame_sp); lldb::SBWatchpoint sb_wp(wp_sp); @@ -118,7 +116,6 @@ std::string& retval ) { - lldb::SBValue sb_value (valobj_sp); lldb::SBTypeSummaryOptions sb_options(options_sp.get()); @@ -190,8 +187,6 @@ const lldb::ValueObjectSP& valobj_sp ) { - - if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -228,8 +223,6 @@ const lldb::DebuggerSP debugger_sp ) { - - if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -260,8 +253,6 @@ const lldb::ThreadPlanSP& thread_plan_sp ) { - - if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -319,8 +310,6 @@ bool &got_error ) { - - got_error = false; PyErr_Cleaner py_err_cleaner(false); @@ -368,8 +357,6 @@ lldb::BreakpointSP &breakpoint_sp ) { - - if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -412,8 +399,6 @@ lldb_private::SymbolContext *sym_ctx ) { - - PyErr_Cleaner py_err_cleaner(false); PythonObject self(PyRefType::Borrowed, static_cast(implementor)); auto pfunc = self.ResolveName(method_name); @@ -464,8 +449,6 @@ bool* was_found = NULL ) { - - PyErr_Cleaner py_err_cleaner(false); PythonObject self(PyRefType::Borrowed, static_cast(implementor)); @@ -493,8 +476,6 @@ uint32_t max ) { - - PythonObject self(PyRefType::Borrowed, implementor); auto pfunc = self.ResolveName("num_children"); @@ -536,7 +517,6 @@ uint32_t idx ) { - PyErr_Cleaner py_err_cleaner(true); PythonObject self(PyRefType::Borrowed, implementor); @@ -567,7 +547,6 @@ const char* child_name ) { - PyErr_Cleaner py_err_cleaner(true); PythonObject self(PyRefType::Borrowed, implementor); @@ -687,7 +666,6 @@ lldb::ExecutionContextRefSP exe_ctx_ref_sp ) { - lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj); lldb::SBDebugger debugger_sb(debugger); lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp); @@ -728,7 +706,6 @@ lldb::ExecutionContextRefSP exe_ctx_ref_sp ) { - lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj); lldb::SBDebugger debugger_sb(debugger); lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp); @@ -760,8 +737,6 @@ const lldb::ProcessSP& process_sp ) { - - if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -795,8 +770,6 @@ const char *session_dictionary_name ) { - - if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -823,8 +796,6 @@ const lldb::StackFrameSP& frame_sp ) { - - static char callee_name[] = "get_recognized_arguments"; lldb::SBFrame frame_sb(frame_sp); @@ -839,8 +810,6 @@ SWIGEXPORT void* LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp) { - - if (!module || !setting) Py_RETURN_NONE; @@ -866,8 +835,6 @@ std::string& output) { - - if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name) return false; @@ -896,8 +863,6 @@ std::string& output) { - - if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name) return false; @@ -926,8 +891,6 @@ std::string& output) { - - if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name) return false; @@ -956,8 +919,6 @@ std::string& output) { - - if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name) return false; @@ -986,8 +947,6 @@ std::string& output) { - - if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name) return false; @@ -1016,8 +975,6 @@ lldb::DebuggerSP& debugger ) { - - std::string python_function_name_string = python_module_name; python_function_name_string += ".__lldb_init_module"; const char* python_function_name = python_function_name_string.c_str(); diff --git a/llvm/include/llvm/ADT/Optional.h b/llvm/include/llvm/ADT/Optional.h --- a/llvm/include/llvm/ADT/Optional.h +++ b/llvm/include/llvm/ADT/Optional.h @@ -31,9 +31,12 @@ struct in_place_t {}; +template struct has_is_valid { + const static bool value = false; +}; + /// Storage for any type. -template ::value> -class OptionalStorage { +template class OptionalStorage { union { char empty; T value; @@ -138,7 +141,72 @@ } }; -template class OptionalStorage { +template +class OptionalStorage< + T, typename std::enable_if::value, void>::type> { + + T value; + typedef has_is_valid THelper; + +public: + ~OptionalStorage() = default; + + constexpr OptionalStorage() noexcept : value{THelper::make_invalid()} {} + + OptionalStorage(OptionalStorage const &other) = default; + OptionalStorage(OptionalStorage &&other) = default; + + OptionalStorage &operator=(OptionalStorage const &other) = default; + OptionalStorage &operator=(OptionalStorage &&other) = default; + + template + explicit OptionalStorage(in_place_t, Args &&... args) + : value(std::forward(args)...) { + asert(THelper::is_valid(value)); + } + + void reset() noexcept { value = THelper::make_invalid; } + + bool hasValue() const noexcept { return THelper::is_valid(value); } + + T &getValue() LLVM_LVALUE_FUNCTION noexcept { + assert(THelper::is_valid(value)); + return value; + } + T const &getValue() const LLVM_LVALUE_FUNCTION noexcept { + assert(THelper::is_valid(value)); + return value; + } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + T &&getValue() && noexcept { + assert(THelper::is_valid(value)); + return std::move(value); + } +#endif + + template void emplace(Args &&... args) { + value = T(std::forward(args)...); + asert(THelper::is_valid(value)); + } + + OptionalStorage &operator=(T const &y) { + assert(THelper::is_valid(y)); + value = y; + return *this; + } + + OptionalStorage &operator=(T &&y) { + assert(THelper::is_valid(y)); + value = std::move(y); + return *this; + } +}; + +template +class OptionalStorage< + T, typename std::enable_if::value && + !has_is_valid::value, + void>::type> { union { char empty; T value; diff --git a/llvm/unittests/ADT/OptionalTest.cpp b/llvm/unittests/ADT/OptionalTest.cpp --- a/llvm/unittests/ADT/OptionalTest.cpp +++ b/llvm/unittests/ADT/OptionalTest.cpp @@ -221,7 +221,7 @@ TEST_F(OptionalTest, Emplace) { MultiArgConstructor::ResetCounts(); Optional A; - + A.emplace(1, 2); EXPECT_TRUE(A.hasValue()); EXPECT_EQ(1, A->x); @@ -592,3 +592,35 @@ } } // end anonymous namespace + +class NaturalNumber { + friend struct llvm::optional_detail::has_is_valid; + int value; + constexpr NaturalNumber() : value(-1) {} + +public: + operator int() const { return value; } + NaturalNumber(int x) : value(x) { assert(value >= 0); } +}; + +template <> struct llvm::optional_detail::has_is_valid { + static const bool value = true; + static bool is_valid(const NaturalNumber &n) { return n.value >= 0; } + static constexpr NaturalNumber make_invalid() { return NaturalNumber(); } +}; + +TEST_F(OptionalTest, TestHasInvalid) { + + constexpr Optional none; + + static_assert(sizeof(Optional) == sizeof(int), + "no extra bool"); + + Optional x = None; + EXPECT_FALSE(x.hasValue()); + EXPECT_TRUE(x == none); + EXPECT_EQ(*reinterpret_cast(&x), -1); + x = NaturalNumber{42}; + EXPECT_TRUE(x.hasValue()); + EXPECT_EQ((int)x.getValue(), 42); +}