summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-06-28 18:54:31 +0200
committerCaolán McNamara <caolanm@redhat.com>2016-06-30 08:19:55 +0000
commit39f64074d34116d9aa647fa637d982b27fef8ae4 (patch)
treeaf866c3a1ed3315e2416e1833590793a091c8481 /compilerplugins
parentbe9cd27b83c573bb143bd2778d6c63828e59aa3e (diff)
More Clang 3.4 "(anonymous namespace)" fixes
Reviewed-on: https://gerrit.libreoffice.org/26748 Reviewed-by: Stephan Bergmann <sbergman@redhat.com> Tested-by: Stephan Bergmann <sbergman@redhat.com> (cherry picked from commit 0d3738a2580d72b778547bfcdf691fdeb0eccbdd) Conflicts: compilerplugins/clang/refcounting.cxx compilerplugins/clang/weakobject.cxx Change-Id: I7cb43f915565dadd611b90ee30373e472f97efb5 Reviewed-on: https://gerrit.libreoffice.org/26779 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/badstatics.cxx2
-rw-r--r--compilerplugins/clang/check.cxx (renamed from compilerplugins/clang/typecheck.cxx)20
-rw-r--r--compilerplugins/clang/check.hxx (renamed from compilerplugins/clang/typecheck.hxx)117
-rw-r--r--compilerplugins/clang/fpcomparison.cxx54
-rw-r--r--compilerplugins/clang/getimplementationname.cxx2
-rw-r--r--compilerplugins/clang/implicitboolconversion.cxx1
-rw-r--r--compilerplugins/clang/passstuffbyref.cxx27
-rw-r--r--compilerplugins/clang/refcounting.cxx9
-rw-r--r--compilerplugins/clang/salbool.cxx1
-rw-r--r--compilerplugins/clang/staticmethods.cxx2
-rw-r--r--compilerplugins/clang/stringconstant.cxx2
11 files changed, 161 insertions, 76 deletions
diff --git a/compilerplugins/clang/badstatics.cxx b/compilerplugins/clang/badstatics.cxx
index aa5024180a91..f316b4d47b88 100644
--- a/compilerplugins/clang/badstatics.cxx
+++ b/compilerplugins/clang/badstatics.cxx
@@ -7,8 +7,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include "check.hxx"
#include "plugin.hxx"
-#include "typecheck.hxx"
namespace {
diff --git a/compilerplugins/clang/typecheck.cxx b/compilerplugins/clang/check.cxx
index dcfc6db4f01c..26a48c2a6bef 100644
--- a/compilerplugins/clang/typecheck.cxx
+++ b/compilerplugins/clang/check.cxx
@@ -7,8 +7,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include <cassert>
+
+#include "check.hxx"
#include "compat.hxx"
-#include "typecheck.hxx"
namespace loplugin {
@@ -46,7 +48,15 @@ TypeCheck TypeCheck::NotSubstTemplateTypeParmType() const {
? *this : TypeCheck();
}
-TerminalCheck NamespaceCheck::GlobalNamespace() const {
+ContextCheck DeclCheck::Operator(clang::OverloadedOperatorKind op) const {
+ assert(op != clang::OO_None);
+ auto f = llvm::dyn_cast_or_null<clang::FunctionDecl>(decl_);
+ return ContextCheck(
+ f != nullptr && f->getOverloadedOperator() == op
+ ? f->getDeclContext() : nullptr);
+}
+
+TerminalCheck ContextCheck::GlobalNamespace() const {
return TerminalCheck(
context_ != nullptr
&& ((compat::isLookupContext(*context_)
@@ -54,14 +64,14 @@ TerminalCheck NamespaceCheck::GlobalNamespace() const {
->isTranslationUnit()));
}
-TerminalCheck NamespaceCheck::StdNamespace() const {
+TerminalCheck ContextCheck::StdNamespace() const {
return TerminalCheck(
context_ != nullptr && compat::isStdNamespace(*context_));
}
-NamespaceCheck NamespaceCheck::AnonymousNamespace() const {
+ContextCheck ContextCheck::AnonymousNamespace() const {
auto n = llvm::dyn_cast_or_null<clang::NamespaceDecl>(context_);
- return NamespaceCheck(
+ return ContextCheck(
n != nullptr && n->isAnonymousNamespace() ? n->getParent() : nullptr);
}
diff --git a/compilerplugins/clang/typecheck.hxx b/compilerplugins/clang/check.hxx
index 02c6382303bc..999a3185d73f 100644
--- a/compilerplugins/clang/typecheck.hxx
+++ b/compilerplugins/clang/check.hxx
@@ -7,23 +7,24 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#ifndef INCLUDED_COMPILERPLUGINS_CLANG_TYPECHECK_HXX
-#define INCLUDED_COMPILERPLUGINS_CLANG_TYPECHECK_HXX
+#ifndef INCLUDED_COMPILERPLUGINS_CLANG_CHECK_HXX
+#define INCLUDED_COMPILERPLUGINS_CLANG_CHECK_HXX
#include <cstddef>
#include <clang/AST/DeclBase.h>
#include <clang/AST/Decl.h>
#include <clang/AST/Type.h>
+#include <clang/Basic/OperatorKinds.h>
namespace loplugin {
-class NamespaceCheck;
+class ContextCheck;
class TerminalCheck;
namespace detail {
-template<std::size_t N> NamespaceCheck checkRecordDecl(
+template<std::size_t N> ContextCheck checkRecordDecl(
clang::Decl const * decl, clang::TagTypeKind tag, char const (& id)[N]);
}
@@ -40,7 +41,7 @@ public:
TypeCheck LvalueReference() const;
- template<std::size_t N> inline NamespaceCheck Class(char const (& id)[N])
+ template<std::size_t N> inline ContextCheck Class(char const (& id)[N])
const;
TypeCheck NotSubstTemplateTypeParmType() const;
@@ -51,50 +52,65 @@ private:
clang::QualType const type_;
};
-class NamespaceCheck {
+class DeclCheck {
+public:
+ explicit DeclCheck(clang::Decl const * decl): decl_(decl) {}
+
+ explicit operator bool() const { return decl_ != nullptr; }
+
+ template<std::size_t N> inline ContextCheck Class(char const (& id)[N])
+ const;
+
+ template<std::size_t N> inline ContextCheck Struct(char const (& id)[N])
+ const;
+
+ template<std::size_t N> inline ContextCheck Function(char const (& id)[N])
+ const;
+
+ ContextCheck Operator(clang::OverloadedOperatorKind op) const;
+
+private:
+ clang::Decl const * const decl_;
+};
+
+class ContextCheck {
public:
explicit operator bool() const { return context_ != nullptr; }
TerminalCheck GlobalNamespace() const;
- template<std::size_t N> inline NamespaceCheck Namespace(
+ template<std::size_t N> inline ContextCheck Namespace(
char const (& id)[N]) const;
TerminalCheck StdNamespace() const;
- NamespaceCheck AnonymousNamespace() const;
+ ContextCheck AnonymousNamespace() const;
+
+ template<std::size_t N> inline ContextCheck Class(char const (& id)[N])
+ const;
+
+ template<std::size_t N> inline ContextCheck Struct(char const (& id)[N])
+ const;
private:
+ friend DeclCheck;
friend TypeCheck;
- template<std::size_t N> friend NamespaceCheck detail::checkRecordDecl(
+ template<std::size_t N> friend ContextCheck detail::checkRecordDecl(
clang::Decl const * decl, clang::TagTypeKind tag, char const (& id)[N]);
- explicit NamespaceCheck(clang::DeclContext const * context = nullptr):
+ explicit ContextCheck(clang::DeclContext const * context = nullptr):
context_(context) {}
clang::DeclContext const * const context_;
};
-class DeclCheck {
-public:
- explicit DeclCheck(clang::Decl const * decl): decl_(decl) {}
-
- explicit operator bool() const { return decl_ != nullptr; }
-
- template<std::size_t N> inline NamespaceCheck Struct(char const (& id)[N])
- const;
-
-private:
- clang::Decl const * const decl_;
-};
-
class TerminalCheck {
public:
explicit operator bool() const { return satisfied_; }
private:
+ friend ContextCheck;
friend TypeCheck;
- friend NamespaceCheck;
explicit TerminalCheck(bool satisfied): satisfied_(satisfied) {}
@@ -103,22 +119,22 @@ private:
namespace detail {
-template<std::size_t N> NamespaceCheck checkRecordDecl(
+template<std::size_t N> ContextCheck checkRecordDecl(
clang::Decl const * decl, clang::TagTypeKind tag, char const (& id)[N])
{
auto r = llvm::dyn_cast_or_null<clang::RecordDecl>(decl);
if (r != nullptr && r->getTagKind() == tag) {
auto const i = r->getIdentifier();
if (i != nullptr && i->isStr(id)) {
- return NamespaceCheck(r->getDeclContext());
+ return ContextCheck(r->getDeclContext());
}
}
- return NamespaceCheck();
+ return ContextCheck();
}
}
-template<std::size_t N> NamespaceCheck TypeCheck::Class(char const (& id)[N])
+template<std::size_t N> ContextCheck TypeCheck::Class(char const (& id)[N])
const
{
if (!type_.isNull()) {
@@ -127,10 +143,35 @@ template<std::size_t N> NamespaceCheck TypeCheck::Class(char const (& id)[N])
return detail::checkRecordDecl(t->getDecl(), clang::TTK_Class, id);
}
}
- return NamespaceCheck();
+ return ContextCheck();
+}
+
+template<std::size_t N> ContextCheck DeclCheck::Class(char const (& id)[N])
+ const
+{
+ return detail::checkRecordDecl(decl_, clang::TTK_Class, id);
}
-template<std::size_t N> NamespaceCheck NamespaceCheck::Namespace(
+template<std::size_t N> ContextCheck DeclCheck::Struct(char const (& id)[N])
+ const
+{
+ return detail::checkRecordDecl(decl_, clang::TTK_Struct, id);
+}
+
+template<std::size_t N> ContextCheck DeclCheck::Function(char const (& id)[N])
+ const
+{
+ auto f = llvm::dyn_cast_or_null<clang::FunctionDecl>(decl_);
+ if (f != nullptr) {
+ auto const i = f->getIdentifier();
+ if (i != nullptr && i->isStr(id)) {
+ return ContextCheck(f->getDeclContext());
+ }
+ }
+ return ContextCheck();
+}
+
+template<std::size_t N> ContextCheck ContextCheck::Namespace(
char const (& id)[N]) const
{
if (context_) {
@@ -138,17 +179,25 @@ template<std::size_t N> NamespaceCheck NamespaceCheck::Namespace(
if (n != nullptr) {
auto const i = n->getIdentifier();
if (i != nullptr && i->isStr(id)) {
- return NamespaceCheck(n->getParent());
+ return ContextCheck(n->getParent());
}
}
}
- return NamespaceCheck();
+ return ContextCheck();
}
-template<std::size_t N> NamespaceCheck DeclCheck::Struct(char const (& id)[N])
+template<std::size_t N> ContextCheck ContextCheck::Class(char const (& id)[N])
const
{
- return detail::checkRecordDecl(decl_, clang::TTK_Struct, id);
+ return detail::checkRecordDecl(
+ llvm::dyn_cast_or_null<clang::Decl>(context_), clang::TTK_Class, id);
+}
+
+template<std::size_t N> ContextCheck ContextCheck::Struct(char const (& id)[N])
+ const
+{
+ return detail::checkRecordDecl(
+ llvm::dyn_cast_or_null<clang::Decl>(context_), clang::TTK_Struct, id);
}
}
diff --git a/compilerplugins/clang/fpcomparison.cxx b/compilerplugins/clang/fpcomparison.cxx
index 491eb80f2d77..63d69c19519d 100644
--- a/compilerplugins/clang/fpcomparison.cxx
+++ b/compilerplugins/clang/fpcomparison.cxx
@@ -12,8 +12,10 @@
#include <iostream>
#include <fstream>
#include <set>
-#include "plugin.hxx"
+
+#include "check.hxx"
#include "compat.hxx"
+#include "plugin.hxx"
/**
comparing floating point numbers using == or != is a bad idea.
@@ -40,25 +42,6 @@ private:
EState meState = EState::None;
};
-const std::set<std::string> whitelist {
- "rtl::math::approxEqual",
- "(anonymous namespace)::doubleToString",
- "(anonymous namespace)::stringToDouble",
- "rtl_math_round",
- "rtl_math_approxValue",
- "rtl_math_asinh",
- "rtl_math_acosh",
- "cppu::_equalSequence", // cppu/source/uno/eq.hxx
- "cppu::_equalData", // cppu/source/uno/eq.hxx
- "xmlscript::equalFont", // xmlscript/source/xmldlg_imexp/xmldlg_export.cxx
-
- // these might need fixing
- "basegfx::tools::getSmallestDistancePointToPolygon", // basegfx/source/polygon/b2dpolygontools.cxx
- "basegfx::tools::getSmallestDistancePointToPolyPolygon", // basegfx/source/polygon/b2dpolypolygontools.cxx
- "bridge_test::performTest", // testtools/source/bridgetest/bridgetest.cxx
- "bridge_test::equals",
- "(anonymous namespace)::lcl_getNANInsteadDBL_MIN", // chart2/source/controller/chartapiwrapper/ChartDataWrapper.cxx
-};
bool FpComparison::TraverseFunctionDecl(FunctionDecl* function)
{
bool bIgnore = ignore(function);
@@ -87,8 +70,35 @@ bool FpComparison::ignore(FunctionDecl* function)
return true;
}
// ignore known good functions
- std::string s = function->getQualifiedNameAsString();
- if (whitelist.find(s) != whitelist.end()) {
+ loplugin::DeclCheck dc(function);
+ if ((dc.Function("approxEqual").Namespace("math").Namespace("rtl")
+ .GlobalNamespace())
+ || dc.Function("doubleToString").AnonymousNamespace().GlobalNamespace()
+ || dc.Function("stringToDouble").AnonymousNamespace().GlobalNamespace()
+ || dc.Function("rtl_math_round").GlobalNamespace()
+ || dc.Function("rtl_math_approxValue").GlobalNamespace()
+ || dc.Function("rtl_math_asinh").GlobalNamespace()
+ || dc.Function("rtl_math_acosh").GlobalNamespace()
+ || dc.Function("_equalSequence").Namespace("cppu").GlobalNamespace()
+ // cppu/source/uno/eq.hxx
+ || dc.Function("_equalData").Namespace("cppu").GlobalNamespace()
+ // cppu/source/uno/eq.hxx
+ || dc.Function("equalFont").Namespace("xmlscript").GlobalNamespace()
+ // xmlscript/source/xmldlg_imexp/xmldlg_export.cxx
+ // These might need fixing:
+ || (dc.Function("getSmallestDistancePointToPolygon").Namespace("tools")
+ .Namespace("basegfx").GlobalNamespace())
+ // basegfx/source/polygon/b2dpolygontools.cxx
+ || (dc.Function("getSmallestDistancePointToPolyPolygon")
+ .Namespace("tools").Namespace("basegfx").GlobalNamespace())
+ // basegfx/source/polygon/b2dpolypolygontools.cxx
+ || dc.Function("performTest").Namespace("bridge_test").GlobalNamespace()
+ // testtools/source/bridgetest/bridgetest.cxx
+ || dc.Function("equals").Namespace("bridge_test").GlobalNamespace()
+ || (dc.Function("lcl_getNANInsteadDBL_MIN").AnonymousNamespace()
+ .GlobalNamespace()))
+ // chart2/source/controller/chartapiwrapper/ChartDataWrapper.cxx
+ {
return true;
}
// cout << "xxx " + function->getQualifiedNameAsString() << endl;
diff --git a/compilerplugins/clang/getimplementationname.cxx b/compilerplugins/clang/getimplementationname.cxx
index b8873961b5fc..6b4c7348ede2 100644
--- a/compilerplugins/clang/getimplementationname.cxx
+++ b/compilerplugins/clang/getimplementationname.cxx
@@ -20,8 +20,8 @@
#include <iostream>
#include <fstream>
#include <regex>
+#include "check.hxx"
#include "plugin.hxx"
-#include "typecheck.hxx"
#include "clang/Frontend/CompilerInstance.h"
namespace {
diff --git a/compilerplugins/clang/implicitboolconversion.cxx b/compilerplugins/clang/implicitboolconversion.cxx
index e035c90f73a1..7e112cd230d2 100644
--- a/compilerplugins/clang/implicitboolconversion.cxx
+++ b/compilerplugins/clang/implicitboolconversion.cxx
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
+#include "check.hxx"
#include "compat.hxx"
#include "plugin.hxx"
diff --git a/compilerplugins/clang/passstuffbyref.cxx b/compilerplugins/clang/passstuffbyref.cxx
index 059b1de30a02..050128e77cab 100644
--- a/compilerplugins/clang/passstuffbyref.cxx
+++ b/compilerplugins/clang/passstuffbyref.cxx
@@ -10,9 +10,9 @@
#include <string>
#include <set>
-#include "plugin.hxx"
+#include "check.hxx"
#include "compat.hxx"
-#include "typecheck.hxx"
+#include "plugin.hxx"
// Find places where various things are passed by value.
// It's not very efficient, because we generally end up copying it twice - once into the parameter and
@@ -135,22 +135,31 @@ void PassStuffByRef::checkReturnValue(const FunctionDecl * functionDecl, const C
functionDecl->getCanonicalDecl()->getNameInfo().getLoc()))) {
return;
}
+ loplugin::DeclCheck dc(functionDecl);
std::string aFunctionName = functionDecl->getQualifiedNameAsString();
// function is passed as parameter to another function
- if (aFunctionName == "GDIMetaFile::ImplColMonoFnc"
- || aFunctionName == "editeng::SvxBorderLine::darkColor"
+ if (dc.Function("ImplColMonoFnc").Class("GDIMetaFile").GlobalNamespace()
+ || (dc.Function("darkColor").Class("SvxBorderLine").Namespace("editeng")
+ .GlobalNamespace())
|| aFunctionName.compare(0, 8, "xforms::") == 0)
return;
// not sure how to exclude this yet, returns copy of one of it's params
- if (aFunctionName == "sameDistColor" || aFunctionName == "sameColor"
- || aFunctionName == "pcr::(anonymous namespace)::StringIdentity::operator()"
+ if (dc.Function("sameDistColor").GlobalNamespace()
+ || dc.Function("sameColor").GlobalNamespace()
+ || (dc.Operator(OO_Call).Struct("StringIdentity").AnonymousNamespace()
+ .Namespace("pcr").GlobalNamespace())
|| aFunctionName == "matop::COp<type-parameter-0-0, svl::SharedString>::operator()"
- || aFunctionName == "slideshow::internal::accumulate"
- || aFunctionName == "slideshow::internal::lerp")
+ || (dc.Function("accumulate").Namespace("internal")
+ .Namespace("slideshow").GlobalNamespace())
+ || (dc.Function("lerp").Namespace("internal").Namespace("slideshow")
+ .GlobalNamespace()))
return;
// depends on a define
- if (aFunctionName == "SfxObjectShell::GetSharedFileURL")
+ if (dc.Function("GetSharedFileURL").Class("SfxObjectShell")
+ .GlobalNamespace())
+ {
return;
+ }
mbInsideFunctionDecl = true;
mbFoundDisqualifier = false;
TraverseStmt(functionDecl->getBody());
diff --git a/compilerplugins/clang/refcounting.cxx b/compilerplugins/clang/refcounting.cxx
index 663fcb7a3958..cd9529018e5d 100644
--- a/compilerplugins/clang/refcounting.cxx
+++ b/compilerplugins/clang/refcounting.cxx
@@ -10,8 +10,9 @@
#include <string>
#include <iostream>
-#include "plugin.hxx"
+#include "check.hxx"
#include "compat.hxx"
+#include "plugin.hxx"
#include "clang/AST/CXXInheritance.h"
/**
@@ -105,7 +106,6 @@ bool containsXInterfaceSubclass(const QualType& qType) {
}
static std::vector<std::string> PROBABLY_GOOD_TEMPLATES = {
- "(anonymous namespace)::FindUnoInstanceHint",
"abp::OMultiInstanceAutoRegistration",
"com::sun::star::uno::Reference",
"com::sun::star::uno::WeakReference",
@@ -186,6 +186,11 @@ bool containsXInterfaceSubclass(const Type* pType0) {
if (pRecordDecl) {
const ClassTemplateSpecializationDecl* pTemplate = dyn_cast<ClassTemplateSpecializationDecl>(pRecordDecl);
if (pTemplate) {
+ if (loplugin::DeclCheck(pTemplate).Struct("FindUnoInstanceHint")
+ .AnonymousNamespace().GlobalNamespace())
+ {
+ return false;
+ }
std::string aName = pTemplate->getQualifiedNameAsString();
if (std::find(PROBABLY_GOOD_TEMPLATES.begin(), PROBABLY_GOOD_TEMPLATES.end(), aName) != PROBABLY_GOOD_TEMPLATES.end())
return false;
diff --git a/compilerplugins/clang/salbool.cxx b/compilerplugins/clang/salbool.cxx
index f70135805fa7..6ae3763f6ca4 100644
--- a/compilerplugins/clang/salbool.cxx
+++ b/compilerplugins/clang/salbool.cxx
@@ -14,6 +14,7 @@
#include "clang/AST/Attr.h"
+#include "check.hxx"
#include "compat.hxx"
#include "plugin.hxx"
diff --git a/compilerplugins/clang/staticmethods.cxx b/compilerplugins/clang/staticmethods.cxx
index 9108e0236d65..7eac313d1218 100644
--- a/compilerplugins/clang/staticmethods.cxx
+++ b/compilerplugins/clang/staticmethods.cxx
@@ -9,9 +9,9 @@
#include "clang/AST/Attr.h"
+#include "check.hxx"
#include "compat.hxx"
#include "plugin.hxx"
-#include "typecheck.hxx"
/*
Look for member functions that can be static
diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx
index 456413c6eb99..28b76ded84d3 100644
--- a/compilerplugins/clang/stringconstant.cxx
+++ b/compilerplugins/clang/stringconstant.cxx
@@ -15,9 +15,9 @@
#include <string>
#include <iostream>
+#include "check.hxx"
#include "compat.hxx"
#include "plugin.hxx"
-#include "typecheck.hxx"
// Define a "string constant" to be a constant expression either of type "array
// of N char" where each array element is a non-NUL ASCII character---except