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 "config_clang.h"
16 #include <unordered_set>
19 * Very aggressive unused variable checker, we allowlist types that are known
25 static bool startswith(const std::string
& rStr
, const char* pSubStr
)
27 return rStr
.compare(0, strlen(pSubStr
), pSubStr
) == 0;
30 class UnusedVariablePlus
: public loplugin::FilteringPlugin
<UnusedVariablePlus
>
33 explicit UnusedVariablePlus(loplugin::InstantiationData
const& data
)
34 : FilteringPlugin(data
)
38 virtual bool preRun() override
40 std::string
fn(handler
.getMainFileName());
41 loplugin::normalizeDotDotInFilePath(fn
);
42 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/canvas/workben/"))
44 if (loplugin::isSamePathname(fn
, SRCDIR
"/vcl/source/uipreviewer/previewer.cxx"))
46 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/vcl/workben/"))
48 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/vcl/qa/"))
50 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/vcl/backendtest/"))
52 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/lotuswordpro/"))
54 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/salhelper/qa/"))
56 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/sal/qa/"))
58 if (loplugin::isSamePathname(fn
, SRCDIR
"/idl/source/prj/svidl.cxx"))
60 if (loplugin::isSamePathname(fn
, SRCDIR
"/sot/source/unoolestorage/xolesimplestorage.cxx"))
62 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/source/core/tool/interpr7.cxx"))
64 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/source/ui/vba/vbaapplication.cxx"))
66 if (loplugin::isSamePathname(fn
, SRCDIR
"/sw/source/core/doc/doccomp.cxx"))
68 if (loplugin::isSamePathname(fn
, SRCDIR
"/sw/source/core/swg/SwXMLTextBlocks.cxx"))
70 if (loplugin::isSamePathname(fn
, SRCDIR
"/sw/source/filter/ww8/wrtw8esh.cxx"))
72 if (loplugin::isSamePathname(fn
, SRCDIR
73 "/shell/source/sessioninstall/SyncDbusSessionHelper.cxx"))
75 if (loplugin::isSamePathname(fn
, SRCDIR
"/svl/qa/unit/items/test_IndexedStyleSheets.cxx"))
77 if (loplugin::isSamePathname(fn
, SRCDIR
"/sd/qa/unit/export-tests-ooxml2.cxx"))
79 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/qa/unit/subsequent_export-test.cxx"))
81 if (loplugin::isSamePathname(fn
, SRCDIR
"/vcl/skia/SkiaHelper.cxx"))
83 if (loplugin::isSamePathname(fn
, SRCDIR
"/svx/source/dialog/dlgctrl.cxx"))
86 // clang has a bug here, with vars in destructing assignments
87 if (loplugin::hasPathnamePrefix(fn
, SRCDIR
"/binaryurp/"))
89 if (loplugin::isSamePathname(fn
, SRCDIR
"/sc/source/filter/excel/xestring.cxx"))
94 virtual void run() override
97 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
100 bool VisitVarDecl(const VarDecl
* var
)
102 if (ignoreLocation(var
))
104 if (var
->isReferenced() || var
->isUsed())
106 if (var
->isDefinedOutsideFunctionOrMethod())
108 if (var
->isExceptionVariable()) // not interesting
110 if (isa
<DecompositionDecl
>(var
))
113 auto type
= var
->getType().getCanonicalType().getUnqualifiedType();
114 auto typeName
= type
.getAsString();
115 if (typeName
.compare(0, 7, "struct ") == 0)
116 typeName
= typeName
.substr(7);
117 if (typeName
.compare(0, 6, "class ") == 0)
118 typeName
= typeName
.substr(6);
119 if (typeName
.compare(0, 2, "::") == 0)
120 typeName
= typeName
.substr(2);
121 if (typeName
.compare(0, 23, "(anonymous namespace)::") == 0)
122 typeName
= typeName
.substr(23);
123 static std::unordered_set
<std::string
> ignoreClassNamesSet
{
124 "apphelper::NegativeGuard<class osl::Mutex>",
125 "avmedia::gstreamer::(anonymous namespace)::FlagGuard",
128 "boost::io::basic_ios_all_saver<char, struct std::char_traits<char> >",
131 "BroadcastRecalcOnRefMoveGuard",
134 "chart::ControllerLockGuard",
135 "chart::ControllerLockGuardUNO",
136 "chart::HiddenUndoContext",
137 "chart::sidebar::(anonymous namespace)::PreventUpdate",
138 "chart::TimerTriggeredControllerLock",
140 "ClearableClipRegion",
141 "osl::ClearableGuard<class osl::Mutex>",
142 "rptui::ColorChanger",
143 "SortRefUpdateSetter",
144 "SortRefNoUpdateSetter",
145 "com::sun::star::uno::ContextLayer",
146 "comphelper::FlagGuard",
147 "comphelper::FlagRestorationGuard",
148 "comphelper::ValueRestorationGuard<_Bool>",
149 "comphelper::(anonymous namespace)::ProfileZone",
150 "comphelper::ProfileZone",
151 "comphelper::ORelease<class osl::Mutex>",
152 "comphelper::OStreamSection",
153 "ConfigurationController::Lock",
157 "connectivity::(anonymous namespace)::ForbidQueryName",
158 "connectivity::calc::OCalcConnection::ODocHolder",
159 "connectivity::writer::OWriterConnection::ODocHolder",
160 "connectivity::jdbc::ContextClassLoaderScope",
162 "dbaccess::ModifyLock",
163 "dbaccess::NameChangeNotifier",
164 "dbaccess::OFilteredContainer::EnsureReset",
165 "dbaccess::OQuery::OAutoActionReset",
166 "dbaccess::OQueryContainer::OAutoActionReset",
167 "dbaccess::(anonymous namespace)::LayoutManagerLock",
168 "dbaccess::(anonymous namespace)::LockModifiable",
169 "dbaccess::(anonymous namespace)::OExecuteImpl",
170 "dbaccess::(anonymous namespace)::PreserveVisualAreaSize",
171 "dbaccess::(anonymous namespace)::ProtectFlag",
172 "dbaui::BrowserViewStatusDisplay",
173 "dbaui::SbaXDataBrowserController::FormErrorHelper",
174 "dbaui::(anonymous namespace)::SelectionGuard",
175 "dbaxml::(anonymous namespace)::FocusWindowWaitGuard",
177 "DeactivateUpdateMode",
180 "desktop::(anonymous namespace)::ConditionSetGuard",
181 "desktop::(anonymous namespace)::RefClearGuard<class "
182 "com::sun::star::uno::Reference<class com::sun::star::frame::XSynchronousDispatch> "
184 "DetachCurrentThread",
185 "DialogReleaseGuard",
186 "DisableCallbackAction",
188 "DisableGetPivotData",
189 "DispatchMutexLock_Impl",
191 "DocTemplLocker_Impl",
192 "DocumentSettingsGuard",
193 "DocxTableExportContext",
194 "dp_misc::AbortChannel::Chain",
195 "dp_misc::ProgressLevel",
196 "E3DModifySceneSnapRectUpdater",
201 "ExportDataSaveRestore",
202 "ExtensionRemoveGuard",
203 "frm::(anonymous namespace)::FieldChangeNotifier",
204 "frm::(anonymous namespace)::DocumentModifyGuard",
205 "FieldDeletionModify",
206 "FieldDeletionListener",
207 "FileHandle_Impl::Guard",
208 "FlowFrameJoinLockGuard",
209 "FmXFormShell::SuspendPropertyTracking",
210 "FocusWindowWaitCursor",
211 "formula::(anonymous namespace)::OpCodeList",
212 "formula::(anonymous namespace)::FormulaCompilerRecursionGuard",
216 "FormulaGrammarSwitch",
217 "framework::DocumentUndoGuard",
218 "framework::ShareGuard",
219 "framework::TransactionGuard",
220 "framework::(anonymous namespace)::QuickstartSuppressor",
223 "GlibThreadDefaultMainContextScope",
225 "HandleResetAttrAtTextNode",
226 "HandleSetAttrAtTextNode",
230 "http_dav_ucp::CurlUri",
232 "jni_uno::JLocalAutoRef",
235 "MacroInterpretIncrementer",
236 "MakeAllOutlineContentTemporarilyVisible",
237 "MailMergeExecuteFinalizer",
238 "ModifyBlocker_Impl",
241 "NewTextListsHelper",
243 "rptui::GeometryHandler::OBlocker",
244 "rptui::OXReportControllerObserver::OEnvLock",
245 "oglcanvas::TransformationPreserver",
246 "io_acceptor::(anonymous namespace)::BeingInAccept",
247 "desktop::LibLibreOffice_Impl",
248 "ToolbarUnoDispatcher",
249 "ooo::vba::excel::(anonymous namespace)::PasteCellsWarningReseter",
250 "oox::drawingml::(anonymous namespace)::ActionLockGuard",
251 "oox::dump::IndentGuard",
252 "oox::dump::ItemGuard",
253 "oox::dump::MultiItemsGuard",
254 "oox::dump::TableGuard",
257 "OpenGLVCLContextZone",
260 "rptui::OXUndoEnvironment::OUndoMode",
261 "rptui::OXUndoEnvironment::OUndoEnvLock",
262 "PaMIntoCursorShellRing",
264 "pcr::ComposedUIAutoFireGuard",
266 "writerperfect::(anonymous namespace)::PositionHolder",
267 "pq_sdbc_driver::DisposeGuard",
268 "PropertyChangeNotifier",
269 "ProtectFormulaGroupContext",
271 "pyuno::PyThreadAttach",
272 "pyuno::PyThreadDetach",
273 "pyuno_loader::(anonymous namespace)::PythonInit",
276 "icu_65::RegexMatcher",
280 "salhelper::ConditionModifier",
281 "salhelper::ConditionWaiter",
284 "sc::AutoCalcSwitch",
285 "sc::DelayDeletingBroadcasters",
286 "sc::DelayFormulaGroupingSwitch",
292 "ScDocument::NumFmtMergeHandler",
293 "ScDocShellModificator",
294 "ScDocShell::PrepareSaveGuard",
295 "ScExternalRefManager::ApiGuard",
296 "ScFormulaGroupCycleCheckGuard",
297 "ScFormulaGroupDependencyComputeGuard",
300 "ScNoteCaptionCreator",
301 "ScValidationRegisteredDlg",
302 "ScopedAntialiasing",
303 "ScRefreshTimerProtector",
305 "ScXMLImport::MutexGuard",
307 "sd::slidesorter::controller::FocusManager::FocusHider",
308 "sd::slidesorter::controller::SlideSorterController::ModelChangeLock",
309 "sd::slidesorter::controller::PageSelector::BroadcastLock",
310 "sd::slidesorter::view::SlideSorterView::DrawLock",
311 "sd::slidesorter::controller::PageSelector::UpdateLock",
312 "sd::ViewShellManager::Implementation::UpdateLock",
313 "sd::(anonymous namespace)::LockUI",
314 "sd::ToolBarManager::UpdateLock",
315 "sd::ViewShellManager::UpdateLock",
316 "sd::OutlineViewPageChangesGuard",
317 "sd::framework::ConfigurationController::Lock",
318 "sd::slidesorter::controller::VisibleAreaManager::TemporaryDisabler",
319 "sd::slidesorter::controller::SelectionObserver::Context",
320 "sd::ToolBarManager::Implementation::UpdateLockImplementation",
321 "sd::OutlineViewModelChangeGuard",
322 "sd::slidesorter::controller::(anonymous "
323 "namespace)::TemporarySlideTrackingDeactivator",
325 "sd::OutlineViewModelChangeGuard",
326 "setFastDocumentHandlerGuard",
327 "SmMathConfig::CommitLocker",
330 "SfxObjectShellLock",
335 "SkAutoCanvasRestore",
337 "SolarMutexReleaser",
339 "std::lock_guard<class std::mutex>",
340 "std::scoped_lock<class std::mutex>",
341 "std::unique_lock<class std::mutex>",
342 "std::unique_lock<class std::recursive_mutex>",
343 "std::unique_ptr<class com::sun::star::uno::ContextLayer>",
344 "std::unique_ptr<class weld::WaitObject>",
345 "std::unique_ptr<class ClearableClipRegion, struct o3tl::default_delete<class "
346 "ClearableClipRegion>>",
347 "std::unique_ptr<class SfxObjectShell::LockAllViewsGuard>",
348 "std::unique_ptr<class SwDocShell::LockAllViewsGuard>",
349 "std::unique_ptr<class SwSaveFootnoteHeight>",
350 "std::unique_ptr<class SwModelTestBase::Resetter>",
351 "StreamExceptionsEnabler",
352 "SvAddressParser_Impl",
353 "svl::undo::impl::LockGuard",
354 "svt::table::(anonymous namespace)::SuppressCursor",
355 "svx::(anonymous namespace)::FontSwitch",
356 "SvXMLElementExport",
357 "svxform::(anonymous namespace)::QuitGuard",
359 "sw::FlyCreationSuppressor",
360 "sw::GroupUndoGuard",
362 "sw::(anonymous namespace)::CursorGuard",
370 "SwDigitModeModifier",
373 "SwEnhancedPDFExportHelper",
380 "SwFrameDeleteGuard",
381 "SwModelTestBase::Resetter",
382 "std::unique_ptr<class ScTokenArray>", // ScCompiler::CompileString has nasty semantics
386 "SwForbidFollowFormat",
387 "SwHandleAnchorNodeChg",
390 "SwKeepConversionDirectionStateContext",
393 "SwLayoutModeModifier",
395 "SwNotifyAccAboutInvalidTextSelections",
396 "SwObjPositioningInProgress",
398 "SwPauseThreadStarting",
400 "SwRedlineItr", // ???
402 "SwSaveFootnoteHeight",
404 "SwStyleBase_Impl::ItemSetOverrider",
405 "SwSwapIfNotSwapped",
407 "SwTableNumFormatMerge",
412 "SwTrnsfrActionAndUndo",
414 "SwXDispatchProviderInterceptor::DispatchMutexLock_Impl",
416 "TargetStateControl_Impl",
418 "TemporaryCellGroupMaker",
419 "TemporaryRedlineUpdater",
420 "TextFrameLockGuard",
422 "TimerTriggeredControllerLock",
423 "ToggleSaveToModule",
424 "toolkit::(anonymous namespace)::ResetFlagOnExit",
425 "tools::ScopedJsonWriterArray",
426 "tools::ScopedJsonWriterNode",
427 "tools::ScopedJsonWriterStruct",
430 "rptui::UndoContext",
431 "rptui::UndoSuppressor",
432 "UndoRedoRedlineGuard",
433 "UnoActionRemoveContext",
436 "utl::CloseableComponent",
437 "utl::DisposableComponent",
440 "vclcanvas::tools::OutDevStateKeeper",
441 "vcl::PaintBufferGuard",
442 "vcl::RoadmapWizardTravelSuspension",
443 "vcl::ScopedAntialiasing",
444 "vcl::WizardTravelSuspension",
445 "VerbExecutionControllerGuard",
447 "VersionCompatWrite",
449 "SlideShowImpl::WaitSymbolLock",
451 "writerfilter::ooxml::(anonymous namespace)::StatusIndicatorGuard",
452 "WriterSpecificAutoFormatBlock",
453 "xmloff::OOfficeFormsExport",
454 "xmlscript::(anonymous namespace)::MGuard",
455 "XMLTextCharStyleNamesElementExport",
457 if (ignoreClassNamesSet
.find(typeName
) != ignoreClassNamesSet
.end())
459 if (startswith(typeName
, "comphelper::ScopeGuard<"))
461 if (startswith(typeName
, "comphelper::ValueRestorationGuard<"))
463 if (startswith(typeName
, "osl::Guard<"))
465 if (startswith(typeName
, "dbaui::OMultiInstanceAutoRegistration<"))
467 if (startswith(typeName
, "pcr::OAutoRegistration<"))
470 if (var
->getIdentifier())
472 auto name
= var
->getName();
473 if (name
== "aBroadcastGuard" || name
== "aDeleteRef" || name
== "aGuard"
474 || name
== "aGuard2" || name
== "aHoldSelf" || name
== "aKeepDoc"
475 || name
== "aAutoRegistration" || name
== "aLoadContentIfExists"
476 || name
== "aOwnRef" || name
== "createImpl" || name
== "flyHolder"
477 || name
== "guard" || name
== "ensureDelete" || name
== "s_xTerminateListener"
478 || name
== "pThis" || name
== "pOldViewShell" || name
== "self"
479 || name
== "xDocStor" || name
== "xDeleteUponLeaving" || name
== "xDeleteRef"
480 || name
== "xHoldAlive" || name
== "xHolder" || name
== "xHoldRefForMethodAlive"
481 || name
== "xLock" || name
== "xMutexGuard" || name
== "xKeepAlive"
482 || name
== "xKeepContentHolderAlive" || name
== "xKeepDocAlive"
483 || name
== "xKeepMeAlive" || name
== "xKeepProviderAlive"
484 || name
== "xOperationHold" || name
== "xPreventDelete" || name
== "xSelf"
485 || name
== "xSelfHold" || name
== "xTempHold" || name
== "xDisposeAfterNewOne"
486 || name
== "xThis" || name
== "xThisPackage" || name
== "xTriggerInit"
487 || name
== "xLifeCycle" || name
== "xAnotherLifeCycle")
491 if (isa
<ParmVarDecl
>(var
))
494 if (typeName
.find("Reference") != std::string::npos
&& var
->getInit())
496 if (auto cxxConstructExpr
497 = dyn_cast
<CXXConstructExpr
>(var
->getInit()->IgnoreImplicit()))
498 if (cxxConstructExpr
->getNumArgs() == 2)
499 if (auto param1
= dyn_cast
<DeclRefExpr
>(cxxConstructExpr
->getArg(1)))
500 if (auto enumDecl
= dyn_cast
<EnumConstantDecl
>(param1
->getDecl()))
501 if (enumDecl
->getName() == "UNO_QUERY_THROW"
502 || enumDecl
->getName() == "UNO_SET_THROW")
506 report(DiagnosticsEngine::Warning
, "unused variable %0 of type %1", var
->getLocation())
507 << var
->getDeclName() << typeName
;
513 loplugin::Plugin::Registration
<UnusedVariablePlus
> unusedvariableplus("unusedvariableplus", false);
517 #endif // LO_CLANG_SHARED_PLUGINS
519 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */