summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/checkunusedparams.cxx
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-08-01 08:40:47 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-08-01 11:06:26 +0200
commit612b489d3e05b24c1b6690082e8518bac033e9d2 (patch)
tree23a6c556989071385d1c64730ed72bdbae7c239c /compilerplugins/clang/checkunusedparams.cxx
parent17e14d459dea201b57be2d8e677fa776ead03291 (diff)
loplugin:checkunusedparams
the "check for taking address of function" part was generating false+ Change-Id: Iad6203850901229b7b1b2f8938c68ec703cd343f Reviewed-on: https://gerrit.libreoffice.org/40613 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/checkunusedparams.cxx')
-rw-r--r--compilerplugins/clang/checkunusedparams.cxx105
1 files changed, 93 insertions, 12 deletions
diff --git a/compilerplugins/clang/checkunusedparams.cxx b/compilerplugins/clang/checkunusedparams.cxx
index d1ff8998a083..a63a1903675a 100644
--- a/compilerplugins/clang/checkunusedparams.cxx
+++ b/compilerplugins/clang/checkunusedparams.cxx
@@ -28,9 +28,14 @@ class CheckUnusedParams: public RecursiveASTVisitor<CheckUnusedParams>, public l
public:
explicit CheckUnusedParams(InstantiationData const & data): Plugin(data) {}
void run() override;
- bool VisitFunctionDecl(FunctionDecl const * decl);
- bool VisitDeclRefExpr(DeclRefExpr const *);
+ bool VisitFunctionDecl(FunctionDecl const *);
+ bool VisitUnaryAddrOf(UnaryOperator const *);
+ bool VisitInitListExpr(InitListExpr const *);
+ bool VisitCallExpr(CallExpr const *);
+ bool VisitBinAssign(BinaryOperator const *);
+ bool VisitCXXConstructExpr(CXXConstructExpr const *);
private:
+ void checkForFunctionDecl(Expr const *, bool bCheckOnly = false);
std::set<FunctionDecl const *> m_addressOfSet;
enum class PluginPhase { FindAddressOf, Warning };
PluginPhase m_phase;
@@ -68,20 +73,57 @@ void CheckUnusedParams::run()
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
-bool CheckUnusedParams::VisitDeclRefExpr(DeclRefExpr const * declRef) {
+bool CheckUnusedParams::VisitUnaryAddrOf(UnaryOperator const * op) {
if (m_phase != PluginPhase::FindAddressOf)
return true;
- if (ignoreLocation(declRef))
+ checkForFunctionDecl(op->getSubExpr());
+ return true;
+}
+
+bool CheckUnusedParams::VisitBinAssign(BinaryOperator const * binaryOperator) {
+ if (m_phase != PluginPhase::FindAddressOf)
return true;
- if (isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(declRef->getLocStart())))
+ checkForFunctionDecl(binaryOperator->getRHS());
+ return true;
+}
+
+bool CheckUnusedParams::VisitCallExpr(CallExpr const * callExpr) {
+ if (m_phase != PluginPhase::FindAddressOf)
return true;
- auto functionDecl = dyn_cast<FunctionDecl>(declRef->getDecl());
- if (!functionDecl)
+ for (auto arg : callExpr->arguments())
+ checkForFunctionDecl(arg);
+ return true;
+}
+
+bool CheckUnusedParams::VisitCXXConstructExpr(CXXConstructExpr const * constructExpr) {
+ if (m_phase != PluginPhase::FindAddressOf)
return true;
- m_addressOfSet.insert(functionDecl);
+ for (auto arg : constructExpr->arguments())
+ checkForFunctionDecl(arg);
return true;
}
+bool CheckUnusedParams::VisitInitListExpr(InitListExpr const * initListExpr) {
+ if (m_phase != PluginPhase::FindAddressOf)
+ return true;
+ for (auto subStmt : *initListExpr)
+ checkForFunctionDecl(dyn_cast<Expr>(subStmt));
+ return true;
+}
+
+void CheckUnusedParams::checkForFunctionDecl(Expr const * expr, bool bCheckOnly) {
+ auto e1 = expr->IgnoreParenCasts();
+ auto declRef = dyn_cast<DeclRefExpr>(e1);
+ if (!declRef)
+ return;
+ auto functionDecl = dyn_cast<FunctionDecl>(declRef->getDecl());
+ if (!functionDecl)
+ return;
+ if (bCheckOnly)
+ parentStmt(expr)->dump();
+ else
+ m_addressOfSet.insert(functionDecl->getCanonicalDecl());
+}
static int noFieldsInRecord(RecordType const * recordType) {
auto recordDecl = recordType->getDecl();
@@ -103,7 +145,7 @@ static bool endswith(const std::string& rStr, const char* pSubStr) {
bool CheckUnusedParams::VisitFunctionDecl(FunctionDecl const * decl) {
if (m_phase != PluginPhase::Warning)
return true;
- if (m_addressOfSet.find(decl) != m_addressOfSet.end())
+ if (m_addressOfSet.find(decl->getCanonicalDecl()) != m_addressOfSet.end())
return true;
if (ignoreLocation(decl))
return true;
@@ -139,7 +181,6 @@ bool CheckUnusedParams::VisitFunctionDecl(FunctionDecl const * decl) {
{
return true;
}
-
FunctionDecl const * canon = decl->getCanonicalDecl();
std::string fqn = canon->getQualifiedNameAsString(); // because sometimes clang returns nonsense for the filename of canon
if (ignoreLocation(canon))
@@ -318,7 +359,30 @@ bool CheckUnusedParams::VisitFunctionDecl(FunctionDecl const * decl) {
|| fqn == "DOM::CDocumentBuilder::_getInstance"
|| fqn == "xml_security::serial_number_adapter::create"
|| fqn == "desktop::splash::create" || fqn == "ScannerManager_CreateInstance"
- || fqn == "formula::FormulaOpCodeMapperObj::create")
+ || fqn == "formula::FormulaOpCodeMapperObj::create"
+ || fqn == "(anonymous namespace)::createInstance"
+ || fqn == "x_error_handler"
+ || fqn == "warning_func"
+ || fqn == "error_func"
+ || fqn == "ScaDateAddIn_CreateInstance"
+ || fqn == "ScaPricingAddIn_CreateInstance"
+ || fqn == "(anonymous namespace)::PDFSigningPKCS7PasswordCallback"
+ || fqn == "ContextMenuEventLink"
+ || fqn == "DelayedCloseEventLink"
+ || fqn == "GDIMetaFile::ImplColMonoFnc"
+ || fqn == "vcl::getGlyph0"
+ || fqn == "vcl::getGlyph6"
+ || fqn == "vcl::getGlyph12"
+ || fqn == "setPasswordCallback"
+ || fqn == "VCLExceptionSignal_impl"
+ || fqn == "getFontTable"
+ || fqn == "textconversiondlgs::ChineseTranslation_UnoDialog::create"
+ || fqn == "pcr::DefaultHelpProvider::Create"
+ || fqn == "pcr::DefaultFormComponentInspectorModel::Create"
+ || fqn == "GraphicExportDialog::GraphicExportDialog"
+ || fqn == "pcr::ObjectInspectorModel::Create"
+ || fqn == "GraphicExportFilter::GraphicExportFilter"
+ )
return true;
// TODO
if (fqn == "FontSubsetInfo::CreateFontSubsetFromType1")
@@ -329,7 +393,24 @@ bool CheckUnusedParams::VisitFunctionDecl(FunctionDecl const * decl) {
return true;
// FIXME
if (fqn == "GtkSalDisplay::filterGdkEvent" || fqn == "SvXMLEmbeddedObjectHelper::ImplReadObject"
- || "chart::CachedDataSequence::CachedDataSequence")
+ || fqn == "chart::CachedDataSequence::CachedDataSequence")
+ return true;
+ // used via macro
+ if (fqn == "framework::MediaTypeDetectionHelper::MediaTypeDetectionHelper"
+ || fqn == "framework::UriAbbreviation::UriAbbreviation"
+ || fqn == "framework::DispatchDisabler::DispatchDisabler"
+ || fqn == "framework::DispatchRecorderSupplier::DispatchRecorderSupplier")
+ return true;
+ // TODO Armin Le Grand is still working on this
+ if (fqn == "svx::frame::CreateDiagFrameBorderPrimitives"
+ || fqn == "svx::frame::CreateBorderPrimitives")
+ return true;
+ // marked with a TODO
+ if (fqn == "pcr::FormLinkDialog::getExistingRelation"
+ || fqn == "ooo::vba::DebugHelper::basicexception")
+ return true;
+ // macros at work
+ if (fqn == "msfilter::lcl_PrintDigest")
return true;
// ignore the LINK macros from include/tools/link.hxx