office-gobmx/compilerplugins/clang/logexceptionnicely.cxx
Stephan Bergmann 9c431f4d3a Don't use Library_tl in URE libraries
This partly reverts 8b5e23eac3 "log nice exception
messages whereever possible", e1eb7cb04a
"loplugin:logexceptionnicely in starmath..svgio",
d6d80c4e17 "OSL_FAIL.*exception ->
TOOLS_WARN_EXCEPTION", and 877f40ac3f "tdf#42949
Fix new IWYU warnings in directories [h-r]*", and adapts
loplugin:logexceptionnicely accordingly.

Change-Id: I792b853b988c7c5f77179ca0672c30cb4223b5a6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130502
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2022-02-25 08:20:55 +01:00

150 lines
5.2 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* Based on LLVM/Clang.
*
* This file is distributed under the University of Illinois Open Source
* License. See LICENSE.TXT for details.
*
*/
#ifndef LO_CLANG_SHARED_PLUGINS
#include "plugin.hxx"
#include "check.hxx"
#include "config_clang.h"
#include <fstream>
#include <unordered_set>
namespace loplugin
{
/*
Check that we are using exceptionToString when printing exceptions inside SAL_WARN, so that we
get nicely formatted exception details in our logs.
*/
class LogExceptionNicely : public loplugin::FilteringPlugin<LogExceptionNicely>
{
std::unordered_set<SourceLocation> m_visited;
public:
LogExceptionNicely(const InstantiationData& data)
: FilteringPlugin(data)
{
}
bool preRun()
{
std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
// these are below tools in the module hierarchy, so we can't use the pretty printing
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/cppuhelper/"))
return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/ucbhelper/"))
return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/"))
return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/comphelper/"))
return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/io/"))
return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/javaunohelper/"))
return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/stoc/"))
return false;
// can't do that here, don't have an Any
if (loplugin::hasPathnamePrefix(fn, SRCDIR
"/connectivity/source/drivers/hsqldb/HStorageMap.cxx"))
return false;
return true;
}
void run()
{
if (preRun())
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
static bool BaseCheckNotExceptionSubclass(const CXXRecordDecl* BaseDefinition)
{
if (!BaseDefinition)
return true;
auto tc = loplugin::TypeCheck(BaseDefinition);
if (tc.Class("Exception")
.Namespace("uno")
.Namespace("star")
.Namespace("sun")
.Namespace("com")
.GlobalNamespace())
return false;
return true;
}
bool isDerivedFromException(const CXXRecordDecl* decl)
{
if (!decl || !decl->hasDefinition())
return false;
auto tc = loplugin::TypeCheck(decl);
if (tc.Class("Exception")
.Namespace("uno")
.Namespace("star")
.Namespace("sun")
.Namespace("com")
.GlobalNamespace())
return true;
if ( // not sure what hasAnyDependentBases() does,
// but it avoids classes we don't want, e.g. WeakAggComponentImplHelper1
!decl->hasAnyDependentBases() && !decl->forallBases(BaseCheckNotExceptionSubclass))
{
return true;
}
return false;
}
bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr* operatorCallExpr)
{
if (ignoreLocation(operatorCallExpr))
return true;
StringRef fn = getFilenameOfLocation(
compiler.getSourceManager().getExpansionLoc(operatorCallExpr->getBeginLoc()));
// these are below tools in the module hierarchy, so we can't use the pretty printing
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/include/comphelper/"))
return true;
if (operatorCallExpr->getOperator() != OO_LessLess)
return true;
auto expr = operatorCallExpr->getArg(1)->IgnoreImplicit();
if (auto declRefExpr = dyn_cast<DeclRefExpr>(expr))
if (auto varDecl = dyn_cast<VarDecl>(declRefExpr->getDecl()))
{
const clang::Type* type = varDecl->getType()->getUnqualifiedDesugaredType();
const CXXRecordDecl* cxxRecordDecl = type->getAsCXXRecordDecl();
if (!cxxRecordDecl)
cxxRecordDecl = type->getPointeeCXXRecordDecl();
if (!cxxRecordDecl)
return true;
if (!isDerivedFromException(cxxRecordDecl))
return true;
auto loc = operatorCallExpr->getBeginLoc();
// for some reason, I'm warning multiple times? so just check if I've warned already
if (!m_visited.insert(compiler.getSourceManager().getExpansionLoc(loc)).second)
return true;
report(DiagnosticsEngine::Warning,
"use TOOLS_WARN_EXCEPTION/TOOLS_INFO_EXCEPTION/exceptionToString to print "
"exception nicely",
loc)
<< operatorCallExpr->getSourceRange();
return true;
}
return true;
}
};
static Plugin::Registration<LogExceptionNicely> logexceptionnicely("logexceptionnicely");
} // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */