diff options
author | Noel Grandin <noel@peralex.com> | 2015-05-07 10:00:46 +0200 |
---|---|---|
committer | Noel Grandin <noel@peralex.com> | 2015-05-07 10:33:51 +0200 |
commit | 0825b020caa0d802a0d76d9a7643daedbf9874e6 (patch) | |
tree | 97d94a7d133ae89f4d58542fa07eb26a65da35be | |
parent | f72e77f4086e4c22072d5815c9a6cbebc323ba8e (diff) |
new clang plugin: rendercontext
to help with converting calls to OutputDevice to pass via
vcl::RenderContext.
Change-Id: I4b49d2f5e4afca46898d2a7c7ed33cbf5577e664
-rw-r--r-- | compilerplugins/clang/rendercontext.cxx | 93 | ||||
-rw-r--r-- | include/vcl/window.hxx | 1 | ||||
-rw-r--r-- | vcl/source/window/brdwin.cxx | 10 |
3 files changed, 98 insertions, 6 deletions
diff --git a/compilerplugins/clang/rendercontext.cxx b/compilerplugins/clang/rendercontext.cxx new file mode 100644 index 000000000000..a1e7018d5fd1 --- /dev/null +++ b/compilerplugins/clang/rendercontext.cxx @@ -0,0 +1,93 @@ +/* -*- 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 <iostream> + +#include "plugin.hxx" +#include "compat.hxx" +#include "clang/AST/CXXInheritance.h" + +// Check for calls to OutputDevice methods that are not passing through RenderContext + +namespace { + +class RenderContext: + public RecursiveASTVisitor<RenderContext>, public loplugin::Plugin +{ +public: + explicit RenderContext(InstantiationData const & data): Plugin(data) {} + + virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } + + bool TraverseFunctionDecl(const FunctionDecl * decl); + + bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *); + +private: + bool mbChecking = false; +}; + +bool RenderContext::TraverseFunctionDecl(const FunctionDecl * pFunctionDecl) { + if (ignoreLocation(pFunctionDecl)) { + return true; + } + if (!pFunctionDecl->hasBody()) { + return true; + } + if ( pFunctionDecl != pFunctionDecl->getCanonicalDecl() ) { + return true; + } + const CXXMethodDecl *pCXXMethodDecl = dyn_cast<CXXMethodDecl>(pFunctionDecl); + if (pCXXMethodDecl) { + std::string aParentName = pCXXMethodDecl->getParent()->getQualifiedNameAsString(); + if (aParentName == "OutputDevice") + return true; + } + mbChecking = true; + TraverseStmt(pFunctionDecl->getBody()); + mbChecking = false; + return true; +} + +bool RenderContext::VisitCXXMemberCallExpr(const CXXMemberCallExpr* pCXXMemberCallExpr) +{ + if (!mbChecking) + return true; + if (ignoreLocation(pCXXMemberCallExpr)) { + return true; + } + const CXXRecordDecl *pCXXRecordDecl = pCXXMemberCallExpr->getRecordDecl(); + if (pCXXRecordDecl->getQualifiedNameAsString() != "OutputDevice") { + return true; + } + const ImplicitCastExpr *pImplicitCastExpr = dyn_cast<ImplicitCastExpr>(pCXXMemberCallExpr->getImplicitObjectArgument()); + std::string t2 = "0"; + if (pImplicitCastExpr) { + t2 = "2"; + QualType aType = pImplicitCastExpr->getSubExpr()->getType(); + if (aType->isPointerType()) + aType = aType->getPointeeType(); + t2 = aType.getAsString(); + if (t2 == "vcl::RenderContext") + return true; + } + report( + DiagnosticsEngine::Warning, + "Should be calling OutputDevice method through RenderContext.", + pCXXMemberCallExpr->getLocStart()) + << pCXXMemberCallExpr->getSourceRange(); + return true; +} + +loplugin::Plugin::Registration< RenderContext > X("rendercontext", false); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx index 3209906ff085..68711110ac42 100644 --- a/include/vcl/window.hxx +++ b/include/vcl/window.hxx @@ -705,7 +705,6 @@ public: virtual void PrePaint(); virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect); virtual void Erase() SAL_OVERRIDE; - virtual void Erase( const Rectangle& rRect ) SAL_OVERRIDE { ::OutputDevice::Erase( rRect ); } virtual void Draw( ::OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags ); virtual void Move(); diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx index bc6b8efaa6e2..1bf2ac8e3677 100644 --- a/vcl/source/window/brdwin.cxx +++ b/vcl/source/window/brdwin.cxx @@ -99,7 +99,7 @@ void Window::ImplCalcSymbolRect( Rectangle& rRect ) } /* namespace vcl */ -static void ImplDrawBrdWinSymbol( OutputDevice* pDev, +static void ImplDrawBrdWinSymbol( vcl::RenderContext* pDev, const Rectangle& rRect, SymbolType eSymbol ) { // we leave 5% room between the symbol and the button border @@ -110,7 +110,7 @@ static void ImplDrawBrdWinSymbol( OutputDevice* pDev, pDev->GetSettings().GetStyleSettings().GetButtonTextColor(), 0 ); } -static void ImplDrawBrdWinSymbolButton( OutputDevice* pDev, +static void ImplDrawBrdWinSymbolButton( vcl::RenderContext* pDev, const Rectangle& rRect, SymbolType eSymbol, sal_uInt16 nState ) { @@ -124,9 +124,9 @@ static void ImplDrawBrdWinSymbolButton( OutputDevice* pDev, if( bMouseOver ) { // provide a bright background for selection effect - pWin->SetFillColor( pDev->GetSettings().GetStyleSettings().GetWindowColor() ); - pWin->SetLineColor(); - pWin->DrawRect( rRect ); + pDev->SetFillColor( pDev->GetSettings().GetStyleSettings().GetWindowColor() ); + pDev->SetLineColor(); + pDev->DrawRect( rRect ); pWin->DrawSelectionBackground( rRect, 2, (nState & BUTTON_DRAW_PRESSED) != 0, true, false ); } |