summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compilerplugins/clang/constantparam.cxx215
-rwxr-xr-xcompilerplugins/clang/constantparam.py61
-rw-r--r--xmlhelp/source/cxxhelp/provider/urlparameter.cxx6
-rw-r--r--xmlhelp/source/cxxhelp/provider/urlparameter.hxx2
-rw-r--r--xmlsecurity/source/framework/saxeventkeeperimpl.cxx15
-rw-r--r--xmlsecurity/source/framework/saxeventkeeperimpl.hxx3
6 files changed, 284 insertions, 18 deletions
diff --git a/compilerplugins/clang/constantparam.cxx b/compilerplugins/clang/constantparam.cxx
new file mode 100644
index 000000000000..6726836d5205
--- /dev/null
+++ b/compilerplugins/clang/constantparam.cxx
@@ -0,0 +1,215 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/.
+ */
+
+#include <string>
+#include <set>
+#include <iostream>
+#include <fstream>
+
+#include "plugin.hxx"
+#include "compat.hxx"
+
+/*
+ Find methods with default params, where the callers never specify the default param i.e.
+ might as well remove it.
+
+ The process goes something like this:
+ $ make check
+ $ make FORCE_COMPILE_ALL=1 COMPILER_PLUGIN_TOOL='unuseddefaultparams' check
+ $ ./compilerplugins/clang/unuseddefaultparams.py unuseddefaultparams.log
+*/
+
+namespace {
+
+struct MyCallSiteInfo
+{
+ std::string returnType;
+ std::string nameAndParams;
+ std::string paramName;
+ std::string callValue;
+ std::string sourceLocation;
+};
+bool operator < (const MyCallSiteInfo &lhs, const MyCallSiteInfo &rhs)
+{
+ if (lhs.sourceLocation < rhs.sourceLocation)
+ return true;
+ else if (lhs.sourceLocation > rhs.sourceLocation)
+ return false;
+ else return lhs.callValue < rhs.callValue;
+}
+
+
+// try to limit the voluminous output a little
+static std::set<MyCallSiteInfo> callSet;
+
+class ConstantParam:
+ public RecursiveASTVisitor<ConstantParam>, public loplugin::Plugin
+{
+public:
+ explicit ConstantParam(InstantiationData const & data): Plugin(data) {}
+
+ virtual void run() override
+ {
+ TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+
+ // dump all our output in one write call - this is to try and limit IO "crosstalk" between multiple processes
+ // writing to the same logfile
+
+ std::string output;
+ for (const MyCallSiteInfo & s : callSet)
+ output += s.returnType + "\t" + s.nameAndParams + "\t" + s.sourceLocation + "\t"
+ + s.paramName + "\t" + s.callValue + "\n";
+ ofstream myfile;
+ myfile.open( SRCDIR "/constantparam.log", ios::app | ios::out);
+ myfile << output;
+ myfile.close();
+ }
+
+ bool shouldVisitTemplateInstantiations () const { return true; }
+
+ bool VisitCallExpr(CallExpr * callExpr);
+ bool VisitDeclRefExpr( const DeclRefExpr* declRefExpr );
+private:
+ MyCallSiteInfo niceName(const FunctionDecl* functionDecl, const ParmVarDecl* parmVarDecl, const std::string& callValue);
+};
+
+MyCallSiteInfo ConstantParam::niceName(const FunctionDecl* functionDecl, const ParmVarDecl* parmVarDecl, const std::string& callValue)
+{
+ if (functionDecl->getInstantiatedFromMemberFunction())
+ functionDecl = functionDecl->getInstantiatedFromMemberFunction();
+ else if (functionDecl->getClassScopeSpecializationPattern())
+ functionDecl = functionDecl->getClassScopeSpecializationPattern();
+// workaround clang-3.5 issue
+#if CLANG_VERSION >= 30600
+ else if (functionDecl->getTemplateInstantiationPattern())
+ functionDecl = functionDecl->getTemplateInstantiationPattern();
+#endif
+
+ MyCallSiteInfo aInfo;
+ aInfo.returnType = compat::getReturnType(*functionDecl).getCanonicalType().getAsString();
+
+ if (isa<CXXMethodDecl>(functionDecl)) {
+ const CXXRecordDecl* recordDecl = dyn_cast<CXXMethodDecl>(functionDecl)->getParent();
+ aInfo.nameAndParams += recordDecl->getQualifiedNameAsString();
+ aInfo.nameAndParams += "::";
+ }
+ aInfo.nameAndParams += functionDecl->getNameAsString() + "(";
+ bool bFirst = true;
+ for (const ParmVarDecl *pParmVarDecl : functionDecl->params()) {
+ if (bFirst)
+ bFirst = false;
+ else
+ aInfo.nameAndParams += ",";
+ aInfo.nameAndParams += pParmVarDecl->getType().getCanonicalType().getAsString();
+ }
+ aInfo.nameAndParams += ")";
+ if (isa<CXXMethodDecl>(functionDecl) && dyn_cast<CXXMethodDecl>(functionDecl)->isConst()) {
+ aInfo.nameAndParams += " const";
+ }
+ aInfo.paramName = parmVarDecl->getName();
+ aInfo.callValue = callValue;
+
+ SourceLocation expansionLoc = compiler.getSourceManager().getExpansionLoc( functionDecl->getLocation() );
+ StringRef name = compiler.getSourceManager().getFilename(expansionLoc);
+ aInfo.sourceLocation = std::string(name.substr(strlen(SRCDIR)+1)) + ":" + std::to_string(compiler.getSourceManager().getSpellingLineNumber(expansionLoc));
+
+ return aInfo;
+}
+
+bool ConstantParam::VisitCallExpr(CallExpr * callExpr) {
+ if (ignoreLocation(callExpr)) {
+ return true;
+ }
+ const FunctionDecl* functionDecl;
+ if (isa<CXXMemberCallExpr>(callExpr)) {
+ functionDecl = dyn_cast<CXXMemberCallExpr>(callExpr)->getMethodDecl();
+ }
+ else {
+ functionDecl = callExpr->getDirectCallee();
+ }
+ if (functionDecl == nullptr) {
+ return true;
+ }
+ functionDecl = functionDecl->getCanonicalDecl();
+ // method overrides don't always specify the same default params (althogh they probably should)
+ // so we need to work our way up to the root method
+ while (isa<CXXMethodDecl>(functionDecl)) {
+ const CXXMethodDecl* methodDecl = dyn_cast<CXXMethodDecl>(functionDecl);
+ if (methodDecl->size_overridden_methods()==0)
+ break;
+ functionDecl = *methodDecl->begin_overridden_methods();
+ }
+ // work our way back to the root definition for template methods
+ if (functionDecl->getInstantiatedFromMemberFunction())
+ functionDecl = functionDecl->getInstantiatedFromMemberFunction();
+ else if (functionDecl->getClassScopeSpecializationPattern())
+ functionDecl = functionDecl->getClassScopeSpecializationPattern();
+// workaround clang-3.5 issue
+#if CLANG_VERSION >= 30600
+ else if (functionDecl->getTemplateInstantiationPattern())
+ functionDecl = functionDecl->getTemplateInstantiationPattern();
+#endif
+
+ // ignore stuff that forms part of the stable URE interface
+ if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(
+ functionDecl->getNameInfo().getLoc()))) {
+ return true;
+ }
+ if (functionDecl->getNameInfo().getLoc().isValid() && ignoreLocation(functionDecl)) {
+ return true;
+ }
+
+ for (unsigned i = 0; i < callExpr->getNumArgs(); ++i) {
+ if (i >= functionDecl->getNumParams()) // can happen in template code
+ break;
+ Expr* arg = callExpr->getArg(i);
+ bool found = false;
+ std::string callValue;
+ // ignore this, it seems to trigger an infinite recursion
+ if (isa<UnaryExprOrTypeTraitExpr>(arg->IgnoreParenCasts())) {
+ found = true;
+ callValue = "unknown";
+ }
+ if (!found)
+ {
+ APSInt x1;
+ if (arg->EvaluateAsInt(x1, compiler.getASTContext()))
+ {
+ found = true;
+ callValue = x1.toString(10);
+ }
+ }
+ if (!found)
+ callValue = "unknown";
+ const ParmVarDecl* parmVarDecl = functionDecl->getParamDecl(i);
+ MyCallSiteInfo funcInfo = niceName(functionDecl, parmVarDecl, callValue);
+ callSet.insert(funcInfo);
+ break;
+ }
+ return true;
+}
+
+// this catches places that take the address of a method
+bool ConstantParam::VisitDeclRefExpr( const DeclRefExpr* declRefExpr )
+{
+ const Decl* functionDecl = declRefExpr->getDecl();
+ if (!isa<FunctionDecl>(functionDecl)) {
+ return true;
+ }
+// TODO
+// MyCallSiteInfo funcInfo = niceName(dyn_cast<FunctionDecl>(functionDecl));
+// callSet.insert(funcInfo);
+ return true;
+}
+
+loplugin::Plugin::Registration< ConstantParam > X("constantparam", false);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/constantparam.py b/compilerplugins/clang/constantparam.py
new file mode 100755
index 000000000000..a23be74be50f
--- /dev/null
+++ b/compilerplugins/clang/constantparam.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+
+import sys
+import re
+import io
+
+definitionSet = set()
+definitionToSourceLocationMap = dict()
+callParamSet = dict()
+
+# things we need to exclude for reasons like :
+# - it's a weird template thingy that confuses the plugin
+exclusionSet = set([
+])
+
+# clang does not always use exactly the same numbers in the type-parameter vars it generates
+# so I need to substitute them to ensure we can match correctly.
+normalizeTypeParamsRegex = re.compile(r"type-parameter-\d+-\d+")
+def normalizeTypeParams( line ):
+ return normalizeTypeParamsRegex.sub("type-parameter-?-?", line)
+
+# The parsing here is designed to avoid grabbing stuff which is mixed in from gbuild.
+# I have not yet found a way of suppressing the gbuild output.
+with io.open(sys.argv[1], "rb", buffering=1024*1024) as txt:
+ for line in txt:
+ idx1 = line.find("\t")
+ idx2 = line.find("\t",idx1+1)
+ idx3 = line.find("\t",idx2+1)
+ idx4 = line.find("\t",idx3+1)
+ returnType = line[:idx1]
+ nameAndParams = line[idx1+1:idx2]
+ sourceLocation = line[idx2+1:idx3]
+ paramName = line[idx3+1:idx4]
+ callValue = line[idx4+1:].strip()
+ callInfo = (normalizeTypeParams(returnType), normalizeTypeParams(nameAndParams), paramName)
+ if callInfo in callParamSet:
+ callParamSet[callInfo].add(callValue)
+ else:
+ callParamSet[callInfo] = set([callValue])
+ definitionToSourceLocationMap[callInfo] = sourceLocation
+
+tmp1set = set()
+for callInfo, callValues in callParamSet.iteritems():
+ if len(callValues) == 1 and "unknown" not in callValues and ("0" in callValues or "1" in callValues or "nullptr" in callValues):
+ v1 = (" ".join(callInfo)) + " " + (",".join(callValues))
+ v2 = definitionToSourceLocationMap[callInfo]
+ tmp1set.add((v1,v2))
+
+# sort results by name and line number
+def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
+ return [int(text) if text.isdigit() else text.lower()
+ for text in re.split(_nsre, s)]
+tmp1list = sorted(tmp1set, key=lambda v: natural_sort_key(v[1]))
+
+# print out the results
+with open("unused.constantparams", "wt") as f:
+ for t in tmp1list:
+ f.write(t[1] + "\n")
+ f.write(" " + t[0] + "\n")
+
+
diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
index b2c3da0d7202..cbb49ef58e74 100644
--- a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
+++ b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx
@@ -84,7 +84,7 @@ URLParameter::URLParameter( const OUString& aURL,
: m_pDatabases( pDatabases ),
m_aURL( aURL )
{
- init( false );
+ init();
parse();
}
@@ -196,10 +196,8 @@ OUString URLParameter::get_program()
}
-void URLParameter::init( bool bDefaultLanguageIsInitialized )
+void URLParameter::init()
{
- (void)bDefaultLanguageIsInitialized;
-
m_bHelpDataFileRead = false;
m_bStart = false;
m_bUseDB = true;
diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.hxx b/xmlhelp/source/cxxhelp/provider/urlparameter.hxx
index 13bdff6dd003..044b92206c40 100644
--- a/xmlhelp/source/cxxhelp/provider/urlparameter.hxx
+++ b/xmlhelp/source/cxxhelp/provider/urlparameter.hxx
@@ -212,7 +212,7 @@ namespace chelp {
// private methods
- void init( bool bDefaultLanguageIsInitialized );
+ void init();
OUString get_the_tag();
diff --git a/xmlsecurity/source/framework/saxeventkeeperimpl.cxx b/xmlsecurity/source/framework/saxeventkeeperimpl.cxx
index 036b541fe425..492e23ef4783 100644
--- a/xmlsecurity/source/framework/saxeventkeeperimpl.cxx
+++ b/xmlsecurity/source/framework/saxeventkeeperimpl.cxx
@@ -855,7 +855,6 @@ void SAXEventKeeperImpl::markElementMarkBuffer(sal_Int32 nId)
}
sal_Int32 SAXEventKeeperImpl::createElementCollector(
- sal_Int32 nSecurityId,
cssxc::sax::ElementMarkPriority nPriority,
bool bModifyElement,
const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& xReferenceResolvedListener)
@@ -875,7 +874,6 @@ sal_Int32 SAXEventKeeperImpl::createElementCollector(
* Add the new created ElementCollector to the new ElementCollecotor list.
*
* INPUTS
- * nSecurityId - the security Id of the new ElementCollector
* nPriority - the priority of the new ElementCollector
* bModifyElement -whether this BufferNode will modify the content of
* the corresponding element it works on
@@ -894,7 +892,7 @@ sal_Int32 SAXEventKeeperImpl::createElementCollector(
ElementCollector* pElementCollector
= new ElementCollector(
- nSecurityId,
+ cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
nId,
nPriority,
bModifyElement,
@@ -911,7 +909,7 @@ sal_Int32 SAXEventKeeperImpl::createElementCollector(
}
-sal_Int32 SAXEventKeeperImpl::createBlocker(sal_Int32 nSecurityId)
+sal_Int32 SAXEventKeeperImpl::createBlocker()
/****** SAXEventKeeperImpl/createBlocker *************************************
*
* NAME
@@ -923,9 +921,6 @@ sal_Int32 SAXEventKeeperImpl::createBlocker(sal_Int32 nSecurityId)
* FUNCTION
* see NAME.
*
- * INPUTS
- * nSecurityId - the security Id of the new Blocker
- *
* RESULT
* nId - the Id of the new Blocker
*
@@ -939,7 +934,7 @@ sal_Int32 SAXEventKeeperImpl::createBlocker(sal_Int32 nSecurityId)
OSL_ASSERT(m_pNewBlocker == nullptr);
- m_pNewBlocker = new ElementMark(nSecurityId, nId);
+ m_pNewBlocker = new ElementMark(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID, nId);
m_vElementMarkBuffers.push_back( m_pNewBlocker );
return nId;
@@ -950,7 +945,6 @@ sal_Int32 SAL_CALL SAXEventKeeperImpl::addElementCollector( )
throw (cssu::RuntimeException, std::exception)
{
return createElementCollector(
- cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
cssxc::sax::ElementMarkPriority_AFTERMODIFY,
false,
nullptr);
@@ -965,7 +959,7 @@ void SAL_CALL SAXEventKeeperImpl::removeElementCollector( sal_Int32 id )
sal_Int32 SAL_CALL SAXEventKeeperImpl::addBlocker( )
throw (cssu::RuntimeException, std::exception)
{
- return createBlocker(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID);
+ return createBlocker();
}
void SAL_CALL SAXEventKeeperImpl::removeBlocker( sal_Int32 id )
@@ -1071,7 +1065,6 @@ sal_Int32 SAL_CALL SAXEventKeeperImpl::addSecurityElementCollector(
throw (cssu::RuntimeException, std::exception)
{
return createElementCollector(
- cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
priority,
modifyElement,
nullptr);
diff --git a/xmlsecurity/source/framework/saxeventkeeperimpl.hxx b/xmlsecurity/source/framework/saxeventkeeperimpl.hxx
index 52fd955d13b5..f1915831a53c 100644
--- a/xmlsecurity/source/framework/saxeventkeeperimpl.hxx
+++ b/xmlsecurity/source/framework/saxeventkeeperimpl.hxx
@@ -213,14 +213,13 @@ private:
void markElementMarkBuffer(sal_Int32 nId);
sal_Int32 createElementCollector(
- sal_Int32 nSecurityId,
com::sun::star::xml::crypto::sax::ElementMarkPriority nPriority,
bool bModifyElement,
const com::sun::star::uno::Reference<
com::sun::star::xml::crypto::sax::XReferenceResolvedListener>&
xReferenceResolvedListener);
- sal_Int32 createBlocker(sal_Int32 nSecurityId);
+ sal_Int32 createBlocker();
public:
SAXEventKeeperImpl();