diff options
-rw-r--r-- | compilerplugins/clang/vclwidgets.cxx | 40 | ||||
-rw-r--r-- | include/vcl/combobox.hxx | 1 | ||||
-rw-r--r-- | include/vcl/dialog.hxx | 1 | ||||
-rw-r--r-- | include/vcl/layout.hxx | 2 | ||||
-rw-r--r-- | vcl/source/control/combobox.cxx | 6 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 7 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 6 |
7 files changed, 63 insertions, 0 deletions
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx index aa2af7fe5962..896cd3f38889 100644 --- a/compilerplugins/clang/vclwidgets.cxx +++ b/compilerplugins/clang/vclwidgets.cxx @@ -31,6 +31,8 @@ public: virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } + bool VisitCXXRecordDecl(const CXXRecordDecl * decl); + bool VisitFieldDecl(const FieldDecl * decl); bool VisitParmVarDecl(ParmVarDecl const * decl); @@ -76,6 +78,44 @@ bool isPointerToWindowSubclass(const QualType& pType) { return isDerivedFromWindow(recordDecl); } +bool VCLWidgets::VisitCXXRecordDecl(const CXXRecordDecl * recordDecl) { + if (ignoreLocation(recordDecl)) { + return true; + } + if (!recordDecl->isCompleteDefinition()) + return true; + // check if this field is derived from Window + if (!isDerivedFromWindow(recordDecl)) { + return true; + } + bool foundVclPtr = false; + for(auto fieldDecl : recordDecl->fields()) { + if (fieldDecl->getType().getAsString().find("VclPtr")==0) { + foundVclPtr = true; + break; + } + } + if (!foundVclPtr) { + return true; + } + bool foundDispose = false; + for(auto methodDecl : recordDecl->methods()) { + if (methodDecl->isInstance() && methodDecl->param_size()==0 && methodDecl->getNameAsString() == "dispose") { + foundDispose = true; + break; + } + } + if (!foundDispose) { + report( + DiagnosticsEngine::Warning, + "vcl::Window subclass with VclPtr members should declare a dispose() method.", + recordDecl->getLocation()) + << recordDecl->getSourceRange(); + } + return true; +} + + bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) { if (ignoreLocation(fieldDecl)) { return true; diff --git a/include/vcl/combobox.hxx b/include/vcl/combobox.hxx index 8842477a6c40..86e6af49d2bb 100644 --- a/include/vcl/combobox.hxx +++ b/include/vcl/combobox.hxx @@ -91,6 +91,7 @@ protected: bool IsDropDownBox() const { return mpFloatWin ? true : false; } virtual void FillLayoutData() const SAL_OVERRIDE; + virtual void dispose() SAL_OVERRIDE; public: explicit ComboBox( vcl::Window* pParent, WinBits nStyle = 0 ); explicit ComboBox( vcl::Window* pParent, const ResId& ); diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx index bd418e8de2d1..ab498f1183b3 100644 --- a/include/vcl/dialog.hxx +++ b/include/vcl/dialog.hxx @@ -62,6 +62,7 @@ private: protected: using Window::ImplInit; SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle ); + virtual void dispose() SAL_OVERRIDE; public: SAL_DLLPRIVATE bool IsInClose() const { return mbInClose; } diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx index d11da2cc05d0..fde760953db0 100644 --- a/include/vcl/layout.hxx +++ b/include/vcl/layout.hxx @@ -620,6 +620,8 @@ private: }; VclPtr<EventBoxHelper> m_aEventBoxHelper; +protected: + virtual void dispose() SAL_OVERRIDE; public: VclEventBox(vcl::Window* pParent) : VclBin(pParent) diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx index d84797564a68..21877ecbaf99 100644 --- a/vcl/source/control/combobox.cxx +++ b/vcl/source/control/combobox.cxx @@ -78,6 +78,12 @@ ComboBox::~ComboBox() delete mpBtn; } +void ComboBox::dispose() +{ + mpSubEdit.disposeAndClear(); + Edit::dispose(); +} + void ComboBox::ImplInitComboBoxData() { mpSubEdit.disposeAndClear(); diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index b5f7b5361f12..60aa87618f44 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -542,6 +542,13 @@ Dialog::~Dialog() mpDialogImpl = NULL; } +void Dialog::dispose() +{ + mpActionArea.disposeAndClear(); + mpContentArea.disposeAndClear(); + SystemWindow::dispose(); +} + IMPL_LINK_NOARG(Dialog, ImplAsyncCloseHdl) { Close(); diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index 6a6c15408fe9..5fee1f0f1bd8 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -1878,6 +1878,12 @@ void VclEventBox::Command(const CommandEvent&) //discard events by default to block them reaching children } +void VclEventBox::dispose() +{ + m_aEventBoxHelper.disposeAndClear(); + VclBin::dispose(); +} + void VclSizeGroup::trigger_queue_resize() { //sufficient to trigger one widget to trigger all of them |