aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/corelib/api/changeset.cpp6
-rw-r--r--src/lib/corelib/api/changeset.h2
-rw-r--r--src/lib/corelib/api/internaljobs.cpp23
-rw-r--r--src/lib/corelib/api/internaljobs.h16
-rw-r--r--src/lib/corelib/api/jobs.cpp11
-rw-r--r--src/lib/corelib/api/jobs.h7
-rw-r--r--src/lib/corelib/api/project.cpp278
-rw-r--r--src/lib/corelib/api/project_p.h23
-rw-r--r--src/lib/corelib/api/projectfileupdater.cpp43
-rw-r--r--src/lib/corelib/api/projectfileupdater.h13
-rw-r--r--src/lib/corelib/api/qmljsrewriter.cpp14
-rw-r--r--src/lib/corelib/api/qmljsrewriter.h4
-rw-r--r--src/lib/corelib/api/rulecommand.cpp12
-rw-r--r--src/lib/corelib/api/runenvironment.cpp2
-rw-r--r--src/lib/corelib/api/runenvironment.h4
-rw-r--r--src/lib/corelib/api/transformerdata.cpp10
-rw-r--r--src/lib/corelib/buildgraph/artifactcleaner.cpp2
-rw-r--r--src/lib/corelib/buildgraph/artifactcleaner.h2
-rw-r--r--src/lib/corelib/buildgraph/artifactvisitor.cpp2
-rw-r--r--src/lib/corelib/buildgraph/buildgraph.cpp8
-rw-r--r--src/lib/corelib/buildgraph/buildgraphloader.cpp15
-rw-r--r--src/lib/corelib/buildgraph/buildgraphloader.h6
-rw-r--r--src/lib/corelib/buildgraph/depscanner.h2
-rw-r--r--src/lib/corelib/buildgraph/environmentscriptrunner.cpp6
-rw-r--r--src/lib/corelib/buildgraph/executor.cpp42
-rw-r--r--src/lib/corelib/buildgraph/executor.h5
-rw-r--r--src/lib/corelib/buildgraph/executorjob.cpp4
-rw-r--r--src/lib/corelib/buildgraph/executorjob.h2
-rw-r--r--src/lib/corelib/buildgraph/filedependency.cpp16
-rw-r--r--src/lib/corelib/buildgraph/inputartifactscanner.cpp24
-rw-r--r--src/lib/corelib/buildgraph/nodetreedumper.cpp4
-rw-r--r--src/lib/corelib/buildgraph/nodetreedumper.h4
-rw-r--r--src/lib/corelib/buildgraph/processcommandexecutor.cpp3
-rw-r--r--src/lib/corelib/buildgraph/productinstaller.cpp6
-rw-r--r--src/lib/corelib/buildgraph/productinstaller.h4
-rw-r--r--src/lib/corelib/buildgraph/projectbuilddata.cpp10
-rw-r--r--src/lib/corelib/buildgraph/qtmocscanner.cpp2
-rw-r--r--src/lib/corelib/buildgraph/requesteddependencies.cpp6
-rw-r--r--src/lib/corelib/buildgraph/rescuableartifactdata.h9
-rw-r--r--src/lib/corelib/buildgraph/rulecommands.cpp17
-rw-r--r--src/lib/corelib/buildgraph/rulecommands.h10
-rw-r--r--src/lib/corelib/buildgraph/rulegraph.cpp8
-rw-r--r--src/lib/corelib/buildgraph/rulenode.cpp12
-rw-r--r--src/lib/corelib/buildgraph/rulesapplicator.cpp19
-rw-r--r--src/lib/corelib/buildgraph/rulesapplicator.h4
-rw-r--r--src/lib/corelib/buildgraph/scriptclasspropertyiterator.h4
-rw-r--r--src/lib/corelib/buildgraph/timestampsupdater.cpp2
-rw-r--r--src/lib/corelib/buildgraph/timestampsupdater.h2
-rw-r--r--src/lib/corelib/buildgraph/transformer.cpp6
-rw-r--r--src/lib/corelib/buildgraph/transformer.h2
-rw-r--r--src/lib/corelib/buildgraph/transformerchangetracking.cpp4
-rw-r--r--src/lib/corelib/corelib.qbs2
-rw-r--r--src/lib/corelib/generators/generatordata.h4
-rw-r--r--src/lib/corelib/generators/generatorutils.h15
-rw-r--r--src/lib/corelib/generators/generatorversioninfo.cpp32
-rw-r--r--src/lib/corelib/generators/generatorversioninfo.h29
-rw-r--r--src/lib/corelib/generators/igeneratableprojectvisitor.h2
-rw-r--r--src/lib/corelib/generators/ixmlnodevisitor.h2
-rw-r--r--src/lib/corelib/generators/xmlprojectwriter.cpp3
-rw-r--r--src/lib/corelib/generators/xmlpropertygroup.cpp5
-rw-r--r--src/lib/corelib/generators/xmlpropertygroup.h2
-rw-r--r--src/lib/corelib/generators/xmlworkspacewriter.cpp3
-rw-r--r--src/lib/corelib/jsextensions/binaryfile.cpp2
-rw-r--r--src/lib/corelib/jsextensions/domxml.cpp5
-rw-r--r--src/lib/corelib/jsextensions/fileinfoextension.cpp14
-rw-r--r--src/lib/corelib/jsextensions/jsextensions.cpp2
-rw-r--r--src/lib/corelib/jsextensions/jsextensions.h2
-rw-r--r--src/lib/corelib/jsextensions/moduleproperties.cpp2
-rw-r--r--src/lib/corelib/jsextensions/propertylist.mm4
-rw-r--r--src/lib/corelib/jsextensions/utilitiesextension.cpp80
-rw-r--r--src/lib/corelib/language/artifactproperties.cpp5
-rw-r--r--src/lib/corelib/language/asttools.cpp4
-rw-r--r--src/lib/corelib/language/builtindeclarations.cpp2
-rw-r--r--src/lib/corelib/language/builtindeclarations.h2
-rw-r--r--src/lib/corelib/language/deprecationinfo.h6
-rw-r--r--src/lib/corelib/language/evaluator.h2
-rw-r--r--src/lib/corelib/language/identifiersearch.cpp4
-rw-r--r--src/lib/corelib/language/item.cpp14
-rw-r--r--src/lib/corelib/language/itempool.cpp4
-rw-r--r--src/lib/corelib/language/itemreadervisitorstate.cpp5
-rw-r--r--src/lib/corelib/language/language.cpp35
-rw-r--r--src/lib/corelib/language/language.h26
-rw-r--r--src/lib/corelib/language/moduleloader.cpp349
-rw-r--r--src/lib/corelib/language/moduleloader.h18
-rw-r--r--src/lib/corelib/language/modulemerger.cpp226
-rw-r--r--src/lib/corelib/language/modulemerger.h31
-rw-r--r--src/lib/corelib/language/moduleproviderinfo.h9
-rw-r--r--src/lib/corelib/language/projectresolver.cpp11
-rw-r--r--src/lib/corelib/language/projectresolver.h6
-rw-r--r--src/lib/corelib/language/property.h10
-rw-r--r--src/lib/corelib/language/propertydeclaration.cpp15
-rw-r--r--src/lib/corelib/language/propertymapinternal.cpp8
-rw-r--r--src/lib/corelib/language/qualifiedid.cpp4
-rw-r--r--src/lib/corelib/language/resolvedfilecontext.h2
-rw-r--r--src/lib/corelib/language/scriptengine.cpp13
-rw-r--r--src/lib/corelib/language/value.cpp10
-rw-r--r--src/lib/corelib/language/value.h8
-rw-r--r--src/lib/corelib/logging/logger.cpp11
-rw-r--r--src/lib/corelib/logging/logger.h4
-rw-r--r--src/lib/corelib/parser/qmljsast_p.h14
-rw-r--r--src/lib/corelib/parser/qmljsastvisitor.cpp8
-rw-r--r--src/lib/corelib/parser/qmljsengine_p.cpp7
-rw-r--r--src/lib/corelib/parser/qmljsengine_p.h9
-rw-r--r--src/lib/corelib/parser/qmljslexer.cpp30
-rw-r--r--src/lib/corelib/parser/qmljslexer_p.h2
-rw-r--r--src/lib/corelib/parser/qmljsmemorypool_p.h4
-rw-r--r--src/lib/corelib/parser/qmljsparser.cpp14
-rw-r--r--src/lib/corelib/tools/buildoptions.cpp14
-rw-r--r--src/lib/corelib/tools/clangclinfo.cpp176
-rw-r--r--src/lib/corelib/tools/clangclinfo.h61
-rw-r--r--src/lib/corelib/tools/cleanoptions.cpp16
-rw-r--r--src/lib/corelib/tools/codelocation.cpp18
-rw-r--r--src/lib/corelib/tools/error.cpp34
-rw-r--r--src/lib/corelib/tools/error.h4
-rw-r--r--src/lib/corelib/tools/executablefinder.cpp4
-rw-r--r--src/lib/corelib/tools/executablefinder.h2
-rw-r--r--src/lib/corelib/tools/fileinfo.cpp2
-rw-r--r--src/lib/corelib/tools/generateoptions.cpp14
-rw-r--r--src/lib/corelib/tools/hostosinfo.h22
-rw-r--r--src/lib/corelib/tools/id.cpp6
-rw-r--r--src/lib/corelib/tools/id.h2
-rw-r--r--src/lib/corelib/tools/installoptions.cpp14
-rw-r--r--src/lib/corelib/tools/joblimits.cpp20
-rw-r--r--src/lib/corelib/tools/jsonhelper.h6
-rw-r--r--src/lib/corelib/tools/launcherinterface.cpp4
-rw-r--r--src/lib/corelib/tools/launcherpackets.cpp2
-rw-r--r--src/lib/corelib/tools/msvcinfo.cpp419
-rw-r--r--src/lib/corelib/tools/msvcinfo.h28
-rw-r--r--src/lib/corelib/tools/persistence.cpp20
-rw-r--r--src/lib/corelib/tools/persistence.h2
-rw-r--r--src/lib/corelib/tools/processresult.cpp14
-rw-r--r--src/lib/corelib/tools/processutils.cpp3
-rw-r--r--src/lib/corelib/tools/profile.cpp10
-rw-r--r--src/lib/corelib/tools/profile.h2
-rw-r--r--src/lib/corelib/tools/progressobserver.h2
-rw-r--r--src/lib/corelib/tools/projectgeneratormanager.cpp8
-rw-r--r--src/lib/corelib/tools/qttools.h19
-rw-r--r--src/lib/corelib/tools/scannerpluginmanager.cpp4
-rw-r--r--src/lib/corelib/tools/set.h2
-rw-r--r--src/lib/corelib/tools/settings.cpp12
-rw-r--r--src/lib/corelib/tools/settings.h6
-rw-r--r--src/lib/corelib/tools/settingscreator.cpp9
-rw-r--r--src/lib/corelib/tools/settingscreator.h2
-rw-r--r--src/lib/corelib/tools/settingsmodel.cpp4
-rw-r--r--src/lib/corelib/tools/setupprojectparameters.cpp20
-rw-r--r--src/lib/corelib/tools/shellutils.cpp4
-rw-r--r--src/lib/corelib/tools/shellutils.h2
-rw-r--r--src/lib/corelib/tools/stlutils.h15
-rw-r--r--src/lib/corelib/tools/stringconstants.h1
-rw-r--r--src/lib/corelib/tools/stringutils.h4
-rw-r--r--src/lib/corelib/tools/toolchains.cpp7
-rw-r--r--src/lib/corelib/tools/tools.pri2
-rw-r--r--src/lib/corelib/tools/version.cpp70
-rw-r--r--src/lib/corelib/tools/version.h70
-rw-r--r--src/lib/corelib/tools/visualstudioversioninfo.cpp6
-rw-r--r--src/lib/corelib/tools/vsenvironmentdetector.cpp7
-rw-r--r--src/lib/scriptengine/use_scriptengine.pri10
157 files changed, 1768 insertions, 1321 deletions
diff --git a/src/lib/corelib/api/changeset.cpp b/src/lib/corelib/api/changeset.cpp
index 5d375fd65..773af328d 100644
--- a/src/lib/corelib/api/changeset.cpp
+++ b/src/lib/corelib/api/changeset.cpp
@@ -48,8 +48,8 @@ ChangeSet::ChangeSet()
{
}
-ChangeSet::ChangeSet(const QList<EditOp> &operations)
- : m_string(nullptr), m_cursor(nullptr), m_operationList(operations), m_error(false)
+ChangeSet::ChangeSet(QList<EditOp> operations)
+ : m_string(nullptr), m_cursor(nullptr), m_operationList(std::move(operations)), m_error(false)
{
}
@@ -393,5 +393,5 @@ void ChangeSet::apply_helper()
m_cursor->endEditBlock();
}
-} // namespace Internal {
+} // namespace QbsQmlJS
diff --git a/src/lib/corelib/api/changeset.h b/src/lib/corelib/api/changeset.h
index 13d3908d4..23248c48e 100644
--- a/src/lib/corelib/api/changeset.h
+++ b/src/lib/corelib/api/changeset.h
@@ -86,7 +86,7 @@ public:
public:
ChangeSet();
- ChangeSet(const QList<EditOp> &operations);
+ ChangeSet(QList<EditOp> operations);
bool empty() const;
diff --git a/src/lib/corelib/api/internaljobs.cpp b/src/lib/corelib/api/internaljobs.cpp
index c74c3d8a4..c53cf3e33 100644
--- a/src/lib/corelib/api/internaljobs.cpp
+++ b/src/lib/corelib/api/internaljobs.cpp
@@ -225,9 +225,7 @@ InternalSetupProjectJob::InternalSetupProjectJob(const Logger &logger)
{
}
-InternalSetupProjectJob::~InternalSetupProjectJob()
-{
-}
+InternalSetupProjectJob::~InternalSetupProjectJob() = default;
void InternalSetupProjectJob::init(const TopLevelProjectPtr &existingProject,
const SetupProjectParameters &parameters)
@@ -350,12 +348,10 @@ BuildGraphTouchingJob::BuildGraphTouchingJob(const Logger &logger, QObject *pare
{
}
-BuildGraphTouchingJob::~BuildGraphTouchingJob()
-{
-}
+BuildGraphTouchingJob::~BuildGraphTouchingJob() = default;
void BuildGraphTouchingJob::setup(const TopLevelProjectPtr &project,
- const QList<ResolvedProductPtr> &products, bool dryRun)
+ const QVector<ResolvedProductPtr> &products, bool dryRun)
{
m_project = project;
m_products = products;
@@ -374,14 +370,14 @@ InternalBuildJob::InternalBuildJob(const Logger &logger, QObject *parent)
}
void InternalBuildJob::build(const TopLevelProjectPtr &project,
- const QList<ResolvedProductPtr> &products, const BuildOptions &buildOptions)
+ const QVector<ResolvedProductPtr> &products, const BuildOptions &buildOptions)
{
setup(project, products, buildOptions.dryRun());
setTimed(buildOptions.logElapsedTime());
m_executor = new Executor(logger());
m_executor->setProject(project);
- m_executor->setProducts(std::vector<ResolvedProductPtr>(products.cbegin(), products.cend()));
+ m_executor->setProducts(products);
m_executor->setBuildOptions(buildOptions);
m_executor->setProgressObserver(observer());
@@ -418,7 +414,8 @@ InternalCleanJob::InternalCleanJob(const Logger &logger, QObject *parent)
}
void InternalCleanJob::init(const TopLevelProjectPtr &project,
- const QList<ResolvedProductPtr> &products, const CleanOptions &options)
+ const QVector<ResolvedProductPtr> &products,
+ const CleanOptions &options)
{
setup(project, products, options.dryRun());
setTimed(options.logElapsedTime());
@@ -443,12 +440,10 @@ InternalInstallJob::InternalInstallJob(const Logger &logger)
{
}
-InternalInstallJob::~InternalInstallJob()
-{
-}
+InternalInstallJob::~InternalInstallJob() = default;
void InternalInstallJob::init(const TopLevelProjectPtr &project,
- const std::vector<ResolvedProductPtr> &products, const InstallOptions &options)
+ const QVector<ResolvedProductPtr> &products, const InstallOptions &options)
{
m_project = project;
m_products = products;
diff --git a/src/lib/corelib/api/internaljobs.h b/src/lib/corelib/api/internaljobs.h
index 58127eb05..d66835941 100644
--- a/src/lib/corelib/api/internaljobs.h
+++ b/src/lib/corelib/api/internaljobs.h
@@ -151,7 +151,7 @@ class BuildGraphTouchingJob : public InternalJob
{
Q_OBJECT
public:
- const QList<ResolvedProductPtr> &products() const { return m_products; }
+ const QVector<ResolvedProductPtr> &products() const { return m_products; }
const TopLevelProjectPtr &project() const { return m_project; }
signals:
@@ -162,13 +162,13 @@ protected:
BuildGraphTouchingJob(const Logger &logger, QObject *parent = nullptr);
~BuildGraphTouchingJob() override;
- void setup(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products,
+ void setup(const TopLevelProjectPtr &project, const QVector<ResolvedProductPtr> &products,
bool dryRun);
void storeBuildGraph();
private:
TopLevelProjectPtr m_project;
- QList<ResolvedProductPtr> m_products;
+ QVector<ResolvedProductPtr> m_products;
bool m_dryRun;
};
@@ -179,7 +179,7 @@ class InternalBuildJob : public BuildGraphTouchingJob
public:
InternalBuildJob(const Logger &logger, QObject *parent = nullptr);
- void build(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products,
+ void build(const TopLevelProjectPtr &project, const QVector<ResolvedProductPtr> &products,
const BuildOptions &buildOptions);
private:
@@ -196,8 +196,8 @@ class InternalCleanJob : public BuildGraphTouchingJob
public:
InternalCleanJob(const Logger &logger, QObject *parent = nullptr);
- void init(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products,
- const CleanOptions &options);
+ void init(const TopLevelProjectPtr &project, const QVector<ResolvedProductPtr> &products,
+ const CleanOptions &options);
private:
void start() override;
@@ -213,14 +213,14 @@ public:
InternalInstallJob(const Logger &logger);
~InternalInstallJob() override;
- void init(const TopLevelProjectPtr &project, const std::vector<ResolvedProductPtr> &products,
+ void init(const TopLevelProjectPtr &project, const QVector<ResolvedProductPtr> &products,
const InstallOptions &options);
private:
void start() override;
TopLevelProjectPtr m_project;
- std::vector<ResolvedProductPtr> m_products;
+ QVector<ResolvedProductPtr> m_products;
InstallOptions m_options;
};
diff --git a/src/lib/corelib/api/jobs.cpp b/src/lib/corelib/api/jobs.cpp
index 32b7accc7..7a845b0ac 100644
--- a/src/lib/corelib/api/jobs.cpp
+++ b/src/lib/corelib/api/jobs.cpp
@@ -309,7 +309,7 @@ BuildJob::BuildJob(const Logger &logger, QObject *parent)
this, &BuildJob::reportProcessResult);
}
-void BuildJob::build(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products,
+void BuildJob::build(const TopLevelProjectPtr &project, const QVector<ResolvedProductPtr> &products,
const BuildOptions &options)
{
if (!lockProject(project))
@@ -340,7 +340,7 @@ CleanJob::CleanJob(const Logger &logger, QObject *parent)
{
}
-void CleanJob::clean(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products,
+void CleanJob::clean(const TopLevelProjectPtr &project, const QVector<ResolvedProductPtr> &products,
const qbs::CleanOptions &options)
{
if (!lockProject(project))
@@ -361,15 +361,14 @@ InstallJob::InstallJob(const Logger &logger, QObject *parent)
}
void InstallJob::install(const TopLevelProjectPtr &project,
- const QList<ResolvedProductPtr> &products, const InstallOptions &options)
+ const QVector<ResolvedProductPtr> &products,
+ const InstallOptions &options)
{
if (!lockProject(project))
return;
auto wrapper = qobject_cast<InternalJobThreadWrapper *>(internalJob());
auto installJob = qobject_cast<InternalInstallJob *>(wrapper->synchronousJob());
- installJob->init(project,
- std::vector<ResolvedProductPtr>(products.cbegin(), products.cend()),
- options);
+ installJob->init(project, products, options);
wrapper->start();
}
diff --git a/src/lib/corelib/api/jobs.h b/src/lib/corelib/api/jobs.h
index 36c6b7a80..64929489e 100644
--- a/src/lib/corelib/api/jobs.h
+++ b/src/lib/corelib/api/jobs.h
@@ -136,7 +136,7 @@ private:
BuildJob(const Internal::Logger &logger, QObject *parent);
void build(const Internal::TopLevelProjectPtr &project,
- const QList<qbs::Internal::ResolvedProductPtr> &products,
+ const QVector<Internal::ResolvedProductPtr> &products,
const BuildOptions &options);
void handleLauncherError(const ErrorInfo &error);
@@ -153,7 +153,7 @@ private:
CleanJob(const Internal::Logger &logger, QObject *parent);
void clean(const Internal::TopLevelProjectPtr &project,
- const QList<Internal::ResolvedProductPtr> &products, const CleanOptions &options);
+ const QVector<Internal::ResolvedProductPtr> &products, const CleanOptions &options);
};
class QBS_EXPORT InstallJob : public AbstractJob
@@ -164,7 +164,8 @@ private:
InstallJob(const Internal::Logger &logger, QObject *parent);
void install(const Internal::TopLevelProjectPtr &project,
- const QList<Internal::ResolvedProductPtr> &products, const InstallOptions &options);
+ const QVector<Internal::ResolvedProductPtr> &products,
+ const InstallOptions &options);
};
} // namespace qbs
diff --git a/src/lib/corelib/api/project.cpp b/src/lib/corelib/api/project.cpp
index d0fe7296e..2b07f1a8d 100644
--- a/src/lib/corelib/api/project.cpp
+++ b/src/lib/corelib/api/project.cpp
@@ -131,7 +131,7 @@ ProjectData ProjectPrivate::projectData()
return m_projectData;
}
-static void addDependencies(QList<ResolvedProductPtr> &products)
+static void addDependencies(QVector<ResolvedProductPtr> &products)
{
for (int i = 0; i < products.size(); ++i) {
const ResolvedProductPtr &product = products.at(i);
@@ -142,11 +142,11 @@ static void addDependencies(QList<ResolvedProductPtr> &products)
}
}
-BuildJob *ProjectPrivate::buildProducts(const QList<ResolvedProductPtr> &products,
+BuildJob *ProjectPrivate::buildProducts(const QVector<ResolvedProductPtr> &products,
const BuildOptions &options, bool needsDepencencyResolving,
QObject *jobOwner)
{
- QList<ResolvedProductPtr> productsToBuild = products;
+ QVector<ResolvedProductPtr> productsToBuild = products;
if (needsDepencencyResolving)
addDependencies(productsToBuild);
@@ -156,7 +156,7 @@ BuildJob *ProjectPrivate::buildProducts(const QList<ResolvedProductPtr> &product
return job;
}
-CleanJob *ProjectPrivate::cleanProducts(const QList<ResolvedProductPtr> &products,
+CleanJob *ProjectPrivate::cleanProducts(const QVector<ResolvedProductPtr> &products,
const CleanOptions &options, QObject *jobOwner)
{
const auto job = new CleanJob(logger, jobOwner);
@@ -165,10 +165,10 @@ CleanJob *ProjectPrivate::cleanProducts(const QList<ResolvedProductPtr> &product
return job;
}
-InstallJob *ProjectPrivate::installProducts(const QList<ResolvedProductPtr> &products,
+InstallJob *ProjectPrivate::installProducts(const QVector<ResolvedProductPtr> &products,
const InstallOptions &options, bool needsDepencencyResolving, QObject *jobOwner)
{
- QList<ResolvedProductPtr> productsToInstall = products;
+ QVector<ResolvedProductPtr> productsToInstall = products;
if (needsDepencencyResolving)
addDependencies(productsToInstall);
const auto job = new InstallJob(logger, jobOwner);
@@ -177,9 +177,9 @@ InstallJob *ProjectPrivate::installProducts(const QList<ResolvedProductPtr> &pro
return job;
}
-QList<ResolvedProductPtr> ProjectPrivate::internalProducts(const QList<ProductData> &products) const
+QVector<ResolvedProductPtr> ProjectPrivate::internalProducts(const QList<ProductData> &products) const
{
- QList<ResolvedProductPtr> internalProducts;
+ QVector<ResolvedProductPtr> internalProducts;
for (const ProductData &product : products) {
if (product.isEnabled())
internalProducts.push_back(internalProduct(product));
@@ -187,20 +187,21 @@ QList<ResolvedProductPtr> ProjectPrivate::internalProducts(const QList<ProductDa
return internalProducts;
}
-static QList<ResolvedProductPtr> enabledInternalProducts(const ResolvedProjectConstPtr &project,
+static QVector<ResolvedProductPtr> enabledInternalProducts(const ResolvedProjectConstPtr &project,
bool includingNonDefault)
{
- QList<ResolvedProductPtr> products;
+ QVector<ResolvedProductPtr> products;
for (const ResolvedProductPtr &p : project->products) {
if (p->enabled && (includingNonDefault || p->builtByDefault()))
products.push_back(p);
}
- for (const ResolvedProjectConstPtr &subProject : qAsConst(project->subProjects))
+ for (const auto &subProject : qAsConst(project->subProjects))
products << enabledInternalProducts(subProject, includingNonDefault);
return products;
}
-QList<ResolvedProductPtr> ProjectPrivate::allEnabledInternalProducts(bool includingNonDefault) const
+QVector<ResolvedProductPtr> ProjectPrivate::allEnabledInternalProducts(
+ bool includingNonDefault) const
{
return enabledInternalProducts(internalProject, includingNonDefault);
}
@@ -218,7 +219,7 @@ static ResolvedProductPtr internalProductForProject(const ResolvedProjectConstPt
if (matches(product, resolvedProduct))
return resolvedProduct;
}
- for (const ResolvedProjectConstPtr &subProject : qAsConst(project->subProjects)) {
+ for (const auto &subProject : qAsConst(project->subProjects)) {
const ResolvedProductPtr &p = internalProductForProject(subProject, product);
if (p)
return p;
@@ -272,13 +273,13 @@ GroupData ProjectPrivate::createGroupDataFromGroup(const GroupPtr &resolvedGroup
group.d->name = resolvedGroup->name;
group.d->prefix = resolvedGroup->prefix;
group.d->location = resolvedGroup->location;
- for (const SourceArtifactConstPtr &sa : resolvedGroup->files) {
+ for (const auto &sa : resolvedGroup->files) {
ArtifactData artifact = createApiSourceArtifact(sa);
setupInstallData(artifact, product);
group.d->sourceArtifacts.push_back(artifact);
}
if (resolvedGroup->wildcards) {
- for (const SourceArtifactConstPtr &sa : resolvedGroup->wildcards->files) {
+ for (const auto &sa : resolvedGroup->wildcards->files) {
ArtifactData artifact = createApiSourceArtifact(sa);
setupInstallData(artifact, product);
group.d->sourceArtifactsFromWildcards.push_back(artifact);
@@ -355,7 +356,7 @@ void ProjectPrivate::addGroup(const ProductData &product, const QString &groupNa
QList<ProductData> products = findProductsByName(product.name());
if (products.empty())
throw ErrorInfo(Tr::tr("Product '%1' does not exist.").arg(product.name()));
- const QList<ResolvedProductPtr> resolvedProducts = internalProducts(products);
+ const auto resolvedProducts = internalProducts(products);
QBS_CHECK(products.size() == resolvedProducts.size());
for (const GroupPtr &resolvedGroup : resolvedProducts.front()->groups) {
@@ -367,28 +368,6 @@ void ProjectPrivate::addGroup(const ProductData &product, const QString &groupNa
ProjectFileGroupInserter groupInserter(products.front(), groupName);
groupInserter.apply();
-
- m_projectData.d.detach(); // The data we already gave out must stay as it is.
-
- updateInternalCodeLocations(internalProject, groupInserter.itemPosition(),
- groupInserter.lineOffset());
- updateExternalCodeLocations(m_projectData, groupInserter.itemPosition(),
- groupInserter.lineOffset());
-
- products = findProductsByName(products.front().name()); // These are new objects.
- QBS_CHECK(products.size() == resolvedProducts.size());
- for (int i = 0; i < products.size(); ++i) {
- const GroupPtr resolvedGroup = ResolvedGroup::create();
- resolvedGroup->location = groupInserter.itemPosition();
- resolvedGroup->enabled = true;
- resolvedGroup->name = groupName;
- resolvedGroup->properties = resolvedProducts[i]->moduleProperties;
- resolvedGroup->overrideTags = false;
- resolvedProducts.at(i)->groups << resolvedGroup;
- QList<GroupData> &groupData = products.at(i).d->groups;
- groupData << createGroupDataFromGroup(resolvedGroup, resolvedProducts.at(i));
- std::sort(groupData.begin(), groupData.end());
- }
}
ProjectPrivate::GroupUpdateContext ProjectPrivate::getGroupContext(const ProductData &product,
@@ -484,15 +463,6 @@ ProjectPrivate::FileListUpdateContext ProjectPrivate::getFileListContext(const P
return filesContext;
}
-static SourceArtifactPtr createSourceArtifact(const QString &filePath,
- const ResolvedProductPtr &product, const GroupPtr &group, bool wildcard)
-{
- const SourceArtifactPtr artifact
- = ProjectResolver::createSourceArtifact(product, filePath, group, wildcard);
- ProjectResolver::applyFileTaggers(artifact, product);
- return artifact;
-}
-
void ProjectPrivate::addFiles(const ProductData &product, const GroupData &group,
const QStringList &filePaths)
{
@@ -503,7 +473,7 @@ void ProjectPrivate::addFiles(const ProductData &product, const GroupData &group
// due to conditions.
for (const GroupPtr &group : qAsConst(groupContext.resolvedGroups)) {
for (const QString &filePath : qAsConst(filesContext.absoluteFilePaths)) {
- for (const SourceArtifactConstPtr &sa : group->files) {
+ for (const auto &sa : group->files) {
if (sa->absoluteFilePath == filePath) {
throw ErrorInfo(Tr::tr("File '%1' already exists in group '%2'.")
.arg(filePath, group->name));
@@ -516,57 +486,6 @@ void ProjectPrivate::addFiles(const ProductData &product, const GroupData &group
group.isValid() ? groupContext.groups.front() : GroupData(),
filesContext.relativeFilePaths);
adder.apply();
-
- m_projectData.d.detach();
- updateInternalCodeLocations(internalProject, adder.itemPosition(), adder.lineOffset());
- updateExternalCodeLocations(m_projectData, adder.itemPosition(), adder.lineOffset());
-
- QHash<QString, std::pair<SourceArtifactPtr, ResolvedProductPtr>> addedSourceArtifacts;
- for (int i = 0; i < groupContext.resolvedGroups.size(); ++i) {
- const ResolvedProductPtr &resolvedProduct = groupContext.resolvedProducts.at(i);
- const GroupPtr &resolvedGroup = groupContext.resolvedGroups.at(i);
- for (const QString &file : qAsConst(filesContext.absoluteFilePaths)) {
- const SourceArtifactPtr sa = createSourceArtifact(file, resolvedProduct, resolvedGroup,
- false);
- addedSourceArtifacts.insert(file, std::make_pair(sa, resolvedProduct));
- }
- for (const QString &file : qAsConst(filesContext.absoluteFilePathsFromWildcards)) {
- QBS_CHECK(resolvedGroup->wildcards);
- const SourceArtifactPtr sa = createSourceArtifact(file, resolvedProduct, resolvedGroup,
- true);
- addedSourceArtifacts.insert(file, std::make_pair(sa, resolvedProduct));
- }
- if (resolvedProduct->enabled) {
- for (const auto &pair : qAsConst(addedSourceArtifacts))
- createArtifact(resolvedProduct, pair.first);
- }
- }
- doSanityChecks(internalProject, logger);
- QList<ArtifactData> sourceArtifacts;
- QList<ArtifactData> sourceArtifactsFromWildcards;
- for (const QString &fp : qAsConst(filesContext.absoluteFilePaths)) {
- const auto pair = addedSourceArtifacts.value(fp);
- const SourceArtifactConstPtr sa = pair.first;
- QBS_CHECK(sa);
- ArtifactData artifactData = createApiSourceArtifact(sa);
- setupInstallData(artifactData, pair.second);
- sourceArtifacts << artifactData;
- }
- for (const QString &fp : qAsConst(filesContext.absoluteFilePathsFromWildcards)) {
- const auto pair = addedSourceArtifacts.value(fp);
- const SourceArtifactConstPtr sa = pair.first;
- QBS_CHECK(sa);
- ArtifactData artifactData = createApiSourceArtifact(sa);
- setupInstallData(artifactData, pair.second);
- sourceArtifactsFromWildcards << artifactData;
- }
- for (const GroupData &g : qAsConst(groupContext.groups)) {
- g.d->sourceArtifacts << sourceArtifacts;
- std::sort(g.d->sourceArtifacts.begin(), g.d->sourceArtifacts.end());
- g.d->sourceArtifactsFromWildcards << sourceArtifactsFromWildcards;
- std::sort(g.d->sourceArtifactsFromWildcards.begin(),
- g.d->sourceArtifactsFromWildcards.end());
- }
}
void ProjectPrivate::removeFiles(const ProductData &product, const GroupData &group,
@@ -595,134 +514,17 @@ void ProjectPrivate::removeFiles(const ProductData &product, const GroupData &gr
group.isValid() ? groupContext.groups.front() : GroupData(),
filesContext.relativeFilePaths);
remover.apply();
-
- for (int i = 0; i < groupContext.resolvedProducts.size(); ++i) {
- removeFilesFromBuildGraph(groupContext.resolvedProducts.at(i), sourceArtifacts);
- for (const SourceArtifactPtr &sa : sourceArtifacts)
- removeOne(groupContext.resolvedGroups.at(i)->files, sa);
- }
- doSanityChecks(internalProject, logger);
-
- m_projectData.d.detach();
- updateInternalCodeLocations(internalProject, remover.itemPosition(), remover.lineOffset());
- updateExternalCodeLocations(m_projectData, remover.itemPosition(), remover.lineOffset());
- for (const GroupData &g : qAsConst(groupContext.groups)) {
- for (int i = g.d->sourceArtifacts.size() - 1; i >= 0; --i) {
- if (filesContext.absoluteFilePaths.contains(g.d->sourceArtifacts.at(i).filePath()))
- g.d->sourceArtifacts.removeAt(i);
- }
- }
}
void ProjectPrivate::removeGroup(const ProductData &product, const GroupData &group)
{
GroupUpdateContext context = getGroupContext(product, group);
-
ProjectFileGroupRemover remover(context.products.front(), context.groups.front());
remover.apply();
- for (int i = 0; i < context.resolvedProducts.size(); ++i) {
- const ResolvedProductPtr &product = context.resolvedProducts.at(i);
- const GroupPtr &group = context.resolvedGroups.at(i);
- removeFilesFromBuildGraph(product, group->allFiles());
- const bool removed = removeOne(product->groups, group);
- QBS_CHECK(removed);
- }
- doSanityChecks(internalProject, logger);
-
- m_projectData.d.detach();
- updateInternalCodeLocations(internalProject, remover.itemPosition(), remover.lineOffset());
- updateExternalCodeLocations(m_projectData, remover.itemPosition(), remover.lineOffset());
- for (int i = 0; i < context.products.size(); ++i) {
- const bool removed = context.products.at(i).d->groups.removeOne(context.groups.at(i));
- QBS_CHECK(removed);
- }
}
#endif // QBS_ENABLE_PROJECT_FILE_UPDATES
-void ProjectPrivate::removeFilesFromBuildGraph(const ResolvedProductConstPtr &product,
- const std::vector<SourceArtifactPtr> &files)
-{
- if (!product->enabled)
- return;
- QBS_CHECK(internalProject->buildData);
- ArtifactSet allRemovedArtifacts;
- for (const SourceArtifactPtr &sa : files) {
- ArtifactSet removedArtifacts;
- Artifact * const artifact = lookupArtifact(product, sa->absoluteFilePath);
- if (artifact) { // Can be null if the executor has not yet applied the respective rule.
- internalProject->buildData->removeArtifactAndExclusiveDependents(artifact, logger,
- true, &removedArtifacts);
- }
- allRemovedArtifacts.unite(removedArtifacts);
- }
- EmptyDirectoriesRemover(product->topLevelProject(), logger)
- .removeEmptyParentDirectories(allRemovedArtifacts);
- qDeleteAll(allRemovedArtifacts);
-}
-
-static void updateLocationIfNecessary(CodeLocation &location, const CodeLocation &changeLocation,
- int lineOffset)
-{
- if (location.filePath() == changeLocation.filePath()
- && location.line() >= changeLocation.line()) {
- location = CodeLocation(location.filePath(), location.line() + lineOffset,
- location.column());
- }
-}
-
-void ProjectPrivate::updateInternalCodeLocations(const ResolvedProjectPtr &project,
- const CodeLocation &changeLocation, int lineOffset)
-{
- if (lineOffset == 0)
- return;
- updateLocationIfNecessary(project->location, changeLocation, lineOffset);
- for (const ResolvedProjectPtr &subProject : qAsConst(project->subProjects))
- updateInternalCodeLocations(subProject, changeLocation, lineOffset);
- for (const ResolvedProductPtr &product : project->products) {
- updateLocationIfNecessary(product->location, changeLocation, lineOffset);
- for (const GroupPtr &group : product->groups)
- updateLocationIfNecessary(group->location, changeLocation, lineOffset);
- for (const RulePtr &rule : qAsConst(product->rules)) {
- updateLocationIfNecessary(rule->prepareScript.location(), changeLocation, lineOffset);
- for (const RuleArtifactPtr &artifact : rule->artifacts) {
- for (auto &binding : artifact->bindings) {
- updateLocationIfNecessary(binding.location, changeLocation, lineOffset);
- }
- }
- }
- for (const ResolvedScannerConstPtr &scanner : product->scanners) {
- updateLocationIfNecessary(scanner->searchPathsScript.location(), changeLocation,
- lineOffset);
- updateLocationIfNecessary(scanner->scanScript.location(), changeLocation, lineOffset);
- }
- for (const ResolvedModuleConstPtr &module : product->modules) {
- updateLocationIfNecessary(module->setupBuildEnvironmentScript.location(),
- changeLocation, lineOffset);
- updateLocationIfNecessary(module->setupRunEnvironmentScript.location(),
- changeLocation, lineOffset);
- }
- }
-}
-
-void ProjectPrivate::updateExternalCodeLocations(const ProjectData &project,
- const CodeLocation &changeLocation, int lineOffset)
-{
- if (lineOffset == 0)
- return;
- updateLocationIfNecessary(project.d->location, changeLocation, lineOffset);
- const auto subProjects = project.subProjects();
- for (const ProjectData &subProject : subProjects)
- updateExternalCodeLocations(subProject, changeLocation, lineOffset);
- const auto products = project.products();
- for (const ProductData &product : products) {
- updateLocationIfNecessary(product.d->location, changeLocation, lineOffset);
- const auto groups = product.groups();
- for (const GroupData &group : groups)
- updateLocationIfNecessary(group.d->location, changeLocation, lineOffset);
- }
-}
-
void ProjectPrivate::prepareChangeToProject()
{
if (internalProject->locked)
@@ -851,7 +653,7 @@ void ProjectPrivate::retrieveProjectData(ProjectData &projectData,
projectData.d->name = internalProject->name;
projectData.d->location = internalProject->location;
projectData.d->enabled = internalProject->enabled;
- for (const ResolvedProductConstPtr &resolvedProduct : internalProject->products) {
+ for (const auto &resolvedProduct : internalProject->products) {
ProductData product;
product.d->type = resolvedProduct->fileTags.toStringList();
product.d->name = resolvedProduct->name;
@@ -904,8 +706,7 @@ void ProjectPrivate::retrieveProjectData(ProjectData &projectData,
product.d->isValid = true;
projectData.d->products << product;
}
- for (const ResolvedProjectConstPtr &internalSubProject
- : qAsConst(internalProject->subProjects)) {
+ for (const auto &internalSubProject : qAsConst(internalProject->subProjects)) {
if (!internalSubProject->enabled)
continue;
ProjectData subProject;
@@ -931,13 +732,9 @@ Project::Project(const TopLevelProjectPtr &internalProject, const Logger &logger
{
}
-Project::Project(const Project &other) : d(other.d)
-{
-}
+Project::Project(const Project &other) = default;
-Project::~Project()
-{
-}
+Project::~Project() = default;
/*!
* \brief Returns true if and only if this object was retrieved from a successful \c SetupProjectJob.
@@ -957,11 +754,7 @@ QString Project::profile() const
return d->internalProject->profile();
}
-Project &Project::operator=(const Project &other)
-{
- d = other.d;
- return *this;
-}
+Project &Project::operator=(const Project &other) = default;
/*!
* \brief Sets up a \c Project from a source file, possibly re-using previously stored information.
@@ -996,10 +789,7 @@ SetupProjectJob *Project::setupProject(const SetupProjectParameters &parameters,
return job;
}
-Project::Project()
-{
-}
-
+Project::Project() = default;
/*!
* \brief Retrieves information for this project.
@@ -1227,9 +1017,9 @@ Project::BuildGraphInfo Project::getBuildGraphInfo(const QString &bgFilePath,
for (const QString &prop : requestedProperties) {
QStringList components = prop.split(QLatin1Char('.'));
const QString propName = components.takeLast();
- props.push_back(std::make_pair(components.join(QLatin1Char('.')), propName));
+ props.emplace_back(components.join(QLatin1Char('.')), propName);
}
- for (const ResolvedProductConstPtr &product : project->allProducts()) {
+ for (const auto &product : project->allProducts()) {
if (props.empty())
break;
if (product->profile() != project->profile())
@@ -1283,10 +1073,10 @@ ErrorInfo Project::addGroup(const ProductData &product, const QString &groupName
QBS_CHECK(isValid());
d->prepareChangeToProject();
d->addGroup(product, groupName);
- d->internalProject->lastStartResolveTime = FileTime::currentTime();
d->internalProject->store(d->logger);
return {};
- } catch (ErrorInfo errorInfo) {
+ } catch (const ErrorInfo &exception) {
+ auto errorInfo = exception;
errorInfo.prepend(Tr::tr("Failure adding group '%1' to product '%2'.")
.arg(groupName, product.name()));
return errorInfo;
@@ -1310,10 +1100,10 @@ ErrorInfo Project::addFiles(const ProductData &product, const GroupData &group,
QBS_CHECK(isValid());
d->prepareChangeToProject();
d->addFiles(product, group, filePaths);
- d->internalProject->lastStartResolveTime = FileTime::currentTime();
d->internalProject->store(d->logger);
return {};
- } catch (ErrorInfo errorInfo) {
+ } catch (const ErrorInfo &exception) {
+ auto errorInfo = exception;
errorInfo.prepend(Tr::tr("Failure adding files to product."));
return errorInfo;
}
@@ -1336,10 +1126,10 @@ ErrorInfo Project::removeFiles(const ProductData &product, const GroupData &grou
QBS_CHECK(isValid());
d->prepareChangeToProject();
d->removeFiles(product, group, filePaths);
- d->internalProject->lastStartResolveTime = FileTime::currentTime();
d->internalProject->store(d->logger);
return {};
- } catch (ErrorInfo errorInfo) {
+ } catch (const ErrorInfo &exception) {
+ auto errorInfo = exception;
errorInfo.prepend(Tr::tr("Failure removing files from product '%1'.").arg(product.name()));
return errorInfo;
}
@@ -1357,10 +1147,10 @@ ErrorInfo Project::removeGroup(const ProductData &product, const GroupData &grou
QBS_CHECK(isValid());
d->prepareChangeToProject();
d->removeGroup(product, group);
- d->internalProject->lastStartResolveTime = FileTime::currentTime();
d->internalProject->store(d->logger);
return {};
- } catch (ErrorInfo errorInfo) {
+ } catch (const ErrorInfo &exception) {
+ auto errorInfo = exception;
errorInfo.prepend(Tr::tr("Failure removing group '%1' from product '%2'.")
.arg(group.name(), product.name()));
return errorInfo;
diff --git a/src/lib/corelib/api/project_p.h b/src/lib/corelib/api/project_p.h
index 58f61a5bc..60c8311f3 100644
--- a/src/lib/corelib/api/project_p.h
+++ b/src/lib/corelib/api/project_p.h
@@ -62,22 +62,22 @@ namespace Internal {
class ProjectPrivate : public QSharedData
{
public:
- ProjectPrivate(const TopLevelProjectPtr &internalProject, const Logger &logger)
- : internalProject(internalProject), logger(logger)
+ ProjectPrivate(TopLevelProjectPtr internalProject, Logger logger)
+ : internalProject(std::move(internalProject)), logger(std::move(logger))
{
}
ProjectData projectData();
- BuildJob *buildProducts(const QList<ResolvedProductPtr> &products, const BuildOptions &options,
+ BuildJob *buildProducts(const QVector<ResolvedProductPtr> &products, const BuildOptions &options,
bool needsDepencencyResolving,
QObject *jobOwner);
- CleanJob *cleanProducts(const QList<ResolvedProductPtr> &products, const CleanOptions &options,
+ CleanJob *cleanProducts(const QVector<ResolvedProductPtr> &products, const CleanOptions &options,
QObject *jobOwner);
- InstallJob *installProducts(const QList<ResolvedProductPtr> &products,
+ InstallJob *installProducts(const QVector<ResolvedProductPtr> &products,
const InstallOptions &options, bool needsDepencencyResolving,
QObject *jobOwner);
- QList<ResolvedProductPtr> internalProducts(const QList<ProductData> &products) const;
- QList<ResolvedProductPtr> allEnabledInternalProducts(bool includingNonDefault) const;
+ QVector<ResolvedProductPtr> internalProducts(const QList<ProductData> &products) const;
+ QVector<ResolvedProductPtr> allEnabledInternalProducts(bool includingNonDefault) const;
ResolvedProductPtr internalProduct(const ProductData &product) const;
ProductData findProductData(const ProductData &product) const;
QList<ProductData> findProductsByName(const QString &name) const;
@@ -92,7 +92,7 @@ public:
void setupInstallData(ArtifactData &artifact, const ResolvedProductConstPtr &product);
struct GroupUpdateContext {
- QList<ResolvedProductPtr> resolvedProducts;
+ QVector<ResolvedProductPtr> resolvedProducts;
QList<GroupPtr> resolvedGroups;
QList<ProductData> products;
QList<GroupData> groups;
@@ -114,12 +114,7 @@ public:
void removeFiles(const ProductData &product, const GroupData &group,
const QStringList &filePaths);
void removeGroup(const ProductData &product, const GroupData &group);
- void removeFilesFromBuildGraph(const ResolvedProductConstPtr &product,
- const std::vector<SourceArtifactPtr> &files);
- void updateInternalCodeLocations(const ResolvedProjectPtr &project,
- const CodeLocation &changeLocation, int lineOffset);
- void updateExternalCodeLocations(const ProjectData &project,
- const CodeLocation &changeLocation, int lineOffset);
+
void prepareChangeToProject();
RuleCommandList ruleCommandListForTransformer(const Transformer *transformer);
diff --git a/src/lib/corelib/api/projectfileupdater.cpp b/src/lib/corelib/api/projectfileupdater.cpp
index 04f8e630f..0bc5bc7c4 100644
--- a/src/lib/corelib/api/projectfileupdater.cpp
+++ b/src/lib/corelib/api/projectfileupdater.cpp
@@ -115,7 +115,7 @@ private:
};
-ProjectFileUpdater::ProjectFileUpdater(const QString &projectFile) : m_projectFile(projectFile)
+ProjectFileUpdater::ProjectFileUpdater(QString projectFile) : m_projectFile(std::move(projectFile))
{
}
@@ -201,11 +201,10 @@ void ProjectFileUpdater::apply()
}
-ProjectFileGroupInserter::ProjectFileGroupInserter(const ProductData &product,
- const QString &groupName)
+ProjectFileGroupInserter::ProjectFileGroupInserter(ProductData product, QString groupName)
: ProjectFileUpdater(product.location().filePath())
- , m_product(product)
- , m_groupName(groupName)
+ , m_product(std::move(product))
+ , m_groupName(std::move(groupName))
{
}
@@ -222,7 +221,7 @@ void ProjectFileGroupInserter::doApply(QString &fileContent, UiProgram *ast)
Rewriter rewriter(fileContent, &changeSet, QStringList());
QString groupItemString;
const int productItemIndentation
- = itemFinder.item()->qualifiedTypeNameId->firstSourceLocation().startColumn - 1;
+ = int(itemFinder.item()->qualifiedTypeNameId->firstSourceLocation().startColumn - 1);
const int groupItemIndentation = productItemIndentation + 4;
const QString groupItemIndentationString = QString(groupItemIndentation, QLatin1Char(' '));
groupItemString += groupItemIndentationString + QLatin1String("Group {\n");
@@ -252,7 +251,7 @@ static QString getNodeRepresentation(const QString &fileContent, const QbsQmlJS:
{
const quint32 start = node->firstSourceLocation().offset;
const quint32 end = node->lastSourceLocation().end();
- return fileContent.mid(start, end - start);
+ return fileContent.mid(start, int(end - start));
}
static const ChangeSet::EditOp &getEditOp(const ChangeSet &changeSet)
@@ -273,12 +272,12 @@ static int getBindingLine(const ChangeSet &changeSet, const QString &fileContent
}
-ProjectFileFilesAdder::ProjectFileFilesAdder(const ProductData &product, const GroupData &group,
- const QStringList &files)
+ProjectFileFilesAdder::ProjectFileFilesAdder(ProductData product, GroupData group,
+ QStringList files)
: ProjectFileUpdater(product.location().filePath())
- , m_product(product)
- , m_group(group)
- , m_files(files)
+ , m_product(std::move(product))
+ , m_group(std::move(group))
+ , m_files(std::move(files))
{
}
@@ -319,7 +318,7 @@ void ProjectFileFilesAdder::doApply(QString &fileContent, UiProgram *ast)
}
const int itemIndentation
- = itemFinder.item()->qualifiedTypeNameId->firstSourceLocation().startColumn - 1;
+ = int(itemFinder.item()->qualifiedTypeNameId->firstSourceLocation().startColumn - 1);
const int bindingIndentation = itemIndentation + 4;
const int arrayElemIndentation = bindingIndentation + 4;
@@ -405,12 +404,12 @@ void ProjectFileFilesAdder::doApply(QString &fileContent, UiProgram *ast)
changeSet.apply(&fileContent);
}
-ProjectFileFilesRemover::ProjectFileFilesRemover(const ProductData &product, const GroupData &group,
- const QStringList &files)
+ProjectFileFilesRemover::ProjectFileFilesRemover(ProductData product, GroupData group,
+ QStringList files)
: ProjectFileUpdater(product.location().filePath())
- , m_product(product)
- , m_group(group)
- , m_files(files)
+ , m_product(std::move(product))
+ , m_group(std::move(group))
+ , m_files(std::move(files))
{
}
@@ -444,7 +443,7 @@ void ProjectFileFilesRemover::doApply(QString &fileContent, UiProgram *ast)
Rewriter rewriter(fileContent, &changeSet, QStringList());
const int itemIndentation
- = itemFinder.item()->qualifiedTypeNameId->firstSourceLocation().startColumn - 1;
+ = int(itemFinder.item()->qualifiedTypeNameId->firstSourceLocation().startColumn - 1);
const int bindingIndentation = itemIndentation + 4;
const int arrayElemIndentation = bindingIndentation + 4;
@@ -512,10 +511,10 @@ void ProjectFileFilesRemover::doApply(QString &fileContent, UiProgram *ast)
}
-ProjectFileGroupRemover::ProjectFileGroupRemover(const ProductData &product, const GroupData &group)
+ProjectFileGroupRemover::ProjectFileGroupRemover(ProductData product, GroupData group)
: ProjectFileUpdater(product.location().filePath())
- , m_product(product)
- , m_group(group)
+ , m_product(std::move(product))
+ , m_group(std::move(group))
{
}
diff --git a/src/lib/corelib/api/projectfileupdater.h b/src/lib/corelib/api/projectfileupdater.h
index c0d46c747..3459d788e 100644
--- a/src/lib/corelib/api/projectfileupdater.h
+++ b/src/lib/corelib/api/projectfileupdater.h
@@ -61,7 +61,7 @@ public:
int lineOffset() const { return m_lineOffset; }
protected:
- ProjectFileUpdater(const QString &projectFile);
+ ProjectFileUpdater(QString projectFile);
QString projectFile() const { return m_projectFile; }
@@ -92,7 +92,7 @@ private:
class ProjectFileGroupInserter : public ProjectFileUpdater
{
public:
- ProjectFileGroupInserter(const ProductData &product, const QString &groupName);
+ ProjectFileGroupInserter(ProductData product, QString groupName);
private:
void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override;
@@ -105,8 +105,7 @@ private:
class ProjectFileFilesAdder : public ProjectFileUpdater
{
public:
- ProjectFileFilesAdder(const ProductData &product, const GroupData &group,
- const QStringList &files);
+ ProjectFileFilesAdder(ProductData product, GroupData group, QStringList files);
private:
void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override;
@@ -119,8 +118,8 @@ private:
class ProjectFileFilesRemover : public ProjectFileUpdater
{
public:
- ProjectFileFilesRemover(const ProductData &product, const GroupData &group,
- const QStringList &files);
+ ProjectFileFilesRemover(ProductData product, GroupData group,
+ QStringList files);
private:
void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override;
@@ -133,7 +132,7 @@ private:
class ProjectFileGroupRemover : public ProjectFileUpdater
{
public:
- ProjectFileGroupRemover(const ProductData &product, const GroupData &group);
+ ProjectFileGroupRemover(ProductData product, GroupData group);
private:
void doApply(QString &fileContent, QbsQmlJS::AST::UiProgram *ast) override;
diff --git a/src/lib/corelib/api/qmljsrewriter.cpp b/src/lib/corelib/api/qmljsrewriter.cpp
index 16817d682..5551e5650 100644
--- a/src/lib/corelib/api/qmljsrewriter.cpp
+++ b/src/lib/corelib/api/qmljsrewriter.cpp
@@ -63,12 +63,12 @@ static QString toString(UiQualifiedId *qualifiedId, QChar delimiter = QLatin1Cha
}
-Rewriter::Rewriter(const QString &originalText,
+Rewriter::Rewriter(QString originalText,
ChangeSet *changeSet,
- const QStringList &propertyOrder)
- : m_originalText(originalText)
+ QStringList propertyOrder)
+ : m_originalText(std::move(originalText))
, m_changeSet(changeSet)
- , m_propertyOrder(propertyOrder)
+ , m_propertyOrder(std::move(propertyOrder))
{
Q_ASSERT(changeSet);
}
@@ -260,7 +260,7 @@ UiObjectMemberList *Rewriter::searchMemberToInsertAfter(UiObjectMemberList *memb
idx = propertyOrder.size() - 1;
for (; idx > 0; --idx) {
- const QString prop = propertyOrder.at(idx - 1);
+ const QString &prop = propertyOrder.at(idx - 1);
UiObjectMemberList *candidate = orderedMembers.value(prop, 0);
if (candidate != nullptr)
return candidate;
@@ -649,7 +649,7 @@ Rewriter::Range Rewriter::addObject(UiObjectInitializer *ast, const QString &con
textToInsert += content;
m_changeSet->insert(insertionPoint, QLatin1String("\n") + textToInsert);
- return Range(insertionPoint, insertionPoint);
+ return {insertionPoint, insertionPoint};
}
Rewriter::Range Rewriter::addObject(UiArrayBinding *ast, const QString &content)
@@ -672,7 +672,7 @@ Rewriter::Range Rewriter::addObject(UiArrayBinding *ast, const QString &content,
m_changeSet->insert(insertionPoint, textToInsert);
- return Range(insertionPoint, insertionPoint);
+ return {insertionPoint, insertionPoint};
}
void Rewriter::removeObjectMember(UiObjectMember *member, UiObjectMember *parent)
diff --git a/src/lib/corelib/api/qmljsrewriter.h b/src/lib/corelib/api/qmljsrewriter.h
index 797b05459..3788035f2 100644
--- a/src/lib/corelib/api/qmljsrewriter.h
+++ b/src/lib/corelib/api/qmljsrewriter.h
@@ -60,9 +60,9 @@ public:
using Range = ChangeSet::Range;
public:
- Rewriter(const QString &originalText,
+ Rewriter(QString originalText,
ChangeSet *changeSet,
- const QStringList &propertyOrder);
+ QStringList propertyOrder);
Range addBinding(AST::UiObjectInitializer *ast,
const QString &propertyName,
diff --git a/src/lib/corelib/api/rulecommand.cpp b/src/lib/corelib/api/rulecommand.cpp
index bc12140f3..e01cde7cc 100644
--- a/src/lib/corelib/api/rulecommand.cpp
+++ b/src/lib/corelib/api/rulecommand.cpp
@@ -65,17 +65,11 @@ RuleCommand::RuleCommand() : d(new Internal::RuleCommandPrivate)
{
}
-RuleCommand::RuleCommand(const RuleCommand &other) : d(other.d) {}
+RuleCommand::RuleCommand(const RuleCommand &other) = default;
-RuleCommand::~RuleCommand()
-{
-}
+RuleCommand::~RuleCommand() = default;
-RuleCommand& RuleCommand::operator=(const RuleCommand &other)
-{
- d = other.d;
- return *this;
-}
+RuleCommand& RuleCommand::operator=(const RuleCommand &other) = default;
/*!
* Returns the type of this object. If the value is \c InvalidType, the object is invalid.
diff --git a/src/lib/corelib/api/runenvironment.cpp b/src/lib/corelib/api/runenvironment.cpp
index df5b4337d..94a74dac2 100644
--- a/src/lib/corelib/api/runenvironment.cpp
+++ b/src/lib/corelib/api/runenvironment.cpp
@@ -62,8 +62,8 @@
#include <QtCore/qtemporaryfile.h>
#include <QtCore/qvariant.h>
+#include <cstdlib>
#include <regex>
-#include <stdlib.h>
namespace qbs {
using namespace Internal;
diff --git a/src/lib/corelib/api/runenvironment.h b/src/lib/corelib/api/runenvironment.h
index 69603bf76..c5123ca9c 100644
--- a/src/lib/corelib/api/runenvironment.h
+++ b/src/lib/corelib/api/runenvironment.h
@@ -52,6 +52,8 @@ class QString;
class QStringList;
QT_END_NAMESPACE
+class TestApi;
+
namespace qbs {
class ErrorInfo;
class InstallOptions;
@@ -66,7 +68,7 @@ class QBS_EXPORT RunEnvironment
{
friend class CommandLineFrontend;
friend class Project;
- friend class TestApi;
+ friend class ::TestApi;
public:
~RunEnvironment();
diff --git a/src/lib/corelib/api/transformerdata.cpp b/src/lib/corelib/api/transformerdata.cpp
index b4ee61d0c..9724e641b 100644
--- a/src/lib/corelib/api/transformerdata.cpp
+++ b/src/lib/corelib/api/transformerdata.cpp
@@ -44,14 +44,10 @@
namespace qbs {
TransformerData::TransformerData() : d(new Internal::TransformerDataPrivate) { }
-TransformerData::TransformerData(const TransformerData &other) : d(other.d) {}
-TransformerData::~TransformerData() { }
+TransformerData::TransformerData(const TransformerData &other) = default;
+TransformerData::~TransformerData() = default;
-TransformerData& TransformerData::operator=(const TransformerData &other)
-{
- d = other.d;
- return *this;
-}
+TransformerData& TransformerData::operator=(const TransformerData &other) = default;
QList<ArtifactData> TransformerData::inputs() const { return d->inputs; }
QList<ArtifactData> TransformerData::outputs() const { return d->outputs; }
diff --git a/src/lib/corelib/buildgraph/artifactcleaner.cpp b/src/lib/corelib/buildgraph/artifactcleaner.cpp
index 000dfda02..03b327232 100644
--- a/src/lib/corelib/buildgraph/artifactcleaner.cpp
+++ b/src/lib/corelib/buildgraph/artifactcleaner.cpp
@@ -162,7 +162,7 @@ ArtifactCleaner::ArtifactCleaner(Logger logger, ProgressObserver *observer)
}
void ArtifactCleaner::cleanup(const TopLevelProjectPtr &project,
- const QList<ResolvedProductPtr> &products, const CleanOptions &options)
+ const QVector<ResolvedProductPtr> &products, const CleanOptions &options)
{
m_hasError = false;
diff --git a/src/lib/corelib/buildgraph/artifactcleaner.h b/src/lib/corelib/buildgraph/artifactcleaner.h
index 5112a75d6..8d0bef275 100644
--- a/src/lib/corelib/buildgraph/artifactcleaner.h
+++ b/src/lib/corelib/buildgraph/artifactcleaner.h
@@ -54,7 +54,7 @@ class ArtifactCleaner
{
public:
ArtifactCleaner(Logger logger, ProgressObserver *observer);
- void cleanup(const TopLevelProjectPtr &project, const QList<ResolvedProductPtr> &products,
+ void cleanup(const TopLevelProjectPtr &project, const QVector<ResolvedProductPtr> &products,
const CleanOptions &options);
private:
diff --git a/src/lib/corelib/buildgraph/artifactvisitor.cpp b/src/lib/corelib/buildgraph/artifactvisitor.cpp
index c28f07424..22c987572 100644
--- a/src/lib/corelib/buildgraph/artifactvisitor.cpp
+++ b/src/lib/corelib/buildgraph/artifactvisitor.cpp
@@ -61,7 +61,7 @@ void ArtifactVisitor::visitProduct(const ResolvedProductConstPtr &product)
void ArtifactVisitor::visitProject(const ResolvedProjectConstPtr &project)
{
- for (const ResolvedProductConstPtr &product : project->allProducts())
+ for (const auto &product : project->allProducts())
visitProduct(product);
}
diff --git a/src/lib/corelib/buildgraph/buildgraph.cpp b/src/lib/corelib/buildgraph/buildgraph.cpp
index 3726c654d..0d5e8a1f0 100644
--- a/src/lib/corelib/buildgraph/buildgraph.cpp
+++ b/src/lib/corelib/buildgraph/buildgraph.cpp
@@ -278,7 +278,7 @@ private:
}
return result;
}
- for (const ResolvedModuleConstPtr &dependency : product->modules) {
+ for (const auto &dependency : product->modules) {
if (dependency->isProduct)
continue;
QScriptValue obj = engine->newObject(engine->modulePropertyScriptClass());
@@ -661,7 +661,7 @@ void provideFullFileTagsAndProperties(Artifact *artifact)
artifact->properties = artifact->product->moduleProperties;
FileTags allTags = artifact->pureFileTags.empty()
? artifact->product->fileTagsForFileName(artifact->fileName()) : artifact->pureFileTags;
- for (const ArtifactPropertiesConstPtr &props : artifact->product->artifactProperties) {
+ for (const auto &props : artifact->product->artifactProperties) {
if (allTags.intersects(props->fileTagsFilter())) {
artifact->properties = props->propertyMap();
allTags += props->extraFileTags();
@@ -733,7 +733,7 @@ static void doSanityChecksForProduct(const ResolvedProductConstPtr &product,
CycleDetector cycleDetector(logger);
cycleDetector.visitProduct(product);
const ProductBuildData * const buildData = product->buildData.get();
- for (const ResolvedModuleConstPtr &m : product->modules)
+ for (const auto &m : product->modules)
QBS_CHECK(m->product == product.get());
qCDebug(lcBuildGraph) << "enabled:" << product->enabled << "build data:" << buildData;
if (product->enabled)
@@ -836,7 +836,7 @@ static void doSanityChecks(const ResolvedProjectPtr &project,
for (const ResolvedProjectPtr &subProject : qAsConst(project->subProjects))
doSanityChecks(subProject, allProducts, productNames, logger);
- for (const ResolvedProductConstPtr &product : project->products) {
+ for (const auto &product : project->products) {
QBS_CHECK(product->project == project);
QBS_CHECK(product->topLevelProject() == project->topLevelProject());
doSanityChecksForProduct(product, allProducts, logger);
diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp
index bf6c30dcd..58a34b616 100644
--- a/src/lib/corelib/buildgraph/buildgraphloader.cpp
+++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp
@@ -71,6 +71,7 @@
#include <algorithm>
#include <functional>
+#include <memory>
#include <unordered_map>
namespace qbs {
@@ -273,7 +274,7 @@ static void updateProductAndRulePointers(const ResolvedProductPtr &newProduct)
const auto it = ruleMap.find(oldRule);
if (it != ruleMap.cend())
return it->second;
- for (const RuleConstPtr &r : qAsConst(newProduct->rules)) {
+ for (const auto &r : qAsConst(newProduct->rules)) {
if (*r == *oldRule) {
ruleMap.insert(std::make_pair(oldRule, r));
return r;
@@ -362,7 +363,7 @@ void BuildGraphLoader::trackProjectChanges()
ChildListHash childLists;
if (!changedProducts.empty()) {
oldBuildData = std::make_shared<ProjectBuildData>(restoredProject->buildData.get());
- for (const ResolvedProductConstPtr &product : qAsConst(allRestoredProducts)) {
+ for (const auto &product : qAsConst(allRestoredProducts)) {
if (!product->buildData)
continue;
@@ -451,7 +452,7 @@ void BuildGraphLoader::trackProjectChanges()
updateGeneratedArtifacts(product.get());
}
- for (const ResolvedProductConstPtr &changedProduct : qAsConst(changedProducts)) {
+ for (const auto &changedProduct : qAsConst(changedProducts)) {
rescueOldBuildData(changedProduct,
m_freshProductsByName.value(changedProduct->uniqueName()),
childLists, rescuableArtifactData.value(changedProduct->uniqueName()));
@@ -614,7 +615,7 @@ bool BuildGraphLoader::hasProductFileChanged(const std::vector<ResolvedProductPt
FileInfo::path(group->location.filePath()),
product->topLevelProject()->buildDirectory);
Set<QString> wcFiles;
- for (const SourceArtifactConstPtr &sourceArtifact : group->wildcards->files)
+ for (const auto &sourceArtifact : group->wildcards->files)
wcFiles += sourceArtifact->absoluteFilePath;
if (files == wcFiles)
continue;
@@ -741,9 +742,9 @@ static bool dependenciesAreEqual(const ResolvedProductConstPtr &p1,
return false;
Set<QString> names1;
Set<QString> names2;
- for (const ResolvedProductConstPtr &dep : qAsConst(p1->dependencies))
+ for (const auto &dep : qAsConst(p1->dependencies))
names1 << dep->uniqueName();
- for (const ResolvedProductConstPtr &dep : qAsConst(p2->dependencies))
+ for (const auto &dep : qAsConst(p2->dependencies))
names2 << dep->uniqueName();
return names1 == names2;
}
@@ -909,7 +910,7 @@ void BuildGraphLoader::rescueOldBuildData(const ResolvedProductConstPtr &restore
if (!restoredProduct->buildData)
return;
if (!newlyResolvedProduct->buildData)
- newlyResolvedProduct->buildData.reset(new ProductBuildData);
+ newlyResolvedProduct->buildData = std::make_unique<ProductBuildData>();
qCDebug(lcBuildGraph) << "rescue data of product" << restoredProduct->uniqueName();
QBS_CHECK(newlyResolvedProduct->buildData);
diff --git a/src/lib/corelib/buildgraph/buildgraphloader.h b/src/lib/corelib/buildgraph/buildgraphloader.h
index 9363b8358..c62ba7fa7 100644
--- a/src/lib/corelib/buildgraph/buildgraphloader.h
+++ b/src/lib/corelib/buildgraph/buildgraphloader.h
@@ -121,9 +121,9 @@ private:
bool checkConfigCompatibility();
struct ChildrenInfo {
- ChildrenInfo() {}
- ChildrenInfo(const ArtifactSet &c1, const ArtifactSet &c2)
- : children(c1), childrenAddedByScanner(c2) {}
+ ChildrenInfo() = default;
+ ChildrenInfo(ArtifactSet c1, ArtifactSet c2)
+ : children(std::move(c1)), childrenAddedByScanner(std::move(c2)) {}
ArtifactSet children;
ArtifactSet childrenAddedByScanner;
};
diff --git a/src/lib/corelib/buildgraph/depscanner.h b/src/lib/corelib/buildgraph/depscanner.h
index ffc0b83de..6b18004f9 100644
--- a/src/lib/corelib/buildgraph/depscanner.h
+++ b/src/lib/corelib/buildgraph/depscanner.h
@@ -61,7 +61,7 @@ class ScriptEngine;
class DependencyScanner
{
public:
- virtual ~DependencyScanner() {}
+ virtual ~DependencyScanner() = default;
QString id() const;
diff --git a/src/lib/corelib/buildgraph/environmentscriptrunner.cpp b/src/lib/corelib/buildgraph/environmentscriptrunner.cpp
index 7d82efb41..9dafbf296 100644
--- a/src/lib/corelib/buildgraph/environmentscriptrunner.cpp
+++ b/src/lib/corelib/buildgraph/environmentscriptrunner.cpp
@@ -129,12 +129,12 @@ void EnvironmentScriptRunner::setupEnvironment()
return;
QMap<QString, const ResolvedModule *> moduleMap;
- for (const ResolvedModuleConstPtr &module : m_product->modules)
+ for (const auto &module : m_product->modules)
moduleMap.insert(module->name, module.get());
QHash<const ResolvedModule*, QList<const ResolvedModule*> > moduleParents;
QHash<const ResolvedModule*, QList<const ResolvedModule*> > moduleChildren;
- for (const ResolvedModuleConstPtr &module : m_product->modules) {
+ for (const auto &module : m_product->modules) {
for (const QString &moduleName : qAsConst(module->moduleDependencies)) {
const ResolvedModule * const depmod = moduleMap.value(moduleName);
QBS_ASSERT(depmod, return);
@@ -144,7 +144,7 @@ void EnvironmentScriptRunner::setupEnvironment()
}
QList<const ResolvedModule *> rootModules;
- for (const ResolvedModuleConstPtr &module : m_product->modules) {
+ for (const auto &module : m_product->modules) {
if (moduleParents.value(module.get()).isEmpty()) {
QBS_ASSERT(module, return);
rootModules.push_back(module.get());
diff --git a/src/lib/corelib/buildgraph/executor.cpp b/src/lib/corelib/buildgraph/executor.cpp
index de81ada20..377222d21 100644
--- a/src/lib/corelib/buildgraph/executor.cpp
+++ b/src/lib/corelib/buildgraph/executor.cpp
@@ -102,12 +102,8 @@ Executor::Executor(Logger logger, QObject *parent)
Executor::~Executor()
{
- // jobs must be destroyed before deleting the shared scan result cache
- for (ExecutorJob *job : qAsConst(m_availableJobs))
- delete job;
- const auto processingJobs = m_processingJobs.keys();
- for (ExecutorJob *job : processingJobs)
- delete job;
+ // jobs must be destroyed before deleting the m_inputArtifactScanContext
+ m_allJobs.clear();
delete m_inputArtifactScanContext;
delete m_productInstaller;
}
@@ -153,7 +149,7 @@ void Executor::retrieveSourceFileTimestamp(Artifact *artifact) const
void Executor::build()
{
try {
- m_partialBuild = m_productsToBuild.size() != m_allProducts.size();
+ m_partialBuild = size_t(m_productsToBuild.size()) != m_allProducts.size();
doBuild();
} catch (const ErrorInfo &e) {
handleError(e);
@@ -170,7 +166,7 @@ void Executor::setProject(const TopLevelProjectPtr &project)
m_projectsByName.insert(std::make_pair(p->name, p.get()));
}
-void Executor::setProducts(const std::vector<ResolvedProductPtr> &productsToBuild)
+void Executor::setProducts(const QVector<ResolvedProductPtr> &productsToBuild)
{
m_productsToBuild = productsToBuild;
m_productsByName.clear();
@@ -266,8 +262,7 @@ void Executor::doBuild()
doSanityChecks();
QBS_CHECK(!m_project->buildData->evaluationContext);
- m_project->buildData->evaluationContext
- = RulesEvaluationContextPtr(new RulesEvaluationContext(m_logger));
+ m_project->buildData->evaluationContext = std::make_shared<RulesEvaluationContext>(m_logger);
m_evalContext = m_project->buildData->evaluationContext;
m_elapsedTimeRules = m_elapsedTimeScanners = m_elapsedTimeInstalling = 0;
@@ -700,7 +695,7 @@ bool Executor::transformerHasMatchingInputFiles(const TransformerConstPtr &trans
void Executor::setupJobLimits()
{
Settings settings(m_buildOptions.settingsDirectory());
- for (const ResolvedProductConstPtr &p : m_productsToBuild) {
+ for (const auto &p : qAsConst(m_productsToBuild)) {
const Preferences prefs(&settings, p->profile());
const JobLimits &jobLimitsFromSettings = prefs.jobLimits();
JobLimits effectiveJobLimits;
@@ -737,7 +732,7 @@ void Executor::setupProgressObserver()
if (!m_progressObserver)
return;
int totalEffort = 1; // For the effort after the last rule application;
- for (const ResolvedProductConstPtr &product : qAsConst(m_productsToBuild)) {
+ for (const auto &product : qAsConst(m_productsToBuild)) {
QBS_CHECK(product->buildData);
const auto filtered = filterByType<RuleNode>(product->buildData->allNodes());
totalEffort += std::distance(filtered.begin(), filtered.end());
@@ -749,7 +744,7 @@ void Executor::doSanityChecks()
{
QBS_CHECK(m_project);
QBS_CHECK(!m_productsToBuild.empty());
- for (const ResolvedProductConstPtr &product : qAsConst(m_productsToBuild)) {
+ for (const auto &product : qAsConst(m_productsToBuild)) {
QBS_CHECK(product->buildData);
QBS_CHECK(product->topLevelProject() == m_project.get());
}
@@ -768,10 +763,13 @@ void Executor::handleError(const ErrorInfo &error)
void Executor::addExecutorJobs()
{
- qCDebug(lcExec) << "preparing executor for" << m_buildOptions.maxJobCount()
- << "jobs in parallel";
- for (int i = 1; i <= m_buildOptions.maxJobCount(); i++) {
- const auto job = new ExecutorJob(m_logger, this);
+ const int count = m_buildOptions.maxJobCount();
+ qCDebug(lcExec) << "preparing executor for" << count << "jobs in parallel";
+ m_allJobs.reserve(count);
+ m_availableJobs.reserve(count);
+ for (int i = 1; i <= count; i++) {
+ m_allJobs.push_back(std::make_unique<ExecutorJob>(m_logger));
+ const auto job = m_allJobs.back().get();
job->setMainThreadScriptEngine(m_evalContext->engine());
job->setObjectName(QStringLiteral("J%1").arg(i));
job->setDryRun(m_buildOptions.dryRun());
@@ -1084,7 +1082,7 @@ void Executor::checkForUnbuiltProducts()
if (m_buildOptions.executeRulesOnly())
return;
std::vector<ResolvedProductPtr> unbuiltProducts;
- for (const ResolvedProductPtr &product : m_productsToBuild) {
+ for (const ResolvedProductPtr &product : qAsConst(m_productsToBuild)) {
bool productBuilt = true;
for (BuildGraphNode *rootNode : qAsConst(product->buildData->rootNodes())) {
if (rootNode->buildState != BuildGraphNode::Built) {
@@ -1206,7 +1204,7 @@ void Executor::prepareAllNodes()
node->buildState = BuildGraphNode::Untouched;
}
}
- for (const ResolvedProductPtr &product : m_productsToBuild) {
+ for (const ResolvedProductPtr &product : qAsConst(m_productsToBuild)) {
QBS_CHECK(product->buildData);
for (Artifact * const artifact : filterByType<Artifact>(product->buildData->allNodes()))
prepareArtifact(artifact);
@@ -1228,7 +1226,7 @@ void Executor::syncFileDependencies()
"removing from lookup table";
m_project->buildData->removeFromLookupTable(dep);
bool isReferencedByArtifact = false;
- for (const ResolvedProductConstPtr &product : m_allProducts) {
+ for (const auto &product : m_allProducts) {
if (!product->buildData)
continue;
const auto artifactList = filterByType<Artifact>(product->buildData->allNodes());
@@ -1310,7 +1308,7 @@ void Executor::prepareProducts()
{
ProductPrioritySetter prioritySetter(m_allProducts);
prioritySetter.apply();
- for (const ResolvedProductPtr &product : m_productsToBuild) {
+ for (const ResolvedProductPtr &product : qAsConst(m_productsToBuild)) {
EnvironmentScriptRunner(product.get(), m_evalContext.get(), m_project->environment)
.setupForBuild();
}
@@ -1319,7 +1317,7 @@ void Executor::prepareProducts()
void Executor::setupRootNodes()
{
m_roots.clear();
- for (const ResolvedProductPtr &product : m_productsToBuild)
+ for (const ResolvedProductPtr &product : qAsConst(m_productsToBuild))
m_roots += product->buildData->rootNodes();
}
diff --git a/src/lib/corelib/buildgraph/executor.h b/src/lib/corelib/buildgraph/executor.h
index 1fd591176..cc879e125 100644
--- a/src/lib/corelib/buildgraph/executor.h
+++ b/src/lib/corelib/buildgraph/executor.h
@@ -81,7 +81,7 @@ public:
~Executor() override;
void setProject(const TopLevelProjectPtr &project);
- void setProducts(const std::vector<ResolvedProductPtr> &productsToBuild);
+ void setProducts(const QVector<ResolvedProductPtr> &productsToBuild);
void setBuildOptions(const BuildOptions &buildOptions);
void setProgressObserver(ProgressObserver *observer) { m_progressObserver = observer; }
@@ -166,10 +166,11 @@ private:
BuildOptions m_buildOptions;
Logger m_logger;
ProgressObserver *m_progressObserver;
+ std::vector<std::unique_ptr<ExecutorJob>> m_allJobs;
QList<ExecutorJob*> m_availableJobs;
ExecutorState m_state;
TopLevelProjectPtr m_project;
- std::vector<ResolvedProductPtr> m_productsToBuild;
+ QVector<ResolvedProductPtr> m_productsToBuild;
std::vector<ResolvedProductPtr> m_allProducts;
std::unordered_map<QString, const ResolvedProduct *> m_productsByName;
std::unordered_map<QString, const ResolvedProject *> m_projectsByName;
diff --git a/src/lib/corelib/buildgraph/executorjob.cpp b/src/lib/corelib/buildgraph/executorjob.cpp
index 79f17377d..bc96cbb6e 100644
--- a/src/lib/corelib/buildgraph/executorjob.cpp
+++ b/src/lib/corelib/buildgraph/executorjob.cpp
@@ -71,9 +71,7 @@ ExecutorJob::ExecutorJob(const Logger &logger, QObject *parent)
reset();
}
-ExecutorJob::~ExecutorJob()
-{
-}
+ExecutorJob::~ExecutorJob() = default;
void ExecutorJob::setMainThreadScriptEngine(ScriptEngine *engine)
{
diff --git a/src/lib/corelib/buildgraph/executorjob.h b/src/lib/corelib/buildgraph/executorjob.h
index bc8954072..1f8f0cd73 100644
--- a/src/lib/corelib/buildgraph/executorjob.h
+++ b/src/lib/corelib/buildgraph/executorjob.h
@@ -65,7 +65,7 @@ class ExecutorJob : public QObject
{
Q_OBJECT
public:
- ExecutorJob(const Logger &logger, QObject *parent);
+ explicit ExecutorJob(const Logger &logger, QObject *parent = nullptr);
~ExecutorJob() override;
void setMainThreadScriptEngine(ScriptEngine *engine);
diff --git a/src/lib/corelib/buildgraph/filedependency.cpp b/src/lib/corelib/buildgraph/filedependency.cpp
index 9420fa96b..cbee758c7 100644
--- a/src/lib/corelib/buildgraph/filedependency.cpp
+++ b/src/lib/corelib/buildgraph/filedependency.cpp
@@ -44,13 +44,9 @@
namespace qbs {
namespace Internal {
-FileResourceBase::FileResourceBase()
-{
-}
+FileResourceBase::FileResourceBase() = default;
-FileResourceBase::~FileResourceBase()
-{
-}
+FileResourceBase::~FileResourceBase() = default;
void FileResourceBase::setTimestamp(const FileTime &t)
@@ -86,13 +82,9 @@ void FileResourceBase::store(PersistentPool &pool)
}
-FileDependency::FileDependency()
-{
-}
+FileDependency::FileDependency() = default;
-FileDependency::~FileDependency()
-{
-}
+FileDependency::~FileDependency() = default;
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/buildgraph/inputartifactscanner.cpp b/src/lib/corelib/buildgraph/inputartifactscanner.cpp
index 81cbe2178..1d00e29e1 100644
--- a/src/lib/corelib/buildgraph/inputartifactscanner.cpp
+++ b/src/lib/corelib/buildgraph/inputartifactscanner.cpp
@@ -77,6 +77,7 @@ static void resolveDepencency(const RawScannedDependency &dependency,
FileDependency *fileDependencyArtifact = nullptr;
Artifact *dependencyInProduct = nullptr;
Artifact *dependencyInOtherProduct = nullptr;
+ bool productOfDependencyIsDependency = false;
const auto files = project->topLevelProject()
->buildData->lookupFiles(absDirPath, dependency.fileName());
for (FileResourceBase *lookupResult : files) {
@@ -86,10 +87,13 @@ static void resolveDepencency(const RawScannedDependency &dependency,
break;
case FileResourceBase::FileTypeArtifact: {
auto const foundArtifact = static_cast<Artifact *>(lookupResult);
- if (foundArtifact->product == product)
+ if (foundArtifact->product == product) {
dependencyInProduct = foundArtifact;
- else
+ } else if (!productOfDependencyIsDependency) {
dependencyInOtherProduct = foundArtifact;
+ productOfDependencyIsDependency
+ = contains(product->dependencies, dependencyInOtherProduct->product.lock());
+ }
break;
}
}
@@ -102,6 +106,14 @@ static void resolveDepencency(const RawScannedDependency &dependency,
|| (result->file = dependencyInOtherProduct)
|| (result->file = fileDependencyArtifact)) {
result->filePath = result->file->filePath();
+
+ if (result->file == dependencyInOtherProduct && !productOfDependencyIsDependency) {
+ qCDebug(lcDepScan) << "product" << dependencyInOtherProduct->product->fullDisplayName()
+ << "of scanned dependency" << result->filePath
+ << "is not a dependency of product" << product->fullDisplayName()
+ << ". The file dependency might get lost during change tracking.";
+ }
+
return;
}
@@ -349,6 +361,8 @@ void InputArtifactScanner::handleDependency(ResolvedDependency &dependency)
if (m_artifact == dependency.file)
return;
+ if (artifactDependency && artifactDependency->transformer == m_artifact->transformer)
+ return;
if (fileDependency) {
m_artifact->fileDependencies << fileDependency;
@@ -372,16 +386,14 @@ void InputArtifactScanner::scanWithScannerPlugin(DependencyScanner *scanner,
const QStringList &dependencies = scanner->collectDependencies(
inputArtifact, fileToBeScanned, m_fileTagsForScanner.constData());
for (const QString &s : dependencies)
- scanResult->deps.push_back(RawScannedDependency(s));
+ scanResult->deps.emplace_back(s);
}
InputArtifactScannerContext::DependencyScannerCacheItem::DependencyScannerCacheItem() : valid(false)
{
}
-InputArtifactScannerContext::DependencyScannerCacheItem::~DependencyScannerCacheItem()
-{
-}
+InputArtifactScannerContext::DependencyScannerCacheItem::~DependencyScannerCacheItem() = default;
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/buildgraph/nodetreedumper.cpp b/src/lib/corelib/buildgraph/nodetreedumper.cpp
index 89975baf2..8475a46cf 100644
--- a/src/lib/corelib/buildgraph/nodetreedumper.cpp
+++ b/src/lib/corelib/buildgraph/nodetreedumper.cpp
@@ -51,13 +51,13 @@
namespace qbs {
namespace Internal {
-static unsigned int indentWidth() { return 4; }
+static int indentWidth() { return 4; }
NodeTreeDumper::NodeTreeDumper(QIODevice &outDevice) : m_outDevice(outDevice)
{
}
-void NodeTreeDumper::start(const QList<ResolvedProductPtr> &products)
+void NodeTreeDumper::start(const QVector<ResolvedProductPtr> &products)
{
m_indentation = 0;
for (const ResolvedProductPtr &p : products) {
diff --git a/src/lib/corelib/buildgraph/nodetreedumper.h b/src/lib/corelib/buildgraph/nodetreedumper.h
index 4175ce727..38ccd6dae 100644
--- a/src/lib/corelib/buildgraph/nodetreedumper.h
+++ b/src/lib/corelib/buildgraph/nodetreedumper.h
@@ -57,7 +57,7 @@ class NodeTreeDumper : public BuildGraphVisitor
public:
NodeTreeDumper(QIODevice &outDevice);
- void start(const QList<ResolvedProductPtr> &products);
+ void start(const QVector<ResolvedProductPtr> &products);
private:
bool visit(Artifact *artifact) override;
@@ -74,7 +74,7 @@ private:
QIODevice &m_outDevice;
ResolvedProductPtr m_currentProduct;
NodeSet m_visited;
- unsigned int m_indentation = 0;
+ int m_indentation = 0;
};
} // namespace Internal
diff --git a/src/lib/corelib/buildgraph/processcommandexecutor.cpp b/src/lib/corelib/buildgraph/processcommandexecutor.cpp
index 79edda320..7cde8553c 100644
--- a/src/lib/corelib/buildgraph/processcommandexecutor.cpp
+++ b/src/lib/corelib/buildgraph/processcommandexecutor.cpp
@@ -166,6 +166,7 @@ bool ProcessCommandExecutor::doStart()
.arg(responseFile.fileName())));
return false;
}
+ const auto separator = cmd->responseFileSeparator().toUtf8();
for (int i = cmd->responseFileArgumentIndex(); i < cmd->arguments().size(); ++i) {
const QString arg = cmd->arguments().at(i);
if (arg.startsWith(cmd->responseFileUsagePrefix())) {
@@ -179,7 +180,7 @@ bool ProcessCommandExecutor::doStart()
} else {
responseFile.write(qbs::Internal::shellQuote(arg).toLocal8Bit());
}
- responseFile.write("\n");
+ responseFile.write(separator);
}
responseFile.close();
m_responseFileName = responseFile.fileName();
diff --git a/src/lib/corelib/buildgraph/productinstaller.cpp b/src/lib/corelib/buildgraph/productinstaller.cpp
index d4acc9ace..80a76d7f5 100644
--- a/src/lib/corelib/buildgraph/productinstaller.cpp
+++ b/src/lib/corelib/buildgraph/productinstaller.cpp
@@ -60,7 +60,7 @@ namespace qbs {
namespace Internal {
ProductInstaller::ProductInstaller(TopLevelProjectPtr project,
- std::vector<ResolvedProductPtr> products, InstallOptions options,
+ QVector<ResolvedProductPtr> products, InstallOptions options,
ProgressObserver *observer, Logger logger)
: m_project(std::move(project)),
m_products(std::move(products)),
@@ -96,7 +96,7 @@ void ProductInstaller::install()
removeInstallRoot();
QList<const Artifact *> artifactsToInstall;
- for (const ResolvedProductConstPtr &product : qAsConst(m_products)) {
+ for (const auto &product : qAsConst(m_products)) {
QBS_CHECK(product->buildData);
for (const Artifact *artifact : filterByType<Artifact>(product->buildData->allNodes())) {
if (artifact->properties->qbsPropertyValue(StringConstants::installProperty()).toBool())
@@ -250,5 +250,5 @@ void ProductInstaller::handleError(const QString &message)
m_logger.qbsWarning() << message;
}
-} // namespace Intern
+} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/buildgraph/productinstaller.h b/src/lib/corelib/buildgraph/productinstaller.h
index 09828cfe9..c07e0b7cf 100644
--- a/src/lib/corelib/buildgraph/productinstaller.h
+++ b/src/lib/corelib/buildgraph/productinstaller.h
@@ -56,7 +56,7 @@ class ProductInstaller
{
public:
ProductInstaller(TopLevelProjectPtr project,
- std::vector<ResolvedProductPtr> products,
+ QVector<ResolvedProductPtr> products,
InstallOptions options, ProgressObserver *observer, Logger logger);
void install();
@@ -72,7 +72,7 @@ private:
void handleError(const QString &message);
const TopLevelProjectConstPtr m_project;
- const std::vector<ResolvedProductPtr> m_products;
+ const QVector<ResolvedProductPtr> m_products;
InstallOptions m_options;
ProgressObserver * const m_observer;
Logger m_logger;
diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp
index 31012e23e..0ac6b1537 100644
--- a/src/lib/corelib/buildgraph/projectbuilddata.cpp
+++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp
@@ -60,6 +60,8 @@
#include <tools/qttools.h>
#include <tools/stlutils.h>
+#include <memory>
+
namespace qbs {
namespace Internal {
@@ -276,7 +278,7 @@ void BuildDataResolver::resolveBuildData(const TopLevelProjectPtr &resolvedProje
{
QBS_CHECK(!resolvedProject->buildData);
m_project = resolvedProject;
- resolvedProject->buildData.reset(new ProjectBuildData);
+ resolvedProject->buildData = std::make_unique<ProjectBuildData>();
resolvedProject->buildData->evaluationContext = evalContext;
const std::vector<ResolvedProductPtr> &allProducts = resolvedProject->allProducts();
evalContext->initializeObserver(Tr::tr("Setting up build graph for configuration %1")
@@ -390,7 +392,7 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc
evalContext()->checkForCancelation();
- product->buildData.reset(new ProductBuildData);
+ product->buildData = std::make_unique<ProductBuildData>();
ArtifactSetByFileTag artifactsPerFileTag;
for (const auto &dependency : qAsConst(product->dependencies)) {
@@ -411,7 +413,7 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc
artifactsPerFileTag["qbs"].insert(qbsFileArtifact);
// read sources
- for (const SourceArtifactConstPtr &sourceArtifact : product->allEnabledFiles()) {
+ for (const auto &sourceArtifact : product->allEnabledFiles()) {
QString filePath = sourceArtifact->absoluteFilePath;
if (lookupArtifact(product, filePath))
continue; // ignore duplicate artifacts
@@ -443,7 +445,7 @@ void BuildDataResolver::connectRulesToDependencies(const ResolvedProductPtr &pro
std::vector<RuleNode *> ruleNodes;
for (RuleNode *ruleNode : filterByType<RuleNode>(product->buildData->allNodes()))
ruleNodes.push_back(ruleNode);
- for (const ResolvedProductConstPtr &dep : dependencies) {
+ for (const auto &dep : dependencies) {
if (!dep->buildData)
continue;
for (RuleNode *depRuleNode : filterByType<RuleNode>(dep->buildData->allNodes())) {
diff --git a/src/lib/corelib/buildgraph/qtmocscanner.cpp b/src/lib/corelib/buildgraph/qtmocscanner.cpp
index c834c60e6..4e054a636 100644
--- a/src/lib/corelib/buildgraph/qtmocscanner.cpp
+++ b/src/lib/corelib/buildgraph/qtmocscanner.cpp
@@ -167,7 +167,7 @@ static RawScanResult runScanner(ScannerPlugin *scanner, const Artifact *artifact
if (FileInfo::exists(localFilePath))
includedFilePath = localFilePath;
}
- scanData.rawScanResult.deps.push_back(RawScannedDependency(includedFilePath));
+ scanData.rawScanResult.deps.emplace_back(includedFilePath);
}
scanner->close(opaq);
diff --git a/src/lib/corelib/buildgraph/requesteddependencies.cpp b/src/lib/corelib/buildgraph/requesteddependencies.cpp
index f993b2518..b95c8db94 100644
--- a/src/lib/corelib/buildgraph/requesteddependencies.cpp
+++ b/src/lib/corelib/buildgraph/requesteddependencies.cpp
@@ -48,9 +48,9 @@ namespace Internal {
static Set<QString> depNamesForProduct(const ResolvedProduct *p)
{
Set<QString> names;
- for (const ResolvedProductConstPtr &dep : p->dependencies)
+ for (const auto &dep : p->dependencies)
names.insert(dep->uniqueName());
- for (const ResolvedModuleConstPtr &m : p->modules) {
+ for (const auto &m : p->modules) {
if (!m->isProduct)
names.insert(m->name);
}
@@ -73,7 +73,7 @@ bool RequestedDependencies::isUpToDate(const TopLevelProject *project) const
{
if (m_depsPerProduct.empty())
return true;
- for (const ResolvedProductConstPtr &product : project->allProducts()) {
+ for (const auto &product : project->allProducts()) {
const auto it = m_depsPerProduct.find(product->uniqueName());
if (it == m_depsPerProduct.cend())
continue;
diff --git a/src/lib/corelib/buildgraph/rescuableartifactdata.h b/src/lib/corelib/buildgraph/rescuableartifactdata.h
index 3e4d6e25f..6dd10f76c 100644
--- a/src/lib/corelib/buildgraph/rescuableartifactdata.h
+++ b/src/lib/corelib/buildgraph/rescuableartifactdata.h
@@ -84,9 +84,12 @@ public:
struct ChildData
{
- ChildData(const QString &n = QString(), const QString &m = QString(),
- const QString &c = QString(), bool byScanner = false)
- : productName(n), productMultiplexId(m), childFilePath(c), addedByScanner(byScanner)
+ ChildData(QString n = QString(), QString m = QString(),
+ QString c = QString(), bool byScanner = false)
+ : productName(std::move(n))
+ , productMultiplexId(std::move(m))
+ , childFilePath(std::move(c))
+ , addedByScanner(byScanner)
{}
template<PersistentPool::OpType opType> void completeSerializationOp(PersistentPool &pool)
diff --git a/src/lib/corelib/buildgraph/rulecommands.cpp b/src/lib/corelib/buildgraph/rulecommands.cpp
index 31ff6be4b..8fa3255f1 100644
--- a/src/lib/corelib/buildgraph/rulecommands.cpp
+++ b/src/lib/corelib/buildgraph/rulecommands.cpp
@@ -70,6 +70,7 @@ static QString responseFileUsagePrefixProperty()
{
return QStringLiteral("responseFileUsagePrefix");
}
+static QString responseFileSeparatorProperty() { return QStringLiteral("responseFileSeparator"); }
static QString silentProperty() { return QStringLiteral("silent"); }
static QString stderrFilePathProperty() { return QStringLiteral("stderrFilePath"); }
static QString stderrFilterFunctionProperty() { return QStringLiteral("stderrFilterFunction"); }
@@ -78,7 +79,7 @@ static QString stdoutFilterFunctionProperty() { return QStringLiteral("stdoutFil
static QString timeoutProperty() { return QStringLiteral("timeout"); }
static QString workingDirProperty() { return QStringLiteral("workingDirectory"); }
-static QString invokedSourceCode(const QScriptValue codeOrFunction)
+static QString invokedSourceCode(const QScriptValue &codeOrFunction)
{
const QString &code = codeOrFunction.toString();
return codeOrFunction.isFunction() ? QStringLiteral("(") + code + QStringLiteral(")()") : code;
@@ -94,9 +95,7 @@ AbstractCommand::AbstractCommand()
{
}
-AbstractCommand::~AbstractCommand()
-{
-}
+AbstractCommand::~AbstractCommand() = default;
bool AbstractCommand::equals(const AbstractCommand *other) const
{
@@ -218,6 +217,8 @@ static QScriptValue js_Command(QScriptContext *context, QScriptEngine *engine)
engine->toScriptValue(commandPrototype->responseFileArgumentIndex()));
cmd.setProperty(responseFileUsagePrefixProperty(),
engine->toScriptValue(commandPrototype->responseFileUsagePrefix()));
+ cmd.setProperty(responseFileSeparatorProperty(),
+ engine->toScriptValue(commandPrototype->responseFileSeparator()));
cmd.setProperty(stdoutFilePathProperty(),
engine->toScriptValue(commandPrototype->stdoutFilePath()));
cmd.setProperty(stderrFilePathProperty(),
@@ -241,6 +242,7 @@ ProcessCommand::ProcessCommand()
: m_maxExitCode(0)
, m_responseFileThreshold(defaultResponseFileThreshold())
, m_responseFileArgumentIndex(0)
+ , m_responseFileSeparator(QStringLiteral("\n"))
{
}
@@ -279,6 +281,7 @@ bool ProcessCommand::equals(const AbstractCommand *otherAbstractCommand) const
&& m_responseFileThreshold == other->m_responseFileThreshold
&& m_responseFileArgumentIndex == other->m_responseFileArgumentIndex
&& m_responseFileUsagePrefix == other->m_responseFileUsagePrefix
+ && m_responseFileSeparator == other->m_responseFileSeparator
&& m_stdoutFilePath == other->m_stdoutFilePath
&& m_stderrFilePath == other->m_stderrFilePath
&& m_relevantEnvVars == other->m_relevantEnvVars
@@ -313,6 +316,8 @@ void ProcessCommand::fillFromScriptValue(const QScriptValue *scriptValue, const
.toInt32();
m_responseFileUsagePrefix = scriptValue->property(responseFileUsagePrefixProperty())
.toString();
+ m_responseFileSeparator = scriptValue->property(responseFileSeparatorProperty())
+ .toString();
QStringList envList = scriptValue->property(environmentProperty()).toVariant()
.toStringList();
getEnvironmentFromList(envList);
@@ -399,9 +404,7 @@ void JavaScriptCommand::setupForJavaScript(QScriptValue targetObject)
targetObject.setProperty(StringConstants::javaScriptCommandType(), ctor);
}
-JavaScriptCommand::JavaScriptCommand()
-{
-}
+JavaScriptCommand::JavaScriptCommand() = default;
bool JavaScriptCommand::equals(const AbstractCommand *otherAbstractCommand) const
{
diff --git a/src/lib/corelib/buildgraph/rulecommands.h b/src/lib/corelib/buildgraph/rulecommands.h
index d4d70d591..725cd6d89 100644
--- a/src/lib/corelib/buildgraph/rulecommands.h
+++ b/src/lib/corelib/buildgraph/rulecommands.h
@@ -136,6 +136,7 @@ public:
int responseFileThreshold() const { return m_responseFileThreshold; }
int responseFileArgumentIndex() const { return m_responseFileArgumentIndex; }
QString responseFileUsagePrefix() const { return m_responseFileUsagePrefix; }
+ QString responseFileSeparator() const { return m_responseFileSeparator; }
QProcessEnvironment environment() const { return m_environment; }
QStringList relevantEnvVars() const;
void clearRelevantEnvValues() { m_relevantEnvValues.clear(); }
@@ -158,10 +159,10 @@ private:
{
pool.serializationOp<opType>(m_program, m_arguments, m_environment, m_workingDir,
m_stdoutFilterFunction, m_stderrFilterFunction,
- m_responseFileUsagePrefix, m_maxExitCode,
- m_responseFileThreshold, m_responseFileArgumentIndex,
- m_relevantEnvVars, m_relevantEnvValues, m_stdoutFilePath,
- m_stderrFilePath);
+ m_responseFileUsagePrefix, m_responseFileSeparator,
+ m_maxExitCode, m_responseFileThreshold,
+ m_responseFileArgumentIndex, m_relevantEnvVars,
+ m_relevantEnvValues, m_stdoutFilePath, m_stderrFilePath);
}
QString m_program;
@@ -173,6 +174,7 @@ private:
int m_responseFileThreshold; // When to use response files? In bytes of (program name + arguments).
int m_responseFileArgumentIndex;
QString m_responseFileUsagePrefix;
+ QString m_responseFileSeparator;
QProcessEnvironment m_environment;
QStringList m_relevantEnvVars;
QProcessEnvironment m_relevantEnvValues;
diff --git a/src/lib/corelib/buildgraph/rulegraph.cpp b/src/lib/corelib/buildgraph/rulegraph.cpp
index 23227ca09..23f22b7f2 100644
--- a/src/lib/corelib/buildgraph/rulegraph.cpp
+++ b/src/lib/corelib/buildgraph/rulegraph.cpp
@@ -46,9 +46,7 @@
namespace qbs {
namespace Internal {
-RuleGraph::RuleGraph()
-{
-}
+RuleGraph::RuleGraph() = default;
void RuleGraph::build(const std::vector<RulePtr> &rules, const FileTags &productFileTags)
{
@@ -63,7 +61,7 @@ void RuleGraph::build(const std::vector<RulePtr> &rules, const FileTags &product
m_parents.resize(rules.size());
m_children.resize(rules.size());
- for (const RuleConstPtr &rule : qAsConst(m_rules)) {
+ for (const auto &rule : qAsConst(m_rules)) {
FileTags inFileTags = rule->inputs;
inFileTags += rule->auxiliaryInputs;
inFileTags += rule->explicitlyDependsOn;
@@ -100,7 +98,7 @@ void RuleGraph::dump() const
QByteArray indent;
printf("---rule graph dump:\n");
Set<int> rootRules;
- for (const RuleConstPtr &rule : qAsConst(m_rules))
+ for (const auto &rule : qAsConst(m_rules))
if (m_parents[rule->ruleGraphId].empty())
rootRules += rule->ruleGraphId;
for (int idx : qAsConst(rootRules))
diff --git a/src/lib/corelib/buildgraph/rulenode.cpp b/src/lib/corelib/buildgraph/rulenode.cpp
index bf25b1da8..0558ba144 100644
--- a/src/lib/corelib/buildgraph/rulenode.cpp
+++ b/src/lib/corelib/buildgraph/rulenode.cpp
@@ -56,13 +56,9 @@
namespace qbs {
namespace Internal {
-RuleNode::RuleNode()
-{
-}
+RuleNode::RuleNode() = default;
-RuleNode::~RuleNode()
-{
-}
+RuleNode::~RuleNode() = default;
void RuleNode::accept(BuildGraphVisitor *visitor)
{
@@ -182,7 +178,7 @@ void RuleNode::apply(const Logger &logger,
if (removedInputForcesOutputRemoval)
outputArtifactsToRemove += parent;
else
- connectionsToBreak.push_back(std::make_pair(parent, artifact));
+ connectionsToBreak.emplace_back(parent, artifact);
}
disconnect(this, artifact);
}
@@ -262,7 +258,7 @@ ArtifactSet RuleNode::currentInputArtifacts() const
}
}
- for (const ResolvedProductConstPtr &dep : qAsConst(product->dependencies)) {
+ for (const auto &dep : qAsConst(product->dependencies)) {
if (!dep->buildData)
continue;
for (Artifact * const a : filterByType<Artifact>(dep->buildData->allNodes())) {
diff --git a/src/lib/corelib/buildgraph/rulesapplicator.cpp b/src/lib/corelib/buildgraph/rulesapplicator.cpp
index 16aa0c001..0d36e1e21 100644
--- a/src/lib/corelib/buildgraph/rulesapplicator.cpp
+++ b/src/lib/corelib/buildgraph/rulesapplicator.cpp
@@ -79,12 +79,13 @@ namespace Internal {
RulesApplicator::RulesApplicator(
ResolvedProductPtr product,
- std::unordered_map<QString, const ResolvedProduct *> productsByName,
- std::unordered_map<QString, const ResolvedProject *> projectsByName,
+ const std::unordered_map<QString, const ResolvedProduct *> &productsByName,
+ const std::unordered_map<QString, const ResolvedProject *> &projectsByName,
Logger logger)
: m_product(std::move(product))
- , m_productsByName(std::move(productsByName))
- , m_projectsByName(std::move(projectsByName))
+ // m_productsByName and m_projectsByName are references, cannot move-construct
+ , m_productsByName(productsByName)
+ , m_projectsByName(projectsByName)
, m_mocScanner(nullptr)
, m_logger(std::move(logger))
{
@@ -213,13 +214,13 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p
ScriptEngine::argumentList(Rule::argumentNamesForOutputArtifacts(), scope()));
} else {
Set<QString> outputFilePaths;
- for (const RuleArtifactConstPtr &ruleArtifact : m_rule->artifacts) {
+ for (const auto &ruleArtifact : m_rule->artifacts) {
const OutputArtifactInfo outputInfo = createOutputArtifactFromRuleArtifact(
ruleArtifact, inputArtifacts, &outputFilePaths);
if (!outputInfo.artifact)
continue;
outputArtifacts.push_back(outputInfo.artifact);
- ruleArtifactArtifactMap.push_back({ ruleArtifact.get(), outputInfo });
+ ruleArtifactArtifactMap.emplace_back(ruleArtifact.get(), outputInfo);
}
if (m_rule->artifacts.empty()) {
outputArtifacts.push_back(createOutputArtifactFromRuleArtifact(
@@ -287,7 +288,7 @@ void RulesApplicator::doApply(const ArtifactSet &inputArtifacts, QScriptValue &p
}
const QVariant value = scriptValue.toVariant();
setConfigProperty(artifactModulesCfg, binding.name, value);
- outputArtifact->pureProperties.push_back(std::make_pair(binding.name, value));
+ outputArtifact->pureProperties.emplace_back(binding.name, value);
}
outputArtifact->properties->setValue(artifactModulesCfg);
if (!outputInfo.newlyCreated && (outputArtifact->fileTags() != outputInfo.oldFileTags
@@ -354,7 +355,7 @@ ArtifactSet RulesApplicator::collectAdditionalInputs(const FileTags &tags, const
}
if (inputsSources.testFlag(Dependencies)) {
- for (const ResolvedProductConstPtr &depProduct : product->dependencies) {
+ for (const auto &depProduct : product->dependencies) {
for (Artifact * const ta : depProduct->targetArtifacts()) {
if (ta->fileTags().contains(fileTag)
&& !ta->fileTags().intersects(rule->excludedInputs)) {
@@ -607,7 +608,7 @@ public:
for (const auto &e : m_propertyValues) {
const QStringList key{e.module, e.name};
setConfigProperty(artifactCfg, key, e.value);
- outputArtifact->pureProperties.push_back(std::make_pair(key, e.value));
+ outputArtifact->pureProperties.emplace_back(key, e.value);
}
outputArtifact->properties->setValue(artifactCfg);
}
diff --git a/src/lib/corelib/buildgraph/rulesapplicator.h b/src/lib/corelib/buildgraph/rulesapplicator.h
index 1160f3d09..da7815014 100644
--- a/src/lib/corelib/buildgraph/rulesapplicator.h
+++ b/src/lib/corelib/buildgraph/rulesapplicator.h
@@ -63,8 +63,8 @@ class RulesApplicator
{
public:
RulesApplicator(ResolvedProductPtr product,
- std::unordered_map<QString, const ResolvedProduct *> productsByName,
- std::unordered_map<QString, const ResolvedProject *> projectsByName,
+ const std::unordered_map<QString, const ResolvedProduct *> &productsByName,
+ const std::unordered_map<QString, const ResolvedProject *> &projectsByName,
Logger logger);
~RulesApplicator();
diff --git a/src/lib/corelib/buildgraph/scriptclasspropertyiterator.h b/src/lib/corelib/buildgraph/scriptclasspropertyiterator.h
index f6154f993..b57072236 100644
--- a/src/lib/corelib/buildgraph/scriptclasspropertyiterator.h
+++ b/src/lib/corelib/buildgraph/scriptclasspropertyiterator.h
@@ -57,10 +57,10 @@ class ScriptClassPropertyIterator : public QScriptClassPropertyIterator
{
public:
ScriptClassPropertyIterator(const QScriptValue &object, const QVariantMap &properties,
- const std::vector<QString> &additionalProperties)
+ std::vector<QString> additionalProperties)
: QScriptClassPropertyIterator(object),
m_it(properties),
- m_additionalProperties(additionalProperties)
+ m_additionalProperties(std::move(additionalProperties))
{
}
diff --git a/src/lib/corelib/buildgraph/timestampsupdater.cpp b/src/lib/corelib/buildgraph/timestampsupdater.cpp
index d31f57445..3f5279dd2 100644
--- a/src/lib/corelib/buildgraph/timestampsupdater.cpp
+++ b/src/lib/corelib/buildgraph/timestampsupdater.cpp
@@ -83,7 +83,7 @@ private:
};
void TimestampsUpdater::updateTimestamps(const TopLevelProjectPtr &project,
- const QList<ResolvedProductPtr> &products, const Logger &logger)
+ const QVector<ResolvedProductPtr> &products, const Logger &logger)
{
TimestampsUpdateVisitor v;
for (const ResolvedProductPtr &product : products)
diff --git a/src/lib/corelib/buildgraph/timestampsupdater.h b/src/lib/corelib/buildgraph/timestampsupdater.h
index cfe20df12..8184ca708 100644
--- a/src/lib/corelib/buildgraph/timestampsupdater.h
+++ b/src/lib/corelib/buildgraph/timestampsupdater.h
@@ -51,7 +51,7 @@ class TimestampsUpdater
{
public:
void updateTimestamps(const TopLevelProjectPtr &project,
- const QList<ResolvedProductPtr> &products, const Logger &logger);
+ const QVector<ResolvedProductPtr> &products, const Logger &logger);
};
} // namespace Internal
diff --git a/src/lib/corelib/buildgraph/transformer.cpp b/src/lib/corelib/buildgraph/transformer.cpp
index cc0b4c923..29f2bcdf0 100644
--- a/src/lib/corelib/buildgraph/transformer.cpp
+++ b/src/lib/corelib/buildgraph/transformer.cpp
@@ -62,9 +62,7 @@ Transformer::Transformer() : alwaysRun(false)
{
}
-Transformer::~Transformer()
-{
-}
+Transformer::~Transformer() = default;
static QScriptValue js_baseName(QScriptContext *ctx, QScriptEngine *engine,
const Artifact *artifact)
@@ -196,7 +194,7 @@ void Transformer::setupInputs(QScriptValue targetScriptValue, const ArtifactSet
targetScriptValue.setProperty(StringConstants::inputVar(), inputScriptValue);
}
-void Transformer::setupInputs(QScriptValue targetScriptValue)
+void Transformer::setupInputs(const QScriptValue &targetScriptValue)
{
setupInputs(targetScriptValue, inputs, rule->module->name);
}
diff --git a/src/lib/corelib/buildgraph/transformer.h b/src/lib/corelib/buildgraph/transformer.h
index 2f6a8e56d..8772ed868 100644
--- a/src/lib/corelib/buildgraph/transformer.h
+++ b/src/lib/corelib/buildgraph/transformer.h
@@ -95,7 +95,7 @@ public:
const Artifact *artifact,
const QString &defaultModuleName);
ResolvedProductPtr product() const;
- void setupInputs(QScriptValue targetScriptValue);
+ void setupInputs(const QScriptValue &targetScriptValue);
void setupOutputs(QScriptValue targetScriptValue);
void setupExplicitlyDependsOn(QScriptValue targetScriptValue);
void createCommands(ScriptEngine *engine, const PrivateScriptFunction &script,
diff --git a/src/lib/corelib/buildgraph/transformerchangetracking.cpp b/src/lib/corelib/buildgraph/transformerchangetracking.cpp
index 505f0cbba..e44c31639 100644
--- a/src/lib/corelib/buildgraph/transformerchangetracking.cpp
+++ b/src/lib/corelib/buildgraph/transformerchangetracking.cpp
@@ -71,7 +71,7 @@ private:
const char *context) const;
bool isExportedModuleUpToDate(const QString &productName, const ExportedModule &module) const;
bool areExportedModulesUpToDate(
- const std::unordered_map<QString, ExportedModule> exportedModules) const;
+ const std::unordered_map<QString, ExportedModule> &exportedModules) const;
const Artifact *getArtifact(const QString &filePath, const QString &productName) const;
const ResolvedProduct *getProduct(const QString &name) const;
@@ -207,7 +207,7 @@ bool TrafoChangeTracker::isExportedModuleUpToDate(const QString &productName,
}
bool TrafoChangeTracker::areExportedModulesUpToDate(
- const std::unordered_map<QString, ExportedModule> exportedModules) const
+ const std::unordered_map<QString, ExportedModule> &exportedModules) const
{
for (const auto &kv : exportedModules) {
if (!isExportedModuleUpToDate(kv.first, kv.second))
diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs
index bd44ac3ed..619c0f0e3 100644
--- a/src/lib/corelib/corelib.qbs
+++ b/src/lib/corelib/corelib.qbs
@@ -395,6 +395,8 @@ QbsLibrary {
"buildgraphlocker.cpp",
"buildgraphlocker.h",
"buildoptions.cpp",
+ "clangclinfo.cpp",
+ "clangclinfo.h",
"cleanoptions.cpp",
"codelocation.cpp",
"commandechomode.cpp",
diff --git a/src/lib/corelib/generators/generatordata.h b/src/lib/corelib/generators/generatordata.h
index da65815ad..fd9bdde31 100644
--- a/src/lib/corelib/generators/generatordata.h
+++ b/src/lib/corelib/generators/generatordata.h
@@ -99,7 +99,7 @@ template <typename U> struct IMultiplexableContainer {
}
protected:
- IMultiplexableContainer() { }
+ IMultiplexableContainer() = default;
};
struct QBS_EXPORT GeneratableProductData : public IMultiplexableContainer<ProductData> {
@@ -114,7 +114,7 @@ struct QBS_EXPORT GeneratableProjectData : public IMultiplexableContainer<Projec
struct Id {
private:
friend struct GeneratableProjectData;
- Id() { }
+ Id() = default;
QString value;
public:
diff --git a/src/lib/corelib/generators/generatorutils.h b/src/lib/corelib/generators/generatorutils.h
index 9348ab18c..58e59cbf8 100644
--- a/src/lib/corelib/generators/generatorutils.h
+++ b/src/lib/corelib/generators/generatorutils.h
@@ -41,14 +41,17 @@ namespace gen {
namespace utils {
enum class Architecture {
- Arm,
- Avr,
- Mcs51,
- Stm8,
- Msp430,
- Unknown
+ Unknown = 0,
+ Arm = 1 << 1,
+ Avr = 1 << 2,
+ Mcs51 = 1 << 3,
+ Stm8 = 1 << 4,
+ Msp430 = 1 << 5
};
+Q_DECLARE_FLAGS(ArchitectureFlags, Architecture)
+Q_DECLARE_OPERATORS_FOR_FLAGS(ArchitectureFlags)
+
QBS_EXPORT QString architectureName(Architecture arch);
QBS_EXPORT Architecture architecture(const Project &qbsProject);
QBS_EXPORT QString buildConfigurationName(const Project &qbsProject);
diff --git a/src/lib/corelib/generators/generatorversioninfo.cpp b/src/lib/corelib/generators/generatorversioninfo.cpp
index 3e2106b57..c5c8db03f 100644
--- a/src/lib/corelib/generators/generatorversioninfo.cpp
+++ b/src/lib/corelib/generators/generatorversioninfo.cpp
@@ -42,42 +42,10 @@
namespace qbs {
namespace gen {
-VersionInfo::VersionInfo(const Version &version,
- const std::set<utils::Architecture> &archs)
- : m_version(version), m_archs(archs)
-{
-}
-
-bool VersionInfo::operator<(const VersionInfo &other) const
-{
- return m_version < other.m_version;
-}
-
-bool VersionInfo::operator==(const VersionInfo &other) const
-{
- return m_version == other.m_version
- && m_archs == other.m_archs;
-}
-
-Version VersionInfo::version() const
-{
- return m_version;
-}
-
-bool VersionInfo::containsArchitecture(utils::Architecture arch) const
-{
- return m_archs.find(arch) != m_archs.cend();
-}
-
int VersionInfo::marketingVersion() const
{
return m_version.majorVersion();
}
-quint32 qHash(const VersionInfo &info)
-{
- return qHash(info.version().toString());
-}
-
} // namespace gen
} // namespace qbs
diff --git a/src/lib/corelib/generators/generatorversioninfo.h b/src/lib/corelib/generators/generatorversioninfo.h
index 65bfcf685..38616eb98 100644
--- a/src/lib/corelib/generators/generatorversioninfo.h
+++ b/src/lib/corelib/generators/generatorversioninfo.h
@@ -45,7 +45,7 @@
#include <tools/qbs_export.h>
#include <tools/version.h>
-#include <set>
+#include <QFlags>
namespace qbs {
namespace gen {
@@ -53,24 +53,31 @@ namespace gen {
class QBS_EXPORT VersionInfo
{
public:
- VersionInfo(const Version &version,
- const std::set<utils::Architecture> &archs);
- virtual ~VersionInfo() = default;
+ constexpr VersionInfo(const Version &version, utils::ArchitectureFlags archs)
+ : m_version(version), m_archs(archs)
+ {
+ }
- bool operator<(const VersionInfo &other) const;
- bool operator==(const VersionInfo &other) const;
+ constexpr bool operator<(const VersionInfo &other) const { return m_version < other.m_version; }
+ constexpr bool operator==(const VersionInfo &other) const
+ {
+ return m_version == other.m_version && m_archs == other.m_archs;
+ }
- Version version() const;
- bool containsArchitecture(utils::Architecture arch) const;
+ constexpr Version version() const { return m_version; }
+ constexpr bool containsArchitecture(utils::Architecture arch) const { return m_archs & arch; }
- virtual int marketingVersion() const;
+ int marketingVersion() const;
private:
Version m_version;
- std::set<utils::Architecture> m_archs;
+ utils::ArchitectureFlags m_archs;
};
-quint32 qHash(const VersionInfo &info);
+inline quint32 qHash(const VersionInfo &info)
+{
+ return qHash(info.version().toString());
+}
} // namespace gen
} // namespace qbs
diff --git a/src/lib/corelib/generators/igeneratableprojectvisitor.h b/src/lib/corelib/generators/igeneratableprojectvisitor.h
index c3bd28580..dbf73b4e0 100644
--- a/src/lib/corelib/generators/igeneratableprojectvisitor.h
+++ b/src/lib/corelib/generators/igeneratableprojectvisitor.h
@@ -46,7 +46,7 @@ namespace qbs {
class IGeneratableProjectVisitor {
public:
- virtual ~IGeneratableProjectVisitor() { }
+ virtual ~IGeneratableProjectVisitor() = default;
// Collapsed configurations
virtual void visitProject(const GeneratableProject &project) {
diff --git a/src/lib/corelib/generators/ixmlnodevisitor.h b/src/lib/corelib/generators/ixmlnodevisitor.h
index d3d118975..278f4cf2e 100644
--- a/src/lib/corelib/generators/ixmlnodevisitor.h
+++ b/src/lib/corelib/generators/ixmlnodevisitor.h
@@ -47,7 +47,7 @@ class Workspace;
class QBS_EXPORT INodeVisitor
{
public:
- virtual ~INodeVisitor() {}
+ virtual ~INodeVisitor() = default;
virtual void visitWorkspaceStart(const Workspace *workspace) { Q_UNUSED(workspace) }
virtual void visitWorkspaceEnd(const Workspace *workspace) { Q_UNUSED(workspace) }
diff --git a/src/lib/corelib/generators/xmlprojectwriter.cpp b/src/lib/corelib/generators/xmlprojectwriter.cpp
index 5554e5935..190e1304f 100644
--- a/src/lib/corelib/generators/xmlprojectwriter.cpp
+++ b/src/lib/corelib/generators/xmlprojectwriter.cpp
@@ -33,6 +33,7 @@
#include "xmlproperty.h"
#include "xmlpropertygroup.h"
+#include <memory>
#include <ostream>
namespace qbs {
@@ -42,7 +43,7 @@ namespace xml {
ProjectWriter::ProjectWriter(std::ostream *device)
: m_device(device)
{
- m_writer.reset(new QXmlStreamWriter(&m_buffer));
+ m_writer = std::make_unique<QXmlStreamWriter>(&m_buffer);
m_writer->setAutoFormatting(true);
}
diff --git a/src/lib/corelib/generators/xmlpropertygroup.cpp b/src/lib/corelib/generators/xmlpropertygroup.cpp
index 398d68e77..c9e6a97c1 100644
--- a/src/lib/corelib/generators/xmlpropertygroup.cpp
+++ b/src/lib/corelib/generators/xmlpropertygroup.cpp
@@ -45,10 +45,9 @@ void PropertyGroup::appendProperty(QByteArray name, QVariant value)
appendChild<Property>(std::move(name), std::move(value));
}
-void PropertyGroup::appendMultiLineProperty(
- QByteArray key, QStringList values, QChar sep)
+void PropertyGroup::appendMultiLineProperty(QByteArray key, const QStringList &values, QChar sep)
{
- const auto line = values.join(std::move(sep));
+ const auto line = values.join(sep);
appendProperty(std::move(key), QVariant::fromValue(line));
}
diff --git a/src/lib/corelib/generators/xmlpropertygroup.h b/src/lib/corelib/generators/xmlpropertygroup.h
index e63b515fc..e7e051a87 100644
--- a/src/lib/corelib/generators/xmlpropertygroup.h
+++ b/src/lib/corelib/generators/xmlpropertygroup.h
@@ -52,7 +52,7 @@ public:
explicit PropertyGroup(QByteArray name);
void appendProperty(QByteArray name, QVariant value);
- void appendMultiLineProperty(QByteArray key, QStringList values,
+ void appendMultiLineProperty(QByteArray key, const QStringList &values,
QChar sep = QLatin1Char(','));
void accept(INodeVisitor *visitor) const final;
diff --git a/src/lib/corelib/generators/xmlworkspacewriter.cpp b/src/lib/corelib/generators/xmlworkspacewriter.cpp
index c88cb06d0..d21b63c42 100644
--- a/src/lib/corelib/generators/xmlworkspacewriter.cpp
+++ b/src/lib/corelib/generators/xmlworkspacewriter.cpp
@@ -33,6 +33,7 @@
#include "xmlworkspace.h"
#include "xmlworkspacewriter.h"
+#include <memory>
#include <ostream>
namespace qbs {
@@ -42,7 +43,7 @@ namespace xml {
WorkspaceWriter::WorkspaceWriter(std::ostream *device)
: m_device(device)
{
- m_writer.reset(new QXmlStreamWriter(&m_buffer));
+ m_writer = std::make_unique<QXmlStreamWriter>(&m_buffer);
m_writer->setAutoFormatting(true);
}
diff --git a/src/lib/corelib/jsextensions/binaryfile.cpp b/src/lib/corelib/jsextensions/binaryfile.cpp
index 5f28f689b..f02f0bff6 100644
--- a/src/lib/corelib/jsextensions/binaryfile.cpp
+++ b/src/lib/corelib/jsextensions/binaryfile.cpp
@@ -235,7 +235,7 @@ void BinaryFile::write(const QVariantList &data)
QByteArray bytes;
std::for_each(data.constBegin(), data.constEnd(), [&bytes](const QVariant &v) {
- bytes.append(v.toUInt() & 0xFF); });
+ bytes.append(char(v.toUInt() & 0xFF)); });
const qint64 size = m_file->write(bytes);
if (Q_UNLIKELY(size == -1)) {
diff --git a/src/lib/corelib/jsextensions/domxml.cpp b/src/lib/corelib/jsextensions/domxml.cpp
index 118e8d5e1..86e1574c6 100644
--- a/src/lib/corelib/jsextensions/domxml.cpp
+++ b/src/lib/corelib/jsextensions/domxml.cpp
@@ -85,7 +85,7 @@ public:
Q_INVOKABLE QScriptValue previousSibling(const QString & tagName = QString()) const;
Q_INVOKABLE QScriptValue nextSibling(const QString & tagName = QString()) const;
- Q_INVOKABLE QScriptValue appendChild(QScriptValue newChild);
+ Q_INVOKABLE QScriptValue appendChild(const QScriptValue &newChild);
Q_INVOKABLE QScriptValue insertBefore(const QScriptValue& newChild, const QScriptValue& refChild);
Q_INVOKABLE QScriptValue insertAfter(const QScriptValue& newChild, const QScriptValue& refChild);
Q_INVOKABLE QScriptValue replaceChild(const QScriptValue& newChild, const QScriptValue& oldChild);
@@ -314,7 +314,6 @@ void XmlDomNode::setData(const QString &v) const
if (m_domNode.isCharacterData())
return m_domNode.toCharacterData().setData(v);
context()->throwError(QStringLiteral("Node '%1' is not a character data node").arg(m_domNode.nodeName()));
- return;
}
void XmlDomNode::clear()
@@ -365,7 +364,7 @@ QScriptValue XmlDomNode::nextSibling(const QString &tagName) const
return engine()->newQObject(new XmlDomNode(m_domNode.nextSiblingElement(tagName)), QScriptEngine::ScriptOwnership);
}
-QScriptValue XmlDomNode::appendChild(QScriptValue newChild)
+QScriptValue XmlDomNode::appendChild(const QScriptValue &newChild)
{
auto newNode = qobject_cast<XmlDomNode*>(newChild.toQObject());
if (!newNode) {
diff --git a/src/lib/corelib/jsextensions/fileinfoextension.cpp b/src/lib/corelib/jsextensions/fileinfoextension.cpp
index 0f2570ed0..038f3db41 100644
--- a/src/lib/corelib/jsextensions/fileinfoextension.cpp
+++ b/src/lib/corelib/jsextensions/fileinfoextension.cpp
@@ -53,6 +53,16 @@
namespace qbs {
namespace Internal {
+// removes duplicate separators from the path
+static QString uniqueSeparators(QString path)
+{
+ const auto it = std::unique(path.begin(), path.end(), [](QChar c1, QChar c2) {
+ return c1 == c2 && c1 == QLatin1Char('/');
+ });
+ path.resize(int(it - path.begin()));
+ return path;
+}
+
class FileInfoExtension : public QObject, QScriptable
{
Q_OBJECT
@@ -268,9 +278,7 @@ QScriptValue FileInfoExtension::js_joinPaths(QScriptContext *context, QScriptEng
paths.push_back(arg);
}
}
- return engine->toScriptValue(QString::fromStdString(
- std::regex_replace(paths.join(QLatin1Char('/')).toStdString(),
- std::regex("/{2,}"), std::string("/"))));
+ return engine->toScriptValue(uniqueSeparators(paths.join(QLatin1Char('/'))));
}
} // namespace Internal
diff --git a/src/lib/corelib/jsextensions/jsextensions.cpp b/src/lib/corelib/jsextensions/jsextensions.cpp
index e5fbd3de8..052fb79e4 100644
--- a/src/lib/corelib/jsextensions/jsextensions.cpp
+++ b/src/lib/corelib/jsextensions/jsextensions.cpp
@@ -75,7 +75,7 @@ static InitializerMap &initializers()
return theMap;
}
-void JsExtensions::setupExtensions(const QStringList &names, QScriptValue scope)
+void JsExtensions::setupExtensions(const QStringList &names, const QScriptValue &scope)
{
for (const QString &name : names)
initializers().value(name)(scope);
diff --git a/src/lib/corelib/jsextensions/jsextensions.h b/src/lib/corelib/jsextensions/jsextensions.h
index 8977dbe8a..f1ebfbdc3 100644
--- a/src/lib/corelib/jsextensions/jsextensions.h
+++ b/src/lib/corelib/jsextensions/jsextensions.h
@@ -54,7 +54,7 @@ namespace Internal {
class JsExtensions
{
public:
- static void setupExtensions(const QStringList &names, QScriptValue scope);
+ static void setupExtensions(const QStringList &names, const QScriptValue &scope);
static QScriptValue loadExtension(QScriptEngine *engine, const QString &name);
static bool hasExtension(const QString &name);
static QStringList extensionNames();
diff --git a/src/lib/corelib/jsextensions/moduleproperties.cpp b/src/lib/corelib/jsextensions/moduleproperties.cpp
index c0fd8ca84..f721e0016 100644
--- a/src/lib/corelib/jsextensions/moduleproperties.cpp
+++ b/src/lib/corelib/jsextensions/moduleproperties.cpp
@@ -195,7 +195,7 @@ static QScriptValue js_moduleDependencies(QScriptContext *, ScriptEngine *engine
QScriptValue result = engine->newArray();
quint32 idx = 0;
for (const QString &depName : qAsConst(module->moduleDependencies)) {
- for (const ResolvedModuleConstPtr &dep : module->product->modules) {
+ for (const auto &dep : module->product->modules) {
if (dep->name != depName)
continue;
QScriptValue obj = engine->newObject(engine->modulePropertyScriptClass());
diff --git a/src/lib/corelib/jsextensions/propertylist.mm b/src/lib/corelib/jsextensions/propertylist.mm
index 6ac9d56c9..2ae422c41 100644
--- a/src/lib/corelib/jsextensions/propertylist.mm
+++ b/src/lib/corelib/jsextensions/propertylist.mm
@@ -95,7 +95,7 @@ public:
QVariant propertyListObject;
int propertyListFormat;
- void readFromData(QScriptContext *context, QByteArray data);
+ void readFromData(QScriptContext *context, const QByteArray &data);
QByteArray writeToData(QScriptContext *context, const QString &format);
};
@@ -263,7 +263,7 @@ QString PropertyList::toJSON(const QString &style) const
namespace qbs {
namespace Internal {
-void PropertyListPrivate::readFromData(QScriptContext *context, QByteArray data)
+void PropertyListPrivate::readFromData(QScriptContext *context, const QByteArray &data)
{
@autoreleasepool {
NSPropertyListFormat format;
diff --git a/src/lib/corelib/jsextensions/utilitiesextension.cpp b/src/lib/corelib/jsextensions/utilitiesextension.cpp
index b425bb4a2..6c693cb61 100644
--- a/src/lib/corelib/jsextensions/utilitiesextension.cpp
+++ b/src/lib/corelib/jsextensions/utilitiesextension.cpp
@@ -72,6 +72,7 @@ struct fat_arch_64 {
#ifdef Q_OS_WIN
+#include <tools/clangclinfo.h>
#include <tools/msvcinfo.h>
#include <tools/vsenvironmentdetector.h>
#endif
@@ -88,6 +89,10 @@ struct fat_arch_64 {
namespace qbs {
namespace Internal {
+class DummyLogSink : public ILogSink {
+ void doPrintMessage(LoggerLevel, const QString &, const QString &) override { }
+};
+
class UtilitiesExtension : public QObject, QScriptable
{
Q_OBJECT
@@ -110,6 +115,8 @@ public:
static QScriptValue js_signingIdentities(QScriptContext *context, QScriptEngine *engine);
static QScriptValue js_msvcCompilerInfo(QScriptContext *context, QScriptEngine *engine);
static QScriptValue js_clangClCompilerInfo(QScriptContext *context, QScriptEngine *engine);
+ static QScriptValue js_installedMSVCs(QScriptContext *context, QScriptEngine *engine);
+ static QScriptValue js_installedClangCls(QScriptContext *context, QScriptEngine *engine);
static QScriptValue js_versionCompare(QScriptContext *context, QScriptEngine *engine);
@@ -132,7 +139,7 @@ QScriptValue UtilitiesExtension::js_canonicalPlatform(QScriptContext *context,
{
const QScriptValue value = context->argument(0);
if (value.isUndefined() || value.isNull())
- return value;
+ return engine->toScriptValue(QStringList());
if (context->argumentCount() == 1 && value.isString()) {
return engine->toScriptValue([&value] {
@@ -529,7 +536,11 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context,
QStringLiteral("clangClCompilerInfo expects 4 arguments"));
const QString compilerFilePath = context->argument(0).toString();
- QString arch = context->argument(1).toString();
+ // architecture cannot be empty as vcvarsall.bat requires at least 1 arg, so fallback
+ // to host architecture if none is present
+ QString arch = !context->argument(1).isNull() && !context->argument(1).isUndefined()
+ ? context->argument(1).toString()
+ : QString::fromStdString(HostOsInfo::hostOSArchitecture());
QString vcvarsallPath = context->argument(2).toString();
const QString compilerLanguage = context->argumentCount() > 3
? context->argument(3).toString()
@@ -551,6 +562,67 @@ QScriptValue UtilitiesExtension::js_clangClCompilerInfo(QScriptContext *context,
#endif
}
+QScriptValue UtilitiesExtension::js_installedMSVCs(QScriptContext *context, QScriptEngine *engine)
+{
+#ifndef Q_OS_WIN
+ Q_UNUSED(engine);
+ return context->throwError(QScriptContext::UnknownError,
+ QStringLiteral("installedMSVCs is not available on this platform"));
+#else
+ if (Q_UNLIKELY(context->argumentCount() != 1)) {
+ return context->throwError(QScriptContext::SyntaxError,
+ QStringLiteral("installedMSVCs expects 1 arguments"));
+ }
+
+ const auto value0 = context->argument(0);
+ const auto hostArch = QString::fromStdString(HostOsInfo::hostOSArchitecture());
+ const auto preferredArch = !value0.isNull() && !value0.isUndefined()
+ ? value0.toString()
+ : hostArch;
+
+ DummyLogSink dummySink;
+ Logger dummyLogger(&dummySink);
+ auto msvcs = MSVC::installedCompilers(dummyLogger);
+
+ const auto predicate = [&preferredArch, &hostArch](const MSVC &msvc)
+ {
+ auto archPair = MSVC::getHostTargetArchPair(msvc.architecture);
+ return archPair.first != hostArch || preferredArch != archPair.second;
+ };
+ msvcs.erase(std::remove_if(msvcs.begin(), msvcs.end(), predicate), msvcs.end());
+ QVariantList result;
+ for (const auto &msvc: msvcs)
+ result.append(msvc.toVariantMap());
+ return engine->toScriptValue(result);
+#endif
+}
+
+QScriptValue UtilitiesExtension::js_installedClangCls(
+ QScriptContext *context, QScriptEngine *engine)
+{
+#ifndef Q_OS_WIN
+ Q_UNUSED(engine);
+ return context->throwError(QScriptContext::UnknownError,
+ QStringLiteral("installedClangCls is not available on this platform"));
+#else
+ if (Q_UNLIKELY(context->argumentCount() != 1)) {
+ return context->throwError(QScriptContext::SyntaxError,
+ QStringLiteral("installedClangCls expects 1 arguments"));
+ }
+
+ const auto value0 = context->argument(0);
+ const auto path = !value0.isNull() && !value0.isUndefined() ? value0.toString() : QString();
+
+ DummyLogSink dummySink;
+ Logger dummyLogger(&dummySink);
+ auto compilers = ClangClInfo::installedCompilers({path}, dummyLogger);
+ QVariantList result;
+ for (const auto &compiler: compilers)
+ result.append(compiler.toVariantMap());
+ return engine->toScriptValue(result);
+#endif
+}
+
QScriptValue UtilitiesExtension::js_versionCompare(QScriptContext *context, QScriptEngine *engine)
{
if (context->argumentCount() == 2) {
@@ -851,6 +923,10 @@ void initializeJsExtensionUtilities(QScriptValue extensionObject)
engine->newFunction(UtilitiesExtension::js_msvcCompilerInfo, 1));
environmentObj.setProperty(QStringLiteral("clangClCompilerInfo"),
engine->newFunction(UtilitiesExtension::js_clangClCompilerInfo, 1));
+ environmentObj.setProperty(QStringLiteral("installedMSVCs"),
+ engine->newFunction(UtilitiesExtension::js_installedMSVCs, 1));
+ environmentObj.setProperty(QStringLiteral("installedClangCls"),
+ engine->newFunction(UtilitiesExtension::js_installedClangCls, 1));
environmentObj.setProperty(QStringLiteral("versionCompare"),
engine->newFunction(UtilitiesExtension::js_versionCompare, 2));
environmentObj.setProperty(QStringLiteral("qmlTypeInfo"),
diff --git a/src/lib/corelib/language/artifactproperties.cpp b/src/lib/corelib/language/artifactproperties.cpp
index dd61bf1a2..011e58d88 100644
--- a/src/lib/corelib/language/artifactproperties.cpp
+++ b/src/lib/corelib/language/artifactproperties.cpp
@@ -48,9 +48,7 @@ ArtifactPropertiesPtr ArtifactProperties::create()
return ArtifactPropertiesPtr(new ArtifactProperties);
}
-ArtifactProperties::ArtifactProperties()
-{
-}
+ArtifactProperties::ArtifactProperties() = default;
FileTags ArtifactProperties::extraFileTags() const
{
@@ -66,6 +64,7 @@ bool operator==(const ArtifactProperties &ap1, const ArtifactProperties &ap2)
{
return ap1.fileTagsFilter() == ap2.fileTagsFilter()
&& ap1.extraFileTags() == ap2.extraFileTags()
+ && !ap1.propertyMap() == !ap2.propertyMap()
&& *ap1.propertyMap() == *ap2.propertyMap();
}
diff --git a/src/lib/corelib/language/asttools.cpp b/src/lib/corelib/language/asttools.cpp
index 617c8b95b..1b6abac7f 100644
--- a/src/lib/corelib/language/asttools.cpp
+++ b/src/lib/corelib/language/asttools.cpp
@@ -61,13 +61,13 @@ QString textOf(const QString &source, QbsQmlJS::AST::Node *node)
if (!node)
return {};
return source.mid(node->firstSourceLocation().begin(),
- node->lastSourceLocation().end() - node->firstSourceLocation().begin());
+ int(node->lastSourceLocation().end() - node->firstSourceLocation().begin()));
}
QStringRef textRefOf(const QString &source, QbsQmlJS::AST::Node *node)
{
const quint32 firstBegin = node->firstSourceLocation().begin();
- return source.midRef(firstBegin, node->lastSourceLocation().end() - firstBegin);
+ return source.midRef(firstBegin, int(node->lastSourceLocation().end() - firstBegin));
}
} // namespace Internal
diff --git a/src/lib/corelib/language/builtindeclarations.cpp b/src/lib/corelib/language/builtindeclarations.cpp
index 68355df51..13783d3b9 100644
--- a/src/lib/corelib/language/builtindeclarations.cpp
+++ b/src/lib/corelib/language/builtindeclarations.cpp
@@ -125,7 +125,7 @@ ItemDeclaration BuiltinDeclarations::declarationsForType(ItemType type) const
}
ItemType BuiltinDeclarations::typeForName(const QString &typeName,
- const CodeLocation location) const
+ const CodeLocation &location) const
{
const auto it = m_typeMap.constFind(typeName);
if (it == m_typeMap.constEnd())
diff --git a/src/lib/corelib/language/builtindeclarations.h b/src/lib/corelib/language/builtindeclarations.h
index 988f9ab81..9d7aee982 100644
--- a/src/lib/corelib/language/builtindeclarations.h
+++ b/src/lib/corelib/language/builtindeclarations.h
@@ -62,7 +62,7 @@ public:
QStringList allTypeNames() const;
ItemDeclaration declarationsForType(ItemType type) const;
ItemType typeForName(const QString &typeName,
- const CodeLocation location = CodeLocation()) const;
+ const CodeLocation &location = CodeLocation()) const;
QString nameForType(ItemType itemType) const;
QStringList argumentNamesForScriptFunction(ItemType itemType, const QString &scriptName) const;
diff --git a/src/lib/corelib/language/deprecationinfo.h b/src/lib/corelib/language/deprecationinfo.h
index 502715b84..89cd07f4a 100644
--- a/src/lib/corelib/language/deprecationinfo.h
+++ b/src/lib/corelib/language/deprecationinfo.h
@@ -50,11 +50,11 @@ class DeprecationInfo
{
public:
explicit DeprecationInfo(const Version &removalVersion,
- const QString &additionalUserInfo = QString())
+ QString additionalUserInfo = QString())
: m_removalVersion(removalVersion)
- , m_additionalUserInfo(additionalUserInfo)
+ , m_additionalUserInfo(std::move(additionalUserInfo))
{}
- DeprecationInfo() {}
+ DeprecationInfo() = default;
bool isValid() const { return m_removalVersion.isValid(); }
Version removalVersion() const { return m_removalVersion; }
diff --git a/src/lib/corelib/language/evaluator.h b/src/lib/corelib/language/evaluator.h
index d8931a37e..f8535d0d7 100644
--- a/src/lib/corelib/language/evaluator.h
+++ b/src/lib/corelib/language/evaluator.h
@@ -64,7 +64,7 @@ class QBS_AUTOTEST_EXPORT Evaluator : private ItemObserver
public:
Evaluator(ScriptEngine *scriptEngine);
- virtual ~Evaluator();
+ ~Evaluator() override;
ScriptEngine *engine() const { return m_scriptEngine; }
QScriptValue property(const Item *item, const QString &name);
diff --git a/src/lib/corelib/language/identifiersearch.cpp b/src/lib/corelib/language/identifiersearch.cpp
index 973aae6a8..49ceab36c 100644
--- a/src/lib/corelib/language/identifiersearch.cpp
+++ b/src/lib/corelib/language/identifiersearch.cpp
@@ -43,9 +43,7 @@
namespace qbs {
namespace Internal {
-IdentifierSearch::IdentifierSearch()
-{
-}
+IdentifierSearch::IdentifierSearch() = default;
void IdentifierSearch::start(QbsQmlJS::AST::Node *node)
{
diff --git a/src/lib/corelib/language/item.cpp b/src/lib/corelib/language/item.cpp
index 9f754bdd7..a86cfeac1 100644
--- a/src/lib/corelib/language/item.cpp
+++ b/src/lib/corelib/language/item.cpp
@@ -203,15 +203,15 @@ bool Item::isOfTypeOrhasParentOfType(ItemType type) const
PropertyDeclaration Item::propertyDeclaration(const QString &name, bool allowExpired) const
{
- PropertyDeclaration decl = m_propertyDeclarations.value(name);
- if (decl.isValid())
- return decl;
+ auto it = m_propertyDeclarations.find(name);
+ if (it != m_propertyDeclarations.end())
+ return it.value();
if (allowExpired) {
- decl = m_expiredPropertyDeclarations.value(name);
- if (decl.isValid())
- return decl;
+ it = m_expiredPropertyDeclarations.find(name);
+ if (it != m_expiredPropertyDeclarations.end())
+ return it.value();
}
- return m_prototype ? m_prototype->propertyDeclaration(name) : decl;
+ return m_prototype ? m_prototype->propertyDeclaration(name) : PropertyDeclaration();
}
void Item::addModule(const Item::Module &module)
diff --git a/src/lib/corelib/language/itempool.cpp b/src/lib/corelib/language/itempool.cpp
index 3da8b947b..ccd22fe2e 100644
--- a/src/lib/corelib/language/itempool.cpp
+++ b/src/lib/corelib/language/itempool.cpp
@@ -43,9 +43,7 @@
namespace qbs {
namespace Internal {
-ItemPool::ItemPool()
-{
-}
+ItemPool::ItemPool() = default;
ItemPool::~ItemPool()
{
diff --git a/src/lib/corelib/language/itemreadervisitorstate.cpp b/src/lib/corelib/language/itemreadervisitorstate.cpp
index ca6ba2e12..20ddb5cfb 100644
--- a/src/lib/corelib/language/itemreadervisitorstate.cpp
+++ b/src/lib/corelib/language/itemreadervisitorstate.cpp
@@ -81,10 +81,7 @@ public:
{
}
- ASTCacheValue(const ASTCacheValue &other)
- : d(other.d)
- {
- }
+ ASTCacheValue(const ASTCacheValue &other) = default;
void setProcessingFlag(bool b) { d->processing = b; }
bool isProcessing() const { return d->processing; }
diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp
index 40549b836..3b3e7401e 100644
--- a/src/lib/corelib/language/language.cpp
+++ b/src/lib/corelib/language/language.cpp
@@ -188,15 +188,9 @@ void ResolvedGroup::store(PersistentPool &pool)
* \sa Rule
*/
-ScriptFunction::ScriptFunction()
-{
-
-}
-
-ScriptFunction::~ScriptFunction()
-{
+ScriptFunction::ScriptFunction() = default;
-}
+ScriptFunction::~ScriptFunction() = default;
/*!
* \variable ScriptFunction::script
@@ -282,7 +276,7 @@ QString Rule::toString() const
FileTags Rule::staticOutputFileTags() const
{
FileTags result;
- for (const RuleArtifactConstPtr &artifact : artifacts)
+ for (const auto &artifact : artifacts)
result.unite(artifact->fileTags);
return result;
}
@@ -312,9 +306,7 @@ ResolvedProduct::ResolvedProduct()
{
}
-ResolvedProduct::~ResolvedProduct()
-{
-}
+ResolvedProduct::~ResolvedProduct() = default;
void ResolvedProduct::accept(BuildGraphVisitor *visitor) const
{
@@ -331,7 +323,7 @@ void ResolvedProduct::accept(BuildGraphVisitor *visitor) const
std::vector<SourceArtifactPtr> ResolvedProduct::allFiles() const
{
std::vector<SourceArtifactPtr> lst;
- for (const GroupConstPtr &group : groups)
+ for (const auto &group : groups)
lst << group->allFiles();
return lst;
}
@@ -343,7 +335,7 @@ std::vector<SourceArtifactPtr> ResolvedProduct::allFiles() const
std::vector<SourceArtifactPtr> ResolvedProduct::allEnabledFiles() const
{
std::vector<SourceArtifactPtr> lst;
- for (const GroupConstPtr &group : groups) {
+ for (const auto &group : groups) {
if (group->enabled)
lst << group->allFiles();
}
@@ -364,7 +356,7 @@ FileTags ResolvedProduct::fileTagsForFileName(const QString &fileName) const
return result;
}
} else {
- priority.reset(new int(tagger->priority()));
+ priority = std::make_unique<int>(tagger->priority());
}
result.unite(tagger->fileTags());
break;
@@ -524,9 +516,7 @@ ResolvedProject::ResolvedProject() : enabled(true), m_topLevelProject(nullptr)
{
}
-ResolvedProject::~ResolvedProject()
-{
-}
+ResolvedProject::~ResolvedProject() = default;
void ResolvedProject::accept(BuildGraphVisitor *visitor) const
{
@@ -551,7 +541,7 @@ TopLevelProject *ResolvedProject::topLevelProject()
std::vector<ResolvedProjectPtr> ResolvedProject::allSubProjects() const
{
std::vector<ResolvedProjectPtr> projectList = subProjects;
- for (const ResolvedProjectConstPtr &subProject : subProjects)
+ for (const auto &subProject : subProjects)
projectList << subProject->allSubProjects();
return projectList;
}
@@ -559,7 +549,7 @@ std::vector<ResolvedProjectPtr> ResolvedProject::allSubProjects() const
std::vector<ResolvedProductPtr> ResolvedProject::allProducts() const
{
std::vector<ResolvedProductPtr> productList = products;
- for (const ResolvedProjectConstPtr &subProject : qAsConst(subProjects))
+ for (const auto &subProject : qAsConst(subProjects))
productList << subProject->allProducts();
return productList;
}
@@ -765,7 +755,7 @@ void SourceWildCards::expandPatterns(Set<QString> &result, const GroupConstPtr &
if (baseDir.startsWith(buildDir))
return;
- dirTimeStamps.push_back({ baseDir, FileInfo(baseDir).lastModified() });
+ dirTimeStamps.emplace_back(baseDir, FileInfo(baseDir).lastModified());
QStringList changed_parts = parts;
bool recursive = false;
@@ -810,7 +800,7 @@ void SourceWildCards::expandPatterns(Set<QString> &result, const GroupConstPtr &
expandPatterns(result, group, changed_parts, filePath, buildDir);
} else {
if (parentDir != baseDir)
- dirTimeStamps.push_back({parentDir, FileInfo(baseDir).lastModified()});
+ dirTimeStamps.emplace_back(parentDir, FileInfo(baseDir).lastModified());
result += QDir::cleanPath(filePath);
}
}
@@ -867,6 +857,7 @@ bool operator==(const SourceArtifactInternal &sa1, const SourceArtifactInternal
&& sa1.fileTags == sa2.fileTags
&& sa1.overrideFileTags == sa2.overrideFileTags
&& sa1.targetOfModule == sa2.targetOfModule
+ && !sa1.properties == !sa2.properties
&& *sa1.properties == *sa2.properties;
}
diff --git a/src/lib/corelib/language/language.h b/src/lib/corelib/language/language.h
index 65879dd56..bbd851333 100644
--- a/src/lib/corelib/language/language.h
+++ b/src/lib/corelib/language/language.h
@@ -99,7 +99,7 @@ public:
private:
FileTagger(const QStringList &patterns, FileTags fileTags, int priority);
- FileTagger() {}
+ FileTagger() = default;
void setPatterns(const QStringList &patterns);
@@ -139,20 +139,20 @@ public:
}
private:
- Probe() {}
- Probe(const QString &globalId,
+ Probe() = default;
+ Probe(QString globalId,
const CodeLocation &location,
bool condition,
- const QString &configureScript,
- const QVariantMap &properties,
- const QVariantMap &initialProperties,
- const std::vector<QString> &importedFilesUsed)
- : m_globalId(globalId)
+ QString configureScript,
+ QVariantMap properties,
+ QVariantMap initialProperties,
+ std::vector<QString> importedFilesUsed)
+ : m_globalId(std::move(globalId))
, m_location(location)
- , m_configureScript(configureScript)
- , m_properties(properties)
- , m_initialProperties(initialProperties)
- , m_importedFilesUsed(importedFilesUsed)
+ , m_configureScript(std::move(configureScript))
+ , m_properties(std::move(properties))
+ , m_initialProperties(std::move(initialProperties))
+ , m_importedFilesUsed(std::move(importedFilesUsed))
, m_condition(condition)
{}
@@ -378,7 +378,7 @@ public:
}
private:
- ResolvedModule() {}
+ ResolvedModule() = default;
};
bool operator==(const ResolvedModule &m1, const ResolvedModule &m2);
inline bool operator!=(const ResolvedModule &m1, const ResolvedModule &m2) { return !(m1 == m2); }
diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp
index 9c8f9da1d..56fbc198e 100644
--- a/src/lib/corelib/language/moduleloader.cpp
+++ b/src/lib/corelib/language/moduleloader.cpp
@@ -71,20 +71,24 @@
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
+#include <QtCore/qglobalstatic.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/qjsondocument.h>
#include <QtCore/qjsonobject.h>
#include <QtCore/qtemporaryfile.h>
#include <QtCore/qtextstream.h>
+#include <QtCore/qthreadstorage.h>
#include <QtScript/qscriptvalueiterator.h>
#include <algorithm>
+#include <memory>
#include <utility>
namespace qbs {
namespace Internal {
-static QString shadowProductPrefix() { return QStringLiteral("__shadow__"); }
+using MultiplexConfigurationByIdTable = QThreadStorage<QHash<QString, QVariantMap> >;
+Q_GLOBAL_STATIC(MultiplexConfigurationByIdTable, multiplexConfigurationsById);
static void handlePropertyError(const ErrorInfo &error, const SetupProjectParameters &params,
Logger &logger)
@@ -94,6 +98,20 @@ static void handlePropertyError(const ErrorInfo &error, const SetupProjectParame
logger.printWarning(error);
}
+static bool multiplexConfigurationIntersects(const QVariantMap &lhs, const QVariantMap &rhs)
+{
+ QBS_CHECK(!lhs.isEmpty() && !rhs.isEmpty());
+
+ for (auto lhsProperty = lhs.constBegin(); lhsProperty != lhs.constEnd(); lhsProperty++) {
+ const auto rhsProperty = rhs.find(lhsProperty.key());
+ const bool isCommonProperty = rhsProperty != rhs.constEnd();
+ if (isCommonProperty && lhsProperty.value() != rhsProperty.value())
+ return false;
+ }
+
+ return true;
+}
+
class ModuleLoader::ItemModuleList : public QList<Item::Module> {};
static QString probeGlobalId(Item *probe)
@@ -292,7 +310,7 @@ ModuleLoaderResult ModuleLoader::load(const SetupProjectParameters &parameters)
= m_elapsedTimePropertyChecking = 0;
m_elapsedTimeProbes = 0;
m_probesEncountered = m_probesRun = m_probesCachedCurrent = m_probesCachedOld = 0;
- m_settings.reset(new Settings(parameters.settingsDirectory()));
+ m_settings = std::make_unique<Settings>(parameters.settingsDirectory());
const auto keys = m_parameters.overriddenValues().keys();
for (const QString &key : keys) {
@@ -381,9 +399,9 @@ class PropertyDeclarationCheck : public ValueHandler
Logger &m_logger;
public:
PropertyDeclarationCheck(const Set<Item *> &disabledItems,
- const SetupProjectParameters &params, Logger &logger)
+ SetupProjectParameters params, Logger &logger)
: m_disabledItems(disabledItems)
- , m_params(params)
+ , m_params(std::move(params))
, m_logger(logger)
{
}
@@ -616,7 +634,7 @@ void ModuleLoader::handleTopLevelProject(ModuleLoaderResult *loadResult, Item *p
for (ProductContext * const p : productSorter.sortedProducts()) {
try {
handleProduct(p);
- if (p->name.startsWith(shadowProductPrefix()))
+ if (p->name.startsWith(StringConstants::shadowProductPrefix()))
tlp.probes << p->info.probes;
} catch (const ErrorInfo &err) {
handleProductError(err, p);
@@ -688,6 +706,9 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult,
m_qbsVersion.toString()));
}
+ for (Item * const child : projectItem->children())
+ child->setScope(projectContext.scope);
+
resolveProbes(&dummyProductContext, projectItem);
projectContext.topLevelProject->probes << dummyProductContext.info.probes;
@@ -695,7 +716,6 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult,
QList<Item *> multiplexedProducts;
for (Item * const child : projectItem->children()) {
- child->setScope(projectContext.scope);
if (child->type() == ItemType::Product)
multiplexedProducts << multiplexProductItem(&dummyProductContext, child);
}
@@ -762,9 +782,24 @@ QString ModuleLoader::MultiplexInfo::toIdString(size_t row) const
const VariantValuePtr &mpvalue = mprow.at(column);
multiplexConfiguration.insert(propertyName, mpvalue->value());
}
- return QString::fromUtf8(QJsonDocument::fromVariant(multiplexConfiguration)
- .toJson(QJsonDocument::Compact)
- .toBase64());
+ QString id = QString::fromUtf8(QJsonDocument::fromVariant(multiplexConfiguration)
+ .toJson(QJsonDocument::Compact)
+ .toBase64());
+ // Cache for later use in:multiplexIdToVariantMap()
+ multiplexConfigurationsById->localData().insert(id, multiplexConfiguration);
+ return id;
+}
+
+QVariantMap ModuleLoader::MultiplexInfo::multiplexIdToVariantMap(const QString &multiplexId)
+{
+ if (multiplexId.isEmpty())
+ return QVariantMap();
+
+ QVariantMap result = multiplexConfigurationsById->localData().value(multiplexId);
+ // We assume that MultiplexInfo::toIdString() has been called for this
+ // particular multiplex configuration.
+ QBS_CHECK(!result.isEmpty());
+ return result;
}
void qbs::Internal::ModuleLoader::ModuleLoader::dump(const ModuleLoader::MultiplexInfo &mpi)
@@ -1085,66 +1120,111 @@ void ModuleLoader::adjustDependenciesForMultiplexing(const ProductContext &produ
StringConstants::profilesProperty(), &profilesPropertyIsSet);
const auto productRange = m_productsByName.equal_range(name);
- std::vector<const ProductContext *> dependencies;
+ if (productRange.first == productRange.second) {
+ // Dependency is a module. Nothing to adjust.
+ return;
+ }
+
+ std::vector<const ProductContext *> multiplexedDependencies;
bool hasNonMultiplexedDependency = false;
for (auto it = productRange.first; it != productRange.second; ++it) {
- if (!it->second->multiplexConfigurationId.isEmpty()) {
- dependencies.push_back(it->second);
- if (productIsMultiplexed && !profilesPropertyIsSet)
- break;
- } else {
+ if (!it->second->multiplexConfigurationId.isEmpty())
+ multiplexedDependencies.push_back(it->second);
+ else
hasNonMultiplexedDependency = true;
- break;
- }
}
+ bool hasMultiplexedDependencies = !multiplexedDependencies.empty();
// These are the allowed cases:
// (1) Normal dependency with no multiplexing whatsoever.
// (2) Both product and dependency are multiplexed.
+ // (2a) The profiles property is not set, we want to depend on the best
+ // matching variant.
+ // (2b) The profiles property is set, we want to depend on all variants
+ // with a matching profile.
// (3) The product is not multiplexed, but the dependency is.
- // (3a) The dependency has an aggregator. We want to depend on the aggregator.
- // (3b) The dependency does not have an aggregator. We want to depend on all the
- // multiplexed variants.
- // (4) The product is multiplexed, but the dependency is not. This case is implicitly
- // handled, because we don't have to adapt any Depends items.
+ // (3a) The profiles property is not set, the dependency has an aggregator.
+ // We want to depend on the aggregator.
+ // (3b) The profiles property is not set, the dependency does not have an
+ // aggregator. We want to depend on all the multiplexed variants.
+ // (3c) The profiles property is set, we want to depend on all variants
+ // with a matching profile regardless of whether an aggregator exists or not.
+ // (4) The product is multiplexed, but the dependency is not. We don't have to adapt
+ // any Depends items.
// (5) The product is a "shadow product". In that case, we know which product
// it should have a dependency on, and we make sure we depend on that.
- // (1) and (3a)
- if (!productIsMultiplexed && hasNonMultiplexedDependency)
+ // (1) and (4)
+ if (!hasMultiplexedDependencies)
+ return;
+
+ // (3a)
+ if (!productIsMultiplexed && hasNonMultiplexedDependency && !profilesPropertyIsSet)
return;
QStringList multiplexIds;
const ShadowProductInfo shadowProductInfo = getShadowProductInfo(product);
const bool isShadowProduct = shadowProductInfo.first && shadowProductInfo.second == name;
- for (const ProductContext *dependency : dependencies) {
+ const auto productMultiplexConfig =
+ MultiplexInfo::multiplexIdToVariantMap(product.multiplexConfigurationId);
+
+ for (const ProductContext *dependency : multiplexedDependencies) {
const bool depMatchesShadowProduct = isShadowProduct
&& dependency->item == product.item->parent();
const QString depMultiplexId = dependency->multiplexConfigurationId;
if (depMatchesShadowProduct) { // (5)
dependsItem->setProperty(StringConstants::multiplexConfigurationIdsProperty(),
VariantValue::create(depMultiplexId));
- multiplexIds.clear();
- break;
- }
- if (productIsMultiplexed && !profilesPropertyIsSet) { // (2)
- const ValuePtr &multiplexId = product.item->property(
- StringConstants::multiplexConfigurationIdProperty());
- dependsItem->setProperty(StringConstants::multiplexConfigurationIdsProperty(),
- multiplexId);
- break;
+ return;
}
+ if (productIsMultiplexed && !profilesPropertyIsSet) { // 2a
+ if (dependency->multiplexConfigurationId == product.multiplexConfigurationId) {
+ const ValuePtr &multiplexId = product.item->property(
+ StringConstants::multiplexConfigurationIdProperty());
+ dependsItem->setProperty(StringConstants::multiplexConfigurationIdsProperty(),
+ multiplexId);
+ return;
- // (3b) (or (2) if Depends.profiles is set).
- const bool profileMatch = !profilesPropertyIsSet || profiles.empty()
- || profiles.contains(dependency->profileName);
- if (profileMatch)
- multiplexIds << depMultiplexId;
- }
- if (!multiplexIds.empty()) {
- dependsItem->setProperty(StringConstants::multiplexConfigurationIdsProperty(),
- VariantValue::create(multiplexIds));
+ } else {
+ // Otherwise collect partial matches and decide later
+ const auto dependencyMultiplexConfig =
+ MultiplexInfo::multiplexIdToVariantMap(dependency->multiplexConfigurationId);
+
+ if (multiplexConfigurationIntersects(dependencyMultiplexConfig, productMultiplexConfig))
+ multiplexIds << dependency->multiplexConfigurationId;
+ }
+ } else {
+ // (2b), (3b) or (3c)
+ const bool profileMatch = !profilesPropertyIsSet || profiles.empty()
+ || profiles.contains(dependency->profileName);
+ if (profileMatch)
+ multiplexIds << depMultiplexId;
+ }
}
+ if (multiplexIds.empty()) {
+ const QString productName = ResolvedProduct::fullDisplayName(
+ product.name, product.multiplexConfigurationId);
+ throw ErrorInfo(Tr::tr("Dependency from product '%1' to product '%2' not fulfilled. "
+ "There are no eligible multiplex candidates.").arg(productName,
+ name),
+ dependsItem->location());
+ }
+
+ // In case of (2a), at most 1 match is allowed
+ if (productIsMultiplexed && !profilesPropertyIsSet && multiplexIds.size() > 1) {
+ const QString productName = ResolvedProduct::fullDisplayName(
+ product.name, product.multiplexConfigurationId);
+ QStringList candidateNames;
+ for (const auto &id : qAsConst(multiplexIds))
+ candidateNames << ResolvedProduct::fullDisplayName(name, id);
+ throw ErrorInfo(Tr::tr("Dependency from product '%1' to product '%2' is ambiguous. "
+ "Eligible multiplex candidates: %3.").arg(
+ productName, name, candidateNames.join(QLatin1String(", "))),
+ dependsItem->location());
+ }
+
+ dependsItem->setProperty(StringConstants::multiplexConfigurationIdsProperty(),
+ VariantValue::create(multiplexIds));
}
void ModuleLoader::prepareProduct(ProjectContext *projectContext, Item *productItem)
@@ -1216,7 +1296,8 @@ void ModuleLoader::prepareProduct(ProjectContext *projectContext, Item *productI
// evaluate the product's exported properties in isolation in the project resolver.
Item * const importer = Item::create(productItem->pool(), ItemType::Product);
importer->setProperty(QStringLiteral("name"),
- VariantValue::create(shadowProductPrefix() + productContext.name));
+ VariantValue::create(StringConstants::shadowProductPrefix()
+ + productContext.name));
importer->setFile(productItem->file());
importer->setLocation(productItem->location());
importer->setScope(projectContext->scope);
@@ -1281,7 +1362,6 @@ void ModuleLoader::createSortedModuleList(const Item::Module &parentModule, Item
for (const Item::Module &dep : parentModule.item->modules())
createSortedModuleList(dep, modules);
modules.push_back(parentModule);
- return;
}
Item::Modules ModuleLoader::modulesSortedByDependency(const Item *productItem)
@@ -1350,8 +1430,7 @@ void ModuleLoader::handleProduct(ModuleLoader::ProductContext *productContext)
// set by the dependency module's merger (namely, scopes of defining items; see
// ModuleMerger::replaceItemInScopes()).
Item::Modules topSortedModules = modulesSortedByDependency(item);
- for (Item::Module &module : topSortedModules)
- ModuleMerger(m_logger, item, module).start();
+ ModuleMerger::merge(m_logger, item, productContext->name, &topSortedModules);
// Re-sort the modules by name. This is more stable; see QBS-818.
// The list of modules in the product now has the same order as before,
@@ -1585,7 +1664,7 @@ void ModuleLoader::handleSubProject(ModuleLoader::ProjectContext *projectContext
const Item::PropertyMap &overriddenProperties = propertiesItem->properties();
for (Item::PropertyMap::ConstIterator it = overriddenProperties.constBegin();
it != overriddenProperties.constEnd(); ++it) {
- loadedItem->setProperty(it.key(), overriddenProperties.value(it.key()));
+ loadedItem->setProperty(it.key(), it.value());
}
}
@@ -1806,7 +1885,7 @@ ProbeConstPtr ModuleLoader::findCurrentProbe(
bool condition,
const QVariantMap &initialProperties) const
{
- const QList<ProbeConstPtr> &cachedProbes = m_currentProbes.value(location);
+ const std::vector<ProbeConstPtr> &cachedProbes = m_currentProbes.value(location);
for (const ProbeConstPtr &probe : cachedProbes) {
if (probeMatches(probe, condition, initialProperties, QString(), CompareScript::No))
return probe;
@@ -1964,7 +2043,7 @@ bool ModuleLoader::mergeExportItems(const ProductContext &productContext)
productContext.project->topLevelProject->productModules.insert(productContext.name, pmi);
if (hasDependenciesOnProductType)
m_exportsWithDeferredDependsItems.insert(merged);
- return exportItems.size() > 0;
+ return !exportItems.empty();
}
Item *ModuleLoader::loadItemFromFile(const QString &filePath,
@@ -2171,9 +2250,10 @@ void ModuleLoader::setSearchPathsForProduct(ModuleLoader::ProductContext *produc
ModuleLoader::ShadowProductInfo ModuleLoader::getShadowProductInfo(
const ModuleLoader::ProductContext &product) const
{
- const bool isShadowProduct = product.name.startsWith(shadowProductPrefix());
+ const bool isShadowProduct = product.name.startsWith(StringConstants::shadowProductPrefix());
return std::make_pair(isShadowProduct, isShadowProduct
- ? product.name.mid(shadowProductPrefix().size()) : QString());
+ ? product.name.mid(StringConstants::shadowProductPrefix().size())
+ : QString());
}
void ModuleLoader::collectProductsByName(const TopLevelProjectContext &topLevelProject)
@@ -2705,7 +2785,7 @@ void ModuleLoader::resolveParameterDeclarations(const Item *module)
for (Item *param : moduleChildren) {
if (param->type() != ItemType::Parameter)
continue;
- const auto paramDecls = param->propertyDeclarations();
+ const auto &paramDecls = param->propertyDeclarations();
for (auto it = paramDecls.begin(); it != paramDecls.end(); ++it)
decls.insert(it.key(), it.value());
}
@@ -2756,7 +2836,8 @@ QVariantMap ModuleLoader::extractParameters(Item *dependsItem) const
QScriptValue sv = m_evaluator->scriptValue(dependsItem);
try {
result = safeToVariant(sv);
- } catch (ErrorInfo ei) {
+ } catch (const ErrorInfo &exception) {
+ auto ei = exception;
ei.prepend(Tr::tr("Error in dependency parameter."), dependsItem->location());
throw ei;
}
@@ -3024,72 +3105,67 @@ Item *ModuleLoader::searchAndLoadModuleFile(ProductContext *productContext,
const CodeLocation &dependsItemLocation, const QualifiedId &moduleName,
FallbackMode fallbackMode, bool isRequired, Item *moduleInstance)
{
- bool triedToLoadModule = false;
+ auto existingPaths = findExistingModulePaths(m_reader->allSearchPaths(), moduleName);
+
+ if (existingPaths.isEmpty()) { // no suitable names found, try to use providers
+ bool moduleAlreadyKnown = false;
+ ModuleProviderResult result;
+ for (QualifiedId providerName = moduleName; !providerName.empty();
+ providerName.pop_back()) {
+ if (!productContext->knownModuleProviders.insert(providerName).second) {
+ moduleAlreadyKnown = true;
+ break;
+ }
+ qCDebug(lcModuleLoader) << "Module" << moduleName.toString()
+ << "not found, checking for module providers";
+ result = findModuleProvider(providerName, *productContext,
+ ModuleProviderLookup::Regular, dependsItemLocation);
+ if (result.providerFound)
+ break;
+ }
+ if (fallbackMode == FallbackMode::Enabled && !result.providerFound
+ && !moduleAlreadyKnown) {
+ qCDebug(lcModuleLoader) << "Specific module provider not found for"
+ << moduleName.toString() << ", setting up fallback.";
+ result = findModuleProvider(moduleName, *productContext,
+ ModuleProviderLookup::Fallback, dependsItemLocation);
+ }
+ if (result.providerAddedSearchPaths) {
+ qCDebug(lcModuleLoader) << "Re-checking for module" << moduleName.toString()
+ << "with newly added search paths from module provider";
+ existingPaths = findExistingModulePaths(m_reader->allSearchPaths(), moduleName);
+ }
+ }
+
const QString fullName = moduleName.toString();
+ bool triedToLoadModule = false;
std::vector<PrioritizedItem> candidates;
- const QStringList &searchPaths = m_reader->allSearchPaths();
- bool matchingDirectoryFound = false;
- for (int i = 0; i < searchPaths.size(); ++i) {
- const QString &path = searchPaths.at(i);
- const QString dirPath = findExistingModulePath(path, moduleName);
- if (dirPath.isEmpty())
- continue;
- matchingDirectoryFound = true;
- QStringList moduleFileNames = m_moduleDirListCache.value(dirPath);
- if (moduleFileNames.empty()) {
- QDirIterator dirIter(dirPath, StringConstants::qbsFileWildcards());
- while (dirIter.hasNext())
- moduleFileNames += dirIter.next();
-
- m_moduleDirListCache.insert(dirPath, moduleFileNames);
- }
- for (const QString &filePath : qAsConst(moduleFileNames)) {
- triedToLoadModule = true;
+ candidates.reserve(size_t(existingPaths.size()));
+ for (int i = 0; i < existingPaths.size(); ++i) {
+ const QString &dirPath = existingPaths.at(i);
+ QStringList &moduleFileNames = getModuleFileNames(dirPath);
+ for (auto it = moduleFileNames.begin(); it != moduleFileNames.end(); ) {
+ const QString &filePath = *it;
+ bool triedToLoad = true;
Item *module = loadModuleFile(productContext, fullName, isBaseModule(moduleName),
- filePath, &triedToLoadModule, moduleInstance);
+ filePath, &triedToLoad, moduleInstance);
if (module)
candidates.emplace_back(module, 0, i);
- if (!triedToLoadModule)
- m_moduleDirListCache[dirPath].removeOne(filePath);
+ if (!triedToLoad)
+ it = moduleFileNames.erase(it);
+ else
+ ++it;
+ triedToLoadModule = triedToLoadModule || triedToLoad;
}
}
if (candidates.empty()) {
- if (!matchingDirectoryFound) {
- bool moduleAlreadyKnown = false;
- ModuleProviderResult result;
- for (QualifiedId providerName = moduleName; !providerName.empty();
- providerName.pop_back()) {
- if (!productContext->knownModuleProviders.insert(providerName).second) {
- moduleAlreadyKnown = true;
- break;
- }
- qCDebug(lcModuleLoader) << "Module" << moduleName.toString()
- << "not found, checking for module providers";
- result = findModuleProvider(providerName, *productContext,
- ModuleProviderLookup::Regular, dependsItemLocation);
- if (result.providerFound)
- break;
- }
- if (fallbackMode == FallbackMode::Enabled && !result.providerFound
- && !moduleAlreadyKnown) {
- qCDebug(lcModuleLoader) << "Specific module provider not found for"
- << moduleName.toString() << ", setting up fallback.";
- result = findModuleProvider(moduleName, *productContext,
- ModuleProviderLookup::Fallback, dependsItemLocation);
- }
- if (result.providerAddedSearchPaths) {
- qCDebug(lcModuleLoader) << "Re-checking for module" << moduleName.toString()
- << "with newly added search paths from module provider";
- return searchAndLoadModuleFile(productContext, dependsItemLocation, moduleName,
- fallbackMode, isRequired, moduleInstance);
- }
- }
if (!isRequired)
return createNonPresentModule(fullName, QStringLiteral("not found"), nullptr);
- if (Q_UNLIKELY(triedToLoadModule))
+ if (Q_UNLIKELY(triedToLoadModule)) {
throw ErrorInfo(Tr::tr("Module %1 could not be loaded.").arg(fullName),
dependsItemLocation);
+ }
return nullptr;
}
@@ -3119,6 +3195,17 @@ Item *ModuleLoader::searchAndLoadModuleFile(ProductContext *productContext,
return moduleItem;
}
+QStringList &ModuleLoader::getModuleFileNames(const QString &dirPath)
+{
+ QStringList &moduleFileNames = m_moduleDirListCache[dirPath];
+ if (moduleFileNames.empty()) {
+ QDirIterator dirIter(dirPath, StringConstants::qbsFileWildcards());
+ while (dirIter.hasNext())
+ moduleFileNames += dirIter.next();
+ }
+ return moduleFileNames;
+}
+
// returns QVariant::Invalid for types that do not need conversion
static QVariant::Type variantType(PropertyDeclaration::Type t)
{
@@ -3227,7 +3314,7 @@ Item *ModuleLoader::getModulePrototype(ProductContext *productContext,
}
}
Item * const module = loadItemFromFile(filePath, CodeLocation());
- prototypeList.push_back(std::make_pair(module, productContext->profileName));
+ prototypeList.emplace_back(module, productContext->profileName);
if (module->type() != ItemType::Module) {
qCDebug(lcModuleLoader).nospace()
<< "Alleged module " << fullModuleName << " has type '"
@@ -3285,6 +3372,9 @@ void ModuleLoader::setupBaseModulePrototype(Item *prototype)
prototype->setProperty(QStringLiteral("hostPlatform"),
VariantValue::create(QString::fromStdString(
HostOsInfo::hostOSIdentifier())));
+ prototype->setProperty(QStringLiteral("hostArchitecture"),
+ VariantValue::create(QString::fromStdString(
+ HostOsInfo::hostOSArchitecture())));
prototype->setProperty(QStringLiteral("libexecPath"),
VariantValue::create(m_parameters.libexecPath()));
@@ -3327,7 +3417,7 @@ static std::vector<std::pair<QualifiedId, ItemValuePtr>> instanceItemProperties(
if (itemValue->item()->type() == ItemType::ModulePrefix)
f(itemValue->item());
else
- result.push_back(std::make_pair(name, itemValue));
+ result.emplace_back(name, itemValue);
name.removeLast();
}
};
@@ -3496,7 +3586,7 @@ void ModuleLoader::resolveProbe(ProductContext *productContext, Item *parent, It
if (Q_UNLIKELY(configureScript->sourceCode() == StringConstants::undefinedValue()))
throw ErrorInfo(Tr::tr("Probe.configure must be set."), probe->location());
using ProbeProperty = std::pair<QString, QScriptValue>;
- QList<ProbeProperty> probeBindings;
+ std::vector<ProbeProperty> probeBindings;
QVariantMap initialProperties;
for (Item *obj = probe; obj; obj = obj->prototype()) {
const Item::PropertyMap &props = obj->properties();
@@ -3505,7 +3595,7 @@ void ModuleLoader::resolveProbe(ProductContext *productContext, Item *parent, It
if (name == StringConstants::configureProperty())
continue;
const QScriptValue value = m_evaluator->value(probe, name);
- probeBindings += ProbeProperty(name, value);
+ probeBindings << ProbeProperty(name, value);
if (name != StringConstants::conditionProperty())
initialProperties.insert(name, value.toVariant());
}
@@ -3516,7 +3606,7 @@ void ModuleLoader::resolveProbe(ProductContext *productContext, Item *parent, It
const QString &sourceCode = configureScript->sourceCode().toString();
ProbeConstPtr resolvedProbe;
if (parent->type() == ItemType::Project
- || productContext->name.startsWith(shadowProductPrefix())) {
+ || productContext->name.startsWith(StringConstants::shadowProductPrefix())) {
resolvedProbe = findOldProjectProbe(probeId, condition, initialProperties, sourceCode);
} else {
const QString &uniqueProductName = productContext->uniqueName();
@@ -3544,7 +3634,7 @@ void ModuleLoader::resolveProbe(ProductContext *productContext, Item *parent, It
engine->currentContext()->pushScope(fileCtxScopes.fileScope);
engine->currentContext()->pushScope(fileCtxScopes.importScope);
configureScope = engine->newObject();
- for (const ProbeProperty &b : qAsConst(probeBindings))
+ for (const ProbeProperty &b : probeBindings)
configureScope.setProperty(b.first, b.second);
engine->currentContext()->pushScope(configureScope);
engine->clearRequestedProperties();
@@ -3560,7 +3650,7 @@ void ModuleLoader::resolveProbe(ProductContext *productContext, Item *parent, It
importedFilesUsedInConfigure = resolvedProbe->importedFilesUsed();
}
QVariantMap properties;
- for (const ProbeProperty &b : qAsConst(probeBindings)) {
+ for (const ProbeProperty &b : probeBindings) {
QVariant newValue;
if (resolvedProbe) {
newValue = resolvedProbe->properties().value(b.first);
@@ -3678,12 +3768,36 @@ QString ModuleLoader::findExistingModulePath(const QString &searchPath,
const QualifiedId &moduleName)
{
QString dirPath = searchPath + QStringLiteral("/modules");
+
+ // isFileCaseCorrect is a very expensive call on macOS, so we cache the value for the
+ // modules and search paths we've already processed
+ auto &moduleInfo = m_existingModulePathCache[{searchPath, moduleName}];
+ if (moduleInfo.first) // poor man's std::optional<QString>
+ return moduleInfo.second;
+
for (const QString &moduleNamePart : moduleName) {
dirPath = FileInfo::resolvePath(dirPath, moduleNamePart);
- if (!FileInfo::exists(dirPath) || !FileInfo::isFileCaseCorrect(dirPath))
- return {};
+ if (!FileInfo::exists(dirPath) || !FileInfo::isFileCaseCorrect(dirPath)) {
+ moduleInfo.first = true;
+ return moduleInfo.second = QString();
+ }
}
- return dirPath;
+
+ moduleInfo.first = true;
+ return moduleInfo.second = dirPath;
+}
+
+QStringList ModuleLoader::findExistingModulePaths(
+ const QStringList &searchPaths, const QualifiedId &moduleName)
+{
+ QStringList result;
+ result.reserve(searchPaths.size());
+ for (const auto &path: searchPaths) {
+ const QString dirPath = findExistingModulePath(path, moduleName);
+ if (!dirPath.isEmpty())
+ result.append(dirPath);
+ }
+ return result;
}
QVariantMap ModuleLoader::moduleProviderConfig(ModuleLoader::ProductContext &product)
@@ -3769,6 +3883,7 @@ ModuleLoader::ModuleProviderResult ModuleLoader::findModuleProvider(const Qualif
const QString searchPathBaseDir = ModuleProviderInfo::outputDirPath(projectBuildDir, name);
const QVariant moduleConfig = moduleProviderConfig(product).value(name.toString());
QTextStream stream(&dummyItemFile);
+ using Qt::endl;
stream.setCodec("UTF-8");
stream << "import qbs.FileInfo" << endl;
stream << "import qbs.Utilities" << endl;
diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h
index 85a2467f2..942f93c83 100644
--- a/src/lib/corelib/language/moduleloader.h
+++ b/src/lib/corelib/language/moduleloader.h
@@ -218,7 +218,7 @@ private:
{
Q_DISABLE_COPY(TopLevelProjectContext)
public:
- TopLevelProjectContext() {}
+ TopLevelProjectContext() = default;
~TopLevelProjectContext() { qDeleteAll(projects); }
std::vector<ProjectContext *> projects;
@@ -252,6 +252,7 @@ private:
VariantValuePtr multiplexedType;
QString toIdString(size_t row) const;
+ static QVariantMap multiplexIdToVariantMap(const QString &multiplexId);
};
void dump(const MultiplexInfo &mpi);
@@ -317,6 +318,7 @@ private:
Item *searchAndLoadModuleFile(ProductContext *productContext,
const CodeLocation &dependsItemLocation, const QualifiedId &moduleName,
FallbackMode fallbackMode, bool isRequired, Item *moduleInstance);
+ QStringList &getModuleFileNames(const QString &dirPath);
Item *loadModuleFile(ProductContext *productContext, const QString &fullModuleName,
bool isBaseModule, const QString &filePath, bool *triedToLoad, Item *moduleInstance);
Item *getModulePrototype(ProductContext *productContext, const QString &fullModuleName,
@@ -337,8 +339,9 @@ private:
QStringList readExtraSearchPaths(Item *item, bool *wasSet = nullptr);
void copyProperties(const Item *sourceProject, Item *targetProject);
Item *wrapInProjectIfNecessary(Item *item);
- static QString findExistingModulePath(const QString &searchPath,
- const QualifiedId &moduleName);
+ QString findExistingModulePath(const QString &searchPath, const QualifiedId &moduleName);
+ QStringList findExistingModulePaths(
+ const QStringList &searchPaths, const QualifiedId &moduleName);
enum class ModuleProviderLookup { Regular, Fallback };
struct ModuleProviderResult
@@ -411,6 +414,7 @@ private:
ItemReader *m_reader;
Evaluator *m_evaluator;
QMap<QString, QStringList> m_moduleDirListCache;
+ QHash<std::pair<QString, QualifiedId>, std::pair<bool, QString>> m_existingModulePathCache;
// The keys are file paths, the values are module prototype items accompanied by a profile.
std::unordered_map<QString, std::vector<std::pair<Item *, QString>>> m_modulePrototypes;
@@ -425,8 +429,8 @@ private:
struct DependsChainEntry
{
- DependsChainEntry(const QualifiedId &name, const CodeLocation &location)
- : name(name), location(location)
+ DependsChainEntry(QualifiedId name, const CodeLocation &location)
+ : name(std::move(name)), location(location)
{
}
@@ -437,10 +441,10 @@ private:
class DependsChainManager;
std::vector<DependsChainEntry> m_dependsChain;
- QHash<QString, QList<ProbeConstPtr>> m_oldProjectProbes;
+ QHash<QString, std::vector<ProbeConstPtr>> m_oldProjectProbes;
QHash<QString, std::vector<ProbeConstPtr>> m_oldProductProbes;
FileTime m_lastResolveTime;
- QHash<CodeLocation, QList<ProbeConstPtr>> m_currentProbes;
+ QHash<CodeLocation, std::vector<ProbeConstPtr>> m_currentProbes;
QVariantMap m_storedProfiles;
QVariantMap m_localProfiles;
std::multimap<QString, const ProductContext *> m_productsByName;
diff --git a/src/lib/corelib/language/modulemerger.cpp b/src/lib/corelib/language/modulemerger.cpp
index 053e90d53..c5deaae04 100644
--- a/src/lib/corelib/language/modulemerger.cpp
+++ b/src/lib/corelib/language/modulemerger.cpp
@@ -50,15 +50,18 @@
namespace qbs {
namespace Internal {
-ModuleMerger::ModuleMerger(Logger &logger, Item *root, Item::Module &moduleToMerge)
+ModuleMerger::ModuleMerger(Logger &logger, Item *productItem, const QString &productName,
+ const Item::Modules::iterator &modulesBegin,
+ const Item::Modules::iterator &modulesEnd)
: m_logger(logger)
- , m_rootItem(root)
- , m_mergedModule(moduleToMerge)
- , m_required(moduleToMerge.required)
- , m_isBaseModule(moduleToMerge.name.first() == StringConstants::qbsModule())
- , m_versionRange(moduleToMerge.versionRange)
+ , m_productItem(productItem)
+ , m_mergedModule(*modulesBegin)
+ , m_isBaseModule(m_mergedModule.name.first() == StringConstants::qbsModule())
+ , m_isShadowProduct(productName.startsWith(StringConstants::shadowProductPrefix()))
+ , m_modulesBegin(std::next(modulesBegin))
+ , m_modulesEnd(modulesEnd)
{
- QBS_CHECK(moduleToMerge.item->type() == ItemType::ModuleInstance);
+ QBS_CHECK(modulesBegin->item->type() == ItemType::ModuleInstance);
}
void ModuleMerger::replaceItemInValues(QualifiedId moduleName, Item *containerItem, Item *toReplace)
@@ -83,48 +86,39 @@ void ModuleMerger::replaceItemInValues(QualifiedId moduleName, Item *containerIt
}
}
-void ModuleMerger::replaceItemInScopes(Item *toReplace)
-{
- // In insertProperties(), we potentially call setDefiningItem() with the "wrong"
- // (to-be-replaced) module instance as an argument. If such module instances
- // are dependencies of other modules, they have the depending module's instance
- // as their "instance scope", which is the scope of their scope. This function takes
- // care that the "wrong" definingItem of values in sub-modules still has the "right"
- // instance scope, namely our merged module instead of some other instance.
- for (const Item::Module &module : toReplace->modules()) {
- for (const ValuePtr &property : module.item->properties()) {
- ValuePtr v = property;
- do {
- if (v->definingItem() && v->definingItem()->scope()
- && v->definingItem()->scope()->scope() == toReplace) {
- v->definingItem()->scope()->setScope(m_mergedModule.item);
- }
- v = v->next();
- } while (v);
- }
- }
-}
-
void ModuleMerger::start()
{
+ // Iterate over any module that our product depends on. These modules
+ // may depend on m_mergedModule and contribute property assignments.
+ Item::PropertyMap props;
+ for (auto module = m_modulesBegin; module != m_modulesEnd; module++)
+ mergeModule(&props, *module);
+
+ // Module property assignments in the product have the highest priority
+ // and are thus prepended.
Item::Module m;
- m.item = m_rootItem;
- const Item::PropertyMap props = dfs(m, Item::PropertyMap());
- if (m_required)
- m_mergedModule.required = true;
- m_mergedModule.versionRange.narrowDown(m_versionRange);
- Item::PropertyMap mergedProps = m_mergedModule.item->properties();
+ m.item = m_productItem;
+ mergeModule(&props, m);
+ // The module's prototype is the essential unmodified module as loaded
+ // from the cache.
Item *moduleProto = m_mergedModule.item->prototype();
while (moduleProto->prototype())
moduleProto = moduleProto->prototype();
+ // The prototype item might contain default values which get appended in
+ // case of list properties. Scalar properties will only be set if not
+ // already specified above.
+ Item::PropertyMap mergedProps = m_mergedModule.item->properties();
for (auto it = props.constBegin(); it != props.constEnd(); ++it) {
appendPrototypeValueToNextChain(moduleProto, it.key(), it.value());
mergedProps[it.key()] = it.value();
}
+
m_mergedModule.item->setProperties(mergedProps);
+ // Update all sibling instances of the to-be-merged module to behave identical
+ // to the merged module.
for (Item *moduleInstanceContainer : qAsConst(m_moduleInstanceContainers)) {
Item::Modules modules;
for (const Item::Module &dep : moduleInstanceContainer->modules()) {
@@ -133,11 +127,9 @@ void ModuleMerger::start()
if (isTheModule && m.item != m_mergedModule.item) {
QBS_CHECK(m.item->type() == ItemType::ModuleInstance);
replaceItemInValues(m.name, moduleInstanceContainer, m.item);
- replaceItemInScopes(m.item);
m.item = m_mergedModule.item;
- if (m_required)
- m.required = true;
- m.versionRange.narrowDown(m_versionRange);
+ m.required = m_mergedModule.required;
+ m.versionRange = m_mergedModule.versionRange;
}
modules << m;
}
@@ -145,94 +137,26 @@ void ModuleMerger::start()
}
}
-Item::PropertyMap ModuleMerger::dfs(const Item::Module &m, Item::PropertyMap props)
+void ModuleMerger::mergeModule(Item::PropertyMap *dstProps, const Item::Module &module)
{
- Item *moduleInstance = nullptr;
- size_t numberOfOutprops = m.item->modules().size();
- for (const Item::Module &dep : m.item->modules()) {
- if (dep.name == m_mergedModule.name) {
- --numberOfOutprops;
- moduleInstance = dep.item;
- insertProperties(&props, moduleInstance, ScalarProperties);
- m_moduleInstanceContainers << m.item;
- if (dep.required)
- m_required = true;
- m_versionRange.narrowDown(dep.versionRange);
- break;
- }
- }
-
- std::vector<Item::PropertyMap> outprops;
- outprops.reserve(numberOfOutprops);
- for (const Item::Module &dep : m.item->modules()) {
- if (dep.item != moduleInstance)
- outprops.push_back(dfs(dep, props));
- }
-
- if (!outprops.empty()) {
- props = outprops.front();
- for (size_t i = 1; i < outprops.size(); ++i)
- mergeOutProps(&props, outprops.at(i));
- }
-
- if (moduleInstance)
- insertProperties(&props, moduleInstance, ListProperties);
-
- const bool isNonPresentModule = m.item->type() != ItemType::Product
- && !m.item->isPresentModule();
- return isNonPresentModule ? Item::PropertyMap() : props;
-}
-
-void ModuleMerger::mergeOutProps(Item::PropertyMap *dst, const Item::PropertyMap &src)
-{
- for (auto it = src.constBegin(); it != src.constEnd(); ++it) {
- ValuePtr &v = (*dst)[it.key()];
- if (!v) {
- v = it.value();
- QBS_ASSERT(it.value(), continue);
- continue;
- }
- if (v->type() != Value::JSSourceValueType)
- continue;
- if (it.value()->type() != Value::JSSourceValueType)
- continue;
- // possible conflict
- const JSSourceValuePtr dstVal = std::static_pointer_cast<JSSourceValue>(v);
- JSSourceValuePtr srcVal = std::static_pointer_cast<JSSourceValue>(it.value());
-
- const PropertyDeclaration pd = m_decls.value(srcVal);
- QBS_CHECK(pd.isValid());
-
- if (pd.isScalar()) {
- if (dstVal->sourceCode() != srcVal->sourceCode()) {
- m_logger.qbsWarning() << Tr::tr("Conflicting scalar values at %1 and %2.").arg(
- dstVal->location().toString(),
- srcVal->location().toString());
- // TODO: yield error with a hint how to solve the conflict.
- }
- v = it.value();
- } else {
- lastInNextChain(dstVal)->setNext(srcVal);
- }
- }
-}
+ const Item::Module *dep = findModule(module.item, m_mergedModule.name);
+ if (!dep)
+ return;
-void ModuleMerger::insertProperties(Item::PropertyMap *dst, Item *srcItem, PropertiesType type)
-{
- Set<const Item *> &seenInstances = type == ScalarProperties
- ? m_seenInstancesTopDown : m_seenInstancesBottomUp;
+ const bool mergingProductItem = (module.item == m_productItem);
+ Item *srcItem = dep->item;
Item *origSrcItem = srcItem;
do {
- if (seenInstances.insert(srcItem).second) {
- for (Item::PropertyMap::const_iterator it = srcItem->properties().constBegin();
- it != srcItem->properties().constEnd(); ++it) {
+ if (m_seenInstances.insert(srcItem).second) {
+ for (auto it = srcItem->properties().constBegin();
+ it != srcItem->properties().constEnd(); ++it) {
const ValuePtr &srcVal = it.value();
if (srcVal->type() == Value::ItemValueType)
continue;
if (it.key() == StringConstants::qbsSourceDirPropertyInternal())
continue;
const PropertyDeclaration srcDecl = srcItem->propertyDeclaration(it.key());
- if (!srcDecl.isValid() || srcDecl.isScalar() != (type == ScalarProperties))
+ if (!srcDecl.isValid())
continue;
// Scalar variant values could stem from product multiplexing, in which case
@@ -242,21 +166,51 @@ void ModuleMerger::insertProperties(Item::PropertyMap *dst, Item *srcItem, Prope
continue;
}
- ValuePtr &v = (*dst)[it.key()];
- if (v && type == ScalarProperties)
- continue;
- ValuePtr clonedVal = srcVal->clone();
- m_decls[clonedVal] = srcDecl;
- clonedVal->setDefiningItem(origSrcItem);
- if (v) {
- QBS_CHECK(!clonedVal->next());
- clonedVal->setNext(v);
+ ValuePtr clonedSrcVal = srcVal->clone();
+ clonedSrcVal->setDefiningItem(origSrcItem);
+
+ ValuePtr &dstVal = (*dstProps)[it.key()];
+ if (dstVal) {
+ if (srcDecl.isScalar()) {
+ // Scalar properties get replaced.
+ if ((dstVal->type() == Value::JSSourceValueType)
+ && (srcVal->type() == Value::JSSourceValueType)) {
+ // Warn only about conflicting source code values
+ const JSSourceValuePtr dstJsVal =
+ std::static_pointer_cast<JSSourceValue>(dstVal);
+ const JSSourceValuePtr srcJsVal =
+ std::static_pointer_cast<JSSourceValue>(srcVal);
+ const bool overriddenInProduct =
+ m_mergedModule.item->properties().contains(it.key());
+
+ if (dstJsVal->sourceCode() != srcJsVal->sourceCode()
+ && !mergingProductItem && !overriddenInProduct
+ && !m_isShadowProduct) {
+ m_logger.qbsWarning()
+ << Tr::tr("Conflicting scalar values at %1 and %2.").arg(
+ dstJsVal->location().toString(),
+ srcJsVal->location().toString());
+ }
+ }
+ } else {
+ // List properties get prepended
+ QBS_CHECK(!clonedSrcVal->next());
+ clonedSrcVal->setNext(dstVal);
+ }
}
- v = clonedVal;
+ dstVal = clonedSrcVal;
}
}
srcItem = srcItem->prototype();
} while (srcItem && srcItem->type() == ItemType::ModuleInstance);
+
+ // Update dependency constraints
+ if (dep->required)
+ m_mergedModule.required = true;
+ m_mergedModule.versionRange.narrowDown(dep->versionRange);
+
+ // We need to touch the unmerged module instances later once more
+ m_moduleInstanceContainers << module.item;
}
void ModuleMerger::appendPrototypeValueToNextChain(Item *moduleProto, const QString &propertyName,
@@ -288,5 +242,23 @@ ValuePtr ModuleMerger::lastInNextChain(const ValuePtr &v)
return n;
}
+const Item::Module *ModuleMerger::findModule(const Item *item, const QualifiedId &name)
+{
+ for (const auto &module : item->modules()) {
+ if (module.name == name)
+ return &module;
+ }
+ return nullptr;
+}
+
+void ModuleMerger::merge(Logger &logger, Item *product, const QString &productName,
+ Item::Modules *topSortedModules)
+{
+ for (auto it = topSortedModules->begin(); it != topSortedModules->end(); ++it)
+ ModuleMerger(logger, product, productName, it, topSortedModules->end()).start();
+}
+
+
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/language/modulemerger.h b/src/lib/corelib/language/modulemerger.h
index 3cc3ba08a..469dc86c4 100644
--- a/src/lib/corelib/language/modulemerger.h
+++ b/src/lib/corelib/language/modulemerger.h
@@ -54,32 +54,33 @@ namespace Internal {
class ModuleMerger {
public:
- ModuleMerger(Logger &logger, Item *root, Item::Module &moduleToMerge);
- void start();
+ static void merge(Logger &logger, Item *productItem, const QString &productName,
+ Item::Modules *topSortedModules);
private:
- Item::PropertyMap dfs(const Item::Module &m, Item::PropertyMap props);
- void mergeOutProps(Item::PropertyMap *dst, const Item::PropertyMap &src);
+ ModuleMerger(Logger &logger, Item *productItem, const QString &productName,
+ const Item::Modules::iterator &modulesBegin,
+ const Item::Modules::iterator &modulesEnd);
+
void appendPrototypeValueToNextChain(Item *moduleProto, const QString &propertyName,
const ValuePtr &sv);
- static ValuePtr lastInNextChain(const ValuePtr &v);
-
- enum PropertiesType { ScalarProperties, ListProperties };
- void insertProperties(Item::PropertyMap *dst, Item *srcItem, PropertiesType type);
+ void mergeModule(Item::PropertyMap *props, const Item::Module &m);
void replaceItemInValues(QualifiedId moduleName, Item *containerItem, Item *toReplace);
- void replaceItemInScopes(Item *toReplace);
+ void start();
+
+ static ValuePtr lastInNextChain(const ValuePtr &v);
+ static const Item::Module *findModule(const Item *item, const QualifiedId &name);
Logger &m_logger;
- Item * const m_rootItem;
+ Item * const m_productItem;
Item::Module &m_mergedModule;
Item *m_clonedModulePrototype = nullptr;
- QHash<ValuePtr, PropertyDeclaration> m_decls;
- Set<const Item *> m_seenInstancesTopDown;
- Set<const Item *> m_seenInstancesBottomUp;
+ Set<const Item *> m_seenInstances;
Set<Item *> m_moduleInstanceContainers;
- bool m_required;
const bool m_isBaseModule;
- VersionRange m_versionRange;
+ const bool m_isShadowProduct;
+ const Item::Modules::iterator m_modulesBegin;
+ const Item::Modules::iterator m_modulesEnd;
};
} // namespace Internal
diff --git a/src/lib/corelib/language/moduleproviderinfo.h b/src/lib/corelib/language/moduleproviderinfo.h
index fef9d9765..4f757d3d9 100644
--- a/src/lib/corelib/language/moduleproviderinfo.h
+++ b/src/lib/corelib/language/moduleproviderinfo.h
@@ -55,9 +55,12 @@ class ModuleProviderInfo
{
public:
ModuleProviderInfo() = default;
- ModuleProviderInfo(const QualifiedId &name, const QVariantMap &config,
- const QStringList &searchPaths, bool transientOutput)
- : name(name), config(config), searchPaths(searchPaths), transientOutput(transientOutput)
+ ModuleProviderInfo(QualifiedId name, QVariantMap config,
+ QStringList searchPaths, bool transientOutput)
+ : name(std::move(name))
+ , config(std::move(config))
+ , searchPaths(std::move(searchPaths))
+ , transientOutput(transientOutput)
{}
static QString outputBaseDirName() { return QStringLiteral("genmodules"); }
diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp
index 049472310..fd6063381 100644
--- a/src/lib/corelib/language/projectresolver.cpp
+++ b/src/lib/corelib/language/projectresolver.cpp
@@ -71,6 +71,7 @@
#include <QtCore/qregexp.h>
#include <algorithm>
+#include <memory>
#include <queue>
namespace qbs {
@@ -126,9 +127,7 @@ ProjectResolver::ProjectResolver(Evaluator *evaluator, ModuleLoaderResult loadRe
QBS_CHECK(FileInfo::isAbsolute(m_setupParams.buildRoot()));
}
-ProjectResolver::~ProjectResolver()
-{
-}
+ProjectResolver::~ProjectResolver() = default;
void ProjectResolver::setProgressObserver(ProgressObserver *observer)
{
@@ -812,7 +811,7 @@ void ProjectResolver::resolveGroupFully(Item *item, ProjectResolver::ProjectCont
group->targetOfModule = moduleProp->value().toString();
ErrorInfo fileError;
if (!patterns.empty()) {
- group->wildcards = std::unique_ptr<SourceWildCards>(new SourceWildCards);
+ group->wildcards = std::make_unique<SourceWildCards>();
SourceWildCards *wildcards = group->wildcards.get();
wildcards->group = group.get();
wildcards->excludePatterns = m_evaluator->stringListValue(
@@ -988,7 +987,7 @@ void ProjectResolver::resolveShadowProduct(Item *item, ProjectResolver::ProjectC
try {
adaptExportedPropertyValues(item);
} catch (const ErrorInfo &) {}
- m_productExportInfo.push_back(std::make_pair(m_productContext->product, item));
+ m_productExportInfo.emplace_back(m_productContext->product, item);
}
void ProjectResolver::setupExportedProperties(const Item *item, const QString &namePrefix,
@@ -1460,7 +1459,7 @@ void ProjectResolver::matchArtifactProperties(const ResolvedProductPtr &product,
const std::vector<SourceArtifactPtr> &artifacts)
{
for (const SourceArtifactPtr &artifact : artifacts) {
- for (const ArtifactPropertiesConstPtr &artifactProperties : product->artifactProperties) {
+ for (const auto &artifactProperties : product->artifactProperties) {
if (!artifact->isTargetOfModule()
&& artifact->fileTags.intersects(artifactProperties->fileTagsFilter())) {
artifact->properties = artifactProperties->propertyMap();
diff --git a/src/lib/corelib/language/projectresolver.h b/src/lib/corelib/language/projectresolver.h
index 428ba144d..a1e24a555 100644
--- a/src/lib/corelib/language/projectresolver.h
+++ b/src/lib/corelib/language/projectresolver.h
@@ -139,9 +139,9 @@ private:
struct ProductDependencyInfo
{
- ProductDependencyInfo(const ResolvedProductPtr &product,
- const QVariantMap &parameters = QVariantMap())
- : product(product), parameters(parameters)
+ ProductDependencyInfo(ResolvedProductPtr product,
+ QVariantMap parameters = QVariantMap())
+ : product(std::move(product)), parameters(std::move(parameters))
{
}
diff --git a/src/lib/corelib/language/property.h b/src/lib/corelib/language/property.h
index 204704672..78061bf6f 100644
--- a/src/lib/corelib/language/property.h
+++ b/src/lib/corelib/language/property.h
@@ -65,9 +65,13 @@ public:
{
}
- Property(const QString &product, const QString &module, const QString &property,
- const QVariant &v, Kind k)
- : productName(product), moduleName(module), propertyName(property), value(v), kind(k)
+ Property(QString product, QString module, QString property,
+ QVariant v, Kind k)
+ : productName(std::move(product))
+ , moduleName(std::move(module))
+ , propertyName(std::move(property))
+ , value(std::move(v))
+ , kind(k)
{
}
diff --git a/src/lib/corelib/language/propertydeclaration.cpp b/src/lib/corelib/language/propertydeclaration.cpp
index 5ea6a3d88..abe6a1626 100644
--- a/src/lib/corelib/language/propertydeclaration.cpp
+++ b/src/lib/corelib/language/propertydeclaration.cpp
@@ -84,20 +84,11 @@ PropertyDeclaration::PropertyDeclaration(const QString &name, Type type,
d->flags = flags;
}
-PropertyDeclaration::PropertyDeclaration(const PropertyDeclaration &other)
- : d(other.d)
-{
-}
+PropertyDeclaration::PropertyDeclaration(const PropertyDeclaration &other) = default;
-PropertyDeclaration::~PropertyDeclaration()
-{
-}
+PropertyDeclaration::~PropertyDeclaration() = default;
-PropertyDeclaration &PropertyDeclaration::operator=(const PropertyDeclaration &other)
-{
- d = other.d;
- return *this;
-}
+PropertyDeclaration &PropertyDeclaration::operator=(const PropertyDeclaration &other) = default;
bool PropertyDeclaration::isValid() const
{
diff --git a/src/lib/corelib/language/propertymapinternal.cpp b/src/lib/corelib/language/propertymapinternal.cpp
index 2a35e2a6a..fe0f672c5 100644
--- a/src/lib/corelib/language/propertymapinternal.cpp
+++ b/src/lib/corelib/language/propertymapinternal.cpp
@@ -58,13 +58,9 @@ namespace Internal {
* \sa ResolvedProduct
* \sa SourceArtifact
*/
-PropertyMapInternal::PropertyMapInternal()
-{
-}
+PropertyMapInternal::PropertyMapInternal() = default;
-PropertyMapInternal::PropertyMapInternal(const PropertyMapInternal &other) : m_value(other.m_value)
-{
-}
+PropertyMapInternal::PropertyMapInternal(const PropertyMapInternal &other) = default;
QVariant PropertyMapInternal::moduleProperty(const QString &moduleName, const QString &key,
bool *isPresent) const
diff --git a/src/lib/corelib/language/qualifiedid.cpp b/src/lib/corelib/language/qualifiedid.cpp
index 5cc315bb1..9eb0e9463 100644
--- a/src/lib/corelib/language/qualifiedid.cpp
+++ b/src/lib/corelib/language/qualifiedid.cpp
@@ -44,9 +44,7 @@
namespace qbs {
namespace Internal {
-QualifiedId::QualifiedId()
-{
-}
+QualifiedId::QualifiedId() = default;
QualifiedId::QualifiedId(const QString &singlePartName)
: QStringList(singlePartName)
diff --git a/src/lib/corelib/language/resolvedfilecontext.h b/src/lib/corelib/language/resolvedfilecontext.h
index 81a3f7472..d783cf725 100644
--- a/src/lib/corelib/language/resolvedfilecontext.h
+++ b/src/lib/corelib/language/resolvedfilecontext.h
@@ -65,7 +65,7 @@ public:
pool.serializationOp<opType>(m_filePath, m_jsExtensions, m_searchPaths, m_jsImports);
}
private:
- ResolvedFileContext() {}
+ ResolvedFileContext() = default;
ResolvedFileContext(const FileContextBase &ctx);
};
diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp
index 7c531e764..e79ec54d7 100644
--- a/src/lib/corelib/language/scriptengine.cpp
+++ b/src/lib/corelib/language/scriptengine.cpp
@@ -478,19 +478,18 @@ QScriptValue ScriptEngine::js_require(QScriptContext *context, QScriptEngine *qt
return context->throwError(
ScriptEngine::tr("require: internal error. No search paths."));
- const QString uri = moduleName;
if (engine->m_logger.debugEnabled()) {
engine->m_logger.qbsDebug()
- << "[require] loading extension " << uri;
+ << "[require] loading extension " << moduleName;
}
- QString uriAsPath = uri;
- uriAsPath.replace(QLatin1Char('.'), QLatin1Char('/'));
+ QString moduleNameAsPath = moduleName;
+ moduleNameAsPath.replace(QLatin1Char('.'), QLatin1Char('/'));
const QStringList searchPaths = engine->m_extensionSearchPathsStack.top();
- const QString dirPath = findExtensionDir(searchPaths, uriAsPath);
+ const QString dirPath = findExtensionDir(searchPaths, moduleNameAsPath);
if (dirPath.isEmpty()) {
- if (uri.startsWith(QStringLiteral("qbs.")))
- return loadInternalExtension(context, engine, uri);
+ if (moduleName.startsWith(QStringLiteral("qbs.")))
+ return loadInternalExtension(context, engine, moduleName);
} else {
QDirIterator dit(dirPath, StringConstants::jsFileWildcards(),
QDir::Files | QDir::Readable);
diff --git a/src/lib/corelib/language/value.cpp b/src/lib/corelib/language/value.cpp
index 656f38874..342fbd89a 100644
--- a/src/lib/corelib/language/value.cpp
+++ b/src/lib/corelib/language/value.cpp
@@ -61,9 +61,7 @@ Value::Value(const Value &other)
{
}
-Value::~Value()
-{
-}
+Value::~Value() = default;
Item *Value::definingItem() const
{
@@ -115,9 +113,7 @@ JSSourceValuePtr JSSourceValue::create(bool createdByPropertiesBlock)
return JSSourceValuePtr(new JSSourceValue(createdByPropertiesBlock));
}
-JSSourceValue::~JSSourceValue()
-{
-}
+JSSourceValue::~JSSourceValue() = default;
ValuePtr JSSourceValue::clone() const
{
@@ -200,7 +196,7 @@ VariantValuePtr VariantValue::create(const QVariant &v)
ValuePtr VariantValue::clone() const
{
- return VariantValuePtr(new VariantValue(*this));
+ return std::make_shared<VariantValue>(*this);
}
const VariantValuePtr &VariantValue::falseValue()
diff --git a/src/lib/corelib/language/value.h b/src/lib/corelib/language/value.h
index f27406f2d..d3a748d92 100644
--- a/src/lib/corelib/language/value.h
+++ b/src/lib/corelib/language/value.h
@@ -151,14 +151,14 @@ public:
struct PropertyData
{
PropertyData() = default;
- PropertyData(const QString &v, const CodeLocation &l) : value(v), location(l) {}
+ PropertyData(QString v, const CodeLocation &l) : value(std::move(v)), location(l) {}
QString value;
CodeLocation location;
};
- Alternative() { }
- Alternative(const PropertyData &c, const PropertyData &o, const JSSourceValuePtr &v)
- : condition(c), overrideListProperties(o), value(v) {}
+ Alternative() = default;
+ Alternative(PropertyData c, PropertyData o, JSSourceValuePtr v)
+ : condition(std::move(c)), overrideListProperties(std::move(o)), value(std::move(v)) {}
Alternative clone() const
{
return Alternative(condition, overrideListProperties,
diff --git a/src/lib/corelib/logging/logger.cpp b/src/lib/corelib/logging/logger.cpp
index 71ca6a96c..2ed29c4c2 100644
--- a/src/lib/corelib/logging/logger.cpp
+++ b/src/lib/corelib/logging/logger.cpp
@@ -50,9 +50,9 @@
#include <QtCore/qvariant.h>
#include <cstdarg>
+#include <cstdio>
#include <mutex>
#include <set>
-#include <stdio.h>
namespace qbs {
namespace Internal {
@@ -183,17 +183,20 @@ LogWriter operator<<(LogWriter w, const QVariant &variant)
LogWriter operator<<(LogWriter w, int n)
{
- return w << QString::number(n);
+ w.write(QString::number(n));
+ return w;
}
LogWriter operator<<(LogWriter w, qint64 n)
{
- return w << QString::number(n);
+ w.write(QString::number(n));
+ return w;
}
LogWriter operator<<(LogWriter w, bool b)
{
- return w << QString::fromLatin1(b ? "true" : "false");
+ w.write(QString::fromLatin1(b ? "true" : "false"));
+ return w;
}
LogWriter operator<<(LogWriter w, const MessageTag &tag)
diff --git a/src/lib/corelib/logging/logger.h b/src/lib/corelib/logging/logger.h
index b0b5dd6f3..389dc7e05 100644
--- a/src/lib/corelib/logging/logger.h
+++ b/src/lib/corelib/logging/logger.h
@@ -70,7 +70,7 @@ public:
// a << chain prints the accumulated data
LogWriter(const LogWriter &other);
~LogWriter();
- const LogWriter &operator=(const LogWriter &other);
+ const LogWriter &operator=(const LogWriter &other); // NOLINT
void write(char c);
void write(const char *str);
@@ -90,7 +90,7 @@ private:
class QBS_EXPORT MessageTag
{
public:
- explicit MessageTag(const QString &tag) : m_tag(tag) {}
+ explicit MessageTag(QString tag) : m_tag(std::move(tag)) {}
const QString &tag() const { return m_tag; }
diff --git a/src/lib/corelib/parser/qmljsast_p.h b/src/lib/corelib/parser/qmljsast_p.h
index 8c6f32140..dcee233da 100644
--- a/src/lib/corelib/parser/qmljsast_p.h
+++ b/src/lib/corelib/parser/qmljsast_p.h
@@ -221,7 +221,7 @@ public:
// NOTE: node destructors are never called,
// instead we block free the memory
// (see the NodePool class)
- virtual ~Node() {}
+ virtual ~Node() = default;
virtual ExpressionNode *expressionCast();
virtual BinaryExpression *binaryExpressionCast();
@@ -245,7 +245,7 @@ public:
class QML_PARSER_EXPORT ExpressionNode: public Node
{
public:
- ExpressionNode() {}
+ ExpressionNode() = default;
ExpressionNode *expressionCast() override;
};
@@ -253,7 +253,7 @@ public:
class QML_PARSER_EXPORT Statement: public Node
{
public:
- Statement() {}
+ Statement() = default;
Statement *statementCast() override;
};
@@ -2303,7 +2303,7 @@ public:
return imports->firstSourceLocation();
else if (members)
return members->firstSourceLocation();
- return SourceLocation();
+ return {};
}
SourceLocation lastSourceLocation() const override
@@ -2312,7 +2312,7 @@ public:
return members->lastSourceLocation();
else if (imports)
return imports->lastSourceLocation();
- return SourceLocation();
+ return {};
}
// attributes
@@ -2519,7 +2519,7 @@ public:
else if (const auto varStmt = cast<const VariableStatement *>(sourceElement))
return varStmt->firstSourceLocation();
- return SourceLocation();
+ return {};
}
SourceLocation lastSourceLocation() const override
@@ -2529,7 +2529,7 @@ public:
else if (const auto varStmt = cast<const VariableStatement *>(sourceElement))
return varStmt->lastSourceLocation();
- return SourceLocation();
+ return {};
}
void accept0(Visitor *visitor) override;
diff --git a/src/lib/corelib/parser/qmljsastvisitor.cpp b/src/lib/corelib/parser/qmljsastvisitor.cpp
index fcb84ec7e..f034a147e 100644
--- a/src/lib/corelib/parser/qmljsastvisitor.cpp
+++ b/src/lib/corelib/parser/qmljsastvisitor.cpp
@@ -42,13 +42,9 @@
namespace QbsQmlJS {
namespace AST {
-Visitor::Visitor()
-{
-}
+Visitor::Visitor() = default;
-Visitor::~Visitor()
-{
-}
+Visitor::~Visitor() = default;
} // namespace AST
} // namespace QbsQmlJS
diff --git a/src/lib/corelib/parser/qmljsengine_p.cpp b/src/lib/corelib/parser/qmljsengine_p.cpp
index 211743190..92ac6452a 100644
--- a/src/lib/corelib/parser/qmljsengine_p.cpp
+++ b/src/lib/corelib/parser/qmljsengine_p.cpp
@@ -117,12 +117,9 @@ double integerFromString(const QString &str, int radix)
}
-Engine::Engine()
- : _lexer(nullptr), _directives(nullptr)
-{ }
+Engine::Engine() = default;
-Engine::~Engine()
-{ }
+Engine::~Engine() = default;
void Engine::setCode(const QString &code)
{ _code = code; }
diff --git a/src/lib/corelib/parser/qmljsengine_p.h b/src/lib/corelib/parser/qmljsengine_p.h
index 6ff53a6e9..c55d525f8 100644
--- a/src/lib/corelib/parser/qmljsengine_p.h
+++ b/src/lib/corelib/parser/qmljsengine_p.h
@@ -59,6 +59,7 @@
#include <QtCore/qstring.h>
#include <set>
+#include <utility>
namespace QbsQmlJS {
@@ -74,8 +75,8 @@ public:
DiagnosticMessage()
: kind(Error) {}
- DiagnosticMessage(Kind kind, const AST::SourceLocation &loc, const QString &message)
- : kind(kind), loc(loc), message(message) {}
+ DiagnosticMessage(Kind kind, const AST::SourceLocation &loc, QString message)
+ : kind(kind), loc(loc), message(std::move(message)) {}
bool isWarning() const
{ return kind == Warning; }
@@ -90,8 +91,8 @@ public:
class QBS_AUTOTEST_EXPORT Engine
{
- Lexer *_lexer;
- Directives *_directives;
+ Lexer *_lexer{nullptr};
+ Directives *_directives{nullptr};
MemoryPool _pool;
QList<AST::SourceLocation> _comments;
QString _extraCode;
diff --git a/src/lib/corelib/parser/qmljslexer.cpp b/src/lib/corelib/parser/qmljslexer.cpp
index dc6ac8a0f..815f1ef0d 100644
--- a/src/lib/corelib/parser/qmljslexer.cpp
+++ b/src/lib/corelib/parser/qmljslexer.cpp
@@ -78,8 +78,8 @@ static QChar convertHex(QChar c1, QChar c2)
static QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
{
- return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
- (convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
+ return {uchar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode())),
+ uchar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()))};
}
Lexer::Lexer(Engine *engine)
@@ -178,7 +178,7 @@ int Lexer::lex()
_tokenSpell = QStringRef();
_tokenKind = scanToken();
- _tokenLength = _codePtr - _tokenStartPtr - 1;
+ _tokenLength = int(_codePtr - _tokenStartPtr - 1);
_delimited = false;
_restrictedKeyword = false;
@@ -397,7 +397,8 @@ again:
scanChar();
if (_engine) {
- _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
+ _engine->addComment(tokenOffset() + 2,
+ int(_codePtr - _tokenStartPtr - 1 - 4),
tokenStartLine(), tokenStartColumn() + 2);
}
@@ -412,7 +413,7 @@ again:
scanChar();
}
if (_engine) {
- _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
+ _engine->addComment(tokenOffset() + 2, int(_codePtr - _tokenStartPtr - 1 - 2),
tokenStartLine(), tokenStartColumn() + 2);
}
goto again;
@@ -554,7 +555,8 @@ again:
if (_char == QLatin1Char('\n') || _char == QLatin1Char('\\')) {
break;
} else if (_char == quote) {
- _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
+ _tokenSpell = _engine->midRef(
+ int(startCode - _code.unicode() - 1), int(_codePtr - startCode));
scanChar();
return T_STRING_LITERAL;
@@ -706,7 +708,7 @@ again:
if (! identifierWithEscapeChars) {
identifierWithEscapeChars = true;
_tokenText.resize(0);
- _tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
+ _tokenText.insert(0, _tokenStartPtr, int(_codePtr - _tokenStartPtr - 1));
_validTokenText = true;
}
@@ -719,7 +721,7 @@ again:
return T_ERROR;
}
} else {
- _tokenLength = _codePtr - _tokenStartPtr - 1;
+ _tokenLength = int(_codePtr - _tokenStartPtr - 1);
int kind = T_IDENTIFIER;
@@ -727,10 +729,12 @@ again:
kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
if (_engine) {
- if (kind == T_IDENTIFIER && identifierWithEscapeChars)
+ if (kind == T_IDENTIFIER && identifierWithEscapeChars) {
_tokenSpell = _engine->newStringRef(_tokenText);
- else
- _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
+ } else {
+ _tokenSpell = _engine->midRef(
+ int(_tokenStartPtr - _code.unicode()), _tokenLength);
+ }
}
return kind;
@@ -891,7 +895,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
scanChar();
}
- _tokenLength = _codePtr - _tokenStartPtr - 1;
+ _tokenLength = int(_codePtr - _tokenStartPtr - 1);
return true;
case '\\':
@@ -995,7 +999,7 @@ int Lexer::tokenEndLine() const
int Lexer::tokenEndColumn() const
{
- return _codePtr - _lastLinePtr;
+ return int(_codePtr - _lastLinePtr);
}
QString Lexer::tokenText() const
diff --git a/src/lib/corelib/parser/qmljslexer_p.h b/src/lib/corelib/parser/qmljslexer_p.h
index e9dff1dd4..cf41fb255 100644
--- a/src/lib/corelib/parser/qmljslexer_p.h
+++ b/src/lib/corelib/parser/qmljslexer_p.h
@@ -62,7 +62,7 @@ class Engine;
class QML_PARSER_EXPORT Directives {
public:
- virtual ~Directives() {}
+ virtual ~Directives() = default;
virtual void pragmaLibrary()
{
diff --git a/src/lib/corelib/parser/qmljsmemorypool_p.h b/src/lib/corelib/parser/qmljsmemorypool_p.h
index 897348712..f7de7bbfb 100644
--- a/src/lib/corelib/parser/qmljsmemorypool_p.h
+++ b/src/lib/corelib/parser/qmljsmemorypool_p.h
@@ -154,8 +154,8 @@ class QML_PARSER_EXPORT Managed
void operator = (const Managed &other);
public:
- Managed() {}
- ~Managed() {}
+ Managed() = default;
+ ~Managed() = default;
void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); }
void operator delete(void *) {}
diff --git a/src/lib/corelib/parser/qmljsparser.cpp b/src/lib/corelib/parser/qmljsparser.cpp
index 6390c8a9d..d2c87c7cb 100644
--- a/src/lib/corelib/parser/qmljsparser.cpp
+++ b/src/lib/corelib/parser/qmljsparser.cpp
@@ -40,7 +40,7 @@
#include <QtCore/qdebug.h>
#include <QtCore/qcoreapplication.h>
-#include <string.h>
+#include <cstring>
#include "qmljsengine_p.h"
#include "qmljslexer_p.h"
@@ -328,7 +328,7 @@ case 26: {
} break;
case 27: {
- const auto node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
+ const auto node = new (pool) AST::UiObjectInitializer(nullptr);
node->lbraceToken = loc(1);
node->rbraceToken = loc(2);
sym(1).Node = node;
@@ -614,7 +614,7 @@ case 80: {
} break;
case 81: {
- const auto node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
+ const auto node = new (pool) AST::ArrayLiteral(static_cast<AST::Elision *>(nullptr));
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
@@ -635,8 +635,7 @@ case 83: {
} break;
case 84: {
- const auto node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
- (AST::Elision *) 0);
+ const auto node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), nullptr);
node->lbracketToken = loc(1);
node->commaToken = loc(3);
node->rbracketToken = loc(4);
@@ -700,7 +699,7 @@ case 89: {
} break;
case 90: {
- sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
+ sym(1).Node = new (pool) AST::ElementList(nullptr, sym(1).Expression);
} break;
case 91: {
@@ -708,8 +707,7 @@ case 91: {
} break;
case 92: {
- const auto node = new (pool) AST::ElementList(sym(1).ElementList,
- (AST::Elision *) 0, sym(3).Expression);
+ const auto node = new (pool) AST::ElementList(sym(1).ElementList, nullptr, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
diff --git a/src/lib/corelib/tools/buildoptions.cpp b/src/lib/corelib/tools/buildoptions.cpp
index 75417ab0b..e4e9ba17f 100644
--- a/src/lib/corelib/tools/buildoptions.cpp
+++ b/src/lib/corelib/tools/buildoptions.cpp
@@ -91,19 +91,11 @@ BuildOptions::BuildOptions() : d(new Internal::BuildOptionsPrivate)
{
}
-BuildOptions::BuildOptions(const BuildOptions &other) : d(other.d)
-{
-}
+BuildOptions::BuildOptions(const BuildOptions &other) = default;
-BuildOptions &BuildOptions::operator=(const BuildOptions &other)
-{
- d = other.d;
- return *this;
-}
+BuildOptions &BuildOptions::operator=(const BuildOptions &other) = default;
-BuildOptions::~BuildOptions()
-{
-}
+BuildOptions::~BuildOptions() = default;
/*!
* \brief If non-empty, qbs pretends that only these files have changed.
diff --git a/src/lib/corelib/tools/clangclinfo.cpp b/src/lib/corelib/tools/clangclinfo.cpp
new file mode 100644
index 000000000..4e1022c28
--- /dev/null
+++ b/src/lib/corelib/tools/clangclinfo.cpp
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangclinfo.h"
+
+#include "hostosinfo.h"
+#include "msvcinfo.h"
+#include "stlutils.h"
+
+namespace qbs {
+namespace Internal {
+
+static std::vector<MSVCInstallInfo> compatibleMsvcs(Logger &logger)
+{
+ auto msvcs = MSVCInstallInfo::installedMSVCs(logger);
+ auto filter = [](const MSVCInstallInfo &info)
+ {
+ const auto versions = info.version.split(QLatin1Char('.'));
+ if (versions.empty())
+ return true;
+ bool ok = false;
+ const int major = versions.at(0).toInt(&ok);
+ return !(ok && major >= 15); // support MSVC2017 and above
+ };
+ const auto it = std::remove_if(msvcs.begin(), msvcs.end(), filter);
+ msvcs.erase(it, msvcs.end());
+ for (const auto &msvc: msvcs) {
+ auto vcvarsallPath = msvc.findVcvarsallBat();
+ if (vcvarsallPath.isEmpty())
+ continue;
+ }
+ return msvcs;
+}
+
+static QString findCompatibleVcsarsallBat(const std::vector<MSVCInstallInfo> &msvcs)
+{
+ for (const auto &msvc: msvcs) {
+ const auto vcvarsallPath = msvc.findVcvarsallBat();
+ if (!vcvarsallPath.isEmpty())
+ return vcvarsallPath;
+ }
+ return {};
+}
+
+static QString wow6432Key()
+{
+#ifdef Q_OS_WIN64
+ return QStringLiteral("\\Wow6432Node");
+#else
+ return {};
+#endif
+}
+
+static QString getToolchainInstallPath(const QFileInfo &compiler)
+{
+ return compiler.path(); // 1 level up
+}
+
+QVariantMap ClangClInfo::toVariantMap() const
+{
+ return {
+ {QStringLiteral("toolchainInstallPath"), toolchainInstallPath},
+ {QStringLiteral("vcvarsallPath"), vcvarsallPath},
+ };
+}
+
+ClangClInfo ClangClInfo::fromCompilerFilePath(const QString &path, Logger &logger)
+{
+ const auto compilerName = QStringLiteral("clang-cl");
+ const auto vcvarsallPath = findCompatibleVcsarsallBat(compatibleMsvcs(logger));
+ if (vcvarsallPath.isEmpty()) {
+ logger.qbsWarning()
+ << Tr::tr("%1 requires installed Visual Studio 2017 or newer, but none was found.")
+ .arg(compilerName);
+ return {};
+ }
+
+ const auto toolchainInstallPath = getToolchainInstallPath(path);
+ return {toolchainInstallPath, vcvarsallPath};
+}
+
+std::vector<ClangClInfo> ClangClInfo::installedCompilers(
+ const std::vector<QString> &extraPaths, Logger &logger)
+{
+ std::vector<QString> compilerPaths;
+ compilerPaths.reserve(extraPaths.size());
+ std::copy_if(extraPaths.begin(), extraPaths.end(),
+ std::back_inserter(compilerPaths),
+ [](const QString &path){ return !path.isEmpty(); });
+ const auto compilerName = HostOsInfo::appendExecutableSuffix(QStringLiteral("clang-cl"));
+
+ const QSettings registry(
+ QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\LLVM\\LLVM").arg(wow6432Key()),
+ QSettings::NativeFormat);
+ const auto key = QStringLiteral(".");
+ if (registry.contains(key)) {
+ const auto compilerPath = QDir::fromNativeSeparators(registry.value(key).toString())
+ + QStringLiteral("/bin/") + compilerName;
+ if (QFileInfo(compilerPath).exists())
+ compilerPaths.push_back(compilerPath);
+ }
+
+ // this branch can be useful in case user had two LLVM installations (e.g. 32bit & 64bit)
+ // but uninstalled one - in that case, registry will be empty
+ static const char * const envVarCandidates[] = {"ProgramFiles", "ProgramFiles(x86)"};
+ for (const auto &envVar : envVarCandidates) {
+ const auto value
+ = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv(envVar)));
+ const auto compilerPath = value + QStringLiteral("/LLVM/bin/") + compilerName;
+ if (QFileInfo(compilerPath).exists() && !contains(compilerPaths, compilerPath))
+ compilerPaths.push_back(compilerPath);
+ }
+
+ const auto msvcs = compatibleMsvcs(logger);
+ const auto vcvarsallPath = findCompatibleVcsarsallBat(msvcs);
+ if (vcvarsallPath.isEmpty()) {
+ logger.qbsWarning()
+ << Tr::tr("%1 requires installed Visual Studio 2017 or newer, but none was found.")
+ .arg(compilerName);
+ return {};
+ }
+
+ std::vector<ClangClInfo> result;
+ result.reserve(compilerPaths.size() + msvcs.size());
+
+ for (const auto &path: compilerPaths)
+ result.push_back({getToolchainInstallPath(path), vcvarsallPath});
+
+ // If we didn't find custom LLVM installation, try to find if it's installed with Visual Studio
+ for (const auto &msvc : msvcs) {
+ const auto compilerPath = QStringLiteral("%1/VC/Tools/Llvm/bin/%2")
+ .arg(msvc.installDir, compilerName);
+ if (QFileInfo(compilerPath).exists()) {
+ const auto vcvarsallPath = msvc.findVcvarsallBat();
+ if (vcvarsallPath.isEmpty()) {
+ logger.qbsWarning()
+ << Tr::tr("Found LLVM in %1, but vcvarsall.bat is missing.")
+ .arg(msvc.installDir);
+ }
+
+ result.push_back({getToolchainInstallPath(compilerPath), vcvarsallPath});
+ }
+ }
+
+ return result;
+}
+
+} // namespace Internal
+} // namespace qbs
diff --git a/src/lib/corelib/tools/clangclinfo.h b/src/lib/corelib/tools/clangclinfo.h
new file mode 100644
index 000000000..76ae169f2
--- /dev/null
+++ b/src/lib/corelib/tools/clangclinfo.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** 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 http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef QBS_CLANGCLINFO_H
+#define QBS_CLANGCLINFO_H
+
+#include "logging/logger.h"
+
+#include <QtCore/qstring.h>
+
+#include <vector>
+
+namespace qbs {
+namespace Internal {
+
+class ClangClInfo
+{
+public:
+ QString toolchainInstallPath;
+ QString vcvarsallPath;
+
+ bool isEmpty() const { return toolchainInstallPath.isEmpty() && vcvarsallPath.isEmpty(); }
+
+ QBS_EXPORT QVariantMap toVariantMap() const;
+
+ QBS_EXPORT static ClangClInfo fromCompilerFilePath(const QString &path, Logger &logger);
+ QBS_EXPORT static std::vector<ClangClInfo> installedCompilers(
+ const std::vector<QString> &extraPaths, qbs::Internal::Logger &logger);
+};
+
+} // namespace Internal
+} // namespace qbs
+
+#endif // QBS_CLANGCLINFO_H
diff --git a/src/lib/corelib/tools/cleanoptions.cpp b/src/lib/corelib/tools/cleanoptions.cpp
index b888fb1e8..affc9b3f7 100644
--- a/src/lib/corelib/tools/cleanoptions.cpp
+++ b/src/lib/corelib/tools/cleanoptions.cpp
@@ -58,7 +58,7 @@ public:
bool logElapsedTime;
};
-}
+} // namespace Internal
/*!
* \class CleanOptions
@@ -79,23 +79,15 @@ CleanOptions::CleanOptions() : d(new Internal::CleanOptionsPrivate)
{
}
-CleanOptions::CleanOptions(const CleanOptions &other) : d(other.d)
-{
-}
+CleanOptions::CleanOptions(const CleanOptions &other) = default;
CleanOptions::CleanOptions(CleanOptions &&other) Q_DECL_NOEXCEPT = default;
-CleanOptions &CleanOptions::operator=(const CleanOptions &other)
-{
- d = other.d;
- return *this;
-}
+CleanOptions &CleanOptions::operator=(const CleanOptions &other) = default;
CleanOptions &CleanOptions::operator=(CleanOptions &&other) Q_DECL_NOEXCEPT = default;
-CleanOptions::~CleanOptions()
-{
-}
+CleanOptions::~CleanOptions() = default;
/*!
* \brief Returns true iff qbs will not actually remove any files, but just show what would happen.
diff --git a/src/lib/corelib/tools/codelocation.cpp b/src/lib/corelib/tools/codelocation.cpp
index 5eff378e1..542408795 100644
--- a/src/lib/corelib/tools/codelocation.cpp
+++ b/src/lib/corelib/tools/codelocation.cpp
@@ -75,9 +75,7 @@ public:
int column = 0;
};
-CodeLocation::CodeLocation()
-{
-}
+CodeLocation::CodeLocation() = default;
CodeLocation::CodeLocation(const QString &aFilePath, int aLine, int aColumn, bool checkPath)
: d(new CodeLocationPrivate)
@@ -88,19 +86,11 @@ CodeLocation::CodeLocation(const QString &aFilePath, int aLine, int aColumn, boo
d->column = aColumn;
}
-CodeLocation::CodeLocation(const CodeLocation &other) : d(other.d)
-{
-}
+CodeLocation::CodeLocation(const CodeLocation &other) = default;
-CodeLocation &CodeLocation::operator=(const CodeLocation &other)
-{
- d = other.d;
- return *this;
-}
+CodeLocation &CodeLocation::operator=(const CodeLocation &other) = default;
-CodeLocation::~CodeLocation()
-{
-}
+CodeLocation::~CodeLocation() = default;
QString CodeLocation::filePath() const
{
diff --git a/src/lib/corelib/tools/error.cpp b/src/lib/corelib/tools/error.cpp
index fc0b9377e..ff7ce46cf 100644
--- a/src/lib/corelib/tools/error.cpp
+++ b/src/lib/corelib/tools/error.cpp
@@ -89,6 +89,8 @@ ErrorItem::ErrorItem() : d(new ErrorItemPrivate)
{
}
+ErrorItem::ErrorItem(ErrorItem &&rhs) noexcept = default;
+
ErrorItem::ErrorItem(const QString &description, const CodeLocation &codeLocation,
bool isBacktraceItem)
: d(new ErrorItemPrivate)
@@ -98,19 +100,12 @@ ErrorItem::ErrorItem(const QString &description, const CodeLocation &codeLocatio
d->isBacktraceItem = isBacktraceItem;
}
-ErrorItem::ErrorItem(const ErrorItem &rhs) : d(rhs.d)
-{
-}
+ErrorItem::ErrorItem(const ErrorItem &rhs) = default;
-ErrorItem &ErrorItem::operator=(const ErrorItem &other)
-{
- d = other.d;
- return *this;
-}
+ErrorItem &ErrorItem::operator=(const ErrorItem &other) = default;
+ErrorItem &ErrorItem::operator=(ErrorItem &&other) noexcept = default;
-ErrorItem::~ErrorItem()
-{
-}
+ErrorItem::~ErrorItem() = default;
QString ErrorItem::description() const
{
@@ -194,9 +189,9 @@ ErrorInfo::ErrorInfo() : d(new ErrorInfoPrivate)
{
}
-ErrorInfo::ErrorInfo(const ErrorInfo &rhs) : d(rhs.d)
-{
-}
+ErrorInfo::ErrorInfo(const ErrorInfo &rhs) = default;
+
+ErrorInfo::ErrorInfo(ErrorInfo &&rhs) noexcept = default;
ErrorInfo::ErrorInfo(const QString &description, const CodeLocation &location, bool internalError)
: d(new ErrorInfoPrivate)
@@ -223,16 +218,11 @@ ErrorInfo::ErrorInfo(const QString &description, const QStringList &backtrace)
}
}
+ErrorInfo &ErrorInfo::operator=(ErrorInfo &&other) noexcept = default;
-ErrorInfo &ErrorInfo::operator =(const ErrorInfo &other)
-{
- d = other.d;
- return *this;
-}
+ErrorInfo &ErrorInfo::operator =(const ErrorInfo &other) = default;
-ErrorInfo::~ErrorInfo()
-{
-}
+ErrorInfo::~ErrorInfo() = default;
void ErrorInfo::appendBacktrace(const QString &description, const CodeLocation &location)
{
diff --git a/src/lib/corelib/tools/error.h b/src/lib/corelib/tools/error.h
index abad85bad..36cf5e0ea 100644
--- a/src/lib/corelib/tools/error.h
+++ b/src/lib/corelib/tools/error.h
@@ -63,7 +63,9 @@ class QBS_EXPORT ErrorItem
public:
ErrorItem();
ErrorItem(const ErrorItem &rhs);
+ ErrorItem(ErrorItem &&rhs) noexcept;
ErrorItem &operator=(const ErrorItem &other);
+ ErrorItem &operator=(ErrorItem &&other) noexcept;
~ErrorItem();
QString description() const;
@@ -89,10 +91,12 @@ class QBS_EXPORT ErrorInfo
public:
ErrorInfo();
ErrorInfo(const ErrorInfo &rhs);
+ ErrorInfo(ErrorInfo &&rhs) noexcept;
ErrorInfo(const QString &description, const CodeLocation &location = CodeLocation(),
bool internalError = false);
ErrorInfo(const QString &description, const QStringList &backtrace);
ErrorInfo &operator=(const ErrorInfo &other);
+ ErrorInfo &operator=(ErrorInfo &&other) noexcept;
~ErrorInfo();
void appendBacktrace(const QString &description, const CodeLocation &location = CodeLocation());
diff --git a/src/lib/corelib/tools/executablefinder.cpp b/src/lib/corelib/tools/executablefinder.cpp
index 4342c82f0..0dc06dd86 100644
--- a/src/lib/corelib/tools/executablefinder.cpp
+++ b/src/lib/corelib/tools/executablefinder.cpp
@@ -64,9 +64,9 @@ static QStringList populateExecutableSuffixes()
QStringList ExecutableFinder::m_executableSuffixes = populateExecutableSuffixes();
-ExecutableFinder::ExecutableFinder(ResolvedProductPtr product, QProcessEnvironment env)
+ExecutableFinder::ExecutableFinder(ResolvedProductPtr product, const QProcessEnvironment &env)
: m_product(std::move(product))
- , m_environment(std::move(env))
+ , m_environment(env) // QProcessEnvironment doesn't have move-ctor, copy here
{
}
diff --git a/src/lib/corelib/tools/executablefinder.h b/src/lib/corelib/tools/executablefinder.h
index 9467756fc..ae834d911 100644
--- a/src/lib/corelib/tools/executablefinder.h
+++ b/src/lib/corelib/tools/executablefinder.h
@@ -53,7 +53,7 @@ namespace Internal {
class ExecutableFinder
{
public:
- ExecutableFinder(ResolvedProductPtr product, QProcessEnvironment env);
+ ExecutableFinder(ResolvedProductPtr product, const QProcessEnvironment &env);
QString findExecutable(const QString &path, const QString &workingDirPath);
diff --git a/src/lib/corelib/tools/fileinfo.cpp b/src/lib/corelib/tools/fileinfo.cpp
index 8b0eedc27..1918117d6 100644
--- a/src/lib/corelib/tools/fileinfo.cpp
+++ b/src/lib/corelib/tools/fileinfo.cpp
@@ -50,7 +50,7 @@
#include <QtCore/qregexp.h>
#if defined(Q_OS_UNIX)
-#include <errno.h>
+#include <cerrno>
#include <sys/stat.h>
#include <unistd.h>
#elif defined(Q_OS_WIN)
diff --git a/src/lib/corelib/tools/generateoptions.cpp b/src/lib/corelib/tools/generateoptions.cpp
index 019e2eb48..596e0acb9 100644
--- a/src/lib/corelib/tools/generateoptions.cpp
+++ b/src/lib/corelib/tools/generateoptions.cpp
@@ -68,19 +68,11 @@ GenerateOptions::GenerateOptions() : d(new Internal::GenerateOptionsPrivate)
{
}
-GenerateOptions::GenerateOptions(const GenerateOptions &other) : d(other.d)
-{
-}
+GenerateOptions::GenerateOptions(const GenerateOptions &other) = default;
-GenerateOptions &GenerateOptions::operator=(const GenerateOptions &other)
-{
- d = other.d;
- return *this;
-}
+GenerateOptions &GenerateOptions::operator=(const GenerateOptions &other) = default;
-GenerateOptions::~GenerateOptions()
-{
-}
+GenerateOptions::~GenerateOptions() = default;
/*!
* Returns the name of the generator used to create the external build system files.
diff --git a/src/lib/corelib/tools/hostosinfo.h b/src/lib/corelib/tools/hostosinfo.h
index d7f718c19..0876d39ec 100644
--- a/src/lib/corelib/tools/hostosinfo.h
+++ b/src/lib/corelib/tools/hostosinfo.h
@@ -112,6 +112,13 @@ public:
return finalName;
}
+ static QString stripExecutableSuffix(const QString &executable)
+ {
+ constexpr QLatin1String suffix(QBS_HOST_EXE_SUFFIX, sizeof(QBS_HOST_EXE_SUFFIX) - 1);
+ return !suffix.isEmpty() && executable.endsWith(suffix)
+ ? executable.chopped(suffix.size()) : executable;
+ }
+
static QString dynamicLibraryName(const QString &libraryBaseName)
{
return QLatin1String(QBS_HOST_DYNAMICLIB_PREFIX) + libraryBaseName
@@ -194,22 +201,21 @@ std::vector<std::string> HostOsInfo::hostOSIdentifiers()
std::vector<std::string> HostOsInfo::canonicalOSIdentifiers(const std::string &name)
{
std::vector<std::string> list { name };
- if (contains(std::vector<std::string> {"ios-simulator"}, name))
+ if (contains({"ios-simulator"}, name))
list << canonicalOSIdentifiers("ios");
- if (contains(std::vector<std::string> {"tvos-simulator"}, name))
+ if (contains({"tvos-simulator"}, name))
list << canonicalOSIdentifiers("tvos");
- if (contains(std::vector<std::string> {"watchos-simulator"}, name))
+ if (contains({"watchos-simulator"}, name))
list << canonicalOSIdentifiers("watchos");
- if (contains(std::vector<std::string> {"macos", "ios", "tvos", "watchos"}, name))
+ if (contains({"macos", "ios", "tvos", "watchos"}, name))
list << canonicalOSIdentifiers("darwin");
- if (contains(std::vector<std::string> {"darwin", "freebsd", "netbsd", "openbsd"}, name))
+ if (contains({"darwin", "freebsd", "netbsd", "openbsd"}, name))
list << canonicalOSIdentifiers("bsd");
- if (contains(std::vector<std::string> {"android"}, name))
+ if (contains({"android"}, name))
list << canonicalOSIdentifiers("linux");
// Note: recognized non-Unix platforms include: windows, haiku, vxworks
- if (contains(std::vector<std::string> {
- "bsd", "aix", "hpux", "solaris", "linux", "hurd", "qnx", "integrity"}, name))
+ if (contains({"bsd", "aix", "hpux", "solaris", "linux", "hurd", "qnx", "integrity"}, name))
list << canonicalOSIdentifiers("unix");
return list;
diff --git a/src/lib/corelib/tools/id.cpp b/src/lib/corelib/tools/id.cpp
index 6dd1147f2..33cfd60f7 100644
--- a/src/lib/corelib/tools/id.cpp
+++ b/src/lib/corelib/tools/id.cpp
@@ -269,9 +269,9 @@ Id Id::withPrefix(const char *prefix) const
bool Id::operator==(const char *name) const
{
- const char *string = getStringFromId(m_id);
- if (string && name)
- return strcmp(string, name) == 0;
+ const auto string = getStringFromId(m_id);
+ if (!string.isNull() && name)
+ return strcmp(string.data(), name) == 0;
else
return false;
}
diff --git a/src/lib/corelib/tools/id.h b/src/lib/corelib/tools/id.h
index f0c3b1588..aa327833f 100644
--- a/src/lib/corelib/tools/id.h
+++ b/src/lib/corelib/tools/id.h
@@ -75,7 +75,7 @@ public:
bool operator>(Id id) const { return m_id > id.m_id; }
bool alphabeticallyBefore(Id other) const;
int uniqueIdentifier() const { return m_id; }
- static Id fromUniqueIdentifier(int uid) { return Id(uid); }
+ static Id fromUniqueIdentifier(int uid) { return {uid}; }
static Id fromSetting(const QVariant &variant); // Good to use.
private:
diff --git a/src/lib/corelib/tools/installoptions.cpp b/src/lib/corelib/tools/installoptions.cpp
index 93fd54efe..5e112e6de 100644
--- a/src/lib/corelib/tools/installoptions.cpp
+++ b/src/lib/corelib/tools/installoptions.cpp
@@ -92,23 +92,15 @@ InstallOptions::InstallOptions() : d(new Internal::InstallOptionsPrivate)
{
}
-InstallOptions::InstallOptions(const InstallOptions &other) : d(other.d)
-{
-}
+InstallOptions::InstallOptions(const InstallOptions &other) = default;
InstallOptions::InstallOptions(InstallOptions &&other) Q_DECL_NOEXCEPT = default;
-InstallOptions &InstallOptions::operator=(const InstallOptions &other)
-{
- d = other.d;
- return *this;
-}
+InstallOptions &InstallOptions::operator=(const InstallOptions &other) = default;
InstallOptions &InstallOptions::operator=(InstallOptions &&other) Q_DECL_NOEXCEPT = default;
-InstallOptions::~InstallOptions()
-{
-}
+InstallOptions::~InstallOptions() = default;
/*!
* \brief The default install root, relative to the build directory.
diff --git a/src/lib/corelib/tools/joblimits.cpp b/src/lib/corelib/tools/joblimits.cpp
index 1a3e3a498..54c8c98ba 100644
--- a/src/lib/corelib/tools/joblimits.cpp
+++ b/src/lib/corelib/tools/joblimits.cpp
@@ -87,13 +87,9 @@ JobLimit::JobLimit() : JobLimit(QString(), -1)
JobLimit::JobLimit(const QString &pool, int limit) : d(new Internal::JobLimitPrivate(pool, limit))
{
}
-JobLimit::JobLimit(const JobLimit &other) : d(other.d) { }
-JobLimit &JobLimit::operator=(const JobLimit &other)
-{
- d = other.d;
- return *this;
-}
-JobLimit::~JobLimit() {}
+JobLimit::JobLimit(const JobLimit &other) = default;
+JobLimit &JobLimit::operator=(const JobLimit &other) = default;
+JobLimit::~JobLimit() = default;
QString JobLimit::pool() const { return d->jobLimit.first; }
int JobLimit::limit() const { return d->jobLimit.second; }
@@ -108,13 +104,9 @@ void JobLimit::store(Internal::PersistentPool &pool)
}
JobLimits::JobLimits() : d(new Internal::JobLimitsPrivate) { }
-JobLimits::JobLimits(const JobLimits &other) : d(other.d) { }
-JobLimits &JobLimits::operator=(const JobLimits &other)
-{
- d = other.d;
- return *this;
-}
-JobLimits::~JobLimits() {}
+JobLimits::JobLimits(const JobLimits &other) = default;
+JobLimits &JobLimits::operator=(const JobLimits &other) = default;
+JobLimits::~JobLimits() = default;
void JobLimits::setJobLimit(const JobLimit &limit)
{
diff --git a/src/lib/corelib/tools/jsonhelper.h b/src/lib/corelib/tools/jsonhelper.h
index d87802c0a..991d6bd6c 100644
--- a/src/lib/corelib/tools/jsonhelper.h
+++ b/src/lib/corelib/tools/jsonhelper.h
@@ -78,9 +78,9 @@ template<> inline QProcessEnvironment fromJson(const QJsonValue &v)
template<typename T> inline void setValueFromJson(T &targetValue, const QJsonObject &data,
const char *jsonProperty)
{
- const QJsonValue v = data.value(QLatin1String(jsonProperty));
- if (!v.isNull())
- targetValue = fromJson<T>(v);
+ const auto it = data.find(QLatin1String(jsonProperty));
+ if (it != data.end())
+ targetValue = fromJson<T>(*it);
}
} // namespace Internal
diff --git a/src/lib/corelib/tools/launcherinterface.cpp b/src/lib/corelib/tools/launcherinterface.cpp
index f4e80c5e2..50ac659a9 100644
--- a/src/lib/corelib/tools/launcherinterface.cpp
+++ b/src/lib/corelib/tools/launcherinterface.cpp
@@ -108,9 +108,7 @@ void LauncherInterface::doStart()
return;
}
m_process = new LauncherProcess(this);
- connect(m_process,
- static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error),
- this, &LauncherInterface::handleProcessError);
+ connect(m_process, &QProcess::errorOccurred, this, &LauncherInterface::handleProcessError);
connect(m_process,
static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
this, &LauncherInterface::handleProcessFinished);
diff --git a/src/lib/corelib/tools/launcherpackets.cpp b/src/lib/corelib/tools/launcherpackets.cpp
index aaa931a49..9c7946d73 100644
--- a/src/lib/corelib/tools/launcherpackets.cpp
+++ b/src/lib/corelib/tools/launcherpackets.cpp
@@ -45,7 +45,7 @@
namespace qbs {
namespace Internal {
-LauncherPacket::~LauncherPacket() { }
+LauncherPacket::~LauncherPacket() = default;
QByteArray LauncherPacket::serialize() const
{
diff --git a/src/lib/corelib/tools/msvcinfo.cpp b/src/lib/corelib/tools/msvcinfo.cpp
index cffec85b2..462f921a4 100644
--- a/src/lib/corelib/tools/msvcinfo.cpp
+++ b/src/lib/corelib/tools/msvcinfo.cpp
@@ -38,14 +38,20 @@
****************************************************************************/
#include "msvcinfo.h"
+#include "visualstudioversioninfo.h"
+#include <logging/logger.h>
#include <tools/error.h>
#include <tools/profile.h>
#include <tools/stringconstants.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qdir.h>
+#include <QtCore/qjsonarray.h>
+#include <QtCore/qjsondocument.h>
+#include <QtCore/qjsonobject.h>
#include <QtCore/qprocess.h>
+#include <QtCore/qsettings.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qtemporaryfile.h>
@@ -54,6 +60,7 @@
#endif
#include <algorithm>
+#include <memory>
#include <mutex>
using namespace qbs;
@@ -129,16 +136,18 @@ public:
#ifdef Q_OS_WIN
static QStringList parseCommandLine(const QString &commandLine)
{
- QStringList list;
- const auto buf = new wchar_t[commandLine.size() + 1];
- buf[commandLine.toWCharArray(buf)] = 0;
+ const auto buf = std::make_unique<wchar_t[]>(size_t(commandLine.size()) + 1);
+ buf[size_t(commandLine.toWCharArray(buf.get()))] = 0;
int argCount = 0;
- LPWSTR *args = CommandLineToArgvW(buf, &argCount);
+ const auto argsDeleter = [](LPWSTR *p){ LocalFree(p); };
+ const auto args = std::unique_ptr<LPWSTR[], decltype(argsDeleter)>(
+ CommandLineToArgvW(buf.get(), &argCount), argsDeleter);
if (!args)
throw ErrorInfo(mkStr("Could not parse command line arguments: ") + commandLine);
+ QStringList list;
+ list.reserve(argCount);
for (int i = 0; i < argCount; ++i)
- list.push_back(QString::fromWCharArray(args[i]));
- delete[] buf;
+ list.push_back(QString::fromWCharArray(args[size_t(i)]));
return list;
}
#endif
@@ -163,7 +172,7 @@ static QVariantMap getMsvcDefines(const QString &compilerFilePath,
QStringList out = QString::fromLocal8Bit(runProcess(compilerFilePath, QStringList()
<< QStringLiteral("/nologo")
<< backendSwitch
- << QString::fromWCharArray(_wgetenv(L"COMSPEC"))
+ << qEnvironmentVariable("COMSPEC")
<< QStringLiteral("/c")
<< languageSwitch
<< QStringLiteral("NUL"),
@@ -206,30 +215,32 @@ static QVariantMap getMsvcDefines(const QString &compilerFilePath,
static QVariantMap getClangClDefines(
const QString &compilerFilePath,
const QProcessEnvironment &compilerEnv,
- MSVC::CompilerLanguage language)
+ MSVC::CompilerLanguage language,
+ const QString &arch)
{
#ifdef Q_OS_WIN
QFileInfo clInfo(compilerFilePath);
- QFileInfo clangInfo(clInfo.absolutePath() + QLatin1String("/clang.exe"));
+ QFileInfo clangInfo(clInfo.absolutePath() + QLatin1String("/clang-cl.exe"));
if (!clangInfo.exists())
throw ErrorInfo(QStringLiteral("%1 does not exist").arg(clangInfo.absoluteFilePath()));
- QString languageSwitch;
- switch (language) {
- case MSVC::CLanguage:
- languageSwitch = QStringLiteral("c");
- break;
- case MSVC::CPlusPlusLanguage:
- languageSwitch = QStringLiteral("c++");
- break;
- }
QStringList args = {
- QStringLiteral("-dM"),
- QStringLiteral("-E"),
- QStringLiteral("-x"),
- languageSwitch,
- QStringLiteral("NUL"),
+ QStringLiteral("/d1PP"), // dump macros
+ QStringLiteral("/E") // preprocess to stdout
};
+
+ if (language == MSVC::CLanguage)
+ args.append(QStringLiteral("/TC"));
+ else if (language == MSVC::CPlusPlusLanguage)
+ args.append(QStringLiteral("/TP"));
+
+ if (arch == QLatin1String("x86"))
+ args.append(QStringLiteral("-m32"));
+ else if (arch == QLatin1String("x86_64"))
+ args.append(QStringLiteral("-m64"));
+
+ args.append(QStringLiteral("NUL")); // filename
+
const auto lines = QString::fromLocal8Bit(
runProcess(
clangInfo.absoluteFilePath(),
@@ -239,10 +250,8 @@ static QVariantMap getClangClDefines(
QVariantMap result;
for (const auto &line: lines) {
static const auto defineString = QLatin1String("#define ");
- if (!line.startsWith(defineString)) {
- throw ErrorInfo(QStringLiteral("Unexpected compiler frontend output: ")
- + lines.join(QLatin1Char('\n')));
- }
+ if (!line.startsWith(defineString))
+ continue;
QStringView view(line.data() + defineString.size());
const auto it = std::find(view.begin(), view.end(), QLatin1Char(' '));
if (it == view.end()) {
@@ -253,15 +262,230 @@ static QVariantMap getClangClDefines(
QStringView value(it + 1, view.end());
result.insert(key.toString(), value.isEmpty() ? QVariant() : QVariant(value.toString()));
}
+ if (result.isEmpty()) {
+ throw ErrorInfo(QStringLiteral("Cannot determine macroses from compiler frontend output: ")
+ + lines.join(QLatin1Char('\n')));
+ }
return result;
#else
Q_UNUSED(compilerFilePath);
Q_UNUSED(compilerEnv);
Q_UNUSED(language);
+ Q_UNUSED(arch);
return {};
#endif
}
+static QString formatVswhereOutput(const QString &out, const QString &err)
+{
+ QString ret;
+ if (!out.isEmpty()) {
+ ret.append(Tr::tr("stdout")).append(QLatin1String(":\n"));
+ for (const QString &line : out.split(QLatin1Char('\n')))
+ ret.append(QLatin1Char('\t')).append(line).append(QLatin1Char('\n'));
+ }
+ if (!err.isEmpty()) {
+ ret.append(Tr::tr("stderr")).append(QLatin1String(":\n"));
+ for (const QString &line : err.split(QLatin1Char('\n')))
+ ret.append(QLatin1Char('\t')).append(line).append(QLatin1Char('\n'));
+ }
+ return ret;
+}
+
+static QString wow6432Key()
+{
+#ifdef Q_OS_WIN64
+ return QStringLiteral("\\Wow6432Node");
+#else
+ return {};
+#endif
+}
+
+static QString vswhereFilePath()
+{
+ static const std::vector<const char *> envVarCandidates{"ProgramFiles", "ProgramFiles(x86)"};
+ for (const char * const envVar : envVarCandidates) {
+ const QString value = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv(envVar)));
+ const QString cmd = value
+ + QStringLiteral("/Microsoft Visual Studio/Installer/vswhere.exe");
+ if (QFileInfo(cmd).exists())
+ return cmd;
+ }
+ return {};
+}
+
+enum class ProductType { VisualStudio, BuildTools };
+static std::vector<MSVCInstallInfo> retrieveInstancesFromVSWhere(
+ ProductType productType, Logger &logger)
+{
+ std::vector<MSVCInstallInfo> result;
+ const QString cmd = vswhereFilePath();
+ if (cmd.isEmpty())
+ return result;
+ QProcess vsWhere;
+ QStringList args = productType == ProductType::VisualStudio
+ ? QStringList({QStringLiteral("-all"), QStringLiteral("-legacy"),
+ QStringLiteral("-prerelease")})
+ : QStringList({QStringLiteral("-products"),
+ QStringLiteral("Microsoft.VisualStudio.Product.BuildTools")});
+ args << QStringLiteral("-format") << QStringLiteral("json") << QStringLiteral("-utf8");
+ vsWhere.start(cmd, args);
+ if (!vsWhere.waitForStarted(-1))
+ return result;
+ if (!vsWhere.waitForFinished(-1)) {
+ logger.qbsWarning() << Tr::tr("The vswhere tool failed to run").append(QLatin1String(": "))
+ .append(vsWhere.errorString());
+ return result;
+ }
+ if (vsWhere.exitCode() != 0) {
+ const QString stdOut = QString::fromLocal8Bit(vsWhere.readAllStandardOutput());
+ const QString stdErr = QString::fromLocal8Bit(vsWhere.readAllStandardError());
+ logger.qbsWarning() << Tr::tr("The vswhere tool failed to run").append(QLatin1String(".\n"))
+ .append(formatVswhereOutput(stdOut, stdErr));
+ return result;
+ }
+ QJsonParseError parseError;
+ QJsonDocument jsonOutput = QJsonDocument::fromJson(vsWhere.readAllStandardOutput(),
+ &parseError);
+ if (parseError.error != QJsonParseError::NoError) {
+ logger.qbsWarning() << Tr::tr("The vswhere tool produced invalid JSON output: %1")
+ .arg(parseError.errorString());
+ return result;
+ }
+ const auto jsonArray = jsonOutput.array();
+ for (const QJsonValue &v : jsonArray) {
+ const QJsonObject o = v.toObject();
+ MSVCInstallInfo info;
+ info.version = o.value(QStringLiteral("installationVersion")).toString();
+ if (productType == ProductType::BuildTools) {
+ // For build tools, the version is e.g. "15.8.28010.2036", rather than "15.0".
+ const int dotIndex = info.version.indexOf(QLatin1Char('.'));
+ if (dotIndex != -1)
+ info.version = info.version.left(dotIndex);
+ }
+ info.installDir = o.value(QStringLiteral("installationPath")).toString();
+ if (!info.version.isEmpty() && !info.installDir.isEmpty())
+ result.push_back(info);
+ }
+ return result;
+}
+
+static std::vector<MSVCInstallInfo> installedMSVCsFromVsWhere(Logger &logger)
+{
+ const std::vector<MSVCInstallInfo> vsInstallations
+ = retrieveInstancesFromVSWhere(ProductType::VisualStudio, logger);
+ const std::vector<MSVCInstallInfo> buildToolInstallations
+ = retrieveInstancesFromVSWhere(ProductType::BuildTools, logger);
+ std::vector<MSVCInstallInfo> all;
+ std::copy(vsInstallations.begin(), vsInstallations.end(), std::back_inserter(all));
+ std::copy(buildToolInstallations.begin(), buildToolInstallations.end(),
+ std::back_inserter(all));
+ return all;
+}
+
+static std::vector<MSVCInstallInfo> installedMSVCsFromRegistry()
+{
+ std::vector<MSVCInstallInfo> result;
+
+ // Detect Visual Studio
+ const QSettings vsRegistry(
+ QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE") + wow6432Key()
+ + QStringLiteral("\\Microsoft\\VisualStudio\\SxS\\VS7"),
+ QSettings::NativeFormat);
+ const auto vsNames = vsRegistry.childKeys();
+ for (const QString &vsName : vsNames) {
+ MSVCInstallInfo entry;
+ entry.version = vsName;
+ entry.installDir = vsRegistry.value(vsName).toString();
+ result.push_back(entry);
+ }
+
+ // Detect Visual C++ Build Tools
+ QSettings vcbtRegistry(
+ QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE") + wow6432Key()
+ + QStringLiteral("\\Microsoft\\VisualCppBuildTools"),
+ QSettings::NativeFormat);
+ const QStringList &vcbtRegistryChildGroups = vcbtRegistry.childGroups();
+ for (const QString &childGroup : vcbtRegistryChildGroups) {
+ vcbtRegistry.beginGroup(childGroup);
+ bool ok;
+ int installed = vcbtRegistry.value(QStringLiteral("Installed")).toInt(&ok);
+ if (ok && installed) {
+ MSVCInstallInfo entry;
+ entry.version = childGroup;
+ const QSettings vsRegistry(
+ QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE") + wow6432Key()
+ + QStringLiteral("\\Microsoft\\VisualStudio\\") + childGroup
+ + QStringLiteral("\\Setup\\VC"),
+ QSettings::NativeFormat);
+ entry.installDir = vsRegistry.value(QStringLiteral("ProductDir")).toString();
+ result.push_back(entry);
+ }
+ vcbtRegistry.endGroup();
+ }
+
+ return result;
+}
+
+/*
+ Returns the list of compilers present in all MSVC installations
+ (Visual Studios or Build Tools) without the architecture, e.g.
+ [VC\Tools\MSVC\14.16.27023, VC\Tools\MSVC\14.14.26428, ...]
+*/
+static std::vector<MSVC> installedCompilersHelper(Logger &logger)
+{
+ std::vector<MSVC> msvcs;
+ std::vector<MSVCInstallInfo> installInfos = installedMSVCsFromVsWhere(logger);
+ if (installInfos.empty())
+ installInfos = installedMSVCsFromRegistry();
+ for (const MSVCInstallInfo &installInfo : installInfos) {
+ MSVC msvc;
+ msvc.internalVsVersion = Version::fromString(installInfo.version, true);
+ if (!msvc.internalVsVersion.isValid())
+ continue;
+
+ QDir vsInstallDir(installInfo.installDir);
+ msvc.vsInstallPath = vsInstallDir.absolutePath();
+ if (vsInstallDir.dirName() != QStringLiteral("VC")
+ && !vsInstallDir.cd(QStringLiteral("VC"))) {
+ continue;
+ }
+
+ msvc.version = QString::number(Internal::VisualStudioVersionInfo(
+ msvc.internalVsVersion).marketingVersion());
+ if (msvc.version.isEmpty()) {
+ logger.qbsWarning()
+ << Tr::tr("Unknown MSVC version %1 found.").arg(installInfo.version);
+ continue;
+ }
+
+ if (msvc.internalVsVersion.majorVersion() < 15) {
+ QDir vcInstallDir = vsInstallDir;
+ if (!vcInstallDir.cd(QStringLiteral("bin")))
+ continue;
+ msvc.vcInstallPath = vcInstallDir.absolutePath();
+ msvcs.push_back(msvc);
+ } else {
+ QDir vcInstallDir = vsInstallDir;
+ vcInstallDir.cd(QStringLiteral("Tools/MSVC"));
+ const auto vcVersionStrs = vcInstallDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QString &vcVersionStr : vcVersionStrs) {
+ const Version vcVersion = Version::fromString(vcVersionStr);
+ if (!vcVersion.isValid())
+ continue;
+ QDir specificVcInstallDir = vcInstallDir;
+ if (!specificVcInstallDir.cd(vcVersionStr)
+ || !specificVcInstallDir.cd(QStringLiteral("bin"))) {
+ continue;
+ }
+ msvc.vcInstallPath = specificVcInstallDir.absolutePath();
+ msvcs.push_back(msvc);
+ }
+ }
+ }
+ return msvcs;
+}
+
void MSVC::init()
{
determineCompilerVersion();
@@ -280,6 +504,28 @@ QString MSVC::architectureFromClPath(const QString &clPath)
return parentDirName;
}
+QString MSVC::canonicalArchitecture(const QString &arch)
+{
+ if (arch == QLatin1String("x64") || arch == QLatin1String("amd64"))
+ return QStringLiteral("x86_64");
+ return arch;
+}
+
+std::pair<QString, QString> MSVC::getHostTargetArchPair(const QString &arch)
+{
+ QString hostArch;
+ QString targetArch;
+ const int index = arch.indexOf(QLatin1Char('_'));
+ if (index != -1) {
+ hostArch = arch.mid(0, index);
+ targetArch = arch.mid(index);
+ } else {
+ hostArch = arch;
+ targetArch = arch;
+ }
+ return {canonicalArchitecture(hostArch), canonicalArchitecture(targetArch)};
+}
+
QString MSVC::binPathForArchitecture(const QString &arch) const
{
QString archSubDir;
@@ -301,10 +547,106 @@ QVariantMap MSVC::compilerDefines(const QString &compilerFilePath,
{
const auto compilerName = QFileInfo(compilerFilePath).fileName().toLower();
if (compilerName == QLatin1String("clang-cl.exe"))
- return getClangClDefines(compilerFilePath, environment, language);
+ return getClangClDefines(compilerFilePath, environment, language, architecture);
return getMsvcDefines(compilerFilePath, environment, language);
}
+std::vector<MSVCArchInfo> MSVC::findSupportedArchitectures(const MSVC &msvc)
+{
+ std::vector<MSVCArchInfo> result;
+ auto addResult = [&result](const MSVCArchInfo &ai) {
+ if (QFile::exists(ai.binPath + QLatin1String("/cl.exe")))
+ result.push_back(ai);
+ };
+ if (msvc.internalVsVersion.majorVersion() < 15) {
+ static const QStringList knownArchitectures = QStringList()
+ << QStringLiteral("x86")
+ << QStringLiteral("amd64_x86")
+ << QStringLiteral("amd64")
+ << QStringLiteral("x86_amd64")
+ << QStringLiteral("ia64")
+ << QStringLiteral("x86_ia64")
+ << QStringLiteral("x86_arm")
+ << QStringLiteral("amd64_arm");
+ for (const QString &knownArchitecture : knownArchitectures) {
+ MSVCArchInfo ai;
+ ai.arch = knownArchitecture;
+ ai.binPath = msvc.binPathForArchitecture(knownArchitecture);
+ addResult(ai);
+ }
+ } else {
+ QDir vcInstallDir(msvc.vcInstallPath);
+ const auto hostArchs = vcInstallDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QString &hostArch : hostArchs) {
+ QDir subdir = vcInstallDir;
+ if (!subdir.cd(hostArch))
+ continue;
+ const QString shortHostArch = hostArch.mid(4).toLower();
+ const auto archs = subdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QString &arch : archs) {
+ MSVCArchInfo ai;
+ ai.binPath = subdir.absoluteFilePath(arch);
+ if (shortHostArch == arch)
+ ai.arch = arch;
+ else
+ ai.arch = shortHostArch + QLatin1Char('_') + arch;
+ addResult(ai);
+ }
+ }
+ }
+ return result;
+}
+
+QVariantMap MSVC::toVariantMap() const
+{
+ return {
+ {QStringLiteral("version"), version},
+ {QStringLiteral("internalVsVersion"), internalVsVersion.toString()},
+ {QStringLiteral("vsInstallPath"), vsInstallPath},
+ {QStringLiteral("vcInstallPath"), vcInstallPath},
+ {QStringLiteral("binPath"), binPath},
+ {QStringLiteral("architecture"), architecture},
+ };
+}
+
+/*!
+ \internal
+ Returns the list of all compilers present in all MSVC installations
+ separated by host/target arch, e.g.
+ [
+ VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64,
+ VC\Tools\MSVC\14.16.27023\bin\Hostx64\x86,
+ VC\Tools\MSVC\14.16.27023\bin\Hostx64\arm,
+ VC\Tools\MSVC\14.16.27023\bin\Hostx64\arm64,
+ VC\Tools\MSVC\14.16.27023\bin\Hostx86\x64,
+ ...
+ ]
+ \note that MSVC.architecture can be either "x64" or "amd64" (depending on the MSVC version)
+ in case of 64-bit platform (but we use the "x86_64" name...)
+*/
+std::vector<MSVC> MSVC::installedCompilers(Logger &logger)
+{
+ std::vector<MSVC> msvcs;
+ const auto instMsvcs = installedCompilersHelper(logger);
+ for (const MSVC &msvc : instMsvcs) {
+ if (msvc.internalVsVersion.majorVersion() < 15) {
+ // Check existence of various install scripts
+ const QString vcvars32bat = msvc.vcInstallPath + QLatin1String("/vcvars32.bat");
+ if (!QFileInfo(vcvars32bat).isFile())
+ continue;
+ }
+
+ const auto ais = findSupportedArchitectures(msvc);
+ for (const MSVCArchInfo &ai : ais) {
+ MSVC specificMSVC = msvc;
+ specificMSVC.architecture = ai.arch;
+ specificMSVC.binPath = ai.binPath;
+ msvcs.push_back(specificMSVC);
+ }
+ }
+ return msvcs;
+}
+
void MSVC::determineCompilerVersion()
{
QString cppFilePath;
@@ -332,3 +674,24 @@ void MSVC::determineCompilerVersion()
compilerVersion = Version(versionStr.mid(0, 2).toInt(), versionStr.mid(2, 2).toInt(),
versionStr.mid(4).toInt());
}
+
+QString MSVCInstallInfo::findVcvarsallBat() const
+{
+ static const auto vcvarsall2017 = QStringLiteral("VC/Auxiliary/Build/vcvarsall.bat");
+ // 2015, 2013 and 2012
+ static const auto vcvarsallOld = QStringLiteral("VC/vcvarsall.bat");
+ QDir dir(installDir);
+ if (dir.exists(vcvarsall2017))
+ return dir.absoluteFilePath(vcvarsall2017);
+ if (dir.exists(vcvarsallOld))
+ return dir.absoluteFilePath(vcvarsallOld);
+ return {};
+}
+
+std::vector<MSVCInstallInfo> MSVCInstallInfo::installedMSVCs(Logger &logger)
+{
+ const auto installInfos = installedMSVCsFromVsWhere(logger);
+ if (installInfos.empty())
+ return installedMSVCsFromRegistry();
+ return installInfos;
+}
diff --git a/src/lib/corelib/tools/msvcinfo.h b/src/lib/corelib/tools/msvcinfo.h
index b5cf04e84..de4470bf0 100644
--- a/src/lib/corelib/tools/msvcinfo.h
+++ b/src/lib/corelib/tools/msvcinfo.h
@@ -53,6 +53,14 @@
namespace qbs {
namespace Internal {
+class Logger;
+
+struct MSVCArchInfo
+{
+ QString arch;
+ QString binPath;
+};
+
/**
* Represents one MSVC installation for one specific target architecture.
* There are potentially multiple MSVCs in one Visual Studio installation.
@@ -75,7 +83,7 @@ public:
QString architecture;
QProcessEnvironment environment;
- MSVC() { }
+ MSVC() = default;
MSVC(const QString &clPath, QString arch):
architecture(std::move(arch))
@@ -90,11 +98,19 @@ public:
QBS_EXPORT void init();
QBS_EXPORT static QString architectureFromClPath(const QString &clPath);
+ QBS_EXPORT static QString canonicalArchitecture(const QString &arch);
+ QBS_EXPORT static std::pair<QString, QString> getHostTargetArchPair(const QString &arch);
QBS_EXPORT QString binPathForArchitecture(const QString &arch) const;
QBS_EXPORT QString clPathForArchitecture(const QString &arch) const;
QBS_EXPORT QVariantMap compilerDefines(const QString &compilerFilePath,
CompilerLanguage language) const;
+ QBS_EXPORT static std::vector<MSVCArchInfo> findSupportedArchitectures(const MSVC &msvc);
+
+ QBS_EXPORT QVariantMap toVariantMap() const;
+
+ QBS_EXPORT static std::vector<MSVC> installedCompilers(Logger &logger);
+
private:
void determineCompilerVersion();
};
@@ -110,6 +126,16 @@ public:
}
};
+struct QBS_EXPORT MSVCInstallInfo
+{
+ QString version;
+ QString installDir;
+
+ QString findVcvarsallBat() const;
+
+ static std::vector<MSVCInstallInfo> installedMSVCs(Logger &logger);
+};
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp
index ea8adf023..3f2b57e01 100644
--- a/src/lib/corelib/tools/persistence.cpp
+++ b/src/lib/corelib/tools/persistence.cpp
@@ -48,7 +48,7 @@
namespace qbs {
namespace Internal {
-static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-127";
+static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-128";
NoBuildGraphError::NoBuildGraphError(const QString &filePath)
: ErrorInfo(Tr::tr("Build graph not found for configuration '%1'. Expected location was '%2'.")
@@ -62,10 +62,7 @@ PersistentPool::PersistentPool(Logger &logger) : m_logger(logger)
m_stream.setVersion(QDataStream::Qt_4_8);
}
-PersistentPool::~PersistentPool()
-{
- closeStream();
-}
+PersistentPool::~PersistentPool() = default;
void PersistentPool::load(const QString &filePath)
{
@@ -89,7 +86,7 @@ void PersistentPool::load(const QString &filePath)
}
m_stream >> m_headData.projectConfig;
- file.release();
+ m_file = std::move(file);
m_loadedRaw.clear();
m_loaded.clear();
m_storageIndices.clear();
@@ -116,7 +113,8 @@ void PersistentPool::setupWriteStream(const QString &filePath)
"Cannot open file '%1' for writing: %2").arg(filePath, file->errorString()));
}
- m_stream.setDevice(file.release());
+ m_stream.setDevice(file.get());
+ m_file = std::move(file);
m_stream << QByteArray(qstrlen(QBS_PERSISTENCE_MAGIC), 0) << m_headData.projectConfig;
m_lastStoredObjectId = 0;
m_lastStoredStringId = 0;
@@ -140,14 +138,6 @@ void PersistentPool::finalizeWriteStream()
}
}
-void PersistentPool::closeStream()
-{
- delete m_stream.device();
- m_stream.setDevice(nullptr);
-}
-
-
-
void PersistentPool::storeVariant(const QVariant &variant)
{
const auto type = static_cast<quint32>(variant.type());
diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h
index 4bda59f7c..e00310321 100644
--- a/src/lib/corelib/tools/persistence.h
+++ b/src/lib/corelib/tools/persistence.h
@@ -128,7 +128,6 @@ public:
void load(const QString &filePath);
void setupWriteStream(const QString &filePath);
void finalizeWriteStream();
- void closeStream();
void clear();
const HeadData &headData() const { return m_headData; }
@@ -167,6 +166,7 @@ private:
static const PersistentObjectId ValueNotFoundId = -1;
static const PersistentObjectId EmptyValueId = -2;
+ std::unique_ptr<QIODevice> m_file;
QDataStream m_stream;
HeadData m_headData;
std::vector<void *> m_loadedRaw;
diff --git a/src/lib/corelib/tools/processresult.cpp b/src/lib/corelib/tools/processresult.cpp
index 3fb2f8dbc..d5591a7ed 100644
--- a/src/lib/corelib/tools/processresult.cpp
+++ b/src/lib/corelib/tools/processresult.cpp
@@ -53,19 +53,11 @@ ProcessResult::ProcessResult() : d(new Internal::ProcessResultPrivate)
{
}
-ProcessResult::ProcessResult(const ProcessResult &other) : d(other.d)
-{
-}
+ProcessResult::ProcessResult(const ProcessResult &other) = default;
-ProcessResult &ProcessResult::operator=(const ProcessResult &other)
-{
- d = other.d;
- return *this;
-}
+ProcessResult &ProcessResult::operator=(const ProcessResult &other) = default;
-ProcessResult::~ProcessResult()
-{
-}
+ProcessResult::~ProcessResult() = default;
/*!
* \brief Returns true iff the command finished successfully.
diff --git a/src/lib/corelib/tools/processutils.cpp b/src/lib/corelib/tools/processutils.cpp
index 04a061e0c..b27592f88 100644
--- a/src/lib/corelib/tools/processutils.cpp
+++ b/src/lib/corelib/tools/processutils.cpp
@@ -92,7 +92,8 @@ QString processNameByPid(qint64 pid)
char buf[PATH_MAX];
memset(buf, 0, sizeof(buf));
sprintf(exePath, "/proc/%lld/exe", pid);
- readlink(exePath, buf, sizeof(buf));
+ if (readlink(exePath, buf, sizeof(buf)) < 0)
+ return {};
return FileInfo::fileName(QString::fromUtf8(buf));
#elif defined(Q_OS_BSD4)
# if defined(Q_OS_NETBSD)
diff --git a/src/lib/corelib/tools/profile.cpp b/src/lib/corelib/tools/profile.cpp
index 7e594fd2d..2eac25091 100644
--- a/src/lib/corelib/tools/profile.cpp
+++ b/src/lib/corelib/tools/profile.cpp
@@ -63,13 +63,13 @@ namespace qbs {
/*!
* \brief Creates an object giving access to the settings for profile \c name.
*/
-Profile::Profile(const QString &name, Settings *settings, const QVariantMap &profiles)
- : m_name(name),
+Profile::Profile(QString name, Settings *settings, QVariantMap profiles)
+ : m_name(std::move(name)),
m_settings(settings),
- m_values(profiles.value(name).toMap()),
- m_profiles(profiles)
+ m_values(profiles.value(m_name).toMap()),
+ m_profiles(std::move(profiles))
{
- QBS_ASSERT(name == cleanName(name), return);
+ QBS_ASSERT(m_name == cleanName(m_name), return);
}
bool Profile::exists() const
diff --git a/src/lib/corelib/tools/profile.h b/src/lib/corelib/tools/profile.h
index aa8b7ef10..0eee23ae4 100644
--- a/src/lib/corelib/tools/profile.h
+++ b/src/lib/corelib/tools/profile.h
@@ -55,7 +55,7 @@ class Settings;
class QBS_EXPORT Profile
{
public:
- Profile(const QString &name, Settings *settings, const QVariantMap &profiles = QVariantMap());
+ Profile(QString name, Settings *settings, QVariantMap profiles = QVariantMap());
bool exists() const;
QVariant value(const QString &key, const QVariant &defaultValue = QVariant(),
diff --git a/src/lib/corelib/tools/progressobserver.h b/src/lib/corelib/tools/progressobserver.h
index 72b9694ba..fc49d9eed 100644
--- a/src/lib/corelib/tools/progressobserver.h
+++ b/src/lib/corelib/tools/progressobserver.h
@@ -51,7 +51,7 @@ namespace Internal {
class ProgressObserver
{
public:
- virtual ~ProgressObserver() { }
+ virtual ~ProgressObserver() = default;
virtual void initialize(const QString &task, int maximum) = 0;
virtual void setProgressValue(int value) = 0;
diff --git a/src/lib/corelib/tools/projectgeneratormanager.cpp b/src/lib/corelib/tools/projectgeneratormanager.cpp
index 3991adfb9..53d72bcd1 100644
--- a/src/lib/corelib/tools/projectgeneratormanager.cpp
+++ b/src/lib/corelib/tools/projectgeneratormanager.cpp
@@ -52,9 +52,7 @@ namespace qbs {
using namespace Internal;
-ProjectGeneratorManager::~ProjectGeneratorManager()
-{
-}
+ProjectGeneratorManager::~ProjectGeneratorManager() = default;
ProjectGeneratorManager *ProjectGeneratorManager::instance()
{
@@ -62,9 +60,7 @@ ProjectGeneratorManager *ProjectGeneratorManager::instance()
return &generatorPlugin;
}
-ProjectGeneratorManager::ProjectGeneratorManager()
-{
-}
+ProjectGeneratorManager::ProjectGeneratorManager() = default;
QStringList ProjectGeneratorManager::loadedGeneratorNames()
{
diff --git a/src/lib/corelib/tools/qttools.h b/src/lib/corelib/tools/qttools.h
index c3b4d3a9f..04fd7d95e 100644
--- a/src/lib/corelib/tools/qttools.h
+++ b/src/lib/corelib/tools/qttools.h
@@ -42,6 +42,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qstringlist.h>
+#include <QtCore/qtextstream.h>
#include <functional>
@@ -66,8 +67,16 @@ template<typename T1, typename T2> struct hash<std::pair<T1, T2>>
} // namespace std
QT_BEGIN_NAMESPACE
+
uint qHash(const QStringList &list);
uint qHash(const QProcessEnvironment &env);
+
+#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
+namespace Qt {
+inline QTextStream &endl(QTextStream &stream) { return stream << QT_PREPEND_NAMESPACE(endl); }
+} // namespace Qt
+#endif
+
QT_END_NAMESPACE
namespace qbs {
@@ -82,6 +91,16 @@ QSet<T> toSet(const QList<T> &list)
#endif
}
+template<class T>
+QList<T> toList(const QSet<T> &set)
+{
+#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
+ return set.toList();
+#else
+ return QList<T>(set.begin(), set.end());
+#endif
+}
+
} // namespace qbs
diff --git a/src/lib/corelib/tools/scannerpluginmanager.cpp b/src/lib/corelib/tools/scannerpluginmanager.cpp
index d6b564832..378f0e11b 100644
--- a/src/lib/corelib/tools/scannerpluginmanager.cpp
+++ b/src/lib/corelib/tools/scannerpluginmanager.cpp
@@ -51,9 +51,7 @@ public:
std::map<FileTag, std::vector<ScannerPlugin* >> scannerPlugins;
};
-ScannerPluginManager::~ScannerPluginManager()
-{
-}
+ScannerPluginManager::~ScannerPluginManager() = default;
ScannerPluginManager *ScannerPluginManager::instance()
{
diff --git a/src/lib/corelib/tools/set.h b/src/lib/corelib/tools/set.h
index eb3bf6632..d2af77d73 100644
--- a/src/lib/corelib/tools/set.h
+++ b/src/lib/corelib/tools/set.h
@@ -98,7 +98,7 @@ public:
const_iterator constBegin() const { return m_data.cbegin(); }
const_iterator constEnd() const { return m_data.cend(); }
- Set() { }
+ Set() = default;
Set(const std::initializer_list<T> &list);
Set &unite(const Set &other);
diff --git a/src/lib/corelib/tools/settings.cpp b/src/lib/corelib/tools/settings.cpp
index 7312cd622..fccb9c9b2 100644
--- a/src/lib/corelib/tools/settings.cpp
+++ b/src/lib/corelib/tools/settings.cpp
@@ -91,8 +91,8 @@ Settings::Settings(const QString &baseDir) : Settings(baseDir, systemSettingsBas
Settings::Settings(const QString &baseDir, const QString &systemBaseDir)
: m_settings(SettingsCreator(baseDir).getQSettings()),
- m_systemSettings(new QSettings(systemBaseDir + QStringLiteral("/qbs.conf"),
- QSettings::IniFormat)),
+ m_systemSettings(std::make_unique<QSettings>(systemBaseDir + QStringLiteral("/qbs.conf"),
+ QSettings::IniFormat)),
m_baseDir(baseDir)
{
// Actual qbs settings are stored transparently within a group, because QSettings
@@ -100,11 +100,7 @@ Settings::Settings(const QString &baseDir, const QString &systemBaseDir)
m_settings->beginGroup(QStringLiteral("org/qt-project/qbs"));
}
-Settings::~Settings()
-{
- delete m_settings;
- delete m_systemSettings;
-}
+Settings::~Settings() = default;
QVariant Settings::value(const QString &key, Scopes scopes, const QVariant &defaultValue) const
{
@@ -241,7 +237,7 @@ void Settings::fixupKeys(QStringList &keys) const
QSettings *Settings::settingsForScope(Settings::Scope scope) const
{
- return scope == UserScope ? m_settings : m_systemSettings;
+ return scope == UserScope ? m_settings.get() : m_systemSettings.get();
}
QSettings *Settings::targetForWriting() const
diff --git a/src/lib/corelib/tools/settings.h b/src/lib/corelib/tools/settings.h
index d4de08490..638216669 100644
--- a/src/lib/corelib/tools/settings.h
+++ b/src/lib/corelib/tools/settings.h
@@ -45,6 +45,8 @@
#include <QtCore/qstring.h>
#include <QtCore/qvariant.h>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QSettings;
class QStringList;
@@ -94,8 +96,8 @@ private:
QSettings *targetForWriting() const;
void checkForWriteError();
- QSettings * const m_settings;
- QSettings * const m_systemSettings;
+ const std::unique_ptr<QSettings> m_settings;
+ const std::unique_ptr<QSettings> m_systemSettings;
const QString m_baseDir;
Scope m_scopeForWriting = UserScope;
};
diff --git a/src/lib/corelib/tools/settingscreator.cpp b/src/lib/corelib/tools/settingscreator.cpp
index eaaf2802c..36e67440c 100644
--- a/src/lib/corelib/tools/settingscreator.cpp
+++ b/src/lib/corelib/tools/settingscreator.cpp
@@ -1,3 +1,4 @@
+#include <memory>
#include <utility>
/****************************************************************************
@@ -64,11 +65,11 @@ SettingsCreator::SettingsCreator(QString baseDir)
{
}
-QSettings *SettingsCreator::getQSettings()
+std::unique_ptr<QSettings> SettingsCreator::getQSettings()
{
createQSettings();
migrate();
- return m_settings.release();
+ return std::move(m_settings);
}
void SettingsCreator::migrate()
@@ -104,7 +105,7 @@ void SettingsCreator::migrate()
// Adapt all paths in settings that point to the old location. At the time of this writing,
// that's only preferences.qbsSearchPaths as written by libqtprofilesetup, but we don't want
// to hardcode that here.
- m_settings.reset(new QSettings(m_newSettingsFilePath, format()));
+ m_settings = std::make_unique<QSettings>(m_newSettingsFilePath, format());
const auto allKeys = m_settings->allKeys();
for (const QString &key : allKeys) {
QVariant v = m_settings->value(key);
@@ -136,7 +137,7 @@ void SettingsCreator::createQSettings()
m_newSettingsDir = m_settingsBaseDir + QLatin1String("/qbs/") + m_qbsVersion.toString();
m_settingsFileName = fi.fileName();
m_newSettingsFilePath = m_newSettingsDir + QLatin1Char('/') + m_settingsFileName;
- m_settings.reset(new QSettings(m_newSettingsFilePath, tmp->format()));
+ m_settings = std::make_unique<QSettings>(m_newSettingsFilePath, tmp->format());
}
Version SettingsCreator::predecessor() const
diff --git a/src/lib/corelib/tools/settingscreator.h b/src/lib/corelib/tools/settingscreator.h
index 39da80a7f..ab491105c 100644
--- a/src/lib/corelib/tools/settingscreator.h
+++ b/src/lib/corelib/tools/settingscreator.h
@@ -58,7 +58,7 @@ class SettingsCreator
public:
SettingsCreator(QString baseDir);
- QSettings *getQSettings();
+ std::unique_ptr<QSettings> getQSettings();
private:
void migrate();
diff --git a/src/lib/corelib/tools/settingsmodel.cpp b/src/lib/corelib/tools/settingsmodel.cpp
index d67f1da5c..7283e959c 100644
--- a/src/lib/corelib/tools/settingsmodel.cpp
+++ b/src/lib/corelib/tools/settingsmodel.cpp
@@ -125,7 +125,7 @@ public:
SettingsModel::SettingsModel(const QString &settingsDir, Settings::Scope scope, QObject *parent)
: QAbstractItemModel(parent), d(new SettingsModelPrivate)
{
- d->settings.reset(new qbs::Settings(settingsDir));
+ d->settings = std::make_unique<qbs::Settings>(settingsDir);
d->settings->setScopeForWriting(scope);
d->readSettings();
}
@@ -155,7 +155,7 @@ void SettingsModel::updateSettingsDir(const QString &settingsDir)
{
const Settings::Scope scope = d->scope();
beginResetModel();
- d->settings.reset(new qbs::Settings(settingsDir));
+ d->settings = std::make_unique<qbs::Settings>(settingsDir);
d->settings->setScopeForWriting(scope);
d->readSettings();
endResetModel();
diff --git a/src/lib/corelib/tools/setupprojectparameters.cpp b/src/lib/corelib/tools/setupprojectparameters.cpp
index 41af7b926..a06ffc4bd 100644
--- a/src/lib/corelib/tools/setupprojectparameters.cpp
+++ b/src/lib/corelib/tools/setupprojectparameters.cpp
@@ -107,21 +107,15 @@ SetupProjectParameters::SetupProjectParameters() : d(new Internal::SetupProjectP
{
}
-SetupProjectParameters::SetupProjectParameters(const SetupProjectParameters &other) : d(other.d)
-{
-}
+SetupProjectParameters::SetupProjectParameters(const SetupProjectParameters &other) = default;
-SetupProjectParameters::SetupProjectParameters(SetupProjectParameters &&other) Q_DECL_NOEXCEPT = default;
+SetupProjectParameters::SetupProjectParameters(
+ SetupProjectParameters &&other) Q_DECL_NOEXCEPT = default;
-SetupProjectParameters::~SetupProjectParameters()
-{
-}
+SetupProjectParameters::~SetupProjectParameters() = default;
-SetupProjectParameters &SetupProjectParameters::operator=(const SetupProjectParameters &other)
-{
- d = other.d;
- return *this;
-}
+SetupProjectParameters &SetupProjectParameters::operator=(
+ const SetupProjectParameters &other) = default;
namespace Internal {
template<> ErrorHandlingMode fromJson(const QJsonValue &v)
@@ -355,7 +349,7 @@ static void provideValuesTree(const QVariantMap &values, QVariantMap *valueTree)
valueTree->clear();
for (QVariantMap::const_iterator it = values.constBegin(); it != values.constEnd(); ++it) {
- const QString name = it.key();
+ const QString &name = it.key();
int idx = name.lastIndexOf(QLatin1Char('.'));
const QStringList nameElements = (idx == -1)
? QStringList() << name
diff --git a/src/lib/corelib/tools/shellutils.cpp b/src/lib/corelib/tools/shellutils.cpp
index 01c177cce..dae98f337 100644
--- a/src/lib/corelib/tools/shellutils.cpp
+++ b/src/lib/corelib/tools/shellutils.cpp
@@ -205,12 +205,12 @@ void CommandLine::setProgram(const std::string &program, bool raw)
void CommandLine::appendArgument(const QString &value)
{
- m_arguments.push_back(value);
+ m_arguments.emplace_back(value);
}
void CommandLine::appendArgument(const std::string &value)
{
- m_arguments.push_back(QString::fromStdString(value));
+ m_arguments.emplace_back(QString::fromStdString(value));
}
void CommandLine::appendArguments(const QList<QString> &args)
diff --git a/src/lib/corelib/tools/shellutils.h b/src/lib/corelib/tools/shellutils.h
index 6f1d82afb..f4ad35044 100644
--- a/src/lib/corelib/tools/shellutils.h
+++ b/src/lib/corelib/tools/shellutils.h
@@ -77,7 +77,7 @@ public:
private:
struct Argument
{
- Argument(const QString &value = QString()) : value(value) { }
+ Argument(QString value = QString()) : value(std::move(value)) { }
QString value;
bool isFilePath = false;
bool shouldQuote = true;
diff --git a/src/lib/corelib/tools/stlutils.h b/src/lib/corelib/tools/stlutils.h
index ad00070cf..5c21c0672 100644
--- a/src/lib/corelib/tools/stlutils.h
+++ b/src/lib/corelib/tools/stlutils.h
@@ -54,11 +54,18 @@ C sorted(const C &container)
return result;
}
-template <class C>
-bool contains(const C &container, const typename C::value_type &v)
+template <class C, class T>
+bool contains(const C &container, const T &v)
{
- const auto &end = container.cend();
- return std::find(container.cbegin(), end, v) != end;
+ const auto &end = std::cend(container);
+ return std::find(std::cbegin(container), end, v) != end;
+}
+
+template <class T, size_t N, class U>
+bool contains(const T (&container)[N], const U &v)
+{
+ const auto &end = std::cend(container);
+ return std::find(std::cbegin(container), end, v) != end;
}
template <class C>
diff --git a/src/lib/corelib/tools/stringconstants.h b/src/lib/corelib/tools/stringconstants.h
index 79cbcd125..f2bc78446 100644
--- a/src/lib/corelib/tools/stringconstants.h
+++ b/src/lib/corelib/tools/stringconstants.h
@@ -153,6 +153,7 @@ public:
QBS_STRING_CONSTANT(searchPathsProperty, "searchPaths")
QBS_STRING_CONSTANT(setupBuildEnvironmentProperty, "setupBuildEnvironment")
QBS_STRING_CONSTANT(setupRunEnvironmentProperty, "setupRunEnvironment")
+ QBS_STRING_CONSTANT(shadowProductPrefix, "__shadow__")
QBS_STRING_CONSTANT(sourceCodeProperty, "sourceCode")
QBS_STRING_CONSTANT(sourceDirectoryProperty, "sourceDirectory")
QBS_STRING_CONSTANT(submodulesProperty, "submodules")
diff --git a/src/lib/corelib/tools/stringutils.h b/src/lib/corelib/tools/stringutils.h
index 7b551a544..59acdccbd 100644
--- a/src/lib/corelib/tools/stringutils.h
+++ b/src/lib/corelib/tools/stringutils.h
@@ -77,14 +77,14 @@ static inline std::string trimmed(const std::string &s)
// trim from start
static const auto ltrim = [](std::string &s) -> std::string & {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
- std::not1(std::ptr_fun<int, int>(std::isspace))));
+ [](char c){ return !std::isspace(c); }));
return s;
};
// trim from end
static const auto rtrim = [](std::string &s) -> std::string & {
s.erase(std::find_if(s.rbegin(), s.rend(),
- std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
+ [](char c){ return !std::isspace(c); }).base(), s.end());
return s;
};
diff --git a/src/lib/corelib/tools/toolchains.cpp b/src/lib/corelib/tools/toolchains.cpp
index 0d793f8aa..6263fb199 100644
--- a/src/lib/corelib/tools/toolchains.cpp
+++ b/src/lib/corelib/tools/toolchains.cpp
@@ -49,9 +49,11 @@ namespace qbs {
namespace Internal {
static const QString clangToolchain() { return QStringLiteral("clang"); }
+static const QString clangClToolchain() { return QStringLiteral("clang-cl"); }
static const QString gccToolchain() { return QStringLiteral("gcc"); }
static const QString llvmToolchain() { return QStringLiteral("llvm"); }
static const QString mingwToolchain() { return QStringLiteral("mingw"); }
+static const QString msvcToolchain() { return QStringLiteral("msvc"); }
}
using namespace Internal;
@@ -64,7 +66,8 @@ QStringList canonicalToolchain(const QStringList &toolchain)
llvmToolchain(),
mingwToolchain(),
gccToolchain(),
- QStringLiteral("msvc")
+ clangClToolchain(),
+ msvcToolchain()
};
// Canonicalize each toolchain in the toolchain list,
@@ -110,6 +113,8 @@ QStringList canonicalToolchain(const QString &name)
else if (toolchainName == llvmToolchain() ||
toolchainName == mingwToolchain()) {
toolchains << canonicalToolchain(QStringLiteral("gcc"));
+ } else if (toolchainName == clangClToolchain()) {
+ toolchains << canonicalToolchain(msvcToolchain());
}
return toolchains;
}
diff --git a/src/lib/corelib/tools/tools.pri b/src/lib/corelib/tools/tools.pri
index 89d752671..00d87ecc7 100644
--- a/src/lib/corelib/tools/tools.pri
+++ b/src/lib/corelib/tools/tools.pri
@@ -10,6 +10,7 @@ QBS_SYSTEM_SETTINGS_DIR = $$(QBS_SYSTEM_SETTINGS_DIR)
HEADERS += \
$$PWD/architectures.h \
$$PWD/buildgraphlocker.h \
+ $$PWD/clangclinfo.h \
$$PWD/codelocation.h \
$$PWD/commandechomode.h \
$$PWD/dynamictypecheck.h \
@@ -68,6 +69,7 @@ HEADERS += \
SOURCES += \
$$PWD/architectures.cpp \
$$PWD/buildgraphlocker.cpp \
+ $$PWD/clangclinfo.cpp \
$$PWD/codelocation.cpp \
$$PWD/commandechomode.cpp \
$$PWD/error.cpp \
diff --git a/src/lib/corelib/tools/version.cpp b/src/lib/corelib/tools/version.cpp
index dfb7f49b7..f653256b3 100644
--- a/src/lib/corelib/tools/version.cpp
+++ b/src/lib/corelib/tools/version.cpp
@@ -44,50 +44,6 @@
namespace qbs {
-Version::Version(int major, int minor, int patch, int buildNr)
- : m_major(major), m_minor(minor), m_patch(patch), m_build(buildNr)
-{
-}
-
-int Version::majorVersion() const
-{
- return m_major;
-}
-
-void Version::setMajorVersion(int major)
-{
- m_major = major;
-}
-
-int Version::minorVersion() const
-{
- return m_minor;
-}
-
-void Version::setMinorVersion(int minor)
-{
- m_minor = minor;
-}
-int Version::patchLevel() const
-{
- return m_patch;
-}
-
-void Version::setPatchLevel(int patch)
-{
- m_patch = patch;
-}
-
-int Version::buildNumber() const
-{
- return m_build;
-}
-
-void Version::setBuildNumber(int nr)
-{
- m_build = nr;
-}
-
Version Version::fromString(const QString &versionString, bool buildNumberAllowed)
{
QString pattern = QStringLiteral("(\\d+)"); // At least one number.
@@ -118,32 +74,6 @@ QString Version::toString(const QChar &separator, const QChar &buildSeparator) c
QString::number(m_patch), separator);
}
-int compare(const Version &lhs, const Version &rhs)
-{
- if (lhs.majorVersion() < rhs.majorVersion())
- return -1;
- if (lhs.majorVersion() > rhs.majorVersion())
- return 1;
- if (lhs.minorVersion() < rhs.minorVersion())
- return -1;
- if (lhs.minorVersion() > rhs.minorVersion())
- return 1;
- if (lhs.patchLevel() < rhs.patchLevel())
- return -1;
- if (lhs.patchLevel() > rhs.patchLevel())
- return 1;
- if (lhs.buildNumber() < rhs.buildNumber())
- return -1;
- if (lhs.buildNumber() > rhs.buildNumber())
- return 1;
- return 0;
-}
-
-VersionRange::VersionRange(const Version &minVersion, const Version &maxVersion)
- : minimum(minVersion), maximum(maxVersion)
-{
-}
-
VersionRange &VersionRange::narrowDown(const VersionRange &other)
{
if (other.minimum > minimum)
diff --git a/src/lib/corelib/tools/version.h b/src/lib/corelib/tools/version.h
index a0239a6e4..63ad3f88c 100644
--- a/src/lib/corelib/tools/version.h
+++ b/src/lib/corelib/tools/version.h
@@ -54,22 +54,24 @@ namespace qbs {
class QBS_EXPORT Version
{
public:
- explicit Version(int majorVersion = 0, int minorVersion = 0, int patchLevel = 0,
- int buildNr = 0);
+ constexpr explicit Version(int majorVersion = 0, int minorVersion = 0, int patchLevel = 0,
+ int buildNr = 0)
+ : m_major(majorVersion), m_minor(minorVersion), m_patch(patchLevel), m_build(buildNr)
+ { }
- bool isValid() const { return m_major || m_minor || m_patch || m_build; }
+ constexpr bool isValid() const { return m_major || m_minor || m_patch || m_build; }
- int majorVersion() const;
- void setMajorVersion(int majorVersion);
+ constexpr int majorVersion() const { return m_major; }
+ constexpr void setMajorVersion(int majorVersion) { m_major = majorVersion; }
- int minorVersion() const;
- void setMinorVersion(int minorVersion);
+ constexpr int minorVersion() const { return m_minor; }
+ constexpr void setMinorVersion(int minorVersion) { m_minor = minorVersion;}
- int patchLevel() const;
- void setPatchLevel(int patchLevel);
+ constexpr int patchLevel() const { return m_patch; }
+ constexpr void setPatchLevel(int patchLevel) { m_patch = patchLevel; }
- int buildNumber() const;
- void setBuildNumber(int nr);
+ constexpr int buildNumber() const { return m_build; }
+ constexpr void setBuildNumber(int nr) { m_build = nr; }
static Version fromString(const QString &versionString, bool buildNumberAllowed = false);
QString toString(const QChar &separator = QLatin1Char('.'),
@@ -85,8 +87,10 @@ private:
class VersionRange
{
public:
- VersionRange() = default;
- VersionRange(const Version &minVersion, const Version &maxVersion);
+ constexpr VersionRange() = default;
+ constexpr VersionRange(const Version &minVersion, const Version &maxVersion)
+ : minimum(minVersion), maximum(maxVersion)
+ { }
Version minimum;
Version maximum; // exclusive
@@ -94,13 +98,39 @@ public:
VersionRange &narrowDown(const VersionRange &other);
};
-QBS_EXPORT int compare(const Version &lhs, const Version &rhs);
-inline bool operator==(const Version &lhs, const Version &rhs) { return compare(lhs, rhs) == 0; }
-inline bool operator!=(const Version &lhs, const Version &rhs) { return !operator==(lhs, rhs); }
-inline bool operator<(const Version &lhs, const Version &rhs) { return compare(lhs, rhs) < 0; }
-inline bool operator>(const Version &lhs, const Version &rhs) { return compare(lhs, rhs) > 0; }
-inline bool operator<=(const Version &lhs, const Version &rhs) { return !operator>(lhs, rhs); }
-inline bool operator>=(const Version &lhs, const Version &rhs) { return !operator<(lhs, rhs); }
+constexpr inline int compare(const Version &lhs, const Version &rhs)
+{
+ if (lhs.majorVersion() < rhs.majorVersion())
+ return -1;
+ if (lhs.majorVersion() > rhs.majorVersion())
+ return 1;
+ if (lhs.minorVersion() < rhs.minorVersion())
+ return -1;
+ if (lhs.minorVersion() > rhs.minorVersion())
+ return 1;
+ if (lhs.patchLevel() < rhs.patchLevel())
+ return -1;
+ if (lhs.patchLevel() > rhs.patchLevel())
+ return 1;
+ if (lhs.buildNumber() < rhs.buildNumber())
+ return -1;
+ if (lhs.buildNumber() > rhs.buildNumber())
+ return 1;
+ return 0;
+}
+
+constexpr inline bool operator==(const Version &lhs, const Version &rhs)
+{ return compare(lhs, rhs) == 0; }
+constexpr inline bool operator!=(const Version &lhs, const Version &rhs)
+{ return !operator==(lhs, rhs); }
+constexpr inline bool operator<(const Version &lhs, const Version &rhs)
+{ return compare(lhs, rhs) < 0; }
+constexpr inline bool operator>(const Version &lhs, const Version &rhs)
+{ return compare(lhs, rhs) > 0; }
+constexpr inline bool operator<=(const Version &lhs, const Version &rhs)
+{ return !operator>(lhs, rhs); }
+constexpr inline bool operator>=(const Version &lhs, const Version &rhs)
+{ return !operator<(lhs, rhs); }
} // namespace qbs
diff --git a/src/lib/corelib/tools/visualstudioversioninfo.cpp b/src/lib/corelib/tools/visualstudioversioninfo.cpp
index d4f8844fa..b5ee3e719 100644
--- a/src/lib/corelib/tools/visualstudioversioninfo.cpp
+++ b/src/lib/corelib/tools/visualstudioversioninfo.cpp
@@ -46,9 +46,7 @@
namespace qbs {
namespace Internal {
-VisualStudioVersionInfo::VisualStudioVersionInfo()
-{
-}
+VisualStudioVersionInfo::VisualStudioVersionInfo() = default;
VisualStudioVersionInfo::VisualStudioVersionInfo(const Version &version)
: m_version(version)
@@ -176,7 +174,7 @@ QString VisualStudioVersionInfo::platformToolsetVersion() const
{16, QStringLiteral("v142")}, // VS 2019
{15, QStringLiteral("v141")} // VS 2017
};
- for (auto p : table) {
+ for (const auto &p : table) {
if (p.first == m_version.majorVersion())
return p.second;
}
diff --git a/src/lib/corelib/tools/vsenvironmentdetector.cpp b/src/lib/corelib/tools/vsenvironmentdetector.cpp
index f8f98e7b7..95451435a 100644
--- a/src/lib/corelib/tools/vsenvironmentdetector.cpp
+++ b/src/lib/corelib/tools/vsenvironmentdetector.cpp
@@ -193,13 +193,13 @@ bool VsEnvironmentDetector::startDetection(const std::vector<MSVC *> &compatible
static void batClearVars(QTextStream &s, const QStringList &varnames)
{
for (const QString &varname : varnames)
- s << "set " << varname << '=' << endl;
+ s << "set " << varname << '=' << Qt::endl;
}
static void batPrintVars(QTextStream &s, const QStringList &varnames)
{
for (const QString &varname : varnames)
- s << "echo " << varname << "=%" << varname << '%' << endl;
+ s << "echo " << varname << "=%" << varname << '%' << Qt::endl;
}
static QString vcArchitecture(const MSVC *msvc)
@@ -232,7 +232,10 @@ void VsEnvironmentDetector::writeBatchFile(QIODevice *device, const QString &vcv
<< QStringLiteral("INCLUDE") << QStringLiteral("LIB") << QStringLiteral("WindowsSdkDir")
<< QStringLiteral("WindowsSDKVersion") << QStringLiteral("VSINSTALLDIR");
QTextStream s(device);
+ using Qt::endl;
s << "@echo off" << endl;
+ // Avoid execution of powershell (in vsdevcmd.bat), which is not in the cleared PATH
+ s << "set VSCMD_SKIP_SENDTELEMETRY=1" << endl;
for (const MSVC *msvc : msvcs) {
s << "echo --" << msvc->architecture << "--" << endl
<< "setlocal" << endl;
diff --git a/src/lib/scriptengine/use_scriptengine.pri b/src/lib/scriptengine/use_scriptengine.pri
index 6450e171f..e8f82a949 100644
--- a/src/lib/scriptengine/use_scriptengine.pri
+++ b/src/lib/scriptengine/use_scriptengine.pri
@@ -3,7 +3,15 @@
isEmpty(QBSLIBDIR) {
QBSLIBDIR = $$shadowed($$PWD/../../../$${QBS_LIBRARY_DIRNAME})
}
- LIBS += -L$$QBSLIBDIR -lqbsscriptengine$$qtPlatformTargetSuffix()
+
+ LIBS += -L$$QBSLIBDIR
+ macos {
+ LIBS += -lqbsscriptengine
+ }
+ else {
+ LIBS += -lqbsscriptengine$$qtPlatformTargetSuffix()
+ }
+
}
INCLUDEPATH += \