[Libreoffice-commits] core.git: Branch 'feature/vclref' - 2 commits - compilerplugins/clang include/vcl vcl/source
Noel Grandin
noel at peralex.com
Thu Jan 8 04:11:09 PST 2015
compilerplugins/clang/vclwidgets.cxx | 106 ++++++++++++++++++++++++++++-------
include/vcl/combobox.hxx | 1
include/vcl/dialog.hxx | 1
include/vcl/layout.hxx | 2
vcl/source/control/combobox.cxx | 6 +
vcl/source/window/dialog.cxx | 7 ++
vcl/source/window/layout.cxx | 6 +
7 files changed, 108 insertions(+), 21 deletions(-)
New commits:
commit 398470ef5de2d88147ce3226890cee9809e4bb82
Author: Noel Grandin <noel at peralex.com>
Date: Thu Jan 8 14:09:13 2015 +0200
compilerplugin: check that necessary Window subclasses have a dispose method
i.e. the ones that declare any VclPtr fields
Change-Id: I7adfc3b3b190a2ede60bfccd08f85a269fae33ca
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx
index aa2af7f..896cd3f 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 99db232..62f0326 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 832c239..cf1c6ff 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -63,6 +63,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 7df6fe0..8f57140 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 bba84b6..39a3164 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 6375621..4526f8a 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -545,6 +545,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 64688e5..85694cb 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
commit eb427a03a1cc1596786dcc03ef4e723da2dee0b2
Author: Noel Grandin <noel at peralex.com>
Date: Thu Jan 8 13:30:36 2015 +0200
clang plugin: check return types for vcl::Window* that should be wrapped
Change-Id: I7121c1727d1374a955fbccb6554aede468d4977f
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx
index db4093f..aa2af7f 100644
--- a/compilerplugins/clang/vclwidgets.cxx
+++ b/compilerplugins/clang/vclwidgets.cxx
@@ -37,6 +37,7 @@ public:
bool VisitVarDecl( const VarDecl* var );
+ bool VisitFunctionDecl( const FunctionDecl* var );
};
bool BaseCheckNotWindowSubclass(const CXXRecordDecl *BaseDefinition, void *) {
@@ -60,6 +61,21 @@ bool isDerivedFromWindow(const CXXRecordDecl *decl) {
return false;
}
+bool isPointerToWindowSubclass(const QualType& pType) {
+ if (!pType->isPointerType())
+ return false;
+ QualType pointeeType = pType->getPointeeType();
+ const RecordType *recordType = pointeeType->getAs<RecordType>();
+ if (recordType == nullptr) {
+ return false;
+ }
+ const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
+ if (recordDecl == nullptr) {
+ return false;
+ }
+ return isDerivedFromWindow(recordDecl);
+}
+
bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (ignoreLocation(fieldDecl)) {
return true;
@@ -67,6 +83,15 @@ bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (fieldDecl->isBitField()) {
return true;
}
+ if (isPointerToWindowSubclass(fieldDecl->getType())) {
+ report(
+ DiagnosticsEngine::Remark,
+ "vcl::Window subclass declared as a pointer field, should be wrapped in VclPtr.",
+ fieldDecl->getLocation())
+ << fieldDecl->getSourceRange();
+ return true;
+ }
+
const RecordType *recordType = fieldDecl->getType()->getAs<RecordType>();
if (recordType == nullptr) {
return true;
@@ -92,18 +117,8 @@ bool VCLWidgets::VisitParmVarDecl(ParmVarDecl const * pvDecl) {
if (ignoreLocation(pvDecl)) {
return true;
}
- if (!pvDecl->getType()->isPointerType())
- return true;
- QualType pointeeType = pvDecl->getType()->getPointeeType();
- const RecordType *recordType = pointeeType->getAs<RecordType>();
- if (recordType == nullptr)
- return true;
- const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
- if (recordDecl == nullptr)
- return true;
-
// check if this parameter is derived from Window
- if (isDerivedFromWindow(recordDecl)) {
+ if (isPointerToWindowSubclass(pvDecl->getType())) {
report(
DiagnosticsEngine::Remark,
"vcl::Window subclass passed as a pointer parameter, should be wrapped in VclPtr.",
@@ -120,18 +135,9 @@ bool VCLWidgets::VisitVarDecl( const VarDecl* varDecl )
}
if (!varDecl->isLocalVarDecl())
return true;
- if (!varDecl->getType()->isPointerType())
- return true;
- QualType pointeeType = varDecl->getType()->getPointeeType();
- const RecordType *recordType = pointeeType->getAs<RecordType>();
- if (recordType == nullptr)
- return true;
- const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl());
- if (recordDecl == nullptr)
- return true;
// check if this variables type is derived from Window
- if (isDerivedFromWindow(recordDecl)) {
+ if (isPointerToWindowSubclass(varDecl->getType())) {
report(
DiagnosticsEngine::Remark,
"vcl::Window subclass declared as a pointer var, should be wrapped in VclPtr.",
@@ -142,6 +148,24 @@ bool VCLWidgets::VisitVarDecl( const VarDecl* varDecl )
return true;
}
+bool VCLWidgets::VisitFunctionDecl( const FunctionDecl* functionDecl )
+{
+ if (ignoreLocation(functionDecl)) {
+ return true;
+ }
+ QualType t1 { compat::getReturnType(*functionDecl) };
+ // check if this variables type is derived from Window
+ if (isPointerToWindowSubclass(t1)) {
+ report(
+ DiagnosticsEngine::Remark,
+ "vcl::Window subclass declared as a return type from a method/function, should be wrapped in VclPtr.",
+ functionDecl->getLocation())
+ << functionDecl->getSourceRange();
+ }
+ return true;
+}
+
+
loplugin::Plugin::Registration< VCLWidgets > X("vclwidgets");
}
More information about the Libreoffice-commits
mailing list