1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
17 // Second-guess that certain private special member function declarations for
18 // which no definition can be found are left undefined to prevent them from
19 // being implicitly declared. Such situations are better expressed by marking
20 // the function as SAL_DELETED_FUNCTION (it e.g. helps compilers determine
21 // whether class members are unused if all of a class's member definitions are
22 // seen in a compilation unit). (Default constructors for classes with multiple
23 // constructors are exempted as they would not be implicitly declared.
24 // Destructors are exempted because it is likely that a destructor is defined
25 // private on purpose.)
29 CXXRecordDecl
const * getClass(CXXMethodDecl
const * decl
) {
30 CXXRecordDecl
const * cls
= dyn_cast
<CXXRecordDecl
>(decl
->getDeclContext());
31 assert(cls
!= nullptr);
36 public RecursiveASTVisitor
<DeletedSpecial
>, public loplugin::Plugin
39 explicit DeletedSpecial(InstantiationData
const & data
): Plugin(data
) {}
41 virtual void run() override
;
43 bool VisitCXXMethodDecl(CXXMethodDecl
const * decl
);
47 CXXMethodDecl
const * decl
, std::string
const & name
,
48 std::string
const & path
);
51 void DeletedSpecial::run() {
52 if (compiler
.getLangOpts().CPlusPlus
53 && compiler
.getPreprocessor().getIdentifierInfo(
54 "LIBO_INTERNAL_ONLY")->hasMacroDefinition())
56 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
60 bool DeletedSpecial::VisitCXXMethodDecl(CXXMethodDecl
const * decl
) {
61 if (ignoreLocation(decl
) || !compat::isFirstDecl(*decl
) || decl
->isDefined()
62 || decl
->isDefaulted() || decl
->getAccess() != AS_private
)
67 if (decl
->isCopyAssignmentOperator()) {
68 if (whitelist(decl
, "ImpGraphic", "vcl/inc/impgraph.hxx")
69 || whitelist(decl
, "SwSubFont", "sw/source/core/inc/swfont.hxx"))
73 desc
= "copy assignment operator";
74 } else if (decl
->isMoveAssignmentOperator()) {
75 desc
= "move assignment operator";
77 CXXConstructorDecl
const * ctor
= dyn_cast
<CXXConstructorDecl
>(decl
);
78 CXXRecordDecl
const * cls
= getClass(decl
);
79 if (ctor
!= nullptr && ctor
->isCopyConstructor()) {
80 if (whitelist(decl
, "ImpGraphic", "vcl/inc/impgraph.hxx")
81 || whitelist(decl
, "SbMethod", "include/basic/sbmeth.hxx")
82 || whitelist(decl
, "ScDBCollection::NamedDBs", "sc/inc/dbdata.hxx")
83 || whitelist(decl
, "ScDrawPage", "sc/inc/drawpage.hxx")
84 || whitelist(decl
, "ScFormEditData", "sc/source/ui/inc/formdata.hxx")
85 || whitelist(decl
, "SmEditSource", "starmath/source/accessibility.hxx")
86 || whitelist(decl
, "SwChartDataSequence", "sw/inc/unochart.hxx")
87 || whitelist(decl
, "SwDPage", "sw/inc/dpage.hxx")
88 || whitelist(decl
, "SwRedlineExtraData_Format", "sw/inc/redline.hxx")
89 || whitelist(decl
, "SwRedlineExtraData_FormattingChanges", "sw/inc/redline.hxx")
90 || whitelist(decl
, "SwTextAPIEditSource", "sw/source/core/inc/textapi.hxx")
91 || whitelist(decl
, "XclImpBiff5Decrypter", "sc/source/filter/inc/xistream.hxx")
92 || whitelist(decl
, "XclImpBiff8Decrypter", "sc/source/filter/inc/xistream.hxx")
93 || whitelist(decl
, "configmgr::LocalizedPropertyNode", "configmgr/source/localizedpropertynode.hxx")
94 || whitelist(decl
, "configmgr::LocalizedValueNode", "configmgr/source/localizedvaluenode.hxx")
95 || whitelist(decl
, "configmgr::PropertyNode", "configmgr/source/propertynode.hxx")
96 || whitelist(decl
, "oox::xls::BiffDecoder_RCF", "sc/source/filter/inc/biffcodec.hxx")
97 || whitelist(decl
, "oox::xls::BiffDecoder_XOR", "sc/source/filter/inc/biffcodec.hxx")
98 || whitelist(decl
, "rptui::OReportPage", "reportdesign/inc/RptPage.hxx"))
102 desc
= "copy constructor";
103 } else if (ctor
!= nullptr && ctor
->isMoveConstructor()) {
104 desc
= "move constructor";
105 } else if (ctor
!= nullptr && ctor
->isDefaultConstructor()
106 && std::distance(cls
->ctor_begin(), cls
->ctor_end()) == 1)
108 if (whitelist(decl
, "AquaA11yFocusListener", "vcl/osx/a11yfocuslistener.hxx")
109 || whitelist(decl
, "DocTemplLocaleHelper", "sfx2/source/doc/doctemplateslocal.hxx")
110 || whitelist(decl
, "ScViewDataTable", "sc/source/filter/excel/../../ui/inc/viewdata.hxx")
111 || whitelist(decl
, "ScViewDataTable", "sc/source/ui/inc/viewdata.hxx")
112 || whitelist(decl
, "SwLineInfo", "sw/source/core/text/inftxt.hxx")
113 || whitelist(decl
, "XRenderPeer", "vcl/unx/generic/gdi/xrender_peer.hxx")
114 || whitelist(decl
, "desktop::DispatchWatcher", "desktop/source/app/dispatchwatcher.hxx")
115 || whitelist(decl
, "desktop::OfficeIPCThread", "desktop/source/app/officeipcthread.hxx")
116 || whitelist(decl
, "desktop::OfficeIPCThread", "desktop/source/lib/../app/officeipcthread.hxx")
117 || whitelist(decl
, "sd::DiscoveryService", "sd/source/ui/remotecontrol/DiscoveryService.hxx")
118 || whitelist(decl
, "sd::IconCache", "sd/source/ui/inc/tools/IconCache.hxx")
119 || whitelist(decl
, "sd::RemoteServer", "sd/source/ui/inc/RemoteServer.hxx")
120 || whitelist(decl
, "sd::slidesorter::cache::PageCacheManager", "sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx")
121 || whitelist(decl
, "sfx2::sidebar::CommandInfoProvider", "include/sfx2/sidebar/CommandInfoProvider.hxx")
122 || whitelist(decl
, "vcl::SettingsConfigItem", "include/vcl/configsettings.hxx")
123 || whitelist(decl
, "writerfilter::ooxml::OOXMLFactory", "writerfilter/source/ooxml/OOXMLFactory.hxx"))
127 desc
= "default constructor";
133 DiagnosticsEngine::Warning
,
134 ("private %0 is not defined at least in this compilation unit, maybe it"
135 " should be marked as deleted?"),
137 << desc
<< decl
->getSourceRange();
141 bool DeletedSpecial::whitelist(
142 CXXMethodDecl
const * decl
, std::string
const & name
,
143 std::string
const & path
)
145 return getClass(decl
)->getQualifiedNameAsString() == name
146 && (compiler
.getSourceManager().getFilename(
147 compiler
.getSourceManager().getSpellingLoc(decl
->getLocation()))
148 == SRCDIR
"/" + path
);
151 loplugin::Plugin::Registration
<DeletedSpecial
> X("deletedspecial", true);
155 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */