summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2018-10-08 12:15:20 +0200
committerNikolai Kosjar <nikolai.kosjar@qt.io>2018-10-10 06:49:13 +0000
commitfeae30d7adefaa4ea79d3f48dbf8dd689715676f (patch)
tree24656425c76d076f0594bf8ed1d78333c8e333ec
parenteb01565c9917327db12800e480e6ee80f3f0b1db (diff)
downloadqt-creator-feae30d7adefaa4ea79d3f48dbf8dd689715676f.tar.gz
ProjectExplorer/MSVC: Cache more predefined macros
...as for the gcc toolchain. Do not cache only the "last" predefined macros, but cache them all. Change-Id: I404955e7419089bb03f7d354488f8b9980e8583b Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.cpp45
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.h6
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.h78
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp2
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro1
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qbs1
-rw-r--r--src/plugins/projectexplorer/toolchaincache.h110
7 files changed, 148 insertions, 95 deletions
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
index 9cbed08156..3983734c75 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -29,6 +29,7 @@
#include "projectexplorer.h"
#include "projectexplorersettings.h"
#include "taskhub.h"
+#include "toolchaincache.h"
#include <utils/hostosinfo.h>
#include <utils/qtcprocess.h>
@@ -46,7 +47,7 @@ namespace Internal {
AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Core::Id l, Detection d,
const Abi &abi,
const QString& vcvarsBat) : ToolChain(typeId, d),
- m_predefinedMacrosMutex(new QMutex),
+ m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>()),
m_lastEnvironment(Utils::Environment::systemEnvironment()),
m_headerPathsMutex(new QMutex),
m_abi(abi),
@@ -57,20 +58,18 @@ AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Core::Id l, Detect
AbstractMsvcToolChain::AbstractMsvcToolChain(Core::Id typeId, Detection d) :
ToolChain(typeId, d),
+ m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>()),
m_lastEnvironment(Utils::Environment::systemEnvironment())
{ }
AbstractMsvcToolChain::~AbstractMsvcToolChain()
{
- delete m_predefinedMacrosMutex;
delete m_headerPathsMutex;
}
AbstractMsvcToolChain::AbstractMsvcToolChain(const AbstractMsvcToolChain &other)
: ToolChain(other),
m_debuggerCommand(other.m_debuggerCommand),
- m_predefinedMacrosMutex(new QMutex),
- m_predefinedMacros(other.m_predefinedMacros),
m_lastEnvironment(other.m_lastEnvironment),
m_resultEnvironment(other.m_resultEnvironment),
m_headerPathsMutex(new QMutex),
@@ -147,6 +146,13 @@ LanguageVersion static languageVersionForMsvc(const Core::Id &language, const Ma
}
}
+bool static hasFlagEffectOnMacros(const QString &arg)
+{
+ if (arg.startsWith("-I"))
+ return false;
+ return true;
+}
+
Q_GLOBAL_STATIC_WITH_ARGS(const QVector<QByteArray>, unwantedMacrosMsvc,
({"_MSVC_LANG",
"_MSC_BUILD",
@@ -157,21 +163,29 @@ ToolChain::MacroInspectionRunner AbstractMsvcToolChain::createMacroInspectionRun
{
Utils::Environment env(m_lastEnvironment);
addToEnvironment(env);
+ std::shared_ptr<Cache<MacroInspectionReport, 64>> macroCache = m_predefinedMacrosCache;
const Core::Id lang = language();
// This runner must be thread-safe!
- return [this, env, lang](const QStringList &cxxflags) {
- QMutexLocker locker(m_predefinedMacrosMutex);
- if (m_predefinedMacros.isEmpty() || m_cxxFlags != cxxflags) {
- m_predefinedMacros = msvcPredefinedMacros(cxxflags, env);
- m_cxxFlags = cxxflags;
- }
+ return [this, env, macroCache, lang](const QStringList &cxxflags) {
+ const QStringList filteredFlags = Utils::filtered(cxxflags, [](const QString &arg) {
+ return hasFlagEffectOnMacros(arg);
+ });
- const QVector<Macro> filteredMacros = Utils::filtered(m_predefinedMacros, [](const Macro &m) {
+ const Utils::optional<MacroInspectionReport> cachedMacros = macroCache->check(filteredFlags);
+ if (cachedMacros)
+ return cachedMacros.value();
+
+ const Macros macros = msvcPredefinedMacros(filteredFlags, env);
+ const QVector<Macro> filteredMacros = Utils::filtered(macros, [](const Macro &m) {
return !ToolChain::isUnwantedMacro(m) && !unwantedMacrosMsvc->contains(m.key);
});
- return MacroInspectionReport{filteredMacros,
- languageVersionForMsvc(lang, m_predefinedMacros)};
+
+ const auto report = MacroInspectionReport{filteredMacros,
+ languageVersionForMsvc(lang, macros)};
+ macroCache->insert(filteredFlags, report);
+
+ return report;
};
}
@@ -460,6 +474,11 @@ void AbstractMsvcToolChain::inferWarningsForLevel(int warningLevel, WarningFlags
flags |= WarningFlags::UnusedParams;
}
+void Internal::AbstractMsvcToolChain::toolChainUpdated()
+{
+ m_predefinedMacrosCache->invalidate();
+}
+
bool AbstractMsvcToolChain::operator ==(const ToolChain &other) const
{
if (!ToolChain::operator ==(other))
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h
index bc6b297e74..a0836e4dc6 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.h
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h
@@ -26,6 +26,7 @@
#pragma once
#include "toolchain.h"
+#include "toolchaincache.h"
#include "abi.h"
#include "headerpath.h"
@@ -92,6 +93,7 @@ protected:
};
static void inferWarningsForLevel(int warningLevel, WarningFlags &flags);
+ void toolChainUpdated() override;
virtual Utils::Environment readEnvironmentSetting(const Utils::Environment& env) const = 0;
// Function must be thread-safe!
virtual Macros msvcPredefinedMacros(const QStringList cxxflags,
@@ -100,9 +102,7 @@ protected:
Utils::FileName m_debuggerCommand;
- mutable QMutex *m_predefinedMacrosMutex = nullptr;
- mutable Macros m_predefinedMacros;
- mutable QStringList m_cxxFlags;
+ mutable std::shared_ptr<Cache<MacroInspectionReport, 64>> m_predefinedMacrosCache;
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
index 63c2b78a44..13685101fd 100644
--- a/src/plugins/projectexplorer/gcctoolchain.h
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -28,14 +28,11 @@
#include "projectexplorer_export.h"
#include "toolchain.h"
+#include "toolchaincache.h"
#include "abi.h"
#include "headerpath.h"
#include <utils/fileutils.h>
-#include <utils/optional.h>
-
-#include <QMutex>
-#include <QStringList>
#include <functional>
#include <memory>
@@ -54,79 +51,6 @@ class LinuxIccToolChainFactory;
// GccToolChain
// --------------------------------------------------------------------------
-template<class T, int Size = 16>
-class Cache
-{
-public:
- Cache() { m_cache.reserve(Size); }
- Cache(const Cache &other) = delete;
- Cache &operator =(const Cache &other) = delete;
-
- Cache(Cache &&other)
- {
- using std::swap;
-
- QMutexLocker otherLocker(&other.m_mutex);
- swap(m_cache, other.m_cache);
- }
-
- Cache &operator =(Cache &&other)
- {
- using std::swap;
-
- QMutexLocker locker(&m_mutex);
- QMutexLocker otherLocker(&other.m_mutex);
- auto temporay(std::move(other.m_cache)); // Make sure other.m_cache is empty!
- swap(m_cache, temporay);
- return *this;
- }
-
- void insert(const QStringList &compilerArguments, const T &values)
- {
- CacheItem runResults;
- runResults.first = compilerArguments;
- runResults.second = values;
-
- QMutexLocker locker(&m_mutex);
- if (!checkImpl(compilerArguments)) {
- if (m_cache.size() < Size) {
- m_cache.push_back(runResults);
- } else {
- std::rotate(m_cache.begin(), std::next(m_cache.begin()), m_cache.end());
- m_cache.back() = runResults;
- }
- }
- }
-
- Utils::optional<T> check(const QStringList &compilerArguments)
- {
- QMutexLocker locker(&m_mutex);
- return checkImpl(compilerArguments);
- }
-
- void invalidate()
- {
- QMutexLocker locker(&m_mutex);
- m_cache.clear();
- }
-
-private:
- Utils::optional<T> checkImpl(const QStringList &compilerArguments)
- {
- auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) {
- return ci.first != compilerArguments;
- });
- if (it != m_cache.end())
- return m_cache.back().second;
- return {};
- }
-
- using CacheItem = QPair<QStringList, T>;
-
- QMutex m_mutex;
- QVector<CacheItem> m_cache;
-};
-
class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain
{
public:
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 7fb74661ec..50c3a9d369 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -470,8 +470,6 @@ Macros MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags,
predefinedMacros.append(Macro::fromKeyValue(define));
} else if (arg.startsWith(QLatin1String("/U"))) {
predefinedMacros.append({arg.mid(2).toLocal8Bit(), ProjectExplorer::MacroType::Undefine});
- } else if (arg.startsWith(QLatin1String("-I"))) {
- // Include paths should not have any effect on defines
} else {
toProcess.append(arg);
}
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index 8e21d9a0dd..adb2d74e37 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -89,6 +89,7 @@ HEADERS += projectexplorer.h \
projectmodels.h \
currentprojectfind.h \
toolchain.h \
+ toolchaincache.h \
toolchainconfigwidget.h \
toolchainmanager.h \
toolchainoptionspage.h \
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 58646326fa..148d9f3057 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -145,6 +145,7 @@ Project {
"taskmodel.cpp", "taskmodel.h",
"taskwindow.cpp", "taskwindow.h",
"toolchain.cpp", "toolchain.h",
+ "toolchaincache.h",
"toolchainconfigwidget.cpp", "toolchainconfigwidget.h",
"toolchainmanager.cpp", "toolchainmanager.h",
"toolchainoptionspage.cpp", "toolchainoptionspage.h",
diff --git a/src/plugins/projectexplorer/toolchaincache.h b/src/plugins/projectexplorer/toolchaincache.h
new file mode 100644
index 0000000000..154c09162f
--- /dev/null
+++ b/src/plugins/projectexplorer/toolchaincache.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QMutex>
+#include <QMutexLocker>
+#include <QStringList>
+#include <QVector>
+
+#include <utils/optional.h>
+
+namespace ProjectExplorer {
+
+template<class T, int Size = 16>
+class Cache
+{
+public:
+ Cache() { m_cache.reserve(Size); }
+ Cache(const Cache &other) = delete;
+ Cache &operator =(const Cache &other) = delete;
+
+ Cache(Cache &&other)
+ {
+ using std::swap;
+
+ QMutexLocker otherLocker(&other.m_mutex);
+ swap(m_cache, other.m_cache);
+ }
+
+ Cache &operator =(Cache &&other)
+ {
+ using std::swap;
+
+ QMutexLocker locker(&m_mutex);
+ QMutexLocker otherLocker(&other.m_mutex);
+ auto temporay(std::move(other.m_cache)); // Make sure other.m_cache is empty!
+ swap(m_cache, temporay);
+ return *this;
+ }
+
+ void insert(const QStringList &compilerArguments, const T &values)
+ {
+ CacheItem runResults;
+ runResults.first = compilerArguments;
+ runResults.second = values;
+
+ QMutexLocker locker(&m_mutex);
+ if (!checkImpl(compilerArguments)) {
+ if (m_cache.size() < Size) {
+ m_cache.push_back(runResults);
+ } else {
+ std::rotate(m_cache.begin(), std::next(m_cache.begin()), m_cache.end());
+ m_cache.back() = runResults;
+ }
+ }
+ }
+
+ Utils::optional<T> check(const QStringList &compilerArguments)
+ {
+ QMutexLocker locker(&m_mutex);
+ return checkImpl(compilerArguments);
+ }
+
+ void invalidate()
+ {
+ QMutexLocker locker(&m_mutex);
+ m_cache.clear();
+ }
+
+private:
+ Utils::optional<T> checkImpl(const QStringList &compilerArguments)
+ {
+ auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) {
+ return ci.first != compilerArguments;
+ });
+ if (it != m_cache.end())
+ return m_cache.back().second;
+ return {};
+ }
+
+ using CacheItem = QPair<QStringList, T>;
+
+ QMutex m_mutex;
+ QVector<CacheItem> m_cache;
+};
+
+} // namespace ProjectExplorer