diff options
author | Noel Grandin <noel@peralex.com> | 2014-07-21 08:27:11 +0200 |
---|---|---|
committer | Chris Sherlock <chris.sherlock79@gmail.com> | 2014-09-21 12:44:59 +0000 |
commit | 44a432e9073b3d39b1bdd34b65cfd91d5541f324 (patch) | |
tree | af35534385288fd254adbde3c91bd480ab546537 /compilerplugins | |
parent | e00d828a2c1bfa62e40b0f2222240d60b1cf5710 (diff) |
new loplugin: VCL widget reference checker
First stage of new VCL widget reference checker
Change-Id: I63a2108a26b3c0e0a896d13672b1daa6f8e60b3a
Reviewed-on: https://gerrit.libreoffice.org/10427
Reviewed-by: Chris Sherlock <chris.sherlock79@gmail.com>
Tested-by: Chris Sherlock <chris.sherlock79@gmail.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/vclwidgets.cxx | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx new file mode 100644 index 000000000000..1bb4650c6bac --- /dev/null +++ b/compilerplugins/clang/vclwidgets.cxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <string> + +#include "plugin.hxx" +#include "compat.hxx" +#include "clang/AST/CXXInheritance.h" + +// Final goal: Checker for VCL widget references. Makes sure that VCL Window subclasses are properly referenced counted and dispose()'ed. +// +// But at the moment it just finds subclasses of Window which are not heap-allocated +// +// TODO do I need to check for local and static variables, too ? +// TODO when we have a dispose() method, verify that the dispose() methods releases all of the Window references +// TODO when we have a dispose() method, verify that it calls the super-class dispose() method at some point. + +namespace { + +class VCLWidgets: + public RecursiveASTVisitor<VCLWidgets>, public loplugin::Plugin +{ +public: + explicit VCLWidgets(InstantiationData const & data): Plugin(data) {} + + virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } + + bool VisitFieldDecl(const FieldDecl * decl); + + bool mbFoundWindow; +}; + +bool forallBasesCallback(const CXXBaseSpecifier *Specifier, CXXBasePath &, void *UserData) { + VCLWidgets* ro = (VCLWidgets*) UserData; + QualType qt = Specifier->getType(); + std::string name = qt.getUnqualifiedType().getCanonicalType().getAsString(); + if (name == "class Window") { + ro->mbFoundWindow = true; + return true; + } + return false; +} + +bool VCLWidgets::VisitFieldDecl(const FieldDecl * fieldDecl) { + if (ignoreLocation(fieldDecl)) { + return true; + } + if (fieldDecl->isBitField()) { + return true; + } + const RecordType *recordType = fieldDecl->getType()->getAs<RecordType>(); + if (recordType == nullptr) { + return true; + } + const CXXRecordDecl *recordDecl = dyn_cast<CXXRecordDecl>(recordType->getDecl()); + if (recordDecl == nullptr) { + return true; + } + // check if this field is derived from Window + mbFoundWindow = false; + CXXBasePaths paths; + recordDecl->lookupInBases(forallBasesCallback, this, paths); + if (!mbFoundWindow) { + return true; + } + + report( + DiagnosticsEngine::Warning, + "vcl::Window subclass not heap allocated", + fieldDecl->getLocation()) + << fieldDecl->getSourceRange(); + return true; +} + + +loplugin::Plugin::Registration< VCLWidgets > X("vclwidgets"); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |