/* -*- 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
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;
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/")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/ucbhelper/")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/comphelper/")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/io/")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/javaunohelper/")) returnfalse; if (loplugin::hasPathnamePrefix(fn, SRCDIR "/stoc/")) returnfalse; // can't do that here, don't have an Any if (loplugin::hasPathnamePrefix(fn, SRCDIR "/connectivity/source/drivers/hsqldb/HStorageMap.cxx")) returnfalse; returntrue;
}
void run()
{ if (preRun())
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
staticbool BaseCheckNotExceptionSubclass(const CXXRecordDecl* BaseDefinition)
{ if (!BaseDefinition) returntrue; auto tc = loplugin::TypeCheck(BaseDefinition); if (tc.Class("Exception")
.Namespace("uno")
.Namespace("star")
.Namespace("sun")
.Namespace("com")
.GlobalNamespace()) returnfalse; returntrue;
}
bool isDerivedFromException(const CXXRecordDecl* decl)
{ if (!decl || !decl->hasDefinition()) returnfalse; auto tc = loplugin::TypeCheck(decl); if (tc.Class("Exception")
.Namespace("uno")
.Namespace("star")
.Namespace("sun")
.Namespace("com")
.GlobalNamespace()) returntrue; if ( // not sure what hasAnyDependentBases() does, // but it avoids classes we don't want, e.g. WeakAggComponentImplHelper1
!decl->hasAnyDependentBases() && !decl->forallBases(BaseCheckNotExceptionSubclass))
{ returntrue;
} returnfalse;
}
bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr* operatorCallExpr)
{ if (ignoreLocation(operatorCallExpr)) returntrue;
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/")) returntrue;
if (operatorCallExpr->getOperator() != OO_LessLess) returntrue; 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) returntrue; if (!isDerivedFromException(cxxRecordDecl)) returntrue; 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) returntrue;
report(DiagnosticsEngine::Warning, "use TOOLS_WARN_EXCEPTION/TOOLS_INFO_EXCEPTION/exceptionToString to print " "exception nicely",
loc)
<< operatorCallExpr->getSourceRange(); returntrue;
} 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 und die Messung sind noch experimentell.