1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
7 * This file is distributed under the University of Illinois Open Source
8 * License. See LICENSE.TXT for details.
12 #ifndef LO_CLANG_SHARED_PLUGINS
15 #include <unordered_set>
18 * Very aggressive unused variable checker, we allowlist types that are known
24 static bool startswith(const std::string
& rStr
, const char* pSubStr
)
26 return rStr
.compare(0, strlen(pSubStr
), pSubStr
) == 0;
29 class UnusedVariablePlus
: public loplugin::FilteringPlugin
<UnusedVariablePlus
>
32 explicit UnusedVariablePlus(loplugin::InstantiationData
const& data
)
33 : FilteringPlugin(data
)
37 virtual bool preRun() override
39 std::string
fn(handler
.getMainFileName());
40 loplugin::normalizeDotDotInFilePath(fn
);
41 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/canvas/workben/"))
43 if (loplugin::isSamePathname(fn
, SRCDIR
"/vcl/source/uipreviewer/previewer.cxx"))
45 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/vcl/workben/"))
47 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/vcl/qa/"))
49 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/vcl/backendtest/"))
51 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/lotuswordpro/"))
53 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/salhelper/qa/"))
55 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/sal/qa/"))
57 if (loplugin::isSamePathname(fn
, SRCDIR
"/idl/source/prj/svidl.cxx"))
59 if (loplugin::isSamePathname(fn
, SRCDIR
"/sot/source/unoolestorage/xolesimplestorage.cxx"))
61 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/source/core/tool/interpr7.cxx"))
63 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/source/ui/vba/vbaapplication.cxx"))
65 if (loplugin::isSamePathname(fn
, SRCDIR
"/sw/source/core/doc/doccomp.cxx"))
67 if (loplugin::isSamePathname(fn
, SRCDIR
"/sw/source/core/swg/SwXMLTextBlocks.cxx"))
69 if (loplugin::isSamePathname(fn
, SRCDIR
"/sw/source/filter/ww8/wrtw8esh.cxx"))
71 if (loplugin::isSamePathname(fn
, SRCDIR
72 "/shell/source/sessioninstall/SyncDbusSessionHelper.cxx"))
74 if (loplugin::isSamePathname(fn
, SRCDIR
"/svl/qa/unit/items/test_IndexedStyleSheets.cxx"))
76 if (loplugin::isSamePathname(fn
, SRCDIR
"/sd/qa/unit/export-tests-ooxml2.cxx"))
78 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/qa/unit/subsequent_export-test.cxx"))
80 if (loplugin::isSamePathname(fn
, SRCDIR
"/vcl/skia/SkiaHelper.cxx"))
82 if (loplugin::isSamePathname(fn
, SRCDIR
"/svx/source/dialog/dlgctrl.cxx"))
85 // clang has a bug here, with vars in destructing assignments
86 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/binaryurp/"))
88 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/source/filter/excel/xestring.cxx"))
93 virtual void run() override
96 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
99 bool VisitVarDecl(const VarDecl
* var
)
101 if (ignoreLocation(var
))
103 if (var
->isReferenced() || var
->isUsed())
105 if (var
->isDefinedOutsideFunctionOrMethod())
107 if (var
->isExceptionVariable()) // not interesting
110 auto type
= var
->getType().getCanonicalType().getUnqualifiedType();
111 auto typeName
= type
.getAsString();
112 if (typeName
.compare(0, 7, "struct ") == 0)
113 typeName
= typeName
.substr(7);
114 if (typeName
.compare(0, 6, "class ") == 0)
115 typeName
= typeName
.substr(6);
116 if (typeName
.compare(0, 2, "::") == 0)
117 typeName
= typeName
.substr(2);
118 if (typeName
.compare(0, 23, "(anonymous namespace)::") == 0)
119 typeName
= typeName
.substr(23);
120 static std::unordered_set
<std::string
> ignoreClassNamesSet
{
121 "apphelper::NegativeGuard<class osl::Mutex>",
122 "avmedia::gstreamer::(anonymous namespace)::FlagGuard",
125 "boost::io::basic_ios_all_saver<char, struct std::char_traits<char> >",
127 "BroadcastRecalcOnRefMoveGuard",
131 "chart::ControllerLockGuard",
132 "chart::ControllerLockGuardUNO",
133 "chart::HiddenUndoContext",
134 "chart::sidebar::(anonymous namespace)::PreventUpdate",
135 "chart::TimerTriggeredControllerLock",
137 "ClearableClipRegion",
138 "osl::ClearableGuard<class osl::Mutex>",
139 "rptui::ColorChanger",
140 "SortRefUpdateSetter",
141 "SortRefNoUpdateSetter",
142 "com::sun::star::uno::ContextLayer",
143 "comphelper::FlagGuard",
144 "comphelper::FlagRestorationGuard",
145 "comphelper::ValueRestorationGuard<_Bool>",
146 "comphelper::(anonymous namespace)::ProfileZone",
147 "comphelper::ProfileZone",
148 "comphelper::ORelease<class osl::Mutex>",
149 "comphelper::OStreamSection",
150 "ConfigurationController::Lock",
154 "connectivity::(anonymous namespace)::ForbidQueryName",
155 "connectivity::calc::OCalcConnection::ODocHolder",
156 "connectivity::writer::OWriterConnection::ODocHolder",
157 "connectivity::jdbc::ContextClassLoaderScope",
159 "dbaccess::ModifyLock",
160 "dbaccess::NameChangeNotifier",
161 "dbaccess::OFilteredContainer::EnsureReset",
162 "dbaccess::OQuery::OAutoActionReset",
163 "dbaccess::OQueryContainer::OAutoActionReset",
164 "dbaccess::(anonymous namespace)::LayoutManagerLock",
165 "dbaccess::(anonymous namespace)::LockModifiable",
166 "dbaccess::(anonymous namespace)::OExecuteImpl",
167 "dbaccess::(anonymous namespace)::PreserveVisualAreaSize",
168 "dbaccess::(anonymous namespace)::ProtectFlag",
169 "dbaui::BrowserViewStatusDisplay",
170 "dbaui::SbaXDataBrowserController::FormErrorHelper",
171 "dbaui::(anonymous namespace)::SelectionGuard",
172 "dbaxml::(anonymous namespace)::FocusWindowWaitGuard",
174 "DeactivateUpdateMode",
176 "desktop::(anonymous namespace)::ConditionSetGuard",
177 "desktop::(anonymous namespace)::RefClearGuard<class "
178 "com::sun::star::uno::Reference<class com::sun::star::frame::XSynchronousDispatch> "
180 "DetachCurrentThread",
181 "DialogReleaseGuard",
182 "DisableCallbackAction",
184 "DisableGetPivotData",
185 "DispatchMutexLock_Impl",
186 "DocTemplLocker_Impl",
187 "DocumentSettingsGuard",
188 "DocxTableExportContext",
189 "dp_misc::AbortChannel::Chain",
190 "dp_misc::ProgressLevel",
191 "E3DModifySceneSnapRectUpdater",
196 "ExportDataSaveRestore",
197 "ExtensionRemoveGuard",
198 "frm::(anonymous namespace)::FieldChangeNotifier",
199 "frm::(anonymous namespace)::DocumentModifyGuard",
200 "FieldDeletionModify",
201 "FieldDeletionListener",
202 "FileHandle_Impl::Guard",
203 "FlowFrameJoinLockGuard",
204 "FmXFormShell::SuspendPropertyTracking",
205 "FocusWindowWaitCursor",
206 "formula::(anonymous namespace)::OpCodeList",
207 "formula::(anonymous namespace)::FormulaCompilerRecursionGuard",
211 "FormulaGrammarSwitch",
212 "framework::DocumentUndoGuard",
213 "framework::ShareGuard",
214 "framework::TransactionGuard",
215 "framework::(anonymous namespace)::QuickstartSuppressor",
218 "GlibThreadDefaultMainContextScope",
220 "HandleResetAttrAtTextNode",
221 "HandleSetAttrAtTextNode",
226 "jni_uno::JLocalAutoRef",
229 "MacroInterpretIncrementer",
230 "MailMergeExecuteFinalizer",
231 "ModifyBlocker_Impl",
234 "NewTextListsHelper",
236 "rptui::GeometryHandler::OBlocker",
237 "rptui::OXReportControllerObserver::OEnvLock",
238 "oglcanvas::TransformationPreserver",
239 "io_acceptor::(anonymous namespace)::BeingInAccept",
240 "desktop::LibLibreOffice_Impl",
241 "ToolbarUnoDispatcher",
242 "ooo::vba::excel::(anonymous namespace)::PasteCellsWarningReseter",
243 "oox::drawingml::(anonymous namespace)::ActionLockGuard",
244 "oox::dump::IndentGuard",
245 "oox::dump::ItemGuard",
246 "oox::dump::MultiItemsGuard",
247 "oox::dump::TableGuard",
250 "OpenGLVCLContextZone",
253 "rptui::OXUndoEnvironment::OUndoMode",
254 "rptui::OXUndoEnvironment::OUndoEnvLock",
255 "PaMIntoCursorShellRing",
258 "pcr::ComposedUIAutoFireGuard",
259 "writerperfect::(anonymous namespace)::PositionHolder",
260 "pq_sdbc_driver::DisposeGuard",
261 "PropertyChangeNotifier",
262 "ProtectFormulaGroupContext",
264 "pyuno::PyThreadAttach",
265 "pyuno::PyThreadDetach",
266 "pyuno_loader::(anonymous namespace)::PythonInit",
269 "icu_65::RegexMatcher",
273 "salhelper::ConditionModifier",
274 "salhelper::ConditionWaiter",
277 "sc::AutoCalcSwitch",
278 "sc::DelayFormulaGroupingSwitch",
284 "ScDocument::NumFmtMergeHandler",
285 "ScDocShellModificator",
286 "ScDocShell::PrepareSaveGuard",
287 "ScExternalRefManager::ApiGuard",
288 "ScFormulaGroupCycleCheckGuard",
289 "ScFormulaGroupDependencyComputeGuard",
292 "ScNoteCaptionCreator",
293 "ScValidationRegisteredDlg",
294 "ScopedAntialiasing",
295 "ScRefreshTimerProtector",
297 "ScXMLImport::MutexGuard",
299 "sd::slidesorter::controller::FocusManager::FocusHider",
300 "sd::slidesorter::controller::SlideSorterController::ModelChangeLock",
301 "sd::slidesorter::controller::PageSelector::BroadcastLock",
302 "sd::slidesorter::view::SlideSorterView::DrawLock",
303 "sd::slidesorter::controller::PageSelector::UpdateLock",
304 "sd::ViewShellManager::Implementation::UpdateLock",
305 "sd::(anonymous namespace)::LockUI",
306 "sd::ToolBarManager::UpdateLock",
307 "sd::ViewShellManager::UpdateLock",
308 "sd::OutlineViewPageChangesGuard",
309 "sd::framework::ConfigurationController::Lock",
310 "sd::slidesorter::controller::VisibleAreaManager::TemporaryDisabler",
311 "sd::slidesorter::controller::SelectionObserver::Context",
312 "sd::ToolBarManager::Implementation::UpdateLockImplementation",
313 "sd::OutlineViewModelChangeGuard",
314 "sd::slidesorter::controller::(anonymous "
315 "namespace)::TemporarySlideTrackingDeactivator",
317 "sd::OutlineViewModelChangeGuard",
318 "setFastDocumentHandlerGuard",
320 "SfxObjectShellLock",
325 "SkAutoCanvasRestore",
327 "SolarMutexReleaser",
329 "std::scoped_lock<class std::mutex>",
330 "std::unique_ptr<class com::sun::star::uno::ContextLayer, struct "
331 "std::default_delete<class com::sun::star::uno::ContextLayer> >",
332 "std::unique_ptr<class weld::WaitObject, struct std::default_delete<class "
333 "weld::WaitObject> >",
334 "std::unique_ptr<class ClearableClipRegion, struct o3tl::default_delete<class "
335 "ClearableClipRegion> >",
336 "std::unique_ptr<class SwDocShell::LockAllViewsGuard, struct "
337 "std::default_delete<class "
338 "SwDocShell::LockAllViewsGuard> >",
339 "std::unique_ptr<class SwSaveFootnoteHeight, struct std::default_delete<class "
340 "SwSaveFootnoteHeight> >",
341 "std::unique_ptr<class SwModelTestBase::Resetter, struct std::default_delete<class "
342 "SwModelTestBase::Resetter> >",
343 "StreamExceptionsEnabler",
344 "SvAddressParser_Impl",
345 "svl::undo::impl::LockGuard",
346 "svt::table::(anonymous namespace)::SuppressCursor",
347 "svx::(anonymous namespace)::FontSwitch",
348 "SvXMLElementExport",
349 "svxform::(anonymous namespace)::QuitGuard",
352 "sw::GroupUndoGuard",
353 "sw::(anonymous namespace)::CursorGuard",
361 "SwDigitModeModifier",
364 "SwEnhancedPDFExportHelper",
371 "SwFrameDeleteGuard",
372 "SwModelTestBase::Resetter",
373 "std::unique_ptr<class ScTokenArray, struct std::default_delete<class "
374 "ScTokenArray> >", // ScCompiler::CompileString has nasty semantics
378 "SwForbidFollowFormat",
379 "SwHandleAnchorNodeChg",
382 "SwKeepConversionDirectionStateContext",
385 "SwLayoutModeModifier",
387 "SwNotifyAccAboutInvalidTextSelections",
388 "SwObjPositioningInProgress",
390 "SwPauseThreadStarting",
392 "SwRedlineItr", // ???
394 "SwSaveFootnoteHeight",
396 "SwStyleBase_Impl::ItemSetOverrider",
397 "SwSwapIfNotSwapped",
399 "SwTableNumFormatMerge",
404 "SwTrnsfrActionAndUndo",
406 "SwXDispatchProviderInterceptor::DispatchMutexLock_Impl",
408 "TargetStateControl_Impl",
410 "TemporaryCellGroupMaker",
411 "TemporaryRedlineUpdater",
412 "TextFrameLockGuard",
414 "TimerTriggeredControllerLock",
415 "ToggleSaveToModule",
416 "toolkit::(anonymous namespace)::ResetFlagOnExit",
419 "rptui::UndoContext",
420 "rptui::UndoSuppressor",
421 "UndoRedoRedlineGuard",
422 "UnoActionRemoveContext",
425 "utl::CloseableComponent",
426 "utl::DisposableComponent",
429 "vclcanvas::tools::OutDevStateKeeper",
430 "vcl::PaintBufferGuard",
431 "vcl::RoadmapWizardTravelSuspension",
432 "vcl::ScopedAntialiasing",
433 "vcl::WizardTravelSuspension",
434 "VerbExecutionControllerGuard",
436 "VersionCompatWrite",
437 "SlideShowImpl::WaitSymbolLock",
438 "webdav_ucp::NeonHeadRequest",
439 "webdav_ucp::NeonPropFindRequest",
440 "webdav_ucp::NeonUri",
442 "writerfilter::ooxml::(anonymous namespace)::StatusIndicatorGuard",
443 "WriterSpecificAutoFormatBlock",
444 "xmloff::OOfficeFormsExport",
445 "xmlscript::(anonymous namespace)::MGuard",
446 "XMLTextCharStyleNamesElementExport",
448 if (ignoreClassNamesSet
.find(typeName
) != ignoreClassNamesSet
.end())
450 if (startswith(typeName
, "comphelper::ScopeGuard<"))
452 if (startswith(typeName
, "comphelper::ValueRestorationGuard<"))
454 if (startswith(typeName
, "osl::Guard<"))
456 if (startswith(typeName
, "dbaui::OMultiInstanceAutoRegistration<"))
458 if (startswith(typeName
, "pcr::OAutoRegistration<"))
461 if (var
->getIdentifier())
463 auto name
= var
->getName();
464 if (name
== "aBroadcastGuard" || name
== "aDeleteRef" || name
== "aGuard"
465 || name
== "aGuard2" || name
== "aHoldSelf" || name
== "aKeepDoc"
466 || name
== "aAutoRegistration" || name
== "aLoadContentIfExists"
467 || name
== "aOwnRef" || name
== "createImpl" || name
== "flyHolder"
468 || name
== "guard" || name
== "ensureDelete" || name
== "s_xTerminateListener"
469 || name
== "pThis" || name
== "pOldViewShell" || name
== "self"
470 || name
== "xDocStor" || name
== "xDeleteUponLeaving" || name
== "xDeleteRef"
471 || name
== "xHoldAlive" || name
== "xHolder" || name
== "xHoldRefForMethodAlive"
472 || name
== "xLock" || name
== "xMutexGuard" || name
== "xKeepAlive"
473 || name
== "xKeepContentHolderAlive" || name
== "xKeepDocAlive"
474 || name
== "xKeepMeAlive" || name
== "xKeepProviderAlive"
475 || name
== "xOperationHold" || name
== "xPreventDelete" || name
== "xSelf"
476 || name
== "xSelfHold" || name
== "xTempHold" || name
== "xDisposeAfterNewOne"
477 || name
== "xThis" || name
== "xThisPackage" || name
== "xTriggerInit"
478 || name
== "xLifeCycle" || name
== "xAnotherLifeCycle")
482 if (isa
<ParmVarDecl
>(var
))
485 if (typeName
.find("Reference") != std::string::npos
&& var
->getInit())
487 if (auto cxxConstructExpr
488 = dyn_cast
<CXXConstructExpr
>(var
->getInit()->IgnoreImplicit()))
489 if (cxxConstructExpr
->getNumArgs() == 2)
490 if (auto param1
= dyn_cast
<DeclRefExpr
>(cxxConstructExpr
->getArg(1)))
491 if (auto enumDecl
= dyn_cast
<EnumConstantDecl
>(param1
->getDecl()))
492 if (enumDecl
->getName() == "UNO_QUERY_THROW"
493 || enumDecl
->getName() == "UNO_SET_THROW")
497 report(DiagnosticsEngine::Warning
, "unused variable %0 of type %1", var
->getLocation())
498 << var
->getDeclName() << typeName
;
504 loplugin::Plugin::Registration
<UnusedVariablePlus
> unusedvariableplus("unusedvariableplus", false);
508 #endif // LO_CLANG_SHARED_PLUGINS
510 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */