/* -*- 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/.
*/
#ifndef LO_CLANG_SHARED_PLUGINS
#include"config_clang.h"
#include"plugin.hxx" #include"check.hxx"
namespace {
Expr const * stripCtor(Expr const * expr) { auto e1 = expr; if (autoconst e = dyn_cast<CXXFunctionalCastExpr>(e1)) {
e1 = e->getSubExpr()->IgnoreParenImpCasts();
} if (autoconst e = dyn_cast<CXXBindTemporaryExpr>(e1)) {
e1 = e->getSubExpr()->IgnoreParenImpCasts();
} autoconst e2 = dyn_cast<CXXConstructExpr>(e1); if (e2 == nullptr) { return expr;
} auto qt = loplugin::DeclCheck(e2->getConstructor()); if (qt.MemberFunction().Class("OStringLiteral").Namespace("rtl").GlobalNamespace()
|| qt.MemberFunction().Class("OUStringLiteral").Namespace("rtl").GlobalNamespace())
{ if (e2->getNumArgs() == 1) { return e2->getArg(0)->IgnoreParenImpCasts();
} return expr;
} if (!((qt.MemberFunction().Class("OString").Namespace("rtl")
.GlobalNamespace())
|| (qt.MemberFunction().Class("OUString").Namespace("rtl")
.GlobalNamespace())))
{ return expr;
} if (e2->getNumArgs() != 2) { return expr;
} return e2->getArg(0)->IgnoreParenImpCasts();
}
class StringConcatLiterals: public loplugin::FilteringPlugin<StringConcatLiterals>
{ public: explicit StringConcatLiterals(loplugin::InstantiationData const & data):
FilteringPlugin(data) {}
// We add an extra " " in the TOOLS_WARN_EXCEPTION macro, which triggers this plugin if (loplugin::isSamePathname(
getFilenameOfLocation(
compiler.getSourceManager().getSpellingLoc(
compiler.getSourceManager().getImmediateMacroCallerLoc(
compiler.getSourceManager().getImmediateMacroCallerLoc(
compiler.getSourceManager().getImmediateMacroCallerLoc(
expr->getBeginLoc()))))),
SRCDIR "/include/comphelper/diagnose_ex.hxx")) returntrue;
StringRef name {
getFilenameOfLocation(
compiler.getSourceManager().getSpellingLoc(expr->getBeginLoc())) }; if (loplugin::isSamePathname(
name, SRCDIR "/sal/qa/rtl/oustringbuffer/test_oustringbuffer_assign.cxx")
|| loplugin::isSamePathname(
name, SRCDIR "/sal/qa/rtl/strings/test_ostring_concat.cxx")
|| loplugin::isSamePathname(
name, SRCDIR "/sal/qa/rtl/strings/test_oustring_concat.cxx"))
{ returntrue;
}
CXXOperatorCallExpr const * op = dyn_cast<CXXOperatorCallExpr>(expr);
report(
DiagnosticsEngine::Warning, "replace '%0' between string literals with juxtaposition",
op == nullptr ? expr->getExprLoc() : op->getOperatorLoc())
<< (oo == OverloadedOperatorKind::OO_Plus ? "+" : "<<")
<< SourceRange(leftLoc, expr->getArg(1)->getEndLoc()); returntrue;
}
bool StringConcatLiterals::isStringLiteral(Expr const * expr) { // Since <https://github.com/llvm/llvm-project/commit/878e590503dff0d9097e91c2bec4409f14503b82> // "Reland [clang] Make predefined expressions string literals under -fms-extensions", in MS // compatibility mode only, IgnoreParens and IgnoreParenImpCasts look through a PredefinedExpr // representing __func__, but which we do not want to do here: while (autoconst e = dyn_cast<ParenExpr>(expr)) {
expr = e->getSubExpr();
}
expr = expr->IgnoreImpCasts(); if (isa<PredefinedExpr>(expr)) { returnfalse;
} // Once we have filtered out the problematic PredefinedExpr above, still call // IgnoreParenImpCasts again, because it does more than just ignore ParenExpr and call // IgnoreImpCasts as is done above:
expr = stripCtor(expr->IgnoreParenImpCasts()); if (!isa<clang::StringLiteral>(expr)) { returnfalse;
} returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.