new loplugin: defaultparams

find places where we do not need to be passing a parameter to a
function, because that function has a default value which matches the
value we are passing.

Change-Id: I04d1fd6275204dd4925e6563282464f461123632
diff --git a/codemaker/source/cppumaker/dependencies.cxx b/codemaker/source/cppumaker/dependencies.cxx
index b56bacf..ebcd839 100644
--- a/codemaker/source/cppumaker/dependencies.cxx
+++ b/codemaker/source/cppumaker/dependencies.cxx
@@ -301,7 +301,7 @@ void Dependencies::insert(OUString const & name, bool base) {
        for (std::vector< OString >::iterator i(args.begin()); i != args.end();
             ++i)
        {
            insert(b2u(*i), false);
            insert(b2u(*i));
        }
        // fall through
    case UnoType::SORT_SEQUENCE_TYPE:
diff --git a/compilerplugins/clang/defaultparams.cxx b/compilerplugins/clang/defaultparams.cxx
new file mode 100644
index 0000000..173cc5e
--- /dev/null
+++ b/compilerplugins/clang/defaultparams.cxx
@@ -0,0 +1,80 @@
/* -*- 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 "plugin.hxx"

// Find places where we call a method with values == the values specified in the parameter defaults.
// i.e. where the code might as well not specify anything.

namespace {

class DefaultParams:
    public RecursiveASTVisitor<DefaultParams>, public loplugin::Plugin
{
public:
    explicit DefaultParams(InstantiationData const & data): Plugin(data) {}

    virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }

    bool VisitCallExpr(const CallExpr * callExpr);
};

bool DefaultParams::VisitCallExpr(const CallExpr * callExpr) {
    if (ignoreLocation(callExpr)) {
        return true;
    }
    if (callExpr->getNumArgs() == 0) {
        return true;
    }
    if (callExpr->getDirectCallee() == nullptr) {
        return true;
    }
    const FunctionDecl* functionDecl = callExpr->getDirectCallee()->getCanonicalDecl();
    unsigned i = callExpr->getNumArgs() - 1;
    const Expr* arg = callExpr->getArg(i);
    // variadic functions
    if (i >= functionDecl->getNumParams()) {
        return true;
    }
    const ParmVarDecl* parmVarDecl = functionDecl->getParamDecl(i);
    const Expr* defaultArgExpr = parmVarDecl->getDefaultArg();
    if (!arg->isDefaultArgument() &&
        arg->isIntegerConstantExpr(compiler.getASTContext()) &&
        parmVarDecl->hasDefaultArg() &&
        !parmVarDecl->hasUninstantiatedDefaultArg() &&
        defaultArgExpr->isIntegerConstantExpr(compiler.getASTContext()))
    {
        APSInt x1, x2;
        if (arg->EvaluateAsInt(x1, compiler.getASTContext()) &&
            defaultArgExpr->EvaluateAsInt(x2, compiler.getASTContext()) &&
            x1 == x2)
        {
            report(
                DiagnosticsEngine::Warning,
                "not necessary to pass this argument, it defaults to the same value",
                callExpr->getSourceRange().getBegin())
              << callExpr->getSourceRange();
            report(
                DiagnosticsEngine::Warning,
                "default method parameter declaration here",
                parmVarDecl->getSourceRange().getBegin())
              << parmVarDecl->getSourceRange();
        }
    }
    return true;
}

loplugin::Plugin::Registration< DefaultParams > X("defaultparams", false);

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/i18npool/source/breakiterator/gendict.cxx b/i18npool/source/breakiterator/gendict.cxx
index 3e649dd..493d053 100644
--- a/i18npool/source/breakiterator/gendict.cxx
+++ b/i18npool/source/breakiterator/gendict.cxx
@@ -126,7 +126,7 @@ static inline void printDataArea(FILE *dictionary_fp, FILE *source_fp, vector<sa
        const sal_Int32 len = Ostr.getLength();

        sal_Int32 i=0;
        Ostr.iterateCodePoints(&i, 1);
        Ostr.iterateCodePoints(&i);
        if (len == i)
            continue;   // skip one character word

diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx
index 995fe7e..b83930e 100644
--- a/include/rtl/string.hxx
+++ b/include/rtl/string.hxx
@@ -737,7 +737,7 @@ public:
      @since LibreOffice 4.0
    */
    bool startsWith(OString const & str, OString * rest = 0) const {
        bool b = match(str, 0);
        bool b = match(str);
        if (b && rest != 0) {
            *rest = copy(str.getLength());
        }
diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx
index 9b0cfb4..ee96da1 100644
--- a/include/rtl/ustring.hxx
+++ b/include/rtl/ustring.hxx
@@ -1048,7 +1048,7 @@ public:
      @since LibreOffice 4.0
    */
    bool startsWith(OUString const & str, OUString * rest = 0) const {
        bool b = match(str, 0);
        bool b = match(str);
        if (b && rest != 0) {
            *rest = copy(str.getLength());
        }
@@ -1104,7 +1104,7 @@ public:
    bool startsWithIgnoreAsciiCase(OUString const & str, OUString * rest = 0)
        const
    {
        bool b = matchIgnoreAsciiCase(str, 0);
        bool b = matchIgnoreAsciiCase(str);
        if (b && rest != 0) {
            *rest = copy(str.getLength());
        }
diff --git a/l10ntools/source/export.cxx b/l10ntools/source/export.cxx
index 6b002ef..a56e1a9 100644
--- a/l10ntools/source/export.cxx
+++ b/l10ntools/source/export.cxx
@@ -1157,7 +1157,7 @@ void Export::MergeRest( ResData *pResData )
                if( pEntrys )
                {
                    OString sText;
                    pEntrys->GetText( sText, STRING_TYP_TEXT, sCur, false );
                    pEntrys->GetText( sText, STRING_TYP_TEXT, sCur );
                    if( !sText.isEmpty())
                    {
                        ConvertMergeContent( sText );
diff --git a/l10ntools/source/xmlparse.cxx b/l10ntools/source/xmlparse.cxx
index f47880d..06fcef0 100644
--- a/l10ntools/source/xmlparse.cxx
+++ b/l10ntools/source/xmlparse.cxx
@@ -374,7 +374,7 @@ void XMLFile::InsertL10NElement( XMLElement* pElement )
    {
        fprintf(stdout,"XMLFile::InsertL10NElement: No AttributeList found");
        fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++");
        Print( pElement , 0 );
        Print( pElement );
        fprintf(stdout,"++++++++++++++++++++++++++++++++++++++++++++++++++");
    }

diff --git a/sal/qa/osl/file/osl_File.cxx b/sal/qa/osl/file/osl_File.cxx
index dbb9b12..b391f69 100644
--- a/sal/qa/osl/file/osl_File.cxx
+++ b/sal/qa/osl/file/osl_File.cxx
@@ -355,7 +355,7 @@ inline bool checkDirectory( const ::rtl::OUString & str, oslCheckMode nCheckMode
                break;
            case osl_Check_Mode_ReadAccess:
                //rc = pDir->getNextItem( rItem, 0 );
                rc = aDir.getNextItem( rItem, 0 );
                rc = aDir.getNextItem( rItem );
                if ( ( rc == ::osl::FileBase::E_None ) || ( rc == ::osl::FileBase::E_NOENT ) )
                    bCheckResult = true;
                else
@@ -1255,7 +1255,7 @@ namespace osl_FileStatus
            Directory pDir( aTmpName3 );
            nError1 = pDir.open();
            CPPUNIT_ASSERT( ::osl::FileBase::E_None == nError1 );
            nError1 = pDir.getNextItem( rItem, 0 );
            nError1 = pDir.getNextItem( rItem );
            CPPUNIT_ASSERT( ::osl::FileBase::E_None == nError1 );
            pDir.close();
            /*
@@ -4228,7 +4228,7 @@ namespace osl_Directory
            nError2 = testDirectory.reset();
            CPPUNIT_ASSERT( ::osl::FileBase::E_None == nError2 );
            //get reseted Item, if reset does not work, getNextItem() should return the second Item (aTmpName1)
            nError1 = testDirectory.getNextItem( rItem, 0 );
            nError1 = testDirectory.getNextItem( rItem );
            CPPUNIT_ASSERT( ::osl::FileBase::E_None == nError1 );

            //check the file name again
diff --git a/store/source/storbios.cxx b/store/source/storbios.cxx
index 3f9ec2d..9f494f1 100644
--- a/store/source/storbios.cxx
+++ b/store/source/storbios.cxx
@@ -742,7 +742,7 @@ storeError OStorePageBIOS::acquirePage (
    else
    {
      // Insert new entry.
      Ace * entry = AceCache::get().create (rDescr.m_nAddr, 1);
      Ace * entry = AceCache::get().create (rDescr.m_nAddr);
      if (!entry)
        return store_E_OutOfMemory;
      Ace::insert (ace, entry);