diff --git a/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/lldb/include/lldb/Utility/ReproducerInstrumentation.h --- a/lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ b/lldb/include/lldb/Utility/ReproducerInstrumentation.h @@ -84,21 +84,20 @@ #Result, #Class, #Method, #Signature) #define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature) \ - R.Register(&invoke::method_const<( \ - &Class::Method)>::doit, \ + R.Register(&invoke::method<(&Class::Method)>::doit, \ #Result, #Class, #Method, #Signature) #define LLDB_REGISTER_STATIC_METHOD(Result, Class, Method, Signature) \ - R.Register( \ - &invoke::method_static<(&Class::Method)>::doit, \ - #Result, #Class, #Method, #Signature) + R.Register(&invoke::method<(&Class::Method)>::doit, \ + #Result, #Class, #Method, #Signature) #define LLDB_REGISTER_CHAR_PTR_REDIRECT_STATIC(Result, Class, Method) \ - R.Register(&invoke::method_static<( \ - &Class::Method)>::doit, \ - &char_ptr_redirect::method_static<( \ - &Class::Method)>::doit, \ - #Result, #Class, #Method, "(char*, size_t"); + R.Register( \ + &invoke::method<(&Class::Method)>::doit, \ + &char_ptr_redirect::method<(&Class::Method)>::doit, \ + #Result, #Class, #Method, "(char*, size_t"); #define LLDB_REGISTER_CHAR_PTR_REDIRECT(Result, Class, Method) \ R.Register(&invoke::method<( \ @@ -109,97 +108,55 @@ #define LLDB_REGISTER_CHAR_PTR_REDIRECT_CONST(Result, Class, Method) \ R.Register(&invoke::method_const<(&Class::Method)>::doit, \ - &char_ptr_redirect::method_const<(&Class::Method)>::doit, \ + const>::method<(&Class::Method)>::doit, \ + &char_ptr_redirect::method<(&Class::Method)>::doit, \ #Result, #Class, #Method, "(char*, size_t"); -#define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...) \ +#define LLDB_CONSTRUCT_(T, ...) \ lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ stringify_args(__VA_ARGS__)); \ if (lldb_private::repro::InstrumentationData _data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ _recorder.Record(_data.GetSerializer(), _data.GetRegistry(), \ - &lldb_private::repro::construct::doit, \ - __VA_ARGS__); \ + &lldb_private::repro::construct::doit, __VA_ARGS__); \ _recorder.RecordResult(this, false); \ } +#define LLDB_RECORD_CONSTRUCTOR(Class, Signature, ...) \ + LLDB_CONSTRUCT_(Class Signature, __VA_ARGS__) + #define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - _recorder.Record(_data.GetSerializer(), _data.GetRegistry(), \ - &lldb_private::repro::construct::doit); \ - _recorder.RecordResult(this, false); \ - } + LLDB_CONSTRUCT_(Class(), lldb_private::repro::EmptyArg()) -#define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \ +#define LLDB_RECORD_(T1, T2, ...) \ lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(*this, __VA_ARGS__)); \ + stringify_args(__VA_ARGS__)); \ if (lldb_private::repro::InstrumentationData _data = \ LLDB_GET_INSTRUMENTATION_DATA()) { \ _recorder.Record(_data.GetSerializer(), _data.GetRegistry(), \ - &lldb_private::repro::invoke::method<(&Class::Method)>::doit, \ - this, __VA_ARGS__); \ + &lldb_private::repro::invoke::method::doit, \ + __VA_ARGS__); \ } +#define LLDB_RECORD_METHOD(Result, Class, Method, Signature, ...) \ + LLDB_RECORD_(Result(Class::*) Signature, (&Class::Method), this, __VA_ARGS__) + #define LLDB_RECORD_METHOD_CONST(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(*this, __VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - _recorder.Record( \ - _data.GetSerializer(), _data.GetRegistry(), \ - &lldb_private::repro::invoke::method_const<(&Class::Method)>::doit, \ - this, __VA_ARGS__); \ - } + LLDB_RECORD_(Result(Class::*) Signature const, (&Class::Method), this, \ + __VA_ARGS__) #define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(*this)); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - _recorder.Record(_data.GetSerializer(), _data.GetRegistry(), \ - &lldb_private::repro::invoke::method<(&Class::Method)>::doit, \ - this); \ - } + LLDB_RECORD_(Result (Class::*)(), (&Class::Method), this) #define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(*this)); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - _recorder.Record( \ - _data.GetSerializer(), _data.GetRegistry(), \ - &lldb_private::repro::invoke::method_const<(&Class::Method)>::doit, \ - this); \ - } + LLDB_RECORD_(Result (Class::*)() const, (&Class::Method), this) #define LLDB_RECORD_STATIC_METHOD(Result, Class, Method, Signature, ...) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION, \ - stringify_args(__VA_ARGS__)); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - _recorder.Record( \ - _data.GetSerializer(), _data.GetRegistry(), \ - lldb_private::repro::invoke::method_static<( \ - &Class::Method)>::doit, \ - __VA_ARGS__); \ - } + LLDB_RECORD_(Result(*) Signature, (&Class::Method), __VA_ARGS__) #define LLDB_RECORD_STATIC_METHOD_NO_ARGS(Result, Class, Method) \ - lldb_private::repro::Recorder _recorder(LLVM_PRETTY_FUNCTION); \ - if (lldb_private::repro::InstrumentationData _data = \ - LLDB_GET_INSTRUMENTATION_DATA()) { \ - _recorder.Record(_data.GetSerializer(), _data.GetRegistry(), \ - lldb_private::repro::invoke::method_static< \ - (&Class::Method)>::doit); \ - } + LLDB_RECORD_(Result (*)(), (&Class::Method), lldb_private::repro::EmptyArg()) #define LLDB_RECORD_RESULT(Result) _recorder.RecordResult(Result, true); @@ -561,20 +518,20 @@ template struct invoke { - template struct method_const { + template struct method { static Result doit(Class *c, Args... args) { return (c->*m)(args...); } }; }; template struct invoke { - template struct method_static { + template struct method { static Result doit(Args... args) { return (*m)(args...); } }; }; template struct invoke { - template struct method_static { + template struct method { static void doit(Args... args) { return (*m)(args...); } }; }; @@ -712,6 +669,8 @@ Registry *m_registry; }; +struct EmptyArg {}; + /// RAII object that records function invocations and their return value. /// /// API calls are only captured when the API boundary is crossed. Once we're in @@ -777,6 +736,15 @@ m_result_recorded = true; } + /// Specializations for the no-argument methods. These are passed an empty + /// dummy argument so the same variadic macro can be used. These methods + /// strip the arguments before forwarding them. + template + void Record(Serializer &serializer, Registry ®istry, Result (*f)(), + const EmptyArg &arg) { + Record(serializer, registry, f); + } + /// Record the result of a function call. template Result RecordResult(Result &&r, bool update_boundary) { @@ -830,7 +798,7 @@ template struct char_ptr_redirect; template struct char_ptr_redirect { - template struct method_const { + template struct method { static Result doit(Class *c, char *s, size_t l) { char *buffer = reinterpret_cast(calloc(l, sizeof(char))); return (c->*m)(buffer, l); @@ -849,7 +817,7 @@ template struct char_ptr_redirect { - template struct method_static { + template struct method { static Result doit(char *s, size_t l) { char *buffer = reinterpret_cast(calloc(l, sizeof(char))); return (*m)(buffer, l);