SBFile support in SBCommandReturnObject
Summary:
This patch add SBFile interfaces to SBCommandReturnObject, and
removes the internal callers of its FILE* interfaces.
Reviewers: JDevlieghere, jasonmolenda, labath
Reviewed By: JDevlieghere
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D68434
llvm-svn: 374238
diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h
index 6aed3208..e3fbacf8 100644
--- a/lldb/include/lldb/API/SBCommandReturnObject.h
+++ b/lldb/include/lldb/API/SBCommandReturnObject.h
@@ -44,13 +44,21 @@
const char *GetError();
- size_t PutOutput(FILE *fh);
+ size_t PutOutput(FILE *fh); // DEPRECATED
+
+ size_t PutOutput(SBFile file);
+
+ size_t PutOutput(FileSP file);
size_t GetOutputSize();
size_t GetErrorSize();
- size_t PutError(FILE *fh);
+ size_t PutError(FILE *fh); // DEPRECATED
+
+ size_t PutError(SBFile file);
+
+ size_t PutError(FileSP file);
void Clear();
@@ -68,14 +76,21 @@
bool GetDescription(lldb::SBStream &description);
- // deprecated, these two functions do not take ownership of file handle
- void SetImmediateOutputFile(FILE *fh);
+ void SetImmediateOutputFile(FILE *fh); // DEPRECATED
- void SetImmediateErrorFile(FILE *fh);
+ void SetImmediateErrorFile(FILE *fh); // DEPRECATED
- void SetImmediateOutputFile(FILE *fh, bool transfer_ownership);
+ void SetImmediateOutputFile(FILE *fh, bool transfer_ownership); // DEPRECATED
- void SetImmediateErrorFile(FILE *fh, bool transfer_ownership);
+ void SetImmediateErrorFile(FILE *fh, bool transfer_ownership); // DEPRECATED
+
+ void SetImmediateOutputFile(SBFile file);
+
+ void SetImmediateErrorFile(SBFile file);
+
+ void SetImmediateOutputFile(FileSP file);
+
+ void SetImmediateErrorFile(FileSP file);
void PutCString(const char *string, int len = -1);
diff --git a/lldb/include/lldb/API/SBFile.h b/lldb/include/lldb/API/SBFile.h
index 872eb1f..4c4b2e0 100644
--- a/lldb/include/lldb/API/SBFile.h
+++ b/lldb/include/lldb/API/SBFile.h
@@ -15,6 +15,7 @@
class LLDB_API SBFile {
friend class SBDebugger;
+ friend class SBCommandReturnObject;
public:
SBFile();
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index 670002d..61e57fb 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -62,13 +62,13 @@
return m_err_stream;
}
- void SetImmediateOutputFile(FILE *fh, bool transfer_fh_ownership = false) {
- lldb::StreamSP stream_sp(new StreamFile(fh, transfer_fh_ownership));
+ void SetImmediateOutputFile(lldb::FileSP file_sp) {
+ lldb::StreamSP stream_sp(new StreamFile(file_sp));
m_out_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
}
- void SetImmediateErrorFile(FILE *fh, bool transfer_fh_ownership = false) {
- lldb::StreamSP stream_sp(new StreamFile(fh, transfer_fh_ownership));
+ void SetImmediateErrorFile(lldb::FileSP file_sp) {
+ lldb::StreamSP stream_sp(new StreamFile(file_sp));
m_err_stream.SetStreamAtIndex(eImmediateStreamIndex, stream_sp);
}
diff --git a/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/lldb/include/lldb/Utility/ReproducerInstrumentation.h
index 6053faf..75d6604 100644
--- a/lldb/include/lldb/Utility/ReproducerInstrumentation.h
+++ b/lldb/include/lldb/Utility/ReproducerInstrumentation.h
@@ -238,9 +238,12 @@
struct ValueTag {};
struct FundamentalPointerTag {};
struct FundamentalReferenceTag {};
+struct NotImplementedTag {};
/// Return the deserialization tag for the given type T.
-template <class T> struct serializer_tag { typedef ValueTag type; };
+template <class T> struct serializer_tag {
+ typedef typename std::conditional<std::is_trivially_copyable<T>::value, ValueTag, NotImplementedTag>::type type;
+};
template <class T> struct serializer_tag<T *> {
typedef
typename std::conditional<std::is_fundamental<T>::value,
@@ -304,6 +307,11 @@
}
private:
+ template <typename T> T Read(NotImplementedTag) {
+ m_buffer = m_buffer.drop_front(sizeof(T));
+ return T();
+ }
+
template <typename T> T Read(ValueTag) {
assert(HasData(sizeof(T)));
T t;
diff --git a/lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py b/lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py
index db7703a..60917b6 100644
--- a/lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py
+++ b/lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py
@@ -309,7 +309,7 @@
@add_test_categories(['pyapi'])
- @expectedFailure # FIXME need SBFile interfaces on SBCommandReturnObject
+ @skipIf(py_version=['<', (3,)])
def test_immediate_string(self):
f = io.StringIO()
ret = lldb.SBCommandReturnObject()
@@ -325,7 +325,7 @@
@add_test_categories(['pyapi'])
- @expectedFailure # FIXME need SBFile interfaces on SBCommandReturnObject
+ @skipIf(py_version=['<', (3,)])
def test_immediate_sbfile_string(self):
f = io.StringIO()
ret = lldb.SBCommandReturnObject()
diff --git a/lldb/scripts/interface/SBCommandReturnObject.i b/lldb/scripts/interface/SBCommandReturnObject.i
index 1e04a8f..73d4001 100644
--- a/lldb/scripts/interface/SBCommandReturnObject.i
+++ b/lldb/scripts/interface/SBCommandReturnObject.i
@@ -49,10 +49,16 @@
GetError (bool if_no_immediate);
size_t
- PutOutput (FILE *fh);
+ PutOutput (lldb::SBFile file);
size_t
- PutError (FILE *fh);
+ PutError (lldb::SBFile file);
+
+ size_t
+ PutOutput (lldb::FileSP BORROWED);
+
+ size_t
+ PutError (lldb::FileSP BORROWED);
void
Clear();
@@ -85,15 +91,20 @@
bool
GetDescription (lldb::SBStream &description);
+ void SetImmediateOutputFile(lldb::SBFile file);
+ void SetImmediateErrorFile(lldb::SBFile file);
+ void SetImmediateOutputFile(lldb::FileSP BORROWED);
+ void SetImmediateErrorFile(lldb::FileSP BORROWED);
- // wrapping here so that lldb takes ownership of the
- // new FILE* created inside of the swig interface
%extend {
- void SetImmediateOutputFile(FILE *fh) {
- self->SetImmediateOutputFile(fh, true);
+ // transfer_ownership does nothing, and is here for compatibility with
+ // old scripts. Ownership is tracked by reference count in the ordinary way.
+
+ void SetImmediateOutputFile(lldb::FileSP BORROWED, bool transfer_ownership) {
+ self->SetImmediateOutputFile(BORROWED);
}
- void SetImmediateErrorFile(FILE *fh) {
- self->SetImmediateErrorFile(fh, true);
+ void SetImmediateErrorFile(lldb::FileSP BORROWED, bool transfer_ownership) {
+ self->SetImmediateErrorFile(BORROWED);
}
}
diff --git a/lldb/source/API/SBCommandReturnObject.cpp b/lldb/source/API/SBCommandReturnObject.cpp
index 39c165c..02e8ea5 100644
--- a/lldb/source/API/SBCommandReturnObject.cpp
+++ b/lldb/source/API/SBCommandReturnObject.cpp
@@ -10,6 +10,7 @@
#include "SBReproducerPrivate.h"
#include "Utils.h"
#include "lldb/API/SBError.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBStream.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Utility/ConstString.h"
@@ -116,7 +117,6 @@
size_t SBCommandReturnObject::PutOutput(FILE *fh) {
LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *), fh);
-
if (fh) {
size_t num_bytes = GetOutputSize();
if (num_bytes)
@@ -125,6 +125,21 @@
return 0;
}
+size_t SBCommandReturnObject::PutOutput(FileSP file_sp) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP),
+ file_sp);
+ if (!file_sp)
+ return 0;
+ return file_sp->Printf("%s", GetOutput());
+}
+
+size_t SBCommandReturnObject::PutOutput(SBFile file) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile), file);
+ if (!file.m_opaque_sp)
+ return 0;
+ return file.m_opaque_sp->Printf("%s", GetOutput());
+}
+
size_t SBCommandReturnObject::PutError(FILE *fh) {
LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *), fh);
@@ -136,6 +151,21 @@
return 0;
}
+size_t SBCommandReturnObject::PutError(FileSP file_sp) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP),
+ file_sp);
+ if (!file_sp)
+ return 0;
+ return file_sp->Printf("%s", GetError());
+}
+
+size_t SBCommandReturnObject::PutError(SBFile file) {
+ LLDB_RECORD_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile), file);
+ if (!file.m_opaque_sp)
+ return 0;
+ return file.m_opaque_sp->Printf("%s", GetError());
+}
+
void SBCommandReturnObject::Clear() {
LLDB_RECORD_METHOD_NO_ARGS(void, SBCommandReturnObject, Clear);
@@ -242,16 +272,40 @@
bool transfer_ownership) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
(FILE *, bool), fh, transfer_ownership);
-
- ref().SetImmediateOutputFile(fh, transfer_ownership);
+ FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
+ ref().SetImmediateOutputFile(file);
}
void SBCommandReturnObject::SetImmediateErrorFile(FILE *fh,
bool transfer_ownership) {
LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
(FILE *, bool), fh, transfer_ownership);
+ FileSP file = std::make_shared<NativeFile>(fh, transfer_ownership);
+ ref().SetImmediateErrorFile(file);
+}
- ref().SetImmediateErrorFile(fh, transfer_ownership);
+void SBCommandReturnObject::SetImmediateOutputFile(SBFile file) {
+ LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (SBFile), file);
+ ref().SetImmediateOutputFile(file.m_opaque_sp);
+}
+
+void SBCommandReturnObject::SetImmediateErrorFile(SBFile file) {
+ LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (SBFile), file);
+ ref().SetImmediateErrorFile(file.m_opaque_sp);
+}
+
+void SBCommandReturnObject::SetImmediateOutputFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (FileSP), file_sp);
+ SetImmediateOutputFile(SBFile(file_sp));
+}
+
+void SBCommandReturnObject::SetImmediateErrorFile(FileSP file_sp) {
+ LLDB_RECORD_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (FileSP), file_sp);
+ SetImmediateErrorFile(SBFile(file_sp));
}
void SBCommandReturnObject::PutCString(const char *string, int len) {
@@ -335,6 +389,10 @@
LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, GetErrorSize, ());
LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FILE *));
LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FILE *));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (SBFile));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (SBFile));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutOutput, (FileSP));
+ LLDB_REGISTER_METHOD(size_t, SBCommandReturnObject, PutError, (FileSP));
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, Clear, ());
LLDB_REGISTER_METHOD(lldb::ReturnStatus, SBCommandReturnObject, GetStatus,
());
@@ -353,6 +411,14 @@
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
(FILE *));
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (SBFile));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (SBFile));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
+ (FileSP));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
+ (FileSP));
+ LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateOutputFile,
(FILE *, bool));
LLDB_REGISTER_METHOD(void, SBCommandReturnObject, SetImmediateErrorFile,
(FILE *, bool));
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 85c8e0a..4bc25c4 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -468,9 +468,9 @@
sb_interpreter.HandleCommand(command, result, false);
if (GetErrorFileHandle() != nullptr)
- result.PutError(GetErrorFileHandle());
+ result.PutError(GetErrorFile());
if (GetOutputFileHandle() != nullptr)
- result.PutOutput(GetOutputFileHandle());
+ result.PutOutput(GetOutputFile());
if (!m_opaque_sp->GetAsyncExecution()) {
SBProcess process(GetCommandInterpreter().GetProcess());
diff --git a/lldb/source/API/SBFile.cpp b/lldb/source/API/SBFile.cpp
index e9e6987..5c003bc 100644
--- a/lldb/source/API/SBFile.cpp
+++ b/lldb/source/API/SBFile.cpp
@@ -23,12 +23,13 @@
SBFile::SBFile() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBFile); }
SBFile::SBFile(FILE *file, bool transfer_ownership) {
+ LLDB_RECORD_DUMMY(void, SBFile, (FILE *, bool), file, transfer_ownership);
m_opaque_sp = std::make_shared<NativeFile>(file, transfer_ownership);
}
SBFile::SBFile(int fd, const char *mode, bool transfer_owndership) {
- LLDB_RECORD_CONSTRUCTOR(SBFile, (int, const char *, bool), fd, mode,
- transfer_owndership);
+ LLDB_RECORD_DUMMY(void, SBFile, (int, const char *, bool), fd, mode,
+ transfer_owndership);
auto options = File::GetOptionsFromMode(mode);
m_opaque_sp = std::make_shared<NativeFile>(fd, options, transfer_owndership);
}
@@ -104,9 +105,9 @@
namespace lldb_private {
namespace repro {
+
template <> void RegisterMethods<SBFile>(Registry &R) {
- LLDB_REGISTER_CONSTRUCTOR(SBFile, ());
- LLDB_REGISTER_CONSTRUCTOR(SBFile, (int, const char *, bool));
+
LLDB_REGISTER_METHOD(lldb::SBError, SBFile, Flush, ());
LLDB_REGISTER_METHOD_CONST(bool, SBFile, IsValid, ());
LLDB_REGISTER_METHOD_CONST(bool, SBFile, operator bool,());
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index fefa12c..2f81c44 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -879,8 +879,9 @@
::setbuf(outfile_handle, nullptr);
result->SetImmediateOutputFile(
- debugger.GetOutputFile().GetStream());
- result->SetImmediateErrorFile(debugger.GetErrorFile().GetStream());
+ debugger.GetOutputStream().GetFileSP());
+ result->SetImmediateErrorFile(
+ debugger.GetErrorStream().GetFileSP());
}
}
}
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index ec70784..661c10a 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -11,6 +11,7 @@
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBFile.h"
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBLanguageRuntime.h"
#include "lldb/API/SBReproducer.h"
@@ -499,16 +500,16 @@
SBCommandReturnObject result;
sb_interpreter.SourceInitFileInHomeDirectory(result);
if (m_option_data.m_debug_mode) {
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
+ result.PutError(m_debugger.GetErrorFile());
+ result.PutOutput(m_debugger.GetOutputFile());
}
// Source the local .lldbinit file if it exists and we're allowed to source.
// Here we want to always print the return object because it contains the
// warning and instructions to load local lldbinit files.
sb_interpreter.SourceInitFileInCurrentWorkingDirectory(result);
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
+ result.PutError(m_debugger.GetErrorFile());
+ result.PutOutput(m_debugger.GetOutputFile());
// We allow the user to specify an exit code when calling quit which we will
// return when exiting.
@@ -574,8 +575,8 @@
}
if (m_option_data.m_debug_mode) {
- result.PutError(m_debugger.GetErrorFileHandle());
- result.PutOutput(m_debugger.GetOutputFileHandle());
+ result.PutError(m_debugger.GetErrorFile());
+ result.PutOutput(m_debugger.GetOutputFile());
}
const bool handle_events = true;