diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2015-08-31 08:07:39 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2015-08-31 14:39:13 +0200 |
commit | 3286c6c854cf7dfa71c24ff98cd47bdddf6b0c27 (patch) | |
tree | defb437fc1e937a81e103383ff51939812683890 /compilerplugins | |
parent | loplugin:stringconstant: OUStringBuffer: appendAscii -> append (diff) | |
download | core-3286c6c854cf7dfa71c24ff98cd47bdddf6b0c27.tar.gz core-3286c6c854cf7dfa71c24ff98cd47bdddf6b0c27.zip |
loplugin:stringconstant: OUStringBuffer: appendAscii -> append
Change-Id: I0d1c988aad308435542dbd381fcf6bf7e1af6290
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/stringconstant.cxx | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx index 7cc6d9a372c5..5c675a8ae022 100644 --- a/compilerplugins/clang/stringconstant.cxx +++ b/compilerplugins/clang/stringconstant.cxx @@ -12,6 +12,7 @@ #include <stack> #include <string> +#include "compat.hxx" #include "plugin.hxx" // Define a "string constant" to be a constant expression either of type "array @@ -47,10 +48,11 @@ SourceLocation getMemberLocation(Expr const * expr) { } class StringConstant: - public RecursiveASTVisitor<StringConstant>, public loplugin::Plugin + public RecursiveASTVisitor<StringConstant>, public loplugin::RewritePlugin { public: - explicit StringConstant(InstantiationData const & data): Plugin(data) {} + explicit StringConstant(InstantiationData const & data): RewritePlugin(data) + {} void run() override; @@ -83,7 +85,8 @@ private: void reportChange( Expr const * expr, ChangeKind kind, std::string const & original, - std::string const & replacement, PassThrough pass); + std::string const & replacement, PassThrough pass, + char const * rewriteFrom, char const * rewriteTo); void checkEmpty( CallExpr const * expr, std::string const & qname, TreatEmpty treatEmpty, @@ -91,7 +94,8 @@ private: void handleChar( CallExpr const * expr, unsigned arg, std::string const & qname, - std::string const & replacement, TreatEmpty treatEmpty, bool literal); + std::string const & replacement, TreatEmpty treatEmpty, bool literal, + char const * rewriteFrom = nullptr, char const * rewriteTo = nullptr); void handleCharLen( CallExpr const * expr, unsigned arg1, unsigned arg2, @@ -524,6 +528,24 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) { } return true; } + if (qname == "rtl::OUStringBuffer::appendAscii" + && fdecl->getNumParams() == 1) + { + // u.appendAscii("foo") -> u.append("foo") + handleChar( + expr, 0, qname, "rtl::OUStringBuffer::append", TreatEmpty::Error, + true, "appendAscii", "append"); + return true; + } + if (qname == "rtl::OUStringBuffer::appendAscii" + && fdecl->getNumParams() == 2) + { + // u.appendAscii("foo", 3) -> u.append("foo"): + handleCharLen( + expr, 0, 1, qname, "rtl::OUStringBuffer::append", + TreatEmpty::Error); + return true; + } return true; } @@ -856,8 +878,10 @@ bool StringConstant::isZero(Expr const * expr) { void StringConstant::reportChange( Expr const * expr, ChangeKind kind, std::string const & original, - std::string const & replacement, PassThrough pass) + std::string const & replacement, PassThrough pass, char const * rewriteFrom, + char const * rewriteTo) { + assert((rewriteFrom == nullptr) == (rewriteTo == nullptr)); if (pass != PassThrough::No && !calls_.empty()) { Expr const * call = calls_.top(); CallExpr::const_arg_iterator argsBeg; @@ -1005,6 +1029,23 @@ void StringConstant::reportChange( } } } + if (rewriter != nullptr && rewriteFrom != nullptr) { + SourceLocation loc = getMemberLocation(expr); + while (compiler.getSourceManager().isMacroArgExpansion(loc)) { + loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc); + } + if (compat::isMacroBodyExpansion(compiler, loc)) { + loc = compiler.getSourceManager().getSpellingLoc(loc); + } + unsigned n = Lexer::MeasureTokenLength( + loc, compiler.getSourceManager(), compiler.getLangOpts()); + if ((std::string(compiler.getSourceManager().getCharacterData(loc), n) + == rewriteFrom) + && replaceText(loc, n, rewriteTo)) + { + return; + } + } report( DiagnosticsEngine::Warning, ("rewrite call of " + original + " with " + describeChangeKind(kind) @@ -1040,7 +1081,8 @@ void StringConstant::checkEmpty( void StringConstant::handleChar( CallExpr const * expr, unsigned arg, std::string const & qname, - std::string const & replacement, TreatEmpty treatEmpty, bool literal) + std::string const & replacement, TreatEmpty treatEmpty, bool literal, + char const * rewriteFrom, char const * rewriteTo) { unsigned n; bool non; @@ -1087,7 +1129,8 @@ void StringConstant::handleChar( ? (n == 0 ? PassThrough::EmptyConstantString : PassThrough::NonEmptyConstantString) - : PassThrough::No)); + : PassThrough::No), + rewriteFrom, rewriteTo); } void StringConstant::handleCharLen( @@ -1158,7 +1201,9 @@ void StringConstant::handleCharLen( } std::string repl(replacement); checkEmpty(expr, qname, treatEmpty, n, &repl); - reportChange(expr, ChangeKind::CharLen, qname, repl, PassThrough::No); + reportChange( + expr, ChangeKind::CharLen, qname, repl, PassThrough::No, nullptr, + nullptr); } void StringConstant::handleOUStringCtor( @@ -1228,7 +1273,7 @@ void StringConstant::handleOUStringCtor( << qname << expr->getSourceRange(); } -loplugin::Plugin::Registration< StringConstant > X("stringconstant"); +loplugin::Plugin::Registration< StringConstant > X("stringconstant", true); } |