make some plugins used the shared framework

Change-Id: Ie283a4774564f25e0fde8ca35212f92be786d671
Reviewed-on: https://gerrit.libreoffice.org/75785
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin 2019-07-17 15:06:43 +02:00
parent 7598810d63
commit dd969ad6e0
16 changed files with 428 additions and 101 deletions

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include "check.hxx" #include "check.hxx"
#include "compat.hxx" #include "compat.hxx"
@ -68,17 +69,21 @@ public:
return true; return true;
} }
private: bool preRun() override { return compiler.getLangOpts().CPlusPlus; }
void run() override void run() override
{ {
if (compiler.getLangOpts().CPlusPlus) if (preRun())
{ {
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} }
} }
}; };
static loplugin::Plugin::Registration<Data> reg("data"); static loplugin::Plugin::Registration<Data> data("data");
}
} // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include "plugin.hxx" #include "plugin.hxx"
@ -57,24 +58,29 @@ public:
return true; return true;
} }
private: bool preRun() override {
void run() override {
// DISABLE_DYNLOADING makes SAL_DLLPUBLIC_{EXPORT,IMPORT,TEMPLATE} expand // DISABLE_DYNLOADING makes SAL_DLLPUBLIC_{EXPORT,IMPORT,TEMPLATE} expand
// to visibility("hidden") attributes, which would cause bogus warnings // to visibility("hidden") attributes, which would cause bogus warnings
// here (e.g., in UBSan builds that explicitly define DISABLE_DYNLOADING // here (e.g., in UBSan builds that explicitly define DISABLE_DYNLOADING
// in jurt/source/pipe/staticsalhack.cxx); alternatively, change // in jurt/source/pipe/staticsalhack.cxx); alternatively, change
// include/sal/types.h to make those SAL_DLLPUBLIC_* expand to nothing // include/sal/types.h to make those SAL_DLLPUBLIC_* expand to nothing
// for DISABLE_DYNLOADING: // for DISABLE_DYNLOADING:
if (!compiler.getPreprocessor().getIdentifierInfo("DISABLE_DYNLOADING") return !compiler.getPreprocessor().getIdentifierInfo("DISABLE_DYNLOADING")
->hasMacroDefinition()) ->hasMacroDefinition();
{ }
void run() override {
if (preRun()) {
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} }
} }
}; };
static loplugin::Plugin::Registration<DllPrivate> reg("dllprivate"); static loplugin::Plugin::Registration<DllPrivate> dllprivate("dllprivate");
} // namespace
#endif // LO_CLANG_SHARED_PLUGINS
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
@ -49,8 +50,12 @@ public:
explicit DynExcSpec(loplugin::InstantiationData const & data): explicit DynExcSpec(loplugin::InstantiationData const & data):
FilteringRewritePlugin(data) {} FilteringRewritePlugin(data) {}
bool preRun() override {
return compiler.getLangOpts().CPlusPlus;
}
void run() override { void run() override {
if (compiler.getLangOpts().CPlusPlus) { if (preRun()) {
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} }
} }
@ -172,8 +177,10 @@ private:
} }
}; };
loplugin::Plugin::Registration<DynExcSpec> X("dynexcspec", true); loplugin::Plugin::Registration<DynExcSpec> dynexcspec("dynexcspec");
} } // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
@ -17,30 +18,6 @@
namespace namespace
{ {
// It appears that, given a function declaration, there is no way to determine
// the language linkage of the function's type, only of the function's name
// (via FunctionDecl::isExternC); however, in a case like
//
// extern "C" { static void f(); }
//
// the function's name does not have C language linkage while the function's
// type does (as clarified in C++11 [decl.link]); cf. <http://clang-developers.
// 42468.n3.nabble.com/Language-linkage-of-function-type-tt4037248.html>
// "Language linkage of function type":
bool hasCLanguageLinkageType(FunctionDecl const* decl)
{
assert(decl != nullptr);
if (decl->isExternC())
{
return true;
}
if (decl->isInExternCContext())
{
return true;
}
return false;
}
bool derivesFromTestFixture(CXXRecordDecl const* decl) bool derivesFromTestFixture(CXXRecordDecl const* decl)
{ {
static auto const pred = [](CXXBaseSpecifier const& spec) { static auto const pred = [](CXXBaseSpecifier const& spec) {
@ -130,7 +107,7 @@ public:
{ {
return true; return true;
} }
if (hasCLanguageLinkageType(decl) if (loplugin::hasCLanguageLinkageType(decl)
&& loplugin::DeclCheck(decl).Function("_DllMainCRTStartup").GlobalNamespace()) && loplugin::DeclCheck(decl).Function("_DllMainCRTStartup").GlobalNamespace())
{ {
return true; return true;
@ -150,7 +127,7 @@ public:
return true; return true;
} }
auto const canon = decl->getCanonicalDecl(); auto const canon = decl->getCanonicalDecl();
if (hasCLanguageLinkageType(canon) if (loplugin::hasCLanguageLinkageType(canon)
&& (canon->hasAttr<ConstructorAttr>() || canon->hasAttr<DestructorAttr>())) && (canon->hasAttr<ConstructorAttr>() || canon->hasAttr<DestructorAttr>()))
{ {
return true; return true;
@ -337,7 +314,10 @@ private:
} }
}; };
loplugin::Plugin::Registration<External> X("external"); loplugin::Plugin::Registration<External> external("external");
}
} // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include <algorithm> #include <algorithm>
@ -98,13 +99,18 @@ public:
bool shouldVisitTemplateInstantiations() const { return true; } bool shouldVisitTemplateInstantiations() const { return true; }
bool preRun() override;
void run() override; void run() override;
bool VisitCXXDynamicCastExpr(CXXDynamicCastExpr const * expr); bool VisitCXXDynamicCastExpr(CXXDynamicCastExpr const * expr);
}; };
bool FailedDynCast::preRun() {
return compiler.getLangOpts().CPlusPlus;
}
void FailedDynCast::run() { void FailedDynCast::run() {
if (compiler.getLangOpts().CPlusPlus) { if (preRun()) {
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} }
} }
@ -123,8 +129,10 @@ bool FailedDynCast::VisitCXXDynamicCastExpr(CXXDynamicCastExpr const * expr) {
return true; return true;
} }
loplugin::Plugin::Registration<FailedDynCast> X("faileddyncast"); loplugin::Plugin::Registration<FailedDynCast> faileddyncast("faileddyncast");
} } // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -74,8 +75,10 @@ bool FinalProtected::VisitFieldDecl(FieldDecl const * fieldDecl)
return true; return true;
} }
loplugin::Plugin::Registration< FinalProtected > X("finalprotected", true); loplugin::Plugin::Registration< FinalProtected > finalprotected("finalprotected");
} } // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -8,6 +8,7 @@
* License. See LICENSE.TXT for details. * License. See LICENSE.TXT for details.
* *
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include <cassert> #include <cassert>
#include <string> #include <string>
@ -33,43 +34,58 @@ public:
{ {
} }
virtual void run() override virtual bool preRun() override
{ {
std::string fn(handler.getMainFileName()); std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn); loplugin::normalizeDotDotInFilePath(fn);
// include another file to build a table // include another file to build a table
if (fn == SRCDIR "/sc/source/core/tool/cellkeytranslator.cxx") if (fn == SRCDIR "/sc/source/core/tool/cellkeytranslator.cxx")
return; return false;
// weird structure // weird structure
if (fn == SRCDIR "/sc/source/core/tool/compiler.cxx") if (fn == SRCDIR "/sc/source/core/tool/compiler.cxx")
return; return false;
// looks like lex/yacc output // looks like lex/yacc output
if (fn == SRCDIR "/hwpfilter/source/grammar.cxx") if (fn == SRCDIR "/hwpfilter/source/grammar.cxx")
return; return false;
// TODO need to learn to handle attributes like "[[maybe_unused]]" // TODO need to learn to handle attributes like "[[maybe_unused]]"
if (fn == SRCDIR "/binaryurp/source/bridge.cxx") if (fn == SRCDIR "/binaryurp/source/bridge.cxx")
return; return false;
// the QEMIT macros // the QEMIT macros
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/qt5/") if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/qt5/")
|| loplugin::isSamePathname(fn, SRCDIR "/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx")) || loplugin::isSamePathname(fn, SRCDIR "/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx"))
return; return false;
return true;
}
virtual void run() override
{
if (preRun())
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} }
bool VisitCompoundStmt(CompoundStmt const*); bool VisitCompoundStmt(CompoundStmt const*);
bool PreTraverseSwitchStmt(SwitchStmt*);
void PostTraverseSwitchStmt(SwitchStmt*);
bool TraverseSwitchStmt(SwitchStmt*); bool TraverseSwitchStmt(SwitchStmt*);
bool VisitSwitchStmt(SwitchStmt const*); bool VisitSwitchStmt(SwitchStmt const*);
private: private:
Stmt const* switchStmtBody = nullptr; std::vector<const Stmt*> switchStmtBodies;
}; };
bool Indentation::PreTraverseSwitchStmt(SwitchStmt* switchStmt)
{
switchStmtBodies.push_back(switchStmt->getBody());
return true;
}
void Indentation::PostTraverseSwitchStmt(SwitchStmt*) { switchStmtBodies.pop_back(); }
bool Indentation::TraverseSwitchStmt(SwitchStmt* switchStmt) bool Indentation::TraverseSwitchStmt(SwitchStmt* switchStmt)
{ {
auto prev = switchStmtBody; PreTraverseSwitchStmt(switchStmt);
switchStmtBody = switchStmt->getBody();
FilteringPlugin::TraverseSwitchStmt(switchStmt); FilteringPlugin::TraverseSwitchStmt(switchStmt);
switchStmtBody = prev; PostTraverseSwitchStmt(switchStmt);
return true; return true;
} }
@ -78,7 +94,7 @@ bool Indentation::VisitCompoundStmt(CompoundStmt const* compoundStmt)
if (ignoreLocation(compoundStmt)) if (ignoreLocation(compoundStmt))
return true; return true;
// these are kind of free form // these are kind of free form
if (switchStmtBody == compoundStmt) if (!switchStmtBodies.empty() && switchStmtBodies.back() == compoundStmt)
return true; return true;
constexpr unsigned MAX = std::numeric_limits<unsigned>::max(); constexpr unsigned MAX = std::numeric_limits<unsigned>::max();
@ -233,8 +249,10 @@ bool Indentation::VisitSwitchStmt(SwitchStmt const* switchStmt)
return true; return true;
} }
loplugin::Plugin::Registration<Indentation> X("indentation"); loplugin::Plugin::Registration<Indentation> indentation("indentation");
} // namespace } // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -6,7 +6,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS #ifndef LO_CLANG_SHARED_PLUGINS
#include <cassert> #include <cassert>

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include "plugin.hxx" #include "plugin.hxx"
#include "check.hxx" #include "check.hxx"
@ -103,7 +104,10 @@ llvm::Optional<double> IntVsFloat::getExprValue(Expr const* expr)
return d; return d;
} }
loplugin::Plugin::Registration<IntVsFloat> X("intvsfloat"); loplugin::Plugin::Registration<IntVsFloat> intvsfloat("intvsfloat");
}
} // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include <cassert> #include <cassert>
#include <limits> #include <limits>
@ -29,6 +30,8 @@ public:
bool VisitImplicitCastExpr(ImplicitCastExpr const * expr); bool VisitImplicitCastExpr(ImplicitCastExpr const * expr);
bool PreTraverseLinkageSpecDecl(LinkageSpecDecl * decl);
void PostTraverseLinkageSpecDecl(LinkageSpecDecl * decl);
bool TraverseLinkageSpecDecl(LinkageSpecDecl * decl); bool TraverseLinkageSpecDecl(LinkageSpecDecl * decl);
private: private:
@ -55,12 +58,21 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr(
return true; return true;
} }
bool LiteralToBoolConversion::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) { bool LiteralToBoolConversion::PreTraverseLinkageSpecDecl(LinkageSpecDecl *) {
assert(externCContexts_ != std::numeric_limits<unsigned int>::max()); //TODO assert(externCContexts_ != std::numeric_limits<unsigned int>::max()); //TODO
++externCContexts_; ++externCContexts_;
bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl(decl); return true;
}
void LiteralToBoolConversion::PostTraverseLinkageSpecDecl(LinkageSpecDecl *) {
assert(externCContexts_ != 0); assert(externCContexts_ != 0);
--externCContexts_; --externCContexts_;
}
bool LiteralToBoolConversion::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) {
PreTraverseLinkageSpecDecl(decl);
bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl(decl);
PostTraverseLinkageSpecDecl(decl);
return ret; return ret;
} }
@ -210,7 +222,8 @@ void LiteralToBoolConversion::handleImplicitCastSubExpr(
} }
} }
loplugin::Plugin::Registration<LiteralToBoolConversion> X( loplugin::Plugin::Registration<LiteralToBoolConversion> literaltoboolconversion("literaltoboolconversion");
"literaltoboolconversion", true);
} } // namespace
#endif // LO_CLANG_SHARED_PLUGINS

View File

@ -8,6 +8,7 @@
* License. See LICENSE.TXT for details. * License. See LICENSE.TXT for details.
* *
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include "plugin.hxx" #include "plugin.hxx"
#include "check.hxx" #include "check.hxx"
@ -32,23 +33,29 @@ public:
{ {
} }
void run() bool preRun()
{ {
std::string fn(handler.getMainFileName()); std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn); loplugin::normalizeDotDotInFilePath(fn);
// these are below tools in the module hierarchy, so we can't use the pretty printing // these are below tools in the module hierarchy, so we can't use the pretty printing
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/cppuhelper/")) if (loplugin::hasPathnamePrefix(fn, SRCDIR "/cppuhelper/"))
return; return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/ucbhelper/")) if (loplugin::hasPathnamePrefix(fn, SRCDIR "/ucbhelper/"))
return; return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/")) if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/"))
return; return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/comphelper/")) if (loplugin::hasPathnamePrefix(fn, SRCDIR "/comphelper/"))
return; return false;
// can't do that here, don't have an Any // can't do that here, don't have an Any
if (loplugin::hasPathnamePrefix(fn, SRCDIR if (loplugin::hasPathnamePrefix(fn, SRCDIR
"/connectivity/source/drivers/hsqldb/HStorageMap.cxx")) "/connectivity/source/drivers/hsqldb/HStorageMap.cxx"))
return; return false;
return true;
}
void run()
{
if (preRun())
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} }
@ -129,8 +136,10 @@ public:
} }
}; };
static Plugin::Registration<LogExceptionNicely> X("logexceptionnicely"); static Plugin::Registration<LogExceptionNicely> logexceptionnicely("logexceptionnicely");
} // namespace } // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -6,6 +6,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#ifndef LO_CLANG_SHARED_PLUGINS
#include <cassert> #include <cassert>
@ -25,9 +26,11 @@ public:
{ {
} }
bool preRun() override { return compiler.getLangOpts().CPlusPlus; }
void run() override void run() override
{ {
if (compiler.getLangOpts().CPlusPlus) if (preRun())
{ {
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} }
@ -69,7 +72,10 @@ public:
} }
}; };
loplugin::Plugin::Registration<NestedUnnamed> X("nestedunnamed"); loplugin::Plugin::Registration<NestedUnnamed> nestedunnamed("nestedunnamed");
}
} // namespace
#endif // LO_CLANG_SHARED_PLUGINS
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -686,6 +686,17 @@ bool isSamePathname(StringRef pathname, StringRef other)
pathname, other, [](StringRef p, StringRef a) { return p == a; }); pathname, other, [](StringRef p, StringRef a) { return p == a; });
} }
bool hasCLanguageLinkageType(FunctionDecl const * decl) {
assert(decl != nullptr);
if (decl->isExternC()) {
return true;
}
if (decl->isInExternCContext()) {
return true;
}
return false;
}
} // namespace } // namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -271,6 +271,18 @@ bool hasPathnamePrefix(StringRef pathname, StringRef prefix);
// also contain backslashes: // also contain backslashes:
bool isSamePathname(StringRef pathname, StringRef other); bool isSamePathname(StringRef pathname, StringRef other);
// It appears that, given a function declaration, there is no way to determine
// the language linkage of the function's type, only of the function's name
// (via FunctionDecl::isExternC); however, in a case like
//
// extern "C" { static void f(); }
//
// the function's name does not have C language linkage while the function's
// type does (as clarified in C++11 [decl.link]); cf. <http://clang-developers.
// 42468.n3.nabble.com/Language-linkage-of-function-type-tt4037248.html>
// "Language linkage of function type":
bool hasCLanguageLinkageType(FunctionDecl const * decl);
} // namespace } // namespace
#endif // COMPILEPLUGIN_H #endif // COMPILEPLUGIN_H

View File

@ -14,16 +14,26 @@
#include "../badstatics.cxx" #include "../badstatics.cxx"
#include "../blockblock.cxx" #include "../blockblock.cxx"
#include "../charrightshift.cxx" #include "../charrightshift.cxx"
#include "../data.cxx"
#include "../datamembershadow.cxx" #include "../datamembershadow.cxx"
#include "../dbgunhandledexception.cxx" #include "../dbgunhandledexception.cxx"
#include "../derefnullptr.cxx" #include "../derefnullptr.cxx"
#include "../dllprivate.cxx"
#include "../doubleconvert.cxx" #include "../doubleconvert.cxx"
#include "../dynexcspec.cxx"
#include "../empty.cxx" #include "../empty.cxx"
#include "../emptyif.cxx" #include "../emptyif.cxx"
#include "../externandnotdefined.cxx" #include "../externandnotdefined.cxx"
#include "../externvar.cxx" #include "../externvar.cxx"
#include "../external.cxx"
#include "../finalprotected.cxx"
#include "../indentation.cxx"
#include "../inlinevisible.cxx" #include "../inlinevisible.cxx"
#include "../intvsfloat.cxx"
#include "../literaltoboolconversion.cxx"
#include "../logexceptionnicely.cxx"
#include "../loopvartoosmall.cxx" #include "../loopvartoosmall.cxx"
#include "../nestedunnamed.cxx"
#include "../overrideparam.cxx" #include "../overrideparam.cxx"
#include "../overridevirtual.cxx" #include "../overridevirtual.cxx"
#include "../passparamsbyref.cxx" #include "../passparamsbyref.cxx"
@ -55,6 +65,7 @@
#include "../weakbase.cxx" #include "../weakbase.cxx"
#include "../weakobject.cxx" #include "../weakobject.cxx"
#include "../dyncastvisibility.cxx" #include "../dyncastvisibility.cxx"
#include "../faileddyncast.cxx"
#include "../ptrvector.cxx" #include "../ptrvector.cxx"
#include "../vclwidgets.cxx" #include "../vclwidgets.cxx"
@ -73,16 +84,26 @@ public:
, badStatics( nullptr ) , badStatics( nullptr )
, blockBlock( nullptr ) , blockBlock( nullptr )
, charRightShift( nullptr ) , charRightShift( nullptr )
, data( nullptr )
, dataMemberShadow( nullptr ) , dataMemberShadow( nullptr )
, dbgUnhandledException( nullptr ) , dbgUnhandledException( nullptr )
, derefNullPtr( nullptr ) , derefNullPtr( nullptr )
, dllPrivate( nullptr )
, doubleConvert( nullptr ) , doubleConvert( nullptr )
, dynExcSpec( nullptr )
, empty( nullptr ) , empty( nullptr )
, emptyIf( nullptr ) , emptyIf( nullptr )
, externAndNotDefined( nullptr ) , externAndNotDefined( nullptr )
, externVar( nullptr ) , externVar( nullptr )
, external( nullptr )
, finalProtected( nullptr )
, indentation( nullptr )
, inlineVisible( nullptr ) , inlineVisible( nullptr )
, intVsFloat( nullptr )
, literalToBoolConversion( nullptr )
, logExceptionNicely( nullptr )
, loopVarTooSmall( nullptr ) , loopVarTooSmall( nullptr )
, nestedUnnamed( nullptr )
, overrideParam( nullptr ) , overrideParam( nullptr )
, overrideVirtual( nullptr ) , overrideVirtual( nullptr )
, passParamsByRef( nullptr ) , passParamsByRef( nullptr )
@ -122,14 +143,20 @@ public:
blockBlock = nullptr; blockBlock = nullptr;
if( charRightShift && !charRightShift->preRun()) if( charRightShift && !charRightShift->preRun())
charRightShift = nullptr; charRightShift = nullptr;
if( data && !data->preRun())
data = nullptr;
if( dataMemberShadow && !dataMemberShadow->preRun()) if( dataMemberShadow && !dataMemberShadow->preRun())
dataMemberShadow = nullptr; dataMemberShadow = nullptr;
if( dbgUnhandledException && !dbgUnhandledException->preRun()) if( dbgUnhandledException && !dbgUnhandledException->preRun())
dbgUnhandledException = nullptr; dbgUnhandledException = nullptr;
if( derefNullPtr && !derefNullPtr->preRun()) if( derefNullPtr && !derefNullPtr->preRun())
derefNullPtr = nullptr; derefNullPtr = nullptr;
if( dllPrivate && !dllPrivate->preRun())
dllPrivate = nullptr;
if( doubleConvert && !doubleConvert->preRun()) if( doubleConvert && !doubleConvert->preRun())
doubleConvert = nullptr; doubleConvert = nullptr;
if( dynExcSpec && !dynExcSpec->preRun())
dynExcSpec = nullptr;
if( empty && !empty->preRun()) if( empty && !empty->preRun())
empty = nullptr; empty = nullptr;
if( emptyIf && !emptyIf->preRun()) if( emptyIf && !emptyIf->preRun())
@ -138,10 +165,24 @@ public:
externAndNotDefined = nullptr; externAndNotDefined = nullptr;
if( externVar && !externVar->preRun()) if( externVar && !externVar->preRun())
externVar = nullptr; externVar = nullptr;
if( external && !external->preRun())
external = nullptr;
if( finalProtected && !finalProtected->preRun())
finalProtected = nullptr;
if( indentation && !indentation->preRun())
indentation = nullptr;
if( inlineVisible && !inlineVisible->preRun()) if( inlineVisible && !inlineVisible->preRun())
inlineVisible = nullptr; inlineVisible = nullptr;
if( intVsFloat && !intVsFloat->preRun())
intVsFloat = nullptr;
if( literalToBoolConversion && !literalToBoolConversion->preRun())
literalToBoolConversion = nullptr;
if( logExceptionNicely && !logExceptionNicely->preRun())
logExceptionNicely = nullptr;
if( loopVarTooSmall && !loopVarTooSmall->preRun()) if( loopVarTooSmall && !loopVarTooSmall->preRun())
loopVarTooSmall = nullptr; loopVarTooSmall = nullptr;
if( nestedUnnamed && !nestedUnnamed->preRun())
nestedUnnamed = nullptr;
if( overrideParam && !overrideParam->preRun()) if( overrideParam && !overrideParam->preRun())
overrideParam = nullptr; overrideParam = nullptr;
if( overrideVirtual && !overrideVirtual->preRun()) if( overrideVirtual && !overrideVirtual->preRun())
@ -212,14 +253,20 @@ public:
blockBlock->postRun(); blockBlock->postRun();
if( charRightShift ) if( charRightShift )
charRightShift->postRun(); charRightShift->postRun();
if( data )
data->postRun();
if( dataMemberShadow ) if( dataMemberShadow )
dataMemberShadow->postRun(); dataMemberShadow->postRun();
if( dbgUnhandledException ) if( dbgUnhandledException )
dbgUnhandledException->postRun(); dbgUnhandledException->postRun();
if( derefNullPtr ) if( derefNullPtr )
derefNullPtr->postRun(); derefNullPtr->postRun();
if( dllPrivate )
dllPrivate->postRun();
if( doubleConvert ) if( doubleConvert )
doubleConvert->postRun(); doubleConvert->postRun();
if( dynExcSpec )
dynExcSpec->postRun();
if( empty ) if( empty )
empty->postRun(); empty->postRun();
if( emptyIf ) if( emptyIf )
@ -228,10 +275,24 @@ public:
externAndNotDefined->postRun(); externAndNotDefined->postRun();
if( externVar ) if( externVar )
externVar->postRun(); externVar->postRun();
if( external )
external->postRun();
if( finalProtected )
finalProtected->postRun();
if( indentation )
indentation->postRun();
if( inlineVisible ) if( inlineVisible )
inlineVisible->postRun(); inlineVisible->postRun();
if( intVsFloat )
intVsFloat->postRun();
if( literalToBoolConversion )
literalToBoolConversion->postRun();
if( logExceptionNicely )
logExceptionNicely->postRun();
if( loopVarTooSmall ) if( loopVarTooSmall )
loopVarTooSmall->postRun(); loopVarTooSmall->postRun();
if( nestedUnnamed )
nestedUnnamed->postRun();
if( overrideParam ) if( overrideParam )
overrideParam->postRun(); overrideParam->postRun();
if( overrideVirtual ) if( overrideVirtual )
@ -308,14 +369,20 @@ public:
blockBlock = static_cast< BlockBlock* >( plugin ); blockBlock = static_cast< BlockBlock* >( plugin );
else if( strcmp( name, "charrightshift" ) == 0 ) else if( strcmp( name, "charrightshift" ) == 0 )
charRightShift = static_cast< CharRightShift* >( plugin ); charRightShift = static_cast< CharRightShift* >( plugin );
else if( strcmp( name, "data" ) == 0 )
data = static_cast< Data* >( plugin );
else if( strcmp( name, "datamembershadow" ) == 0 ) else if( strcmp( name, "datamembershadow" ) == 0 )
dataMemberShadow = static_cast< DataMemberShadow* >( plugin ); dataMemberShadow = static_cast< DataMemberShadow* >( plugin );
else if( strcmp( name, "dbgunhandledexception" ) == 0 ) else if( strcmp( name, "dbgunhandledexception" ) == 0 )
dbgUnhandledException = static_cast< DbgUnhandledException* >( plugin ); dbgUnhandledException = static_cast< DbgUnhandledException* >( plugin );
else if( strcmp( name, "derefnullptr" ) == 0 ) else if( strcmp( name, "derefnullptr" ) == 0 )
derefNullPtr = static_cast< DerefNullPtr* >( plugin ); derefNullPtr = static_cast< DerefNullPtr* >( plugin );
else if( strcmp( name, "dllprivate" ) == 0 )
dllPrivate = static_cast< DllPrivate* >( plugin );
else if( strcmp( name, "doubleconvert" ) == 0 ) else if( strcmp( name, "doubleconvert" ) == 0 )
doubleConvert = static_cast< DoubleConvert* >( plugin ); doubleConvert = static_cast< DoubleConvert* >( plugin );
else if( strcmp( name, "dynexcspec" ) == 0 )
dynExcSpec = static_cast< DynExcSpec* >( plugin );
else if( strcmp( name, "empty" ) == 0 ) else if( strcmp( name, "empty" ) == 0 )
empty = static_cast< Empty* >( plugin ); empty = static_cast< Empty* >( plugin );
else if( strcmp( name, "emptyif" ) == 0 ) else if( strcmp( name, "emptyif" ) == 0 )
@ -324,10 +391,24 @@ public:
externAndNotDefined = static_cast< ExternAndNotDefined* >( plugin ); externAndNotDefined = static_cast< ExternAndNotDefined* >( plugin );
else if( strcmp( name, "externvar" ) == 0 ) else if( strcmp( name, "externvar" ) == 0 )
externVar = static_cast< ExternVar* >( plugin ); externVar = static_cast< ExternVar* >( plugin );
else if( strcmp( name, "external" ) == 0 )
external = static_cast< External* >( plugin );
else if( strcmp( name, "finalprotected" ) == 0 )
finalProtected = static_cast< FinalProtected* >( plugin );
else if( strcmp( name, "indentation" ) == 0 )
indentation = static_cast< Indentation* >( plugin );
else if( strcmp( name, "inlinevisible" ) == 0 ) else if( strcmp( name, "inlinevisible" ) == 0 )
inlineVisible = static_cast< InlineVisible* >( plugin ); inlineVisible = static_cast< InlineVisible* >( plugin );
else if( strcmp( name, "intvsfloat" ) == 0 )
intVsFloat = static_cast< IntVsFloat* >( plugin );
else if( strcmp( name, "literaltoboolconversion" ) == 0 )
literalToBoolConversion = static_cast< LiteralToBoolConversion* >( plugin );
else if( strcmp( name, "logexceptionnicely" ) == 0 )
logExceptionNicely = static_cast< LogExceptionNicely* >( plugin );
else if( strcmp( name, "loopvartoosmall" ) == 0 ) else if( strcmp( name, "loopvartoosmall" ) == 0 )
loopVarTooSmall = static_cast< LoopVarTooSmall* >( plugin ); loopVarTooSmall = static_cast< LoopVarTooSmall* >( plugin );
else if( strcmp( name, "nestedunnamed" ) == 0 )
nestedUnnamed = static_cast< NestedUnnamed* >( plugin );
else if( strcmp( name, "overrideparam" ) == 0 ) else if( strcmp( name, "overrideparam" ) == 0 )
overrideParam = static_cast< OverrideParam* >( plugin ); overrideParam = static_cast< OverrideParam* >( plugin );
else if( strcmp( name, "overridevirtual" ) == 0 ) else if( strcmp( name, "overridevirtual" ) == 0 )
@ -412,6 +493,11 @@ public:
if( !empty->VisitBinEQ( arg )) if( !empty->VisitBinEQ( arg ))
empty = nullptr; empty = nullptr;
} }
if( intVsFloat != nullptr )
{
if( !intVsFloat->VisitBinEQ( arg ))
intVsFloat = nullptr;
}
return anyPluginActive(); return anyPluginActive();
} }
bool VisitBinGE(const class clang::BinaryOperator * arg) bool VisitBinGE(const class clang::BinaryOperator * arg)
@ -571,6 +657,11 @@ public:
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
return true; return true;
if( finalProtected != nullptr )
{
if( !finalProtected->VisitCXXMethodDecl( arg ))
finalProtected = nullptr;
}
if( overrideParam != nullptr ) if( overrideParam != nullptr )
{ {
if( !overrideParam->VisitCXXMethodDecl( arg )) if( !overrideParam->VisitCXXMethodDecl( arg ))
@ -613,6 +704,11 @@ public:
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
return true; return true;
if( logExceptionNicely != nullptr )
{
if( !logExceptionNicely->VisitCXXOperatorCallExpr( arg ))
logExceptionNicely = nullptr;
}
if( passParamsByRef != nullptr ) if( passParamsByRef != nullptr )
{ {
if( !passParamsByRef->VisitCXXOperatorCallExpr( arg )) if( !passParamsByRef->VisitCXXOperatorCallExpr( arg ))
@ -725,6 +821,17 @@ public:
} }
return anyPluginActive(); return anyPluginActive();
} }
bool VisitClassTemplateDecl(const class clang::ClassTemplateDecl * arg)
{
if( ignoreLocation( arg ))
return true;
if( external != nullptr )
{
if( !external->VisitClassTemplateDecl( arg ))
external = nullptr;
}
return anyPluginActive();
}
bool VisitCompoundStmt(const class clang::CompoundStmt * arg) bool VisitCompoundStmt(const class clang::CompoundStmt * arg)
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
@ -734,6 +841,11 @@ public:
if( !blockBlock->VisitCompoundStmt( arg )) if( !blockBlock->VisitCompoundStmt( arg ))
blockBlock = nullptr; blockBlock = nullptr;
} }
if( indentation != nullptr )
{
if( !indentation->VisitCompoundStmt( arg ))
indentation = nullptr;
}
return anyPluginActive(); return anyPluginActive();
} }
bool VisitConditionalOperator(const class clang::ConditionalOperator * arg) bool VisitConditionalOperator(const class clang::ConditionalOperator * arg)
@ -772,6 +884,11 @@ public:
if( !dataMemberShadow->VisitFieldDecl( arg )) if( !dataMemberShadow->VisitFieldDecl( arg ))
dataMemberShadow = nullptr; dataMemberShadow = nullptr;
} }
if( finalProtected != nullptr )
{
if( !finalProtected->VisitFieldDecl( arg ))
finalProtected = nullptr;
}
return anyPluginActive(); return anyPluginActive();
} }
bool VisitForStmt(const class clang::ForStmt * arg) bool VisitForStmt(const class clang::ForStmt * arg)
@ -794,11 +911,21 @@ public:
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
return true; return true;
if( dynExcSpec != nullptr )
{
if( !dynExcSpec->VisitFunctionDecl( arg ))
dynExcSpec = nullptr;
}
if( externAndNotDefined != nullptr ) if( externAndNotDefined != nullptr )
{ {
if( !externAndNotDefined->VisitFunctionDecl( arg )) if( !externAndNotDefined->VisitFunctionDecl( arg ))
externAndNotDefined = nullptr; externAndNotDefined = nullptr;
} }
if( external != nullptr )
{
if( !external->VisitFunctionDecl( arg ))
external = nullptr;
}
if( inlineVisible != nullptr ) if( inlineVisible != nullptr )
{ {
if( !inlineVisible->VisitFunctionDecl( arg )) if( !inlineVisible->VisitFunctionDecl( arg ))
@ -836,6 +963,17 @@ public:
} }
return anyPluginActive(); return anyPluginActive();
} }
bool VisitFunctionTemplateDecl(const class clang::FunctionTemplateDecl * arg)
{
if( ignoreLocation( arg ))
return true;
if( external != nullptr )
{
if( !external->VisitFunctionTemplateDecl( arg ))
external = nullptr;
}
return anyPluginActive();
}
bool VisitIfStmt(const class clang::IfStmt * arg) bool VisitIfStmt(const class clang::IfStmt * arg)
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
@ -856,6 +994,11 @@ public:
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
return true; return true;
if( literalToBoolConversion != nullptr )
{
if( !literalToBoolConversion->VisitImplicitCastExpr( arg ))
literalToBoolConversion = nullptr;
}
if( unicodeToChar != nullptr ) if( unicodeToChar != nullptr )
{ {
if( !unicodeToChar->VisitImplicitCastExpr( arg )) if( !unicodeToChar->VisitImplicitCastExpr( arg ))
@ -899,6 +1042,11 @@ public:
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
return true; return true;
if( dllPrivate != nullptr )
{
if( !dllPrivate->VisitNamedDecl( arg ))
dllPrivate = nullptr;
}
if( reservedId != nullptr ) if( reservedId != nullptr )
{ {
if( !reservedId->VisitNamedDecl( arg )) if( !reservedId->VisitNamedDecl( arg ))
@ -906,6 +1054,17 @@ public:
} }
return anyPluginActive(); return anyPluginActive();
} }
bool VisitNamespaceDecl(const class clang::NamespaceDecl * arg)
{
if( ignoreLocation( arg ))
return true;
if( nestedUnnamed != nullptr )
{
if( !nestedUnnamed->VisitNamespaceDecl( arg ))
nestedUnnamed = nullptr;
}
return anyPluginActive();
}
bool VisitParenExpr(const class clang::ParenExpr * arg) bool VisitParenExpr(const class clang::ParenExpr * arg)
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
@ -942,6 +1101,11 @@ public:
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
return true; return true;
if( indentation != nullptr )
{
if( !indentation->VisitSwitchStmt( arg ))
indentation = nullptr;
}
if( unnecessaryParen != nullptr ) if( unnecessaryParen != nullptr )
{ {
if( !unnecessaryParen->VisitSwitchStmt( arg )) if( !unnecessaryParen->VisitSwitchStmt( arg ))
@ -949,6 +1113,17 @@ public:
} }
return anyPluginActive(); return anyPluginActive();
} }
bool VisitTagDecl(const class clang::TagDecl * arg)
{
if( ignoreLocation( arg ))
return true;
if( external != nullptr )
{
if( !external->VisitTagDecl( arg ))
external = nullptr;
}
return anyPluginActive();
}
bool VisitUnaryDeref(const class clang::UnaryOperator * arg) bool VisitUnaryDeref(const class clang::UnaryOperator * arg)
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
@ -975,6 +1150,11 @@ public:
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
return true; return true;
if( data != nullptr )
{
if( !data->VisitUnaryOperator( arg ))
data = nullptr;
}
if( redundantPointerOps != nullptr ) if( redundantPointerOps != nullptr )
{ {
if( !redundantPointerOps->VisitUnaryOperator( arg )) if( !redundantPointerOps->VisitUnaryOperator( arg ))
@ -996,6 +1176,16 @@ public:
if( !externVar->VisitVarDecl( arg )) if( !externVar->VisitVarDecl( arg ))
externVar = nullptr; externVar = nullptr;
} }
if( external != nullptr )
{
if( !external->VisitVarDecl( arg ))
external = nullptr;
}
if( intVsFloat != nullptr )
{
if( !intVsFloat->VisitVarDecl( arg ))
intVsFloat = nullptr;
}
if( simplifyConstruct != nullptr ) if( simplifyConstruct != nullptr )
{ {
if( !simplifyConstruct->VisitVarDecl( arg )) if( !simplifyConstruct->VisitVarDecl( arg ))
@ -1018,6 +1208,17 @@ public:
} }
return anyPluginActive(); return anyPluginActive();
} }
bool VisitVarTemplateDecl(const class clang::VarTemplateDecl * arg)
{
if( ignoreLocation( arg ))
return true;
if( external != nullptr )
{
if( !external->VisitVarTemplateDecl( arg ))
external = nullptr;
}
return anyPluginActive();
}
bool VisitWhileStmt(const class clang::WhileStmt * arg) bool VisitWhileStmt(const class clang::WhileStmt * arg)
{ {
if( ignoreLocation( arg )) if( ignoreLocation( arg ))
@ -1166,6 +1367,22 @@ public:
simplifyConstruct = saveSimplifyConstruct; simplifyConstruct = saveSimplifyConstruct;
return ret; return ret;
} }
bool TraverseLinkageSpecDecl(class clang::LinkageSpecDecl * arg)
{
LiteralToBoolConversion* saveLiteralToBoolConversion = literalToBoolConversion;
if( literalToBoolConversion != nullptr )
{
if( !literalToBoolConversion->PreTraverseLinkageSpecDecl( arg ))
literalToBoolConversion = nullptr;
}
bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl( arg );
if( literalToBoolConversion != nullptr )
{
literalToBoolConversion->PostTraverseLinkageSpecDecl( arg );
}
literalToBoolConversion = saveLiteralToBoolConversion;
return ret;
}
bool TraverseReturnStmt(class clang::ReturnStmt * arg) bool TraverseReturnStmt(class clang::ReturnStmt * arg)
{ {
SimplifyConstruct* saveSimplifyConstruct = simplifyConstruct; SimplifyConstruct* saveSimplifyConstruct = simplifyConstruct;
@ -1178,22 +1395,48 @@ public:
simplifyConstruct = saveSimplifyConstruct; simplifyConstruct = saveSimplifyConstruct;
return ret; return ret;
} }
bool TraverseSwitchStmt(class clang::SwitchStmt * arg)
{
Indentation* saveIndentation = indentation;
if( indentation != nullptr )
{
if( !indentation->PreTraverseSwitchStmt( arg ))
indentation = nullptr;
}
bool ret = RecursiveASTVisitor::TraverseSwitchStmt( arg );
if( indentation != nullptr )
{
indentation->PostTraverseSwitchStmt( arg );
}
indentation = saveIndentation;
return ret;
}
private: private:
bool anyPluginActive() const bool anyPluginActive() const
{ {
return badStatics != nullptr return badStatics != nullptr
|| blockBlock != nullptr || blockBlock != nullptr
|| charRightShift != nullptr || charRightShift != nullptr
|| data != nullptr
|| dataMemberShadow != nullptr || dataMemberShadow != nullptr
|| dbgUnhandledException != nullptr || dbgUnhandledException != nullptr
|| derefNullPtr != nullptr || derefNullPtr != nullptr
|| dllPrivate != nullptr
|| doubleConvert != nullptr || doubleConvert != nullptr
|| dynExcSpec != nullptr
|| empty != nullptr || empty != nullptr
|| emptyIf != nullptr || emptyIf != nullptr
|| externAndNotDefined != nullptr || externAndNotDefined != nullptr
|| externVar != nullptr || externVar != nullptr
|| external != nullptr
|| finalProtected != nullptr
|| indentation != nullptr
|| inlineVisible != nullptr || inlineVisible != nullptr
|| intVsFloat != nullptr
|| literalToBoolConversion != nullptr
|| logExceptionNicely != nullptr
|| loopVarTooSmall != nullptr || loopVarTooSmall != nullptr
|| nestedUnnamed != nullptr
|| overrideParam != nullptr || overrideParam != nullptr
|| overrideVirtual != nullptr || overrideVirtual != nullptr
|| passParamsByRef != nullptr || passParamsByRef != nullptr
@ -1228,16 +1471,26 @@ private:
BadStatics* badStatics; BadStatics* badStatics;
BlockBlock* blockBlock; BlockBlock* blockBlock;
CharRightShift* charRightShift; CharRightShift* charRightShift;
Data* data;
DataMemberShadow* dataMemberShadow; DataMemberShadow* dataMemberShadow;
DbgUnhandledException* dbgUnhandledException; DbgUnhandledException* dbgUnhandledException;
DerefNullPtr* derefNullPtr; DerefNullPtr* derefNullPtr;
DllPrivate* dllPrivate;
DoubleConvert* doubleConvert; DoubleConvert* doubleConvert;
DynExcSpec* dynExcSpec;
Empty* empty; Empty* empty;
EmptyIf* emptyIf; EmptyIf* emptyIf;
ExternAndNotDefined* externAndNotDefined; ExternAndNotDefined* externAndNotDefined;
ExternVar* externVar; ExternVar* externVar;
External* external;
FinalProtected* finalProtected;
Indentation* indentation;
InlineVisible* inlineVisible; InlineVisible* inlineVisible;
IntVsFloat* intVsFloat;
LiteralToBoolConversion* literalToBoolConversion;
LogExceptionNicely* logExceptionNicely;
LoopVarTooSmall* loopVarTooSmall; LoopVarTooSmall* loopVarTooSmall;
NestedUnnamed* nestedUnnamed;
OverrideParam* overrideParam; OverrideParam* overrideParam;
OverrideVirtual* overrideVirtual; OverrideVirtual* overrideVirtual;
PassParamsByRef* passParamsByRef; PassParamsByRef* passParamsByRef;
@ -1280,6 +1533,7 @@ public:
explicit SharedRecursiveASTVisitorVisitTemplates(const InstantiationData& rData) explicit SharedRecursiveASTVisitorVisitTemplates(const InstantiationData& rData)
: FilteringPlugin(rData) : FilteringPlugin(rData)
, dynCastVisibility( nullptr ) , dynCastVisibility( nullptr )
, failedDynCast( nullptr )
, ptrVector( nullptr ) , ptrVector( nullptr )
, vCLWidgets( nullptr ) , vCLWidgets( nullptr )
{} {}
@ -1287,6 +1541,8 @@ public:
{ {
if( dynCastVisibility && !dynCastVisibility->preRun()) if( dynCastVisibility && !dynCastVisibility->preRun())
dynCastVisibility = nullptr; dynCastVisibility = nullptr;
if( failedDynCast && !failedDynCast->preRun())
failedDynCast = nullptr;
if( ptrVector && !ptrVector->preRun()) if( ptrVector && !ptrVector->preRun())
ptrVector = nullptr; ptrVector = nullptr;
if( vCLWidgets && !vCLWidgets->preRun()) if( vCLWidgets && !vCLWidgets->preRun())
@ -1297,6 +1553,8 @@ public:
{ {
if( dynCastVisibility ) if( dynCastVisibility )
dynCastVisibility->postRun(); dynCastVisibility->postRun();
if( failedDynCast )
failedDynCast->postRun();
if( ptrVector ) if( ptrVector )
ptrVector->postRun(); ptrVector->postRun();
if( vCLWidgets ) if( vCLWidgets )
@ -1313,6 +1571,8 @@ public:
{ {
if( strcmp( name, "dyncastvisibility" ) == 0 ) if( strcmp( name, "dyncastvisibility" ) == 0 )
dynCastVisibility = static_cast< DynCastVisibility* >( plugin ); dynCastVisibility = static_cast< DynCastVisibility* >( plugin );
else if( strcmp( name, "faileddyncast" ) == 0 )
failedDynCast = static_cast< FailedDynCast* >( plugin );
else if( strcmp( name, "ptrvector" ) == 0 ) else if( strcmp( name, "ptrvector" ) == 0 )
ptrVector = static_cast< PtrVector* >( plugin ); ptrVector = static_cast< PtrVector* >( plugin );
else if( strcmp( name, "vclwidgets" ) == 0 ) else if( strcmp( name, "vclwidgets" ) == 0 )
@ -1375,6 +1635,11 @@ bool shouldVisitTemplateInstantiations() const { return true; }
if( !dynCastVisibility->VisitCXXDynamicCastExpr( arg )) if( !dynCastVisibility->VisitCXXDynamicCastExpr( arg ))
dynCastVisibility = nullptr; dynCastVisibility = nullptr;
} }
if( failedDynCast != nullptr )
{
if( !failedDynCast->VisitCXXDynamicCastExpr( arg ))
failedDynCast = nullptr;
}
return anyPluginActive(); return anyPluginActive();
} }
bool VisitCXXOperatorCallExpr(const class clang::CXXOperatorCallExpr * arg) bool VisitCXXOperatorCallExpr(const class clang::CXXOperatorCallExpr * arg)
@ -1458,10 +1723,12 @@ private:
bool anyPluginActive() const bool anyPluginActive() const
{ {
return dynCastVisibility != nullptr return dynCastVisibility != nullptr
|| failedDynCast != nullptr
|| ptrVector != nullptr || ptrVector != nullptr
|| vCLWidgets != nullptr; || vCLWidgets != nullptr;
} }
DynCastVisibility* dynCastVisibility; DynCastVisibility* dynCastVisibility;
FailedDynCast* failedDynCast;
PtrVector* ptrVector; PtrVector* ptrVector;
VCLWidgets* vCLWidgets; VCLWidgets* vCLWidgets;
}; };

View File

@ -20,27 +20,6 @@
namespace { namespace {
// It appears that, given a function declaration, there is no way to determine
// the language linkage of the function's type, only of the function's name
// (via FunctionDecl::isExternC); however, in a case like
//
// extern "C" { static void f(); }
//
// the function's name does not have C language linkage while the function's
// type does (as clarified in C++11 [decl.link]); cf. <http://clang-developers.
// 42468.n3.nabble.com/Language-linkage-of-function-type-tt4037248.html>
// "Language linkage of function type":
bool hasCLanguageLinkageType(FunctionDecl const * decl) {
assert(decl != nullptr);
if (decl->isExternC()) {
return true;
}
if (decl->isInExternCContext()) {
return true;
}
return false;
}
bool isFriendDecl(Decl const * decl) { bool isFriendDecl(Decl const * decl) {
return decl->getFriendObjectKind() != Decl::FOK_None; return decl->getFriendObjectKind() != Decl::FOK_None;
} }
@ -173,7 +152,7 @@ bool UnrefFun::VisitFunctionDecl(FunctionDecl const * decl) {
} }
LinkageInfo info(canon->getLinkageAndVisibility()); LinkageInfo info(canon->getLinkageAndVisibility());
if (info.getLinkage() == ExternalLinkage if (info.getLinkage() == ExternalLinkage
&& hasCLanguageLinkageType(canon) && canon->isDefined() && loplugin::hasCLanguageLinkageType(canon) && canon->isDefined()
&& ((decl == canon && info.getVisibility() == DefaultVisibility) && ((decl == canon && info.getVisibility() == DefaultVisibility)
|| ((canon->hasAttr<ConstructorAttr>() || ((canon->hasAttr<ConstructorAttr>()
|| canon->hasAttr<DestructorAttr>()) || canon->hasAttr<DestructorAttr>())