summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-01-26 15:36:47 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-02-01 12:49:42 +0000
commit994e38e336beeacbd983faafac480afc94d3947e (patch)
treef6dd4fc3427d9051701637d2d052a9a51bb76c88 /compilerplugins
parenteb6c18dfbeb7d2ad20ba7221d156969bd754faed (diff)
loplugin: use TypeCheck instead of getQualifiedNameAsString
since the latter is rather slow Change-Id: Ib73cdb923585580777c2265b561c1808e93b2baa Reviewed-on: https://gerrit.libreoffice.org/33585 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/check.hxx2
-rw-r--r--compilerplugins/clang/cppunitassertequals.cxx5
-rw-r--r--compilerplugins/clang/rendercontext.cxx9
-rw-r--r--compilerplugins/clang/sallogareas.cxx8
-rw-r--r--compilerplugins/clang/sfxpoolitem.cxx15
-rw-r--r--compilerplugins/clang/staticmethods.cxx2
-rw-r--r--compilerplugins/clang/store/changefunctioncalls.cxx6
-rw-r--r--compilerplugins/clang/stringconcat.cxx6
-rw-r--r--compilerplugins/clang/stringconstant.cxx3
-rw-r--r--compilerplugins/clang/unusedvariablecheck.cxx27
-rw-r--r--compilerplugins/clang/weakobject.cxx22
11 files changed, 58 insertions, 47 deletions
diff --git a/compilerplugins/clang/check.hxx b/compilerplugins/clang/check.hxx
index 40f205d977fa..8c3edf773ea1 100644
--- a/compilerplugins/clang/check.hxx
+++ b/compilerplugins/clang/check.hxx
@@ -33,6 +33,8 @@ class TypeCheck {
public:
explicit TypeCheck(clang::QualType type): type_(type) {}
+ explicit TypeCheck(clang::TypeDecl const * decl): type_(decl->getTypeForDecl(), 0) {}
+
explicit operator bool() const { return !type_.isNull(); }
TypeCheck NonConstVolatile() const;
diff --git a/compilerplugins/clang/cppunitassertequals.cxx b/compilerplugins/clang/cppunitassertequals.cxx
index f14dde6300e4..e9f4c0256516 100644
--- a/compilerplugins/clang/cppunitassertequals.cxx
+++ b/compilerplugins/clang/cppunitassertequals.cxx
@@ -13,6 +13,7 @@
#include <fstream>
#include <set>
#include "plugin.hxx"
+#include "check.hxx"
/**
Check for calls to CPPUNIT_ASSERT when it should be using CPPUNIT_ASSERT_EQUALS
@@ -87,7 +88,9 @@ void CppunitAssertEquals::checkExpr(const Stmt* stmt)
return;
}
const FunctionDecl* functionDecl = callExpr->getDirectCallee()->getCanonicalDecl();
- if (!functionDecl || functionDecl->getQualifiedNameAsString().find("Asserter::failIf") == std::string::npos) {
+ if (!functionDecl ||
+ !loplugin::DeclCheck(functionDecl).Function("failIf").Namespace("Asserter").Namespace("CppUnit").GlobalNamespace())
+ {
return;
}
report(
diff --git a/compilerplugins/clang/rendercontext.cxx b/compilerplugins/clang/rendercontext.cxx
index e3d1da40ae1e..2ea4a0c3380b 100644
--- a/compilerplugins/clang/rendercontext.cxx
+++ b/compilerplugins/clang/rendercontext.cxx
@@ -11,6 +11,7 @@
#include <iostream>
#include "plugin.hxx"
+#include "check.hxx"
#include "clang/AST/CXXInheritance.h"
// Check for calls to OutputDevice methods that are not passing through RenderContext
@@ -51,15 +52,13 @@ bool RenderContext::TraverseFunctionDecl(const FunctionDecl * pFunctionDecl)
// Ignore methods inside the OutputDevice class
const CXXMethodDecl *pCXXMethodDecl = dyn_cast<CXXMethodDecl>(pFunctionDecl);
if (pCXXMethodDecl) {
- std::string aParentName = pCXXMethodDecl->getParent()->getQualifiedNameAsString();
- if (aParentName == "OutputDevice")
+ if (loplugin::TypeCheck(pCXXMethodDecl->getParent()).Class("OutputDevice").GlobalNamespace())
return true;
}
// we are only currently interested in methods where the first parameter is RenderContext
if (pFunctionDecl->getNumParams() == 0)
return true;
- string arg0 = pFunctionDecl->getParamDecl( 0 )->getType().getAsString();
- if ( arg0.find("RenderContext") != std::string::npos ) {
+ if ( loplugin::TypeCheck(pFunctionDecl->getParamDecl( 0 )->getType()).Class("RenderContext").GlobalNamespace() ) {
return true;
}
mbChecking = true;
@@ -76,7 +75,7 @@ bool RenderContext::VisitCXXMemberCallExpr(const CXXMemberCallExpr* pCXXMemberCa
return true;
}
const CXXRecordDecl *pCXXRecordDecl = pCXXMemberCallExpr->getRecordDecl();
- if (pCXXRecordDecl->getQualifiedNameAsString() != "OutputDevice") {
+ if (!loplugin::TypeCheck(pCXXRecordDecl).Class("OutputDevice").GlobalNamespace()) {
return true;
}
// ignore a handful of methods. They will most probably still be present in Window for use during processing outside of the Paint()
diff --git a/compilerplugins/clang/sallogareas.cxx b/compilerplugins/clang/sallogareas.cxx
index d54918755624..e0ccf0bde7a3 100644
--- a/compilerplugins/clang/sallogareas.cxx
+++ b/compilerplugins/clang/sallogareas.cxx
@@ -10,6 +10,7 @@
*/
#include "sallogareas.hxx"
+#include "check.hxx"
#include <clang/Lex/Lexer.h>
@@ -50,12 +51,11 @@ bool SalLogAreas::VisitCallExpr( const CallExpr* call )
return true;
if( const FunctionDecl* func = call->getDirectCallee())
{
- // Optimize, getQualifiedNameAsString() is reportedly expensive.
if( func->getNumParams() == 4 && func->getIdentifier() != NULL
&& ( func->getName() == "sal_detail_log" || func->getName() == "log" ))
{
- string qualifiedName = func->getQualifiedNameAsString();
- if( qualifiedName == "sal_detail_log" || qualifiedName == "sal::detail::log" )
+ auto tc = loplugin::DeclCheck(func);
+ if( tc.Function("sal_detail_log") || tc.Function("log").Namespace("detail").Namespace("sal").GlobalNamespace() )
{
// The SAL_DETAIL_LOG_STREAM macro expands to two calls to sal::detail::log(),
// so do not warn repeatedly about the same macro (the area->getLocStart() of all the calls
@@ -73,7 +73,7 @@ bool SalLogAreas::VisitCallExpr( const CallExpr* call )
area->getLocStart());
return true;
}
- if( inFunction->getQualifiedNameAsString() == "sal::detail::log" )
+ if( loplugin::DeclCheck(inFunction).Function("log").Namespace("detail").Namespace("sal").GlobalNamespace() )
return true; // This function only forwards to sal_detail_log, so ok.
if( call->getArg( 1 )->isNullPointerConstant( compiler.getASTContext(),
Expr::NPC_ValueDependentIsNotNull ) != Expr::NPCK_NotNull )
diff --git a/compilerplugins/clang/sfxpoolitem.cxx b/compilerplugins/clang/sfxpoolitem.cxx
index f01adf578235..b18251795486 100644
--- a/compilerplugins/clang/sfxpoolitem.cxx
+++ b/compilerplugins/clang/sfxpoolitem.cxx
@@ -12,6 +12,7 @@
#include "plugin.hxx"
#include "compat.hxx"
+#include "check.hxx"
#include "clang/AST/CXXInheritance.h"
/*
@@ -39,7 +40,7 @@ bool BaseCheckNotSfxPoolItemSubclass(
#endif
)
{
- if (BaseDefinition && BaseDefinition->getQualifiedNameAsString() == "SfxPoolItem") {
+ if (BaseDefinition && loplugin::TypeCheck(BaseDefinition).Class("SfxPoolItem").GlobalNamespace()) {
return false;
}
return true;
@@ -48,7 +49,7 @@ bool BaseCheckNotSfxPoolItemSubclass(
bool isDerivedFromSfxPoolItem(const CXXRecordDecl *decl) {
if (!decl)
return false;
- if (decl->getQualifiedNameAsString() == "SfxPoolItem")
+ if (loplugin::TypeCheck(decl).Class("SfxPoolItem").GlobalNamespace())
return true;
if (!decl->hasDefinition()) {
return false;
@@ -70,7 +71,7 @@ bool BaseCheckNotSwMsgPoolItemSubclass(
#endif
)
{
- if (BaseDefinition && BaseDefinition->getQualifiedNameAsString() == "SwMsgPoolItem") {
+ if (BaseDefinition && loplugin::TypeCheck(BaseDefinition).Class("SwMsgPoolItem")) {
return false;
}
return true;
@@ -79,7 +80,7 @@ bool BaseCheckNotSwMsgPoolItemSubclass(
bool isDerivedFromSwMsgPoolItem(const CXXRecordDecl *decl) {
if (!decl)
return false;
- if (decl->getQualifiedNameAsString() == "SwMsgPoolItem")
+ if (loplugin::TypeCheck(decl).Class("SwMsgPoolItem").GlobalNamespace())
return true;
if (!decl->hasDefinition()) {
return false;
@@ -118,12 +119,12 @@ bool SfxPoolItem::VisitCXXRecordDecl(const CXXRecordDecl* decl)
return true;
}
// the enum types do some weird stuff involving SfxEnumItemInterface
- std::string sRecordName = decl->getQualifiedNameAsString();
- if (sRecordName == "SfxEnumItem" || sRecordName == "SfxAllEnumItem")
+ auto tc = loplugin::TypeCheck(decl);
+ if (tc.Class("SfxEnumItem").GlobalNamespace() || tc.Class("SfxAllEnumItem").GlobalNamespace())
return true;
// the new field is only used for reading and writing to storage
- if (sRecordName == "SvxCharSetColorItem")
+ if (tc.Class("SvxCharSetColorItem").GlobalNamespace())
return true;
for (auto it = decl->method_begin(); it != decl->method_end(); ++it) {
diff --git a/compilerplugins/clang/staticmethods.cxx b/compilerplugins/clang/staticmethods.cxx
index 588e534c482c..f33f10f907c7 100644
--- a/compilerplugins/clang/staticmethods.cxx
+++ b/compilerplugins/clang/staticmethods.cxx
@@ -46,7 +46,7 @@ bool BaseCheckNotTestFixtureSubclass(
#endif
)
{
- if (BaseDefinition->getQualifiedNameAsString().compare("CppUnit::TestFixture") == 0) {
+ if (loplugin::TypeCheck(BaseDefinition).Class("TestFixture").Namespace("CppUnit").GlobalNamespace()) {
return false;
}
return true;
diff --git a/compilerplugins/clang/store/changefunctioncalls.cxx b/compilerplugins/clang/store/changefunctioncalls.cxx
index abc8ce62ceba..a728ad5a310a 100644
--- a/compilerplugins/clang/store/changefunctioncalls.cxx
+++ b/compilerplugins/clang/store/changefunctioncalls.cxx
@@ -27,6 +27,7 @@ This can be easily adjusted for different modifications to a function:
*/
#include "plugin.hxx"
+#include "check.hxx"
namespace loplugin
{
@@ -61,15 +62,14 @@ bool ChangeFunctionCalls::VisitCallExpr( const CallExpr* call )
// if( const FunctionDecl* func = dyn_cast_or_null< FunctionDecl >( call->getCalleeDecl()))
if( const FunctionDecl* func = call->getDirectCallee())
{
- // Optimize, getQualifiedNameAsString() is reportedly expensive,
// so first check fast details like number of arguments or the (unqualified)
// name before checking the fully qualified name.
// See FunctionDecl for all the API about the function.
if( func->getNumParams() == 1 && func->getIdentifier() != NULL
&& ( func->getName() == "bar" ))
{
- string qualifiedName = func->getQualifiedNameAsString();
- if( qualifiedName == "bar" )
+ auto qt = loplugin::DeclCheck(func);
+ if( qt.Function("bar").GlobalNamespace() )
{
// Further checks about arguments. Check mainly ParmVarDecl, VarDecl,
// ValueDecl and QualType for Clang API details.
diff --git a/compilerplugins/clang/stringconcat.cxx b/compilerplugins/clang/stringconcat.cxx
index a944f4fcf319..670d8929016a 100644
--- a/compilerplugins/clang/stringconcat.cxx
+++ b/compilerplugins/clang/stringconcat.cxx
@@ -8,6 +8,7 @@
*/
#include "plugin.hxx"
+#include "check.hxx"
namespace {
@@ -26,8 +27,9 @@ Expr const * stripCtor(Expr const * expr) {
if (e3 == nullptr) {
return expr;
}
- auto const n = e3->getConstructor()->getQualifiedNameAsString();
- if (n != "rtl::OString::OString" && n != "rtl::OUString::OUString") {
+ auto qt = loplugin::DeclCheck(e3->getConstructor());
+ if (!qt.Function("OString").Class("OString").Namespace("rtl").GlobalNamespace() &&
+ !qt.Function("OUString").Class("OUString").Namespace("rtl").GlobalNamespace()) {
return expr;
}
if (e3->getNumArgs() != 2) {
diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx
index 9ae672ae9050..426f8bd2c244 100644
--- a/compilerplugins/clang/stringconstant.cxx
+++ b/compilerplugins/clang/stringconstant.cxx
@@ -1626,8 +1626,7 @@ void StringConstant::handleOUStringCtor(
if (e3 == nullptr) {
return;
}
- if (e3->getConstructor()->getQualifiedNameAsString()
- != "rtl::OUString::OUString")
+ if (!loplugin::DeclCheck(e3->getConstructor()).Function("OUString").Class("OUString").Namespace("rtl").GlobalNamespace())
{
return;
}
diff --git a/compilerplugins/clang/unusedvariablecheck.cxx b/compilerplugins/clang/unusedvariablecheck.cxx
index db6a45e1ae3f..50b41d5664f8 100644
--- a/compilerplugins/clang/unusedvariablecheck.cxx
+++ b/compilerplugins/clang/unusedvariablecheck.cxx
@@ -17,6 +17,7 @@
#if !HAVE_GCC_ATTRIBUTE_WARN_UNUSED_STL
#include "compat.hxx"
+#include "check.hxx"
#include "unusedvariablecheck.hxx"
#include <clang/AST/Attr.h>
@@ -56,11 +57,11 @@ bool BaseCheckNotSomethingInterestingSubclass(
#endif
)
{
- if (BaseDefinition && BaseDefinition->getQualifiedNameAsString().compare("Dialog") == 0) {
- return false;
- }
- if (BaseDefinition && BaseDefinition->getQualifiedNameAsString().compare("SfxPoolItem") == 0) {
- return false;
+ if (BaseDefinition) {
+ auto tc = loplugin::TypeCheck(BaseDefinition);
+ if (tc.Class("Dialog").GlobalNamespace() || tc.Class("SfxPoolItem").GlobalNamespace()) {
+ return false;
+ }
}
return true;
}
@@ -68,9 +69,10 @@ bool BaseCheckNotSomethingInterestingSubclass(
bool isDerivedFromSomethingInteresting(const CXXRecordDecl *decl) {
if (!decl)
return false;
- if (decl->getQualifiedNameAsString() == "Dialog")
+ auto tc = loplugin::TypeCheck(decl);
+ if (tc.Class("Dialog"))
return true;
- if (decl->getQualifiedNameAsString() == "SfxPoolItem")
+ if (tc.Class("SfxPoolItem"))
return true;
if (!decl->hasDefinition()) {
return false;
@@ -113,11 +115,14 @@ bool UnusedVariableCheck::VisitVarDecl( const VarDecl* var )
}
if( !warn_unused )
{
- string n = type->getQualifiedNameAsString();
+ auto tc = loplugin::TypeCheck(type);
// Check some common non-LO types.
- if( n == "std::string" || n == "std::basic_string"
- || n == "std::list" || n == "std::__debug::list"
- || n == "std::vector" || n == "std::__debug::vector" )
+ if( tc.Class("string").Namespace("std").GlobalNamespace()
+ || tc.Class("basic_string").Namespace("std").GlobalNamespace()
+ || tc.Class("list").Namespace("std").GlobalNamespace()
+ || tc.Class("list").Namespace("__debug").Namespace("std").GlobalNamespace()
+ || tc.Class("vector").Namespace("std").GlobalNamespace()
+ || tc.Class("vector" ).Namespace("__debug").Namespace("std").GlobalNamespace())
warn_unused = true;
if (!warn_unused && isDerivedFromSomethingInteresting(type))
warn_unused = true;
diff --git a/compilerplugins/clang/weakobject.cxx b/compilerplugins/clang/weakobject.cxx
index 7c36f93a1d92..9ccbb8ac3c86 100644
--- a/compilerplugins/clang/weakobject.cxx
+++ b/compilerplugins/clang/weakobject.cxx
@@ -117,8 +117,8 @@ public:
// Allow this convenient shortcut:
auto td = dyn_cast<TypeDecl>(pCalled->getParent());
if (td != nullptr
- && (loplugin::TypeCheck(QualType(td->getTypeForDecl(), 0)).Class("OWeakObject").Namespace("cppu")
- || loplugin::TypeCheck(QualType(td->getTypeForDecl(), 0)).Class("OWeakAggObject").Namespace("cppu")))
+ && (loplugin::TypeCheck(td).Class("OWeakObject").Namespace("cppu").GlobalNamespace()
+ || loplugin::TypeCheck(td).Class("OWeakAggObject").Namespace("cppu").GlobalNamespace()))
{
return true;
}
@@ -131,15 +131,15 @@ public:
}
// whitelist
- auto const name(pMethodDecl->getParent()->getQualifiedNameAsString());
- if ( name == "cppu::OWeakAggObject" // conditional call
- || name == "cppu::WeakComponentImplHelperBase" // extra magic
- || name == "cppu::WeakAggComponentImplHelperBase" // extra magic
- || name == "DOM::CDOMImplementation" // a static oddity
- || name == "SwXTextFrame" // ambiguous, 3 parents
- || name == "SwXTextDocument" // ambiguous, ~4 parents
- || name == "SdStyleSheet" // same extra magic as WeakComponentImplHelperBase
- || name == "SdXImpressDocument" // same extra magic as WeakComponentImplHelperBase
+ auto tc = loplugin::TypeCheck(pMethodDecl->getParent());
+ if ( tc.Class("OWeakAggObject").Namespace("cppu").GlobalNamespace() // conditional call
+ || tc.Class("WeakComponentImplHelperBase").Namespace("cppu").GlobalNamespace() // extra magic
+ || tc.Class("WeakAggComponentImplHelperBase").Namespace("cppu").GlobalNamespace() // extra magic
+ || tc.Class("CDOMImplementation").Namespace("DOM").GlobalNamespace() // a static oddity
+ || tc.Class("SwXTextFrame").GlobalNamespace() // ambiguous, 3 parents
+ || tc.Class("SwXTextDocument").GlobalNamespace() // ambiguous, ~4 parents
+ || tc.Class("SdStyleSheet").GlobalNamespace() // same extra magic as WeakComponentImplHelperBase
+ || tc.Class("SdXImpressDocument").GlobalNamespace() // same extra magic as WeakComponentImplHelperBase
)
{
return true;