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/.
15 #include "config_clang.h"
16 #include "clang/AST/CXXInheritance.h"
20 Look for places where we should be using ImplInheritanceHelper
26 class ImplInheritanceHelper
: public loplugin::FilteringPlugin
<ImplInheritanceHelper
>
29 explicit ImplInheritanceHelper(loplugin::InstantiationData
const& data
)
30 : FilteringPlugin(data
)
34 virtual bool preRun() override
{ return true; }
36 virtual void run() override
39 TraverseDecl(compiler
.getASTContext().getTranslationUnitDecl());
42 bool VisitCXXRecordDecl(const CXXRecordDecl
*);
45 bool ImplInheritanceHelper::VisitCXXRecordDecl(const CXXRecordDecl
* cxxRecordDecl
)
47 if (ignoreLocation(cxxRecordDecl
))
49 if (!cxxRecordDecl
->isThisDeclarationADefinition())
51 if (cxxRecordDecl
->isDependentContext())
54 // ignore the utility template classes
55 SourceLocation spellingLocation
56 = compiler
.getSourceManager().getSpellingLoc(cxxRecordDecl
->getBeginLoc());
57 StringRef fileName
= getFilenameOfLocation(spellingLocation
);
58 if (loplugin::hasPathnamePrefix(fileName
, SRCDIR
"/include/cppu"))
60 if (loplugin::isSamePathname(fileName
, SRCDIR
"/include/comphelper/compbase.hxx"))
63 // not sure why this extends XPropertyState but does not support it in queryInterface.
64 if (loplugin::DeclCheck(cxxRecordDecl
)
65 .Class("ChainablePropertySet")
66 .Namespace("comphelper")
69 // in these cases the UNO interface is optional
70 if (loplugin::DeclCheck(cxxRecordDecl
).Class("OFSInputStreamContainer").GlobalNamespace())
72 if (loplugin::DeclCheck(cxxRecordDecl
)
73 .Class("OPropertyBrowserController")
78 // check if this class extends cppu::WeakImplHelper
79 if (!loplugin::isDerivedFrom(cxxRecordDecl
, [](Decl
const* decl
) -> bool {
80 return bool(loplugin::DeclCheck(decl
)
81 .Class("WeakImplHelper")
86 // check if this class directly inherits from a UNO interface class
87 bool foundOne
= false;
88 for (auto const& i
: cxxRecordDecl
->bases())
90 auto rt
= i
.getType()->getAs
<RecordType
>();
93 auto const bd
= cast
<CXXRecordDecl
>(rt
->getDecl())->getDefinition();
94 auto ctx
= bd
->getDeclContext();
95 if (!ctx
->isNamespace())
97 auto ns
= dyn_cast
<NamespaceDecl
>(ctx
);
100 if (ns
->getIdentifier() && ns
->getName() == "star")
105 ns
= dyn_cast_or_null
<NamespaceDecl
>(ns
->getParent());
110 report(DiagnosticsEngine::Warning
, "can probably use ImplInheritanceHelper here",
111 cxxRecordDecl
->getLocation())
112 << cxxRecordDecl
->getSourceRange();
116 loplugin::Plugin::Registration
<ImplInheritanceHelper
>
117 implinheritancehelper("implinheritancehelper");
120 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */