compilerplugins/Makefile-clang.mk | 2 compilerplugins/clang/literalalternative.cxx | 111 +++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-)
New commits: commit 24387f1c58b30cae26618c377acd95a336c28380 Author: Stephan Bergmann <[email protected]> Date: Tue Mar 19 10:48:22 2013 +0100 A plugin to find suboptimal equalsIgnoreAsciiCaseAscii[L] calls Change-Id: Id2572982ca899223b89016ee7482ccb960032805 diff --git a/compilerplugins/clang/literalalternative.cxx b/compilerplugins/clang/literalalternative.cxx new file mode 100644 index 0000000..e90b688 --- /dev/null +++ b/compilerplugins/clang/literalalternative.cxx @@ -0,0 +1,111 @@ +/* -*- 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" + +// Find those calls of rtl::OUString::equalsIgnoreAsciiCaseAscii and +// rtl::OUString::equalsIgnoreAsciiCaseAsciiL that could be simplified to call +// rtl::OUString::equalsIgnoreAsciiCase instead: + +namespace { + +class LiteralAlternative: + public RecursiveASTVisitor<LiteralAlternative>, public loplugin::Plugin +{ +public: + explicit LiteralAlternative(ASTContext & context): Plugin(context) {} + + virtual void run() { TraverseDecl(context.getTranslationUnitDecl()); } + + bool VisitCallExpr(CallExpr * expr); +}; + +bool LiteralAlternative::VisitCallExpr(CallExpr * expr) { + if (ignoreLocation(expr)) { + return true; + } + FunctionDecl const * fdecl = expr->getDirectCallee(); + if (fdecl == nullptr) { + return true; + } + std::string qname { fdecl->getQualifiedNameAsString() }; + if (qname == "rtl::OUString::equalsIgnoreAsciiCaseAscii" + && fdecl->getNumParams() == 1 && expr->getNumArgs() == 1) + { + // equalsIgnoreAsciiCaseAscii("foo") -> equalsIngoreAsciiCase("foo"): + StringLiteral const * lit + = dyn_cast<StringLiteral>(expr->getArg(0)->IgnoreParenImpCasts()); + if (lit != nullptr) { + report( + DiagnosticsEngine::Warning, + ("rewrite call of rtl::OUString::equalsIgnoreAsciiCaseAscii" + " with string literal argument as call of" + " rtl::OUString::equalsIgnoreAsciiCase"), + expr->getExprLoc()); + //TODO: a better loc (the "equalsIgnoreAsciiCaseAscii" part)? + } + return true; + } + if (qname == "rtl::OUString::equalsIgnoreAsciiCaseAsciiL" + && fdecl->getNumParams() == 2 && expr->getNumArgs() == 2) + { + // equalsIgnoreAsciiCaseAsciiL("foo", 3) -> equalsIngoreAsciiCase("foo") + // especially also for + // equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("foo")), where + // RTL_CONSTASCII_STRINGPARAM expands to complicated expressions + // involving (&(X)[0] sub-expressions (and it might or might not be + // better to handle that at the level of non-expanded macros instead, + // but I have not found out how to do that yet anyway): + APSInt res; + if (expr->getArg(1)->isIntegerConstantExpr(res, context)) { + Expr const * arg0 = expr->getArg(0)->IgnoreParenImpCasts(); + StringLiteral const * lit = dyn_cast<StringLiteral>(arg0); + bool match = false; + if (lit != nullptr) { + match = res == lit->getLength(); + } else { + UnaryOperator const * op = dyn_cast<UnaryOperator>(arg0); + if (op != nullptr && op->getOpcode() == UO_AddrOf) { + ArraySubscriptExpr const * subs + = dyn_cast<ArraySubscriptExpr>( + op->getSubExpr()->IgnoreParenImpCasts()); + if (subs != nullptr) { + lit = dyn_cast<StringLiteral>( + subs->getBase()->IgnoreParenImpCasts()); + match = lit != nullptr + && subs->getIdx()->isIntegerConstantExpr( + res, context) + && res == 0; + } + } + } + if (match) { + report( + DiagnosticsEngine::Warning, + ("rewrite call of" + " rtl::OUString::equalsIgnoreAsciiCaseAsciiL with string" + " literal and matching length arguments as call of" + " rtl::OUString::equalsIgnoreAsciiCase"), + expr->getExprLoc()); + //TODO: a better loc (the "equalsIgnoreAsciiCaseAsciiL" + // part)? + } + } + return true; + } + return true; +} + +loplugin::Plugin::Registration< LiteralAlternative > X("literalalternative"); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit f9e96c364108ddd57f330a7bd52528937aef41e8 Author: Stephan Bergmann <[email protected]> Date: Tue Mar 19 10:46:45 2013 +0100 Enable -std=c++11 for compilerplugins/clang Change-Id: I4849656b16c2a7103217870050b0de3ccb97af56 diff --git a/compilerplugins/Makefile-clang.mk b/compilerplugins/Makefile-clang.mk index 688ab42..c762912 100644 --- a/compilerplugins/Makefile-clang.mk +++ b/compilerplugins/Makefile-clang.mk @@ -67,7 +67,7 @@ CLANGOBJS= define clangbuildsrc $(3): $(2) $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp @echo [build CXX] $(subst $(SRCDIR)/,,$(2)) - $(CXX) $(CLANGCXXFLAGS) $(CLANGDEFS) $(CLANGINCLUDES) -I$(BUILDDIR)/config_host $(2) -fPIC -c -o $(3) -MMD -MT $(3) -MP -MF $(CLANGOUTDIR)/$(1).d + $(CXX) $(CLANGCXXFLAGS) $(CLANGDEFS) $(CLANGINCLUDES) -I$(BUILDDIR)/config_host $(2) -fPIC -std=c++11 -c -o $(3) -MMD -MT $(3) -MP -MF $(CLANGOUTDIR)/$(1).d -include $(CLANGOUTDIR)/$(1).d _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
