lok: getSlideShowInfo: interactions: check that properties are available
[LibreOffice.git] / compilerplugins / clang / refcountingbase.cxx
blobdddc7335e8d5b98c0a68c22d04263f37a9edf3f0
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 #ifndef LO_CLANG_SHARED_PLUGINS
12 #include <string>
13 #include <iostream>
14 #include <map>
15 #include <set>
17 #include "plugin.hxx"
18 #include "check.hxx"
19 #include "clang/AST/CXXInheritance.h"
21 /**
22 * Make sure a class does not have multiple reference-counting base classes
24 namespace
26 class RefCountingBase : public loplugin::FilteringPlugin<RefCountingBase>
28 public:
29 explicit RefCountingBase(loplugin::InstantiationData const& data)
30 : FilteringPlugin(data)
34 bool preRun() override { return compiler.getLangOpts().CPlusPlus; }
36 void run() override
38 if (preRun())
40 TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
44 bool VisitCXXRecordDecl(CXXRecordDecl const*);
47 bool RefCountingBase::VisitCXXRecordDecl(CXXRecordDecl const* recordDecl)
49 if (ignoreLocation(recordDecl))
50 return true;
51 if (!recordDecl->isThisDeclarationADefinition())
52 return true;
54 int virtualWeakBase = 0;
55 int virtualOWeakObject = 0;
56 int virtualSimpleReferenceObject = 0;
57 int virtualSvRefBase = 0;
58 int virtualXmlImportContenxt = 0;
59 int virtualVclReferenceBase = 0;
60 int noRefCountingBases = 0;
61 std::string basePaths;
62 auto BaseMatchesCallback = [&](const CXXBaseSpecifier* cxxBaseSpecifier, CXXBasePath& Paths) {
63 if (!cxxBaseSpecifier->getType().getTypePtr())
64 return false;
65 const CXXRecordDecl* baseCXXRecordDecl = cxxBaseSpecifier->getType()->getAsCXXRecordDecl();
66 if (!baseCXXRecordDecl)
67 return false;
68 if (baseCXXRecordDecl->isInvalidDecl())
69 return false;
71 if (baseCXXRecordDecl->getName() != "WeakBase" // tools::WeakBase
72 && baseCXXRecordDecl->getName() != "OWeakObject" // cppu::WeakBase
73 && baseCXXRecordDecl->getName()
74 != "SimpleReferenceObject" // salhelper::SimpleReferenceObject
75 && baseCXXRecordDecl->getName() != "SvRefBase" // tool::SvRefBase
76 && baseCXXRecordDecl->getName() != "SvXMLImportContext" // in xmloff
77 && baseCXXRecordDecl->getName() != "VclReferenceBase") // in vcl
78 return false;
79 if (cxxBaseSpecifier->isVirtual())
81 if (baseCXXRecordDecl->getName() == "WeakBase")
82 virtualWeakBase = 1;
83 else if (baseCXXRecordDecl->getName() != "OWeakObject")
84 virtualOWeakObject = 1;
85 else if (baseCXXRecordDecl->getName() != "SimpleReferenceObject")
86 virtualSimpleReferenceObject = 1;
87 else if (baseCXXRecordDecl->getName() != "SvRefBase")
88 virtualSvRefBase = 1;
89 else if (baseCXXRecordDecl->getName() != "SvXMLImportContext")
90 virtualXmlImportContenxt = 1;
91 else if (baseCXXRecordDecl->getName() != "VclReferenceBase")
92 virtualVclReferenceBase = 1;
93 else
94 assert(false);
96 else
97 ++noRefCountingBases;
98 std::string sPath;
99 for (CXXBasePathElement const& pathElement : Paths)
101 if (!sPath.empty())
103 sPath += "->";
105 if (pathElement.Class->hasDefinition())
106 sPath += pathElement.Class->getNameAsString();
107 else
108 sPath += "???";
110 sPath += "->";
111 sPath += baseCXXRecordDecl->getNameAsString();
112 if (!basePaths.empty())
113 basePaths += ", ";
114 basePaths += sPath;
115 return false;
118 CXXBasePaths aPaths;
119 recordDecl->lookupInBases(BaseMatchesCallback, aPaths);
121 int total = virtualWeakBase + virtualOWeakObject + virtualSimpleReferenceObject
122 + virtualSvRefBase + virtualXmlImportContenxt + virtualVclReferenceBase
123 + noRefCountingBases;
124 if (total > 1)
126 report(DiagnosticsEngine::Warning,
127 "this class has multiple copies of a reference-counting base class, through "
128 "inheritance paths %0",
129 recordDecl->getBeginLoc())
130 << basePaths << recordDecl->getSourceRange();
132 return true;
135 loplugin::Plugin::Registration<RefCountingBase> refcountingbase("refcountingbase", true);
137 } // namespace
139 #endif // LO_CLANG_SHARED_PLUGINS
141 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */