diff --git a/include/tools/link.hxx b/include/tools/link.hxx index c4989e0593f3..b127a79054d0 100644 --- a/include/tools/link.hxx +++ b/include/tools/link.hxx @@ -67,18 +67,46 @@ RetType Class::Member( \ SAL_UNUSED_PARAMETER Class *, SAL_UNUSED_PARAMETER ArgType) +#ifdef DBG_UTIL +#define XSTRINGIFY(X) #X +#define STRINGIFY(X) XSTRINGIFY(X) +#define LINK(Instance, Class, Member) ::tools::detail::makeLink( \ + ::tools::detail::castTo(Instance), &Class::LinkStub##Member, __FILE__, __LINE__, STRINGIFY(Class::LinkStub##Member)) +#else #define LINK(Instance, Class, Member) ::tools::detail::makeLink( \ ::tools::detail::castTo(Instance), &Class::LinkStub##Member) +#endif template class SAL_WARN_UNUSED Link { public: typedef Ret Stub(void *, Arg); +#ifdef DBG_UTIL + Link() + : function_(nullptr) + , instance_(nullptr) + , file_("unknown") + , line_(0) + , target_("unknown") + { + } + + Link(void* instance, Stub* function, const char* const file = "unknown", const int line = 0, + const char* const target = "unknown") + : function_(function) + , instance_(instance) + , file_(file) + , line_(line) + , target_(target) + { + } +#else Link(): function_(nullptr), instance_(nullptr) {} Link(void * instance, Stub * function): function_(function), instance_(instance) {} +#endif Ret Call(Arg data) const { return function_ == nullptr ? Ret() : (*function_)(instance_, data); } @@ -103,9 +131,25 @@ public: void *GetInstance() const { return instance_; } +#ifdef DBG_UTIL + const char* getSourceFilename() const { return file_; } + int getSourceLineNumber() const { return line_; } + const char* getTargetName() const { return target_; } +#endif + private: Stub * function_; void * instance_; + +#ifdef DBG_UTIL + /// Support tracing link source and target. + /// When debugging async events, it's often critical + /// to find out not only where a link leads (i.e. the target + /// function), but also where it was created (file:line). + const char* file_; + int line_; + const char* target_; +#endif }; // Class used to indicate that the Call() parameter is not in use: @@ -118,10 +162,17 @@ namespace tools { namespace detail { template To castTo(From from) { return static_cast(from); } +#ifdef DBG_UTIL +template +Link makeLink(void * instance, Ret (* function)(void *, Arg), const char* file, int line, const char* target) { + return Link(instance, function, file, line, target); +} +#else template Link makeLink(void * instance, Ret (* function)(void *, Arg)) { return Link(instance, function); } +#endif } }