/* -*- 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"plugin.hxx" #include <iostream>
/* Look for member functions that merely return a compile-time constant, or they are empty, and can thus be either removed, or converted into a constant.
This mostly tends to happen as a side-effect of other cleanups.
*/ namespace {
class ConstantFunction: public loplugin::FilteringPlugin<ConstantFunction>
{
StringRef getFilename(const FunctionDecl* functionDecl); public: explicit ConstantFunction(InstantiationData const & data): FilteringRewritePlugin(data) {}
void run() override
{ // these files crash clang-3.5 somewhere in the isEvaluatable/EvaluateAsXXX stuff /* FileID mainFileID = compiler.getSourceManager().getMainFileID(); if (strstr(compiler.getSourceManager().getFileEntryForID(mainFileID)->getName(), "bootstrapfixture.cxx") != 0) { return; } if (strstr(compiler.getSourceManager().getFileEntryForID(mainFileID)->getName(), "gtkinst.cxx") != 0) { return;
}*/
bool ConstantFunction::VisitFunctionDecl(const FunctionDecl * pFunctionDecl) { if (ignoreLocation(pFunctionDecl)) { returntrue;
} if (!pFunctionDecl->hasBody()) { returntrue;
} if (!pFunctionDecl->isThisDeclarationADefinition()) { returntrue;
} // stuff declared extern-C is almost always used as a some kind of callback if (pFunctionDecl->isExternC()) { returntrue;
} if (pFunctionDecl->isConstexpr()) { returntrue;
} if (pFunctionDecl->isMain()) { returntrue;
}
StringRef aFileName = getFilename(pFunctionDecl);
// various tests in here are empty stubs under Linux if (aFileName.startswith(SRCDIR "/sal/qa/")) { returntrue;
} // lots of empty stuff here where it looks like someone is still going to "fill in the blanks" if (aFileName.startswith(SRCDIR "/basegfx/test/")) { returntrue;
} // bridges has some weird stuff in it... if (aFileName.startswith(SRCDIR "/bridges/")) { returntrue;
} // dummy implementation of DDE, since it is only active on Windows if (aFileName == SRCDIR "/svl/unx/source/svdde/ddedummy.cxx"
|| aFileName == SRCDIR "/include/svl/svdde.hxx") { returntrue;
} // fancy templates at work here if (aFileName == SRCDIR "/vcl/source/gdi/bmpfast.cxx") { returntrue;
} // bunch of stuff used as callbacks here if (aFileName == SRCDIR "/vcl/generic/glyphs/gcach_layout.cxx") { returntrue;
} // salplug runtime-loading mechanism at work if (aFileName == SRCDIR "/vcl/inc/salinst.hxx") { returntrue;
} // lots of callbacks here if (aFileName == SRCDIR "/extensions/source/plugin/unx/npnapi.cxx") { returntrue;
} // vcl/unx/gtk3 re-using vcl/unx/gtk: if (aFileName.find("/../../gtk/") != std::string::npos) { returntrue;
} // used by code generated by python if (aFileName == SRCDIR "/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx") { returntrue;
} // this test just test the include of some headers if (aFileName == SRCDIR "/officecfg/qa/cppheader.cxx") { returntrue;
} // just ignore this for now, people furiously hacking in there if (startsWith(aFileName, SRCDIR "/libreofficekit")) { returntrue;
}
const CXXMethodDecl *pCXXMethodDecl = dyn_cast<CXXMethodDecl>(pFunctionDecl); if (pCXXMethodDecl) { if (pCXXMethodDecl->isVirtual()) { returntrue;
} // static with inline body will be optimised at compile-time to a constant anyway if (pCXXMethodDecl->isStatic() && (pCXXMethodDecl->hasInlineBody() || pCXXMethodDecl->isInlineSpecified())) { returntrue;
} // this catches some stuff in templates if (pFunctionDecl->hasAttr<OverrideAttr>()) { returntrue;
}
} // a free function with an inline body will be optimised at compile-time to a constant anyway if (!pCXXMethodDecl && pFunctionDecl->isInlineSpecified()) { returntrue;
} if (isa<CXXConstructorDecl>(pFunctionDecl) || isa<CXXDestructorDecl>(pFunctionDecl) || isa<CXXConversionDecl>(pFunctionDecl)) { returntrue;
} if (isInUnoIncludeFile(pFunctionDecl)) { returntrue;
}
switch (pFunctionDecl->getOverloadedOperator()) { case OO_Delete: case OO_EqualEqual: case OO_Call: returntrue; default: break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.