Index: API/SBStructuredData.cpp =================================================================== --- API/SBStructuredData.cpp +++ API/SBStructuredData.cpp @@ -20,23 +20,23 @@ using namespace lldb_private; #pragma mark-- -#pragma mark Impl +#pragma mark StructuredDataImpl -class SBStructuredData::Impl { +class StructuredDataImpl { public: - Impl() : m_plugin_wp(), m_data_sp() {} + StructuredDataImpl() : m_plugin_wp(), m_data_sp() {} - Impl(const Impl &rhs) = default; + StructuredDataImpl(const StructuredDataImpl &rhs) = default; - Impl(const EventSP &event_sp) + StructuredDataImpl(const EventSP &event_sp) : m_plugin_wp( EventDataStructuredData::GetPluginFromEvent(event_sp.get())), m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) { } - ~Impl() = default; + ~StructuredDataImpl() = default; - Impl &operator=(const Impl &rhs) = default; + StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default; bool IsValid() const { return m_data_sp.get() != nullptr; } @@ -45,7 +45,7 @@ m_data_sp.reset(); } - SBError GetAsJSON(lldb::SBStream &stream) const { + SBError GetAsJSON(lldb_private::Stream &stream) const { SBError sb_error; if (!m_data_sp) { @@ -53,33 +53,29 @@ return sb_error; } - m_data_sp->Dump(stream.ref()); + m_data_sp->Dump(stream); return sb_error; } - lldb::SBError GetDescription(lldb::SBStream &stream) const { - SBError sb_error; + Error GetDescription(lldb_private::Stream &stream) const { + Error error; if (!m_data_sp) { - sb_error.SetErrorString("Cannot pretty print structured data: " - "no data to print."); - return sb_error; + error.SetErrorString("Cannot pretty print structured data: " + "no data to print."); + return error; } // Grab the plugin. auto plugin_sp = StructuredDataPluginSP(m_plugin_wp); if (!plugin_sp) { - sb_error.SetErrorString("Cannot pretty print structured data: " - "plugin doesn't exist."); - return sb_error; + error.SetErrorString("Cannot pretty print structured data: " + "plugin doesn't exist."); + return error; } // Get the data's description. - auto error = plugin_sp->GetDescription(m_data_sp, stream.ref()); - if (!error.Success()) - sb_error.SetError(error); - - return sb_error; + return plugin_sp->GetDescription(m_data_sp, stream); } private: @@ -90,13 +86,13 @@ #pragma mark-- #pragma mark SBStructuredData -SBStructuredData::SBStructuredData() : m_impl_up(new Impl()) {} +SBStructuredData::SBStructuredData() : m_impl_up(new StructuredDataImpl()) {} SBStructuredData::SBStructuredData(const lldb::SBStructuredData &rhs) - : m_impl_up(new Impl(*rhs.m_impl_up.get())) {} + : m_impl_up(new StructuredDataImpl(*rhs.m_impl_up.get())) {} SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp) - : m_impl_up(new Impl(event_sp)) {} + : m_impl_up(new StructuredDataImpl(event_sp)) {} SBStructuredData::~SBStructuredData() {} @@ -111,9 +107,12 @@ void SBStructuredData::Clear() { m_impl_up->Clear(); } SBError SBStructuredData::GetAsJSON(lldb::SBStream &stream) const { - return m_impl_up->GetAsJSON(stream); + return m_impl_up->GetAsJSON(stream.ref()); } lldb::SBError SBStructuredData::GetDescription(lldb::SBStream &stream) const { - return m_impl_up->GetDescription(stream); + Error error = m_impl_up->GetDescription(stream.ref()); + SBError sb_error; + sb_error.SetError(error); + return sb_error; } Index: SB-api-coding-rules.html =================================================================== --- SB-api-coding-rules.html +++ SB-api-coding-rules.html @@ -48,7 +48,10 @@ make the SB object hold a shared or unique pointer to the Impl object. The theory behind this is that if you need more state in the SB object, those needs are likely to change over time, and this way the impl class can pick up members without changing the size of the object. - An example of this is the SBValue class. + An example of this is the SBValue class. Please note it is necessary for the Impl class to + not be a class embedded in the SB class, but rather should be a separate class that is not + present in the public lldb namespace. Failure to do so leads to leakage of weak-linked symbols + in the SBAPI.

In order to fit into the Python API's, we need to be able to default construct all the SB objects. Since the ivars of the classes are all pointers of one sort or other, this can easily be done, but Index: lldb/API/SBStructuredData.h =================================================================== --- lldb/API/SBStructuredData.h +++ lldb/API/SBStructuredData.h @@ -13,6 +13,8 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" +class StructuredDataImpl; + namespace lldb { class SBStructuredData { @@ -36,8 +38,7 @@ lldb::SBError GetDescription(lldb::SBStream &stream) const; private: - class Impl; - std::unique_ptr m_impl_up; + std::unique_ptr m_impl_up; }; }