summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-07-17 15:06:43 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-07-17 19:32:43 +0200
commitdd969ad6e006adb4a9585c0d1b3378f29bbe5787 (patch)
treea4f479f3f7170205c075e5ce6837949b41acc604 /compilerplugins
parent7598810d6372bac07e503728ee28c4600a1c9b5d (diff)
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>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/data.cxx13
-rw-r--r--compilerplugins/clang/dllprivate.cxx20
-rw-r--r--compilerplugins/clang/dynexcspec.cxx13
-rw-r--r--compilerplugins/clang/external.cxx36
-rw-r--r--compilerplugins/clang/faileddyncast.cxx14
-rw-r--r--compilerplugins/clang/finalprotected.cxx7
-rw-r--r--compilerplugins/clang/indentation.cxx44
-rw-r--r--compilerplugins/clang/inlinevisible.cxx1
-rw-r--r--compilerplugins/clang/intvsfloat.cxx8
-rw-r--r--compilerplugins/clang/literaltoboolconversion.cxx23
-rw-r--r--compilerplugins/clang/logexceptionnicely.cxx25
-rw-r--r--compilerplugins/clang/nestedunnamed.cxx12
-rw-r--r--compilerplugins/clang/plugin.cxx11
-rw-r--r--compilerplugins/clang/plugin.hxx12
-rw-r--r--compilerplugins/clang/sharedvisitor/sharedvisitor.cxx267
-rw-r--r--compilerplugins/clang/unreffun.cxx23
16 files changed, 428 insertions, 101 deletions
diff --git a/compilerplugins/clang/data.cxx b/compilerplugins/clang/data.cxx
index 7e2f019e47a1..9cff5426fc1d 100644
--- a/compilerplugins/clang/data.cxx
+++ b/compilerplugins/clang/data.cxx
@@ -6,6 +6,7 @@
* 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 "check.hxx"
#include "compat.hxx"
@@ -68,17 +69,21 @@ public:
return true;
}
-private:
+ bool preRun() override { return compiler.getLangOpts().CPlusPlus; }
+
void run() override
{
- if (compiler.getLangOpts().CPlusPlus)
+ if (preRun())
{
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: */
diff --git a/compilerplugins/clang/dllprivate.cxx b/compilerplugins/clang/dllprivate.cxx
index 8d0f221c327c..5fbace1010b7 100644
--- a/compilerplugins/clang/dllprivate.cxx
+++ b/compilerplugins/clang/dllprivate.cxx
@@ -6,6 +6,7 @@
* 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 "plugin.hxx"
@@ -57,24 +58,29 @@ public:
return true;
}
-private:
- void run() override {
+ bool preRun() override {
// DISABLE_DYNLOADING makes SAL_DLLPUBLIC_{EXPORT,IMPORT,TEMPLATE} expand
// to visibility("hidden") attributes, which would cause bogus warnings
// here (e.g., in UBSan builds that explicitly define DISABLE_DYNLOADING
// in jurt/source/pipe/staticsalhack.cxx); alternatively, change
// include/sal/types.h to make those SAL_DLLPUBLIC_* expand to nothing
// for DISABLE_DYNLOADING:
- if (!compiler.getPreprocessor().getIdentifierInfo("DISABLE_DYNLOADING")
- ->hasMacroDefinition())
- {
+ return !compiler.getPreprocessor().getIdentifierInfo("DISABLE_DYNLOADING")
+ ->hasMacroDefinition();
+ }
+
+ void run() override {
+ if (preRun()) {
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: */
diff --git a/compilerplugins/clang/dynexcspec.cxx b/compilerplugins/clang/dynexcspec.cxx
index e5e15cb139fc..af733ec4f10f 100644
--- a/compilerplugins/clang/dynexcspec.cxx
+++ b/compilerplugins/clang/dynexcspec.cxx
@@ -6,6 +6,7 @@
* 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 <algorithm>
#include <functional>
@@ -49,8 +50,12 @@ public:
explicit DynExcSpec(loplugin::InstantiationData const & data):
FilteringRewritePlugin(data) {}
+ bool preRun() override {
+ return compiler.getLangOpts().CPlusPlus;
+ }
+
void run() override {
- if (compiler.getLangOpts().CPlusPlus) {
+ if (preRun()) {
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: */
diff --git a/compilerplugins/clang/external.cxx b/compilerplugins/clang/external.cxx
index 8e66cf2ee5df..fe4328c1187b 100644
--- a/compilerplugins/clang/external.cxx
+++ b/compilerplugins/clang/external.cxx
@@ -6,6 +6,7 @@
* 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 <algorithm>
#include <cassert>
@@ -17,30 +18,6 @@
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)
{
static auto const pred = [](CXXBaseSpecifier const& spec) {
@@ -130,7 +107,7 @@ public:
{
return true;
}
- if (hasCLanguageLinkageType(decl)
+ if (loplugin::hasCLanguageLinkageType(decl)
&& loplugin::DeclCheck(decl).Function("_DllMainCRTStartup").GlobalNamespace())
{
return true;
@@ -150,7 +127,7 @@ public:
return true;
}
auto const canon = decl->getCanonicalDecl();
- if (hasCLanguageLinkageType(canon)
+ if (loplugin::hasCLanguageLinkageType(canon)
&& (canon->hasAttr<ConstructorAttr>() || canon->hasAttr<DestructorAttr>()))
{
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: */
diff --git a/compilerplugins/clang/faileddyncast.cxx b/compilerplugins/clang/faileddyncast.cxx
index ef52b09a185d..03d4feb48550 100644
--- a/compilerplugins/clang/faileddyncast.cxx
+++ b/compilerplugins/clang/faileddyncast.cxx
@@ -6,6 +6,7 @@
* 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 <algorithm>
@@ -98,13 +99,18 @@ public:
bool shouldVisitTemplateInstantiations() const { return true; }
+ bool preRun() override;
void run() override;
bool VisitCXXDynamicCastExpr(CXXDynamicCastExpr const * expr);
};
+bool FailedDynCast::preRun() {
+ return compiler.getLangOpts().CPlusPlus;
+}
+
void FailedDynCast::run() {
- if (compiler.getLangOpts().CPlusPlus) {
+ if (preRun()) {
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
}
@@ -123,8 +129,10 @@ bool FailedDynCast::VisitCXXDynamicCastExpr(CXXDynamicCastExpr const * expr) {
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: */
diff --git a/compilerplugins/clang/finalprotected.cxx b/compilerplugins/clang/finalprotected.cxx
index e35f573fb979..41b994c049d5 100644
--- a/compilerplugins/clang/finalprotected.cxx
+++ b/compilerplugins/clang/finalprotected.cxx
@@ -6,6 +6,7 @@
* 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 <string>
#include <iostream>
@@ -74,8 +75,10 @@ bool FinalProtected::VisitFieldDecl(FieldDecl const * fieldDecl)
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: */
diff --git a/compilerplugins/clang/indentation.cxx b/compilerplugins/clang/indentation.cxx
index deac18121443..b544138f9f5d 100644
--- a/compilerplugins/clang/indentation.cxx
+++ b/compilerplugins/clang/indentation.cxx
@@ -8,6 +8,7 @@
* License. See LICENSE.TXT for details.
*
*/
+#ifndef LO_CLANG_SHARED_PLUGINS
#include <cassert>
#include <string>
@@ -33,43 +34,58 @@ public:
{
}
- virtual void run() override
+ virtual bool preRun() override
{
std::string fn(handler.getMainFileName());
loplugin::normalizeDotDotInFilePath(fn);
// include another file to build a table
if (fn == SRCDIR "/sc/source/core/tool/cellkeytranslator.cxx")
- return;
+ return false;
// weird structure
if (fn == SRCDIR "/sc/source/core/tool/compiler.cxx")
- return;
+ return false;
// looks like lex/yacc output
if (fn == SRCDIR "/hwpfilter/source/grammar.cxx")
- return;
+ return false;
// TODO need to learn to handle attributes like "[[maybe_unused]]"
if (fn == SRCDIR "/binaryurp/source/bridge.cxx")
- return;
+ return false;
// the QEMIT macros
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/vcl/qt5/")
|| loplugin::isSamePathname(fn, SRCDIR "/vcl/unx/gtk3_kde5/kde5_filepicker_ipc.cxx"))
- return;
- TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+ return false;
+ return true;
+ }
+
+ virtual void run() override
+ {
+ if (preRun())
+ TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
bool VisitCompoundStmt(CompoundStmt const*);
+ bool PreTraverseSwitchStmt(SwitchStmt*);
+ void PostTraverseSwitchStmt(SwitchStmt*);
bool TraverseSwitchStmt(SwitchStmt*);
bool VisitSwitchStmt(SwitchStmt const*);
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)
{
- auto prev = switchStmtBody;
- switchStmtBody = switchStmt->getBody();
+ PreTraverseSwitchStmt(switchStmt);
FilteringPlugin::TraverseSwitchStmt(switchStmt);
- switchStmtBody = prev;
+ PostTraverseSwitchStmt(switchStmt);
return true;
}
@@ -78,7 +94,7 @@ bool Indentation::VisitCompoundStmt(CompoundStmt const* compoundStmt)
if (ignoreLocation(compoundStmt))
return true;
// these are kind of free form
- if (switchStmtBody == compoundStmt)
+ if (!switchStmtBodies.empty() && switchStmtBodies.back() == compoundStmt)
return true;
constexpr unsigned MAX = std::numeric_limits<unsigned>::max();
@@ -233,8 +249,10 @@ bool Indentation::VisitSwitchStmt(SwitchStmt const* switchStmt)
return true;
}
-loplugin::Plugin::Registration<Indentation> X("indentation");
+loplugin::Plugin::Registration<Indentation> indentation("indentation");
} // namespace
+#endif // LO_CLANG_SHARED_PLUGINS
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/inlinevisible.cxx b/compilerplugins/clang/inlinevisible.cxx
index 8e232a337837..eb3e249f5835 100644
--- a/compilerplugins/clang/inlinevisible.cxx
+++ b/compilerplugins/clang/inlinevisible.cxx
@@ -6,7 +6,6 @@
* 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 <cassert>
diff --git a/compilerplugins/clang/intvsfloat.cxx b/compilerplugins/clang/intvsfloat.cxx
index e9ee3fa9b306..922d14db2b1c 100644
--- a/compilerplugins/clang/intvsfloat.cxx
+++ b/compilerplugins/clang/intvsfloat.cxx
@@ -6,6 +6,7 @@
* 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 "plugin.hxx"
#include "check.hxx"
@@ -103,7 +104,10 @@ llvm::Optional<double> IntVsFloat::getExprValue(Expr const* expr)
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: */
diff --git a/compilerplugins/clang/literaltoboolconversion.cxx b/compilerplugins/clang/literaltoboolconversion.cxx
index 32e820502f39..9e9b0b391523 100644
--- a/compilerplugins/clang/literaltoboolconversion.cxx
+++ b/compilerplugins/clang/literaltoboolconversion.cxx
@@ -6,6 +6,7 @@
* 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 <cassert>
#include <limits>
@@ -29,6 +30,8 @@ public:
bool VisitImplicitCastExpr(ImplicitCastExpr const * expr);
+ bool PreTraverseLinkageSpecDecl(LinkageSpecDecl * decl);
+ void PostTraverseLinkageSpecDecl(LinkageSpecDecl * decl);
bool TraverseLinkageSpecDecl(LinkageSpecDecl * decl);
private:
@@ -55,12 +58,21 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr(
return true;
}
-bool LiteralToBoolConversion::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) {
+bool LiteralToBoolConversion::PreTraverseLinkageSpecDecl(LinkageSpecDecl *) {
assert(externCContexts_ != std::numeric_limits<unsigned int>::max()); //TODO
++externCContexts_;
- bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl(decl);
+ return true;
+}
+
+void LiteralToBoolConversion::PostTraverseLinkageSpecDecl(LinkageSpecDecl *) {
assert(externCContexts_ != 0);
--externCContexts_;
+}
+
+bool LiteralToBoolConversion::TraverseLinkageSpecDecl(LinkageSpecDecl * decl) {
+ PreTraverseLinkageSpecDecl(decl);
+ bool ret = RecursiveASTVisitor::TraverseLinkageSpecDecl(decl);
+ PostTraverseLinkageSpecDecl(decl);
return ret;
}
@@ -210,7 +222,8 @@ void LiteralToBoolConversion::handleImplicitCastSubExpr(
}
}
-loplugin::Plugin::Registration<LiteralToBoolConversion> X(
- "literaltoboolconversion", true);
+loplugin::Plugin::Registration<LiteralToBoolConversion> literaltoboolconversion("literaltoboolconversion");
-}
+} // namespace
+
+#endif // LO_CLANG_SHARED_PLUGINS
diff --git a/compilerplugins/clang/logexceptionnicely.cxx b/compilerplugins/clang/logexceptionnicely.cxx
index b6f7ef8bb31d..8c272b6d7556 100644
--- a/compilerplugins/clang/logexceptionnicely.cxx
+++ b/compilerplugins/clang/logexceptionnicely.cxx
@@ -8,6 +8,7 @@
* License. See LICENSE.TXT for details.
*
*/
+#ifndef LO_CLANG_SHARED_PLUGINS
#include "plugin.hxx"
#include "check.hxx"
@@ -32,24 +33,30 @@ public:
{
}
- void run()
+ 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;
+ return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/ucbhelper/"))
- return;
+ return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/binaryurp/"))
- return;
+ return false;
if (loplugin::hasPathnamePrefix(fn, SRCDIR "/comphelper/"))
- return;
+ return false;
// can't do that here, don't have an Any
if (loplugin::hasPathnamePrefix(fn, SRCDIR
"/connectivity/source/drivers/hsqldb/HStorageMap.cxx"))
- return;
- TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+ return false;
+ return true;
+ }
+
+ void run()
+ {
+ if (preRun())
+ TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
static bool BaseCheckNotExceptionSubclass(const CXXRecordDecl* BaseDefinition)
@@ -129,8 +136,10 @@ public:
}
};
-static Plugin::Registration<LogExceptionNicely> X("logexceptionnicely");
+static Plugin::Registration<LogExceptionNicely> logexceptionnicely("logexceptionnicely");
} // namespace
+#endif // LO_CLANG_SHARED_PLUGINS
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/nestedunnamed.cxx b/compilerplugins/clang/nestedunnamed.cxx
index 4c8923eb402c..adc4f81a8130 100644
--- a/compilerplugins/clang/nestedunnamed.cxx
+++ b/compilerplugins/clang/nestedunnamed.cxx
@@ -6,6 +6,7 @@
* 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 <cassert>
@@ -25,9 +26,11 @@ public:
{
}
+ bool preRun() override { return compiler.getLangOpts().CPlusPlus; }
+
void run() override
{
- if (compiler.getLangOpts().CPlusPlus)
+ if (preRun())
{
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: */
diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx
index 1a1ca44a91ab..7e8dfb664b15 100644
--- a/compilerplugins/clang/plugin.cxx
+++ b/compilerplugins/clang/plugin.cxx
@@ -686,6 +686,17 @@ bool isSamePathname(StringRef pathname, StringRef other)
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
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/plugin.hxx b/compilerplugins/clang/plugin.hxx
index 984bd11cd315..12ae6f7ba7c2 100644
--- a/compilerplugins/clang/plugin.hxx
+++ b/compilerplugins/clang/plugin.hxx
@@ -271,6 +271,18 @@ bool hasPathnamePrefix(StringRef pathname, StringRef prefix);
// also contain backslashes:
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
#endif // COMPILEPLUGIN_H
diff --git a/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx b/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx
index f2b6906541fe..33db9d878021 100644
--- a/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx
+++ b/compilerplugins/clang/sharedvisitor/sharedvisitor.cxx
@@ -14,16 +14,26 @@
#include "../badstatics.cxx"
#include "../blockblock.cxx"
#include "../charrightshift.cxx"
+#include "../data.cxx"
#include "../datamembershadow.cxx"
#include "../dbgunhandledexception.cxx"
#include "../derefnullptr.cxx"
+#include "../dllprivate.cxx"
#include "../doubleconvert.cxx"
+#include "../dynexcspec.cxx"
#include "../empty.cxx"
#include "../emptyif.cxx"
#include "../externandnotdefined.cxx"
#include "../externvar.cxx"
+#include "../external.cxx"
+#include "../finalprotected.cxx"
+#include "../indentation.cxx"
#include "../inlinevisible.cxx"
+#include "../intvsfloat.cxx"
+#include "../literaltoboolconversion.cxx"
+#include "../logexceptionnicely.cxx"
#include "../loopvartoosmall.cxx"
+#include "../nestedunnamed.cxx"
#include "../overrideparam.cxx"
#include "../overridevirtual.cxx"
#include "../passparamsbyref.cxx"
@@ -55,6 +65,7 @@
#include "../weakbase.cxx"
#include "../weakobject.cxx"
#include "../dyncastvisibility.cxx"
+#include "../faileddyncast.cxx"
#include "../ptrvector.cxx"
#include "../vclwidgets.cxx"
@@ -73,16 +84,26 @@ public:
, badStatics( nullptr )
, blockBlock( nullptr )
, charRightShift( nullptr )
+ , data( nullptr )
, dataMemberShadow( nullptr )
, dbgUnhandledException( nullptr )
, derefNullPtr( nullptr )
+ , dllPrivate( nullptr )
, doubleConvert( nullptr )
+ , dynExcSpec( nullptr )
, empty( nullptr )
, emptyIf( nullptr )
, externAndNotDefined( nullptr )
, externVar( nullptr )
+ , external( nullptr )
+ , finalProtected( nullptr )
+ , indentation( nullptr )
, inlineVisible( nullptr )
+ , intVsFloat( nullptr )
+ , literalToBoolConversion( nullptr )
+ , logExceptionNicely( nullptr )
, loopVarTooSmall( nullptr )
+ , nestedUnnamed( nullptr )
, overrideParam( nullptr )
, overrideVirtual( nullptr )
, passParamsByRef( nullptr )
@@ -122,14 +143,20 @@ public:
blockBlock = nullptr;
if( charRightShift && !charRightShift->preRun())
charRightShift = nullptr;
+ if( data && !data->preRun())
+ data = nullptr;
if( dataMemberShadow && !dataMemberShadow->preRun())
dataMemberShadow = nullptr;
if( dbgUnhandledException && !dbgUnhandledException->preRun())
dbgUnhandledException = nullptr;
if( derefNullPtr && !derefNullPtr->preRun())
derefNullPtr = nullptr;
+ if( dllPrivate && !dllPrivate->preRun())
+ dllPrivate = nullptr;
if( doubleConvert && !doubleConvert->preRun())
doubleConvert = nullptr;
+ if( dynExcSpec && !dynExcSpec->preRun())
+ dynExcSpec = nullptr;
if( empty && !empty->preRun())
empty = nullptr;
if( emptyIf && !emptyIf->preRun())
@@ -138,10 +165,24 @@ public:
externAndNotDefined = nullptr;
if( externVar && !externVar->preRun())
externVar = nullptr;
+ if( external && !external->preRun())
+ external = nullptr;
+ if( finalProtected && !finalProtected->preRun())
+ finalProtected = nullptr;
+ if( indentation && !indentation->preRun())
+ indentation = nullptr;
if( inlineVisible && !inlineVisible->preRun())
inlineVisible = nullptr;
+ if( intVsFloat && !intVsFloat->preRun())
+ intVsFloat = nullptr;
+ if( literalToBoolConversion && !literalToBoolConversion->preRun())
+ literalToBoolConversion = nullptr;
+ if( logExceptionNicely && !logExceptionNicely->preRun())
+ logExceptionNicely = nullptr;
if( loopVarTooSmall && !loopVarTooSmall->preRun())
loopVarTooSmall = nullptr;
+ if( nestedUnnamed && !nestedUnnamed->preRun())
+ nestedUnnamed = nullptr;
if( overrideParam && !overrideParam->preRun())
overrideParam = nullptr;
if( overrideVirtual && !overrideVirtual->preRun())
@@ -212,14 +253,20 @@ public:
blockBlock->postRun();
if( charRightShift )
charRightShift->postRun();
+ if( data )
+ data->postRun();
if( dataMemberShadow )
dataMemberShadow->postRun();
if( dbgUnhandledException )
dbgUnhandledException->postRun();
if( derefNullPtr )
derefNullPtr->postRun();
+ if( dllPrivate )
+ dllPrivate->postRun();
if( doubleConvert )
doubleConvert->postRun();
+ if( dynExcSpec )
+ dynExcSpec->postRun();
if( empty )
empty->postRun();
if( emptyIf )
@@ -228,10 +275,24 @@ public:
externAndNotDefined->postRun();
if( externVar )
externVar->postRun();
+ if( external )
+ external->postRun();
+ if( finalProtected )
+ finalProtected->postRun();
+ if( indentation )
+ indentation->postRun();
if( inlineVisible )
inlineVisible->postRun();
+ if( intVsFloat )
+ intVsFloat->postRun();
+ if( literalToBoolConversion )
+ literalToBoolConversion->postRun();
+ if( logExceptionNicely )
+ logExceptionNicely->postRun();
if( loopVarTooSmall )
loopVarTooSmall->postRun();
+ if( nestedUnnamed )
+ nestedUnnamed->postRun();
if( overrideParam )
overrideParam->postRun();
if( overrideVirtual )
@@ -308,14 +369,20 @@ public:
blockBlock = static_cast< BlockBlock* >( plugin );
else if( strcmp( name, "charrightshift" ) == 0 )
charRightShift = static_cast< CharRightShift* >( plugin );
+ else if( strcmp( name, "data" ) == 0 )
+ data = static_cast< Data* >( plugin );
else if( strcmp( name, "datamembershadow" ) == 0 )
dataMemberShadow = static_cast< DataMemberShadow* >( plugin );
else if( strcmp( name, "dbgunhandledexception" ) == 0 )
dbgUnhandledException = static_cast< DbgUnhandledException* >( plugin );
else if( strcmp( name, "derefnullptr" ) == 0 )
derefNullPtr = static_cast< DerefNullPtr* >( plugin );
+ else if( strcmp( name, "dllprivate" ) == 0 )
+ dllPrivate = static_cast< DllPrivate* >( plugin );
else if( strcmp( name, "doubleconvert" ) == 0 )
doubleConvert = static_cast< DoubleConvert* >( plugin );
+ else if( strcmp( name, "dynexcspec" ) == 0 )
+ dynExcSpec = static_cast< DynExcSpec* >( plugin );
else if( strcmp( name, "empty" ) == 0 )
empty = static_cast< Empty* >( plugin );
else if( strcmp( name, "emptyif" ) == 0 )
@@ -324,10 +391,24 @@ public:
externAndNotDefined = static_cast< ExternAndNotDefined* >( plugin );
else if( strcmp( name, "externvar" ) == 0 )
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 )
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 )
loopVarTooSmall = static_cast< LoopVarTooSmall* >( plugin );
+ else if( strcmp( name, "nestedunnamed" ) == 0 )
+ nestedUnnamed = static_cast< NestedUnnamed* >( plugin );
else if( strcmp( name, "overrideparam" ) == 0 )
overrideParam = static_cast< OverrideParam* >( plugin );
else if( strcmp( name, "overridevirtual" ) == 0 )
@@ -412,6 +493,11 @@ public:
if( !empty->VisitBinEQ( arg ))
empty = nullptr;
}
+ if( intVsFloat != nullptr )
+ {
+ if( !intVsFloat->VisitBinEQ( arg ))
+ intVsFloat = nullptr;
+ }
return anyPluginActive();
}
bool VisitBinGE(const class clang::BinaryOperator * arg)
@@ -571,6 +657,11 @@ public:
{
if( ignoreLocation( arg ))
return true;
+ if( finalProtected != nullptr )
+ {
+ if( !finalProtected->VisitCXXMethodDecl( arg ))
+ finalProtected = nullptr;
+ }
if( overrideParam != nullptr )
{
if( !overrideParam->VisitCXXMethodDecl( arg ))
@@ -613,6 +704,11 @@ public:
{
if( ignoreLocation( arg ))
return true;
+ if( logExceptionNicely != nullptr )
+ {
+ if( !logExceptionNicely->VisitCXXOperatorCallExpr( arg ))
+ logExceptionNicely = nullptr;
+ }
if( passParamsByRef != nullptr )
{
if( !passParamsByRef->VisitCXXOperatorCallExpr( arg ))
@@ -725,6 +821,17 @@ public:
}
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)
{
if( ignoreLocation( arg ))
@@ -734,6 +841,11 @@ public:
if( !blockBlock->VisitCompoundStmt( arg ))
blockBlock = nullptr;
}
+ if( indentation != nullptr )
+ {
+ if( !indentation->VisitCompoundStmt( arg ))
+ indentation = nullptr;
+ }
return anyPluginActive();
}
bool VisitConditionalOperator(const class clang::ConditionalOperator * arg)
@@ -772,6 +884,11 @@ public:
if( !dataMemberShadow->VisitFieldDecl( arg ))
dataMemberShadow = nullptr;
}
+ if( finalProtected != nullptr )
+ {
+ if( !finalProtected->VisitFieldDecl( arg ))
+ finalProtected = nullptr;
+ }
return anyPluginActive();
}
bool VisitForStmt(const class clang::ForStmt * arg)
@@ -794,11 +911,21 @@ public:
{
if( ignoreLocation( arg ))
return true;
+ if( dynExcSpec != nullptr )
+ {
+ if( !dynExcSpec->VisitFunctionDecl( arg ))
+ dynExcSpec = nullptr;
+ }
if( externAndNotDefined != nullptr )
{
if( !externAndNotDefined->VisitFunctionDecl( arg ))
externAndNotDefined = nullptr;
}
+ if( external != nullptr )
+ {
+ if( !external->VisitFunctionDecl( arg ))
+ external = nullptr;
+ }
if( inlineVisible != nullptr )
{
if( !inlineVisible->VisitFunctionDecl( arg ))
@@ -836,6 +963,17 @@ public:
}
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)
{
if( ignoreLocation( arg ))
@@ -856,6 +994,11 @@ public:
{
if( ignoreLocation( arg ))
return true;
+ if( literalToBoolConversion != nullptr )
+ {
+ if( !literalToBoolConversion->VisitImplicitCastExpr( arg ))
+ literalToBoolConversion = nullptr;
+ }
if( unicodeToChar != nullptr )
{
if( !unicodeToChar->VisitImplicitCastExpr( arg ))
@@ -899,6 +1042,11 @@ public:
{
if( ignoreLocation( arg ))
return true;
+ if( dllPrivate != nullptr )
+ {
+ if( !dllPrivate->VisitNamedDecl( arg ))
+ dllPrivate = nullptr;
+ }
if( reservedId != nullptr )
{
if( !reservedId->VisitNamedDecl( arg ))
@@ -906,6 +1054,17 @@ public:
}
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)
{
if( ignoreLocation( arg ))
@@ -942,6 +1101,11 @@ public:
{
if( ignoreLocation( arg ))
return true;
+ if( indentation != nullptr )
+ {
+ if( !indentation->VisitSwitchStmt( arg ))
+ indentation = nullptr;
+ }
if( unnecessaryParen != nullptr )
{
if( !unnecessaryParen->VisitSwitchStmt( arg ))
@@ -949,6 +1113,17 @@ public:
}
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)
{
if( ignoreLocation( arg ))
@@ -975,6 +1150,11 @@ public:
{
if( ignoreLocation( arg ))
return true;
+ if( data != nullptr )
+ {
+ if( !data->VisitUnaryOperator( arg ))
+ data = nullptr;
+ }
if( redundantPointerOps != nullptr )
{
if( !redundantPointerOps->VisitUnaryOperator( arg ))
@@ -996,6 +1176,16 @@ public:
if( !externVar->VisitVarDecl( arg ))
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->VisitVarDecl( arg ))
@@ -1018,6 +1208,17 @@ public:
}
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)
{
if( ignoreLocation( arg ))
@@ -1166,6 +1367,22 @@ public:
simplifyConstruct = saveSimplifyConstruct;
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)
{
SimplifyConstruct* saveSimplifyConstruct = simplifyConstruct;
@@ -1178,22 +1395,48 @@ public:
simplifyConstruct = saveSimplifyConstruct;
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:
bool anyPluginActive() const
{
return badStatics != nullptr
|| blockBlock != nullptr
|| charRightShift != nullptr
+ || data != nullptr
|| dataMemberShadow != nullptr
|| dbgUnhandledException != nullptr
|| derefNullPtr != nullptr
+ || dllPrivate != nullptr
|| doubleConvert != nullptr
+ || dynExcSpec != nullptr
|| empty != nullptr
|| emptyIf != nullptr
|| externAndNotDefined != nullptr
|| externVar != nullptr
+ || external != nullptr
+ || finalProtected != nullptr
+ || indentation != nullptr
|| inlineVisible != nullptr
+ || intVsFloat != nullptr
+ || literalToBoolConversion != nullptr
+ || logExceptionNicely != nullptr
|| loopVarTooSmall != nullptr
+ || nestedUnnamed != nullptr
|| overrideParam != nullptr
|| overrideVirtual != nullptr
|| passParamsByRef != nullptr
@@ -1228,16 +1471,26 @@ private:
BadStatics* badStatics;
BlockBlock* blockBlock;
CharRightShift* charRightShift;
+ Data* data;
DataMemberShadow* dataMemberShadow;
DbgUnhandledException* dbgUnhandledException;
DerefNullPtr* derefNullPtr;
+ DllPrivate* dllPrivate;
DoubleConvert* doubleConvert;
+ DynExcSpec* dynExcSpec;
Empty* empty;
EmptyIf* emptyIf;
ExternAndNotDefined* externAndNotDefined;
ExternVar* externVar;
+ External* external;
+ FinalProtected* finalProtected;
+ Indentation* indentation;
InlineVisible* inlineVisible;
+ IntVsFloat* intVsFloat;
+ LiteralToBoolConversion* literalToBoolConversion;
+ LogExceptionNicely* logExceptionNicely;
LoopVarTooSmall* loopVarTooSmall;
+ NestedUnnamed* nestedUnnamed;
OverrideParam* overrideParam;
OverrideVirtual* overrideVirtual;
PassParamsByRef* passParamsByRef;
@@ -1280,6 +1533,7 @@ public:
explicit SharedRecursiveASTVisitorVisitTemplates(const InstantiationData& rData)
: FilteringPlugin(rData)
, dynCastVisibility( nullptr )
+ , failedDynCast( nullptr )
, ptrVector( nullptr )
, vCLWidgets( nullptr )
{}
@@ -1287,6 +1541,8 @@ public:
{
if( dynCastVisibility && !dynCastVisibility->preRun())
dynCastVisibility = nullptr;
+ if( failedDynCast && !failedDynCast->preRun())
+ failedDynCast = nullptr;
if( ptrVector && !ptrVector->preRun())
ptrVector = nullptr;
if( vCLWidgets && !vCLWidgets->preRun())
@@ -1297,6 +1553,8 @@ public:
{
if( dynCastVisibility )
dynCastVisibility->postRun();
+ if( failedDynCast )
+ failedDynCast->postRun();
if( ptrVector )
ptrVector->postRun();
if( vCLWidgets )
@@ -1313,6 +1571,8 @@ public:
{
if( strcmp( name, "dyncastvisibility" ) == 0 )
dynCastVisibility = static_cast< DynCastVisibility* >( plugin );
+ else if( strcmp( name, "faileddyncast" ) == 0 )
+ failedDynCast = static_cast< FailedDynCast* >( plugin );
else if( strcmp( name, "ptrvector" ) == 0 )
ptrVector = static_cast< PtrVector* >( plugin );
else if( strcmp( name, "vclwidgets" ) == 0 )
@@ -1375,6 +1635,11 @@ bool shouldVisitTemplateInstantiations() const { return true; }
if( !dynCastVisibility->VisitCXXDynamicCastExpr( arg ))
dynCastVisibility = nullptr;
}
+ if( failedDynCast != nullptr )
+ {
+ if( !failedDynCast->VisitCXXDynamicCastExpr( arg ))
+ failedDynCast = nullptr;
+ }
return anyPluginActive();
}
bool VisitCXXOperatorCallExpr(const class clang::CXXOperatorCallExpr * arg)
@@ -1458,10 +1723,12 @@ private:
bool anyPluginActive() const
{
return dynCastVisibility != nullptr
+ || failedDynCast != nullptr
|| ptrVector != nullptr
|| vCLWidgets != nullptr;
}
DynCastVisibility* dynCastVisibility;
+ FailedDynCast* failedDynCast;
PtrVector* ptrVector;
VCLWidgets* vCLWidgets;
};
diff --git a/compilerplugins/clang/unreffun.cxx b/compilerplugins/clang/unreffun.cxx
index 3321037c8580..ab0e01b70ecb 100644
--- a/compilerplugins/clang/unreffun.cxx
+++ b/compilerplugins/clang/unreffun.cxx
@@ -20,27 +20,6 @@
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) {
return decl->getFriendObjectKind() != Decl::FOK_None;
}
@@ -173,7 +152,7 @@ bool UnrefFun::VisitFunctionDecl(FunctionDecl const * decl) {
}
LinkageInfo info(canon->getLinkageAndVisibility());
if (info.getLinkage() == ExternalLinkage
- && hasCLanguageLinkageType(canon) && canon->isDefined()
+ && loplugin::hasCLanguageLinkageType(canon) && canon->isDefined()
&& ((decl == canon && info.getVisibility() == DefaultVisibility)
|| ((canon->hasAttr<ConstructorAttr>()
|| canon->hasAttr<DestructorAttr>())