avoid windres preprocessor quoting-messups with current cygwin
[LibreOffice.git] / compilerplugins / clang / overrideparam.cxx
blob820127e1343df79fc70ab5585200629539ddc12d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <string>
11 #include <set>
13 #include "plugin.hxx"
14 #include "compat.hxx"
15 #include "check.hxx"
18 Find overridden methods that :
19 (a) declare default params in different palces to their super-method(s)
21 Still TODO
22 (b) Find places where the values of the default parameters are different
23 (c) Find places where the names of the parameters differ
26 namespace {
28 class OverrideParam:
29 public RecursiveASTVisitor<OverrideParam>, public loplugin::Plugin
31 public:
32 explicit OverrideParam(loplugin::InstantiationData const & data):
33 Plugin(data) {}
35 virtual void run() override;
37 bool VisitCXXMethodDecl(const CXXMethodDecl *);
39 private:
40 bool hasSameDefaultParams(const ParmVarDecl * parmVarDecl, const ParmVarDecl * superParmVarDecl);
43 void OverrideParam::run()
46 StringRef fn( compiler.getSourceManager().getFileEntryForID(
47 compiler.getSourceManager().getMainFileID())->getName() );
48 if (fn == SRCDIR "/include/svx/checklbx.hxx")
49 return;
51 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
54 bool OverrideParam::VisitCXXMethodDecl(const CXXMethodDecl * methodDecl) {
55 if (ignoreLocation(methodDecl)) {
56 return true;
58 if (methodDecl->isThisDeclarationADefinition() || methodDecl->size_overridden_methods() == 0) {
59 return true;
61 loplugin::DeclCheck dc(methodDecl);
62 // there is an InsertEntry override here which causes trouble if I modify it
63 if (dc.Function("InsertEntry").Class("SvxCheckListBox").GlobalNamespace()) {
64 return true;
66 // This class is overriding ShowCursor(bool) AND declaring a ShowCursor() method.
67 // Adding a default param causes 'ambiguous override'.
68 if (dc.Function("ShowCursor").Class("ScTabViewShell").GlobalNamespace()) {
69 return true;
72 for(auto superMethodIt = methodDecl->begin_overridden_methods();
73 superMethodIt != methodDecl->end_overridden_methods(); ++superMethodIt)
75 const CXXMethodDecl * superMethodDecl = *superMethodIt;
76 if (ignoreLocation(superMethodDecl)) {
77 continue;
79 int i = 0;
80 for (const ParmVarDecl *superParmVarDecl : compat::parameters(*superMethodDecl)) {
81 const ParmVarDecl *parmVarDecl = methodDecl->getParamDecl(i);
82 if (parmVarDecl->hasDefaultArg() && !superParmVarDecl->hasDefaultArg()) {
83 report(
84 DiagnosticsEngine::Warning,
85 "overridden method declaration has default arg, but super-method does not",
86 parmVarDecl->getSourceRange().getBegin())
87 << parmVarDecl->getSourceRange();
88 report(
89 DiagnosticsEngine::Note,
90 "original param here",
91 superParmVarDecl->getSourceRange().getBegin())
92 << superParmVarDecl->getSourceRange();
94 else if (!parmVarDecl->hasDefaultArg() && superParmVarDecl->hasDefaultArg()) {
95 report(
96 DiagnosticsEngine::Warning,
97 "overridden method declaration has no default arg, but super-method does",
98 parmVarDecl->getSourceRange().getBegin())
99 << parmVarDecl->getSourceRange();
100 report(
101 DiagnosticsEngine::Note,
102 "original param here",
103 superParmVarDecl->getSourceRange().getBegin())
104 << superParmVarDecl->getSourceRange();
106 else if (parmVarDecl->hasDefaultArg() && superParmVarDecl->hasDefaultArg()
107 && !hasSameDefaultParams(parmVarDecl, superParmVarDecl)) {
108 report(
109 DiagnosticsEngine::Warning,
110 "overridden method declaration has different default param to super-method",
111 parmVarDecl->getSourceRange().getBegin())
112 << parmVarDecl->getSourceRange();
113 report(
114 DiagnosticsEngine::Note,
115 "original param here",
116 superParmVarDecl->getSourceRange().getBegin())
117 << superParmVarDecl->getSourceRange();
119 /* do nothing for now, will enable this in a later commit
120 if (methodDecl->isThisDeclarationADefinition() && parmVarDecl->getName().empty()) {
121 // ignore this - means the param is unused
123 else if (superParmVarDecl->getName().empty()) {
124 // ignore, nothing reasonable I can do
126 else if (superParmVarDecl->getName() != parmVarDecl->getName()) {
127 report(
128 DiagnosticsEngine::Warning,
129 "overridden method declaration uses different name for parameter",
130 parmVarDecl->getSourceRange().getBegin())
131 << parmVarDecl->getSourceRange();
132 report(
133 DiagnosticsEngine::Note,
134 "original param here",
135 superParmVarDecl->getSourceRange().getBegin())
136 << superParmVarDecl->getSourceRange();
138 ++i;
141 return true;
144 bool OverrideParam::hasSameDefaultParams(const ParmVarDecl * parmVarDecl, const ParmVarDecl * superParmVarDecl)
146 // don't know what this means, but it prevents a clang crash
147 if (parmVarDecl->hasUninstantiatedDefaultArg() || superParmVarDecl->hasUninstantiatedDefaultArg()) {
148 return true;
150 return
151 checkIdenticalDefaultArguments(
152 parmVarDecl->getDefaultArg(), superParmVarDecl->getDefaultArg())
153 != IdenticalDefaultArgumentsResult::No;
154 // for one, Clang 3.8 doesn't have EvaluateAsFloat; for another, since
155 // <http://llvm.org/viewvc/llvm-project?view=revision&revision=291318>
156 // "PR23135: Don't instantiate constexpr functions referenced in
157 // unevaluated operands where possible", default args are not
158 // necessarily evaluated, so the above calls to EvaluateAsInt etc. may
159 // fail (as they do e.g. for SfxViewShell::SetPrinter and derived
160 // classes' 'SfxPrinterChangeFlags nDiffFlags = SFX_PRINTER_ALL' arg,
161 // include/sfx2/viewsh.hxx; what appears would help is to call
162 // 'compiler.getSema().MarkDeclarationsReferencedInExpr()' on
163 // defaultArgExpr and superDefaultArgExpr before any of the calls to
164 // EvaluateAsInt etc., cf. the implementation of
165 // Sema::CheckCXXDefaultArgExpr in Clang's lib/Sema/SemaExpr.cpp, but
166 // that would probably have unwanted side-effects)
169 loplugin::Plugin::Registration< OverrideParam > X("overrideparam");
173 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */