summaryrefslogtreecommitdiff
path: root/compilerplugins/clang
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-04-24 13:40:59 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-04-24 16:09:08 +0200
commitbd44b3eef62f4325a189539d6ab1b90ca63cfc28 (patch)
treec7acf752ad231602fe05069606df3e5b65caae56 /compilerplugins/clang
parent81297c29ceb55dec44999e31a11dea81668c3c8f (diff)
tdf#89522 PERF FILEOPEN xlsx, part 1
Inherit from tools::WeakBase non-virtually, so that we can use a static_cast in tools::WeakReference::get instead of a dynamic_cast. This takes the file-open time from 1m21 to 40s for me. Add a clang plugin to make sure we don't accidentally end up inheriting from tools::WeakBase more than once. Change-Id: I9c7c36403333f99094e1f9d8cce2ecd9200377f9 Reviewed-on: https://gerrit.libreoffice.org/71231 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang')
-rw-r--r--compilerplugins/clang/test/weakbase.cxx34
-rw-r--r--compilerplugins/clang/weakbase.cxx110
2 files changed, 144 insertions, 0 deletions
diff --git a/compilerplugins/clang/test/weakbase.cxx b/compilerplugins/clang/test/weakbase.cxx
new file mode 100644
index 000000000000..a59a5372891e
--- /dev/null
+++ b/compilerplugins/clang/test/weakbase.cxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+namespace tools
+{
+struct WeakBase
+{
+ virtual ~WeakBase();
+};
+}
+
+struct Foo1 : public tools::WeakBase
+{
+ virtual ~Foo1();
+};
+
+struct Foo2 : public tools::WeakBase
+{
+ virtual ~Foo2();
+};
+
+// expected-error@+1 {{multiple copies of WeakBase, through inheritance paths Bar->Foo1->WeakBase, Bar->Foo2->WeakBase [loplugin:weakbase]}}
+struct Bar : public Foo1, public Foo2
+{
+ virtual ~Bar();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/compilerplugins/clang/weakbase.cxx b/compilerplugins/clang/weakbase.cxx
new file mode 100644
index 000000000000..fbd72955c0ba
--- /dev/null
+++ b/compilerplugins/clang/weakbase.cxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <string>
+#include <iostream>
+#include <map>
+#include <set>
+
+#include "plugin.hxx"
+#include "clang/AST/CXXInheritance.h"
+
+/**
+ * Check for multiple copies of WeakBase in base classes
+ */
+namespace
+{
+class WeakBase : public loplugin::FilteringPlugin<WeakBase>
+{
+public:
+ explicit WeakBase(loplugin::InstantiationData const& data)
+ : FilteringPlugin(data)
+ {
+ }
+
+ virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); }
+
+ bool VisitCXXRecordDecl(CXXRecordDecl const*);
+};
+
+bool WeakBase::VisitCXXRecordDecl(CXXRecordDecl const* recordDecl)
+{
+ if (ignoreLocation(recordDecl))
+ {
+ return true;
+ }
+ // StringRef aFileName = getFileNameOfSpellingLoc(
+ // compiler.getSourceManager().getSpellingLoc(compat::getBeginLoc(fieldDecl)));
+
+ // if (loplugin::hasPathnamePrefix(aFileName, SRCDIR "/chart2/source/"))
+ // return true;
+ // if (loplugin::isSamePathname(aFileName, SRCDIR "/include/sfx2/recentdocsview.hxx"))
+ // return true;
+ // if (loplugin::isSamePathname(aFileName, SRCDIR "/include/sfx2/templatelocalview.hxx"))
+ // return true;
+ // if (loplugin::isSamePathname(aFileName, SRCDIR "/store/source/stortree.hxx")
+ // || loplugin::isSamePathname(aFileName, SRCDIR "/store/source/stordata.hxx"))
+ // return true;
+ // if (loplugin::isSamePathname(aFileName, SRCDIR "/sw/source/uibase/inc/dbtree.hxx"))
+ // return true;
+
+ recordDecl = recordDecl->getCanonicalDecl();
+ if (!recordDecl->hasDefinition())
+ return true;
+
+ int noWeakBases = 0;
+ std::string basePaths;
+ auto BaseMatchesCallback = [&](const CXXBaseSpecifier* cxxBaseSpecifier, CXXBasePath& Paths) {
+ if (!cxxBaseSpecifier->getType().getTypePtr())
+ return false;
+ const CXXRecordDecl* baseCXXRecordDecl = cxxBaseSpecifier->getType()->getAsCXXRecordDecl();
+ if (!baseCXXRecordDecl)
+ return false;
+ if (baseCXXRecordDecl->isInvalidDecl())
+ return false;
+ if (baseCXXRecordDecl->getName() != "WeakBase")
+ return false;
+ ++noWeakBases;
+ std::string sPath;
+ for (CXXBasePathElement const& pathElement : Paths)
+ {
+ if (!sPath.empty())
+ {
+ sPath += "->";
+ }
+ if (pathElement.Class->hasDefinition())
+ sPath += pathElement.Class->getNameAsString();
+ else
+ sPath += "???";
+ }
+ sPath += "->";
+ sPath += baseCXXRecordDecl->getNameAsString();
+ if (!basePaths.empty())
+ basePaths += ", ";
+ basePaths += sPath;
+ return false;
+ };
+
+ CXXBasePaths aPaths;
+ recordDecl->lookupInBases(BaseMatchesCallback, aPaths);
+
+ if (noWeakBases > 1)
+ {
+ report(DiagnosticsEngine::Warning,
+ "multiple copies of WeakBase, through inheritance paths %0",
+ compat::getBeginLoc(recordDecl))
+ << basePaths << recordDecl->getSourceRange();
+ }
+ return true;
+}
+
+loplugin::Plugin::Registration<WeakBase> WeakBase("weakbase", true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */