forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.5'
Change-Id: I7bc3615fb4bbafffa9636d731d8840445352b592
This commit is contained in:
BIN
doc/images/qtcreator-filesystem-view.png
Normal file
BIN
doc/images/qtcreator-filesystem-view.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 35 KiB |
@@ -244,7 +244,8 @@
|
||||
\section2 List of JavaScript and QML Checks
|
||||
|
||||
Many of the JavaScript checks are similar to the ones in Douglas Crockford's
|
||||
\l{http://www.jslint.com}{JSLint} tool.
|
||||
\l{http://www.jslint.com}{JSLint} tool. For more information about JSLint
|
||||
errors, see \l{http://linterrors.com/js}{JSLint Error Explanations}.
|
||||
|
||||
\table
|
||||
\header
|
||||
@@ -311,25 +312,33 @@
|
||||
\li M10
|
||||
\li Error
|
||||
\li Duplicate property binding
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/duplicate-key-a}
|
||||
{Duplicate key '{a}'}.
|
||||
|
||||
\row
|
||||
\li M11
|
||||
\li Error
|
||||
\li Id expected
|
||||
\li
|
||||
\li See also:
|
||||
\l{http://linterrors.com/js/expected-an-identifier-and-instead-saw-a-a-reserved-word}
|
||||
{Expected an identifier and instead saw '{a}' (a reserved word)}.
|
||||
|
||||
\row
|
||||
\li M14
|
||||
\li Error
|
||||
\li Invalid id
|
||||
\li
|
||||
\li See also:
|
||||
\l{http://linterrors.com/js/expected-an-identifier-and-instead-saw-a-a-reserved-word}
|
||||
{Expected an identifier and instead saw '{a}' (a reserved word)}.
|
||||
|
||||
|
||||
\row
|
||||
\li M15
|
||||
\li Error
|
||||
\li Duplicate id
|
||||
\li Ids in a file must be unique.
|
||||
See also: \l{http://linterrors.com/js/duplicate-key-a}
|
||||
{Duplicate key '{a}'}.
|
||||
|
||||
\row
|
||||
\li M16
|
||||
@@ -369,7 +378,7 @@
|
||||
\li M23
|
||||
\li Warning
|
||||
\li Do not use \c eval
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/eval-is-evil}{eval is evil}.
|
||||
|
||||
\row
|
||||
\li M28
|
||||
@@ -381,7 +390,8 @@
|
||||
\li M29
|
||||
\li Warning
|
||||
\li Do not use \c with
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/unexpected-with}
|
||||
{Unexpected 'with'}.
|
||||
|
||||
\row
|
||||
\li M30
|
||||
@@ -431,44 +441,51 @@
|
||||
\li M108
|
||||
\li Warning
|
||||
\li Function \c name is used before its declaration
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/a-was-used-before-it-was-defined}
|
||||
{{a} was used before it was defined}.
|
||||
|
||||
\row
|
||||
\li M109
|
||||
\li Warning
|
||||
\li Do not use \c Boolean as a constructor
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/do-not-use-a-as-a-constructor}
|
||||
{Do not use {a} as a constructor}.
|
||||
|
||||
\row
|
||||
\li M110
|
||||
\li Warning
|
||||
\li Do not use \c String as a constructor
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/do-not-use-a-as-a-constructor}
|
||||
{Do not use {a} as a constructor}.
|
||||
|
||||
\row
|
||||
\li M111
|
||||
\li Warning
|
||||
\li Do not use \c Object as a constructor
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/do-not-use-a-as-a-constructor}
|
||||
{Do not use {a} as a constructor}.
|
||||
|
||||
\row
|
||||
\li M112
|
||||
\li Warning
|
||||
\li Do not use \c Array as a constructor
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/do-not-use-a-as-a-constructor}
|
||||
{Do not use {a} as a constructor}.
|
||||
|
||||
\row
|
||||
\li M113
|
||||
\li Warning
|
||||
\li Do not use \c Function as a constructor
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/do-not-use-a-as-a-constructor}
|
||||
{Do not use {a} as a constructor}.
|
||||
|
||||
\row
|
||||
\li M114
|
||||
\li Hint
|
||||
\li The \c function keyword and the opening parenthesis should be
|
||||
separated by a single space
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/expected-exactly-one-space-between-a-and-b}
|
||||
{Expected exactly one space between {a} and {b}}.
|
||||
|
||||
\row
|
||||
\li M115
|
||||
@@ -488,13 +505,15 @@
|
||||
\li M117
|
||||
\li Warning
|
||||
\li Confusing pluses
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/confusing-pluses}
|
||||
{Confusing pluses}.
|
||||
|
||||
\row
|
||||
\li M119
|
||||
\li Warning
|
||||
\li Confusing minuses
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/confusing-minuses}
|
||||
{Confusing minuses}.
|
||||
|
||||
\row
|
||||
\li M121
|
||||
@@ -536,7 +555,9 @@
|
||||
\li M201
|
||||
\li Hint
|
||||
\li Place var declarations at the start of a function
|
||||
\li
|
||||
\li See also:
|
||||
\l{http://linterrors.com/js/move-var-declarations-to-the-top-of-the-function}
|
||||
{Move 'var' declarations to the top of the function}.
|
||||
|
||||
\row
|
||||
\li M202
|
||||
@@ -678,13 +699,15 @@
|
||||
\li M307
|
||||
\li Warning
|
||||
\li Use \c new only with functions that start with an uppercase letter
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/do-not-use-a-as-a-constructor}
|
||||
{Do not use {a} as a constructor}.
|
||||
|
||||
\row
|
||||
\li M308
|
||||
\li Warning
|
||||
\li Do not use \c Number as a constructor
|
||||
\li
|
||||
\li See also: \l{http://linterrors.com/js/do-not-use-a-as-a-constructor}
|
||||
{Do not use {a} as a constructor}.
|
||||
|
||||
\row
|
||||
\li M309
|
||||
@@ -774,7 +797,9 @@
|
||||
\li M323
|
||||
\li Error
|
||||
\li \c Number elements expected in array value
|
||||
\li
|
||||
\li See also:
|
||||
\l{http://linterrors.com/js/the-array-literal-notation-is-preferrable}
|
||||
{The array literal notation [] is preferable}.
|
||||
|
||||
\row
|
||||
\li M324
|
||||
|
||||
@@ -215,8 +215,8 @@
|
||||
\li To hide source files which are automatically generated by the build
|
||||
system, select \uicontrol {Filter Tree > Hide Generated Files}.
|
||||
|
||||
\li To keep the position in the project tree synchronized with the file
|
||||
currently opened in the editor, click \inlineimage linkicon.png
|
||||
\li To stop synchronizing the position in the project tree with the file
|
||||
currently opened in the editor, deselect \inlineimage linkicon.png
|
||||
(\uicontrol {Synchronize with Editor}).
|
||||
|
||||
\li To see the absolute path of a file, move the mouse pointer over the
|
||||
@@ -258,10 +258,20 @@
|
||||
If you cannot see a file in the \uicontrol Projects view, switch to the
|
||||
\uicontrol {File System} view, which shows all the files in the file system.
|
||||
|
||||
To also show hidden files, select \uicontrol {Filter Files} > \uicontrol {Show Hidden Files}.
|
||||
\image qtcreator-filesystem-view.png
|
||||
|
||||
To keep the position in the tree synchronized with the file
|
||||
opened in the editor, select \uicontrol {Synchronize with Editor}.
|
||||
By default, the contents of the directory that contains the file currently
|
||||
active in the editor are displayed. To move to the root directory of the
|
||||
file system, select \uicontrol Computer in the menu (1). Select
|
||||
\uicontrol Home to move to the user's home directory. Further, you can
|
||||
select a project to move to an open project or \uicontrol Projects to open
|
||||
the \uicontrol Projects view.
|
||||
|
||||
To stop the synchronization with the file currently opened in the editor,
|
||||
deselect \uicontrol {Synchronize with Editor}.
|
||||
|
||||
To also show hidden files, select \uicontrol {Filter Files} >
|
||||
\uicontrol {Show Hidden Files}.
|
||||
|
||||
Use the context menu functions to:
|
||||
|
||||
@@ -269,6 +279,8 @@
|
||||
|
||||
\li Open files with the default editor or some other editor.
|
||||
|
||||
\li Open a project located in the selected directory.
|
||||
|
||||
\li Show the file or directory in the file explorer.
|
||||
|
||||
\li Open a terminal window in the selected directory or in the directory
|
||||
@@ -299,8 +311,8 @@
|
||||
\li To see a complete list of all bindings, select \uicontrol {Filter Tree >
|
||||
Show All Bindings}.
|
||||
|
||||
\li To keep the position in the view synchronized with the QML type
|
||||
selected in the editor, select \uicontrol {Synchronize with Editor}.
|
||||
\li To stop the synchronization with the QML type selected in the
|
||||
editor, deselect \uicontrol {Synchronize with Editor}.
|
||||
|
||||
\endlist
|
||||
|
||||
@@ -467,6 +479,8 @@
|
||||
when building applications, select \uicontrol Tools > \uicontrol Options >
|
||||
\uicontrol {Build & Run} > \uicontrol General, and then select the
|
||||
\uicontrol {Open Compile Output pane when building} check box.
|
||||
In the \uicontrol {Limit build output to} field, you can specify the maximum
|
||||
amount of build output lines to display in the pane.
|
||||
|
||||
\section2 Debugger Console
|
||||
|
||||
|
||||
@@ -138,6 +138,9 @@
|
||||
paths may fail. For example, remounting parts of a file system
|
||||
using the --bind mount option.
|
||||
|
||||
\li Setting breakpoints in files will fail when using LLDB if the file path
|
||||
contains symbolic links.
|
||||
|
||||
\li A regression in GCC 4.5.0 causes return value optimization to
|
||||
produce inaccurate debug info that GCC applies also to
|
||||
non-optimized builds. For more information, see
|
||||
|
||||
@@ -26,6 +26,10 @@ Product {
|
||||
cpp.minimumMacosVersion: project.minimumMacosVersion
|
||||
}
|
||||
|
||||
Properties {
|
||||
condition: qbs.toolchain.contains("gcc") && !qbs.toolchain.contains("clang")
|
||||
cpp.cxxFlags: base.concat(["-Wno-noexcept-type"])
|
||||
}
|
||||
cpp.cxxLanguageVersion: "c++14"
|
||||
cpp.defines: qtc.generalDefines
|
||||
cpp.minimumWindowsVersion: qbs.architecture === "x86" ? "5.1" : "5.2"
|
||||
|
||||
@@ -118,9 +118,9 @@ QRegularExpression CamelHumpMatcher::createCamelHumpRegExp(
|
||||
|
||||
first = false;
|
||||
}
|
||||
keyRegExp += ")|(" + plainRegExp + ')';
|
||||
keyRegExp += ')';
|
||||
|
||||
return QRegularExpression(keyRegExp);
|
||||
return QRegularExpression('(' + plainRegExp + ")|" + keyRegExp);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -323,7 +323,7 @@ void ServerModeReader::generateProjectTree(CMakeProjectNode *root,
|
||||
const FileName path = fn->filePath();
|
||||
if (path.fileName().compare("CMakeLists.txt", HostOsInfo::fileNameCaseSensitivity()) == 0)
|
||||
cmakeLists.append(fn);
|
||||
else if (path.isChildOf(m_parameters.buildDirectory))
|
||||
else if (path.isChildOf(m_parameters.workDirectory))
|
||||
cmakeFilesBuild.append(fn);
|
||||
else if (path.isChildOf(m_parameters.sourceDirectory))
|
||||
cmakeFilesSource.append(fn);
|
||||
@@ -345,7 +345,7 @@ void ServerModeReader::generateProjectTree(CMakeProjectNode *root,
|
||||
addHeaderNodes(root, knownHeaders, allFiles);
|
||||
|
||||
if (!cmakeFilesSource.isEmpty() || !cmakeFilesBuild.isEmpty() || !cmakeFilesOther.isEmpty())
|
||||
addCMakeInputs(root, m_parameters.sourceDirectory, m_parameters.buildDirectory,
|
||||
addCMakeInputs(root, m_parameters.sourceDirectory, m_parameters.workDirectory,
|
||||
cmakeFilesSource, cmakeFilesBuild, cmakeFilesOther);
|
||||
}
|
||||
|
||||
@@ -859,12 +859,12 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot,
|
||||
}
|
||||
|
||||
// Split up files in groups (based on location):
|
||||
const bool inSourceBuild = (m_parameters.buildDirectory == m_parameters.sourceDirectory);
|
||||
const bool inSourceBuild = (m_parameters.workDirectory == m_parameters.sourceDirectory);
|
||||
QList<FileNode *> sourceFileNodes;
|
||||
QList<FileNode *> buildFileNodes;
|
||||
QList<FileNode *> otherFileNodes;
|
||||
foreach (FileNode *fn, toList) {
|
||||
if (fn->filePath().isChildOf(m_parameters.buildDirectory) && !inSourceBuild)
|
||||
if (fn->filePath().isChildOf(m_parameters.workDirectory) && !inSourceBuild)
|
||||
buildFileNodes.append(fn);
|
||||
else if (fn->filePath().isChildOf(m_parameters.sourceDirectory))
|
||||
sourceFileNodes.append(fn);
|
||||
|
||||
@@ -192,7 +192,7 @@ static QString findCbpFile(const QDir &directory)
|
||||
|
||||
void TeaLeafReader::parse(bool forceConfiguration)
|
||||
{
|
||||
const QString cbpFile = findCbpFile(QDir(m_parameters.buildDirectory.toString()));
|
||||
const QString cbpFile = findCbpFile(QDir(m_parameters.workDirectory.toString()));
|
||||
const QFileInfo cbpFileFi = cbpFile.isEmpty() ? QFileInfo() : QFileInfo(cbpFile);
|
||||
if (!cbpFileFi.exists() || forceConfiguration) {
|
||||
// Initial create:
|
||||
@@ -236,7 +236,7 @@ QList<CMakeBuildTarget> TeaLeafReader::takeBuildTargets()
|
||||
|
||||
CMakeConfig TeaLeafReader::takeParsedConfiguration()
|
||||
{
|
||||
FileName cacheFile = m_parameters.buildDirectory;
|
||||
FileName cacheFile = m_parameters.workDirectory;
|
||||
cacheFile.appendPath(QLatin1String("CMakeCache.txt"));
|
||||
|
||||
if (!cacheFile.exists())
|
||||
@@ -366,7 +366,7 @@ void TeaLeafReader::updateCodeModel(CppTools::RawProjectParts &rpps)
|
||||
} else {
|
||||
includePaths = transform(cbt.includeFiles, &FileName::toString);
|
||||
}
|
||||
includePaths += m_parameters.buildDirectory.toString();
|
||||
includePaths += m_parameters.workDirectory.toString();
|
||||
CppTools::RawProjectPart rpp;
|
||||
rpp.setProjectFileLocation(cbt.sourceDirectory.toString() + "/CMakeLists.txt");
|
||||
rpp.setBuildSystemTarget(cbt.title);
|
||||
@@ -411,7 +411,7 @@ void TeaLeafReader::extractData()
|
||||
QTC_ASSERT(m_parameters.isValid() && m_parameters.cmakeTool, return);
|
||||
|
||||
const FileName srcDir = m_parameters.sourceDirectory;
|
||||
const FileName bldDir = m_parameters.buildDirectory;
|
||||
const FileName bldDir = m_parameters.workDirectory;
|
||||
const FileName topCMake = Utils::FileName(srcDir).appendPath("CMakeLists.txt");
|
||||
|
||||
resetData();
|
||||
@@ -427,7 +427,7 @@ void TeaLeafReader::extractData()
|
||||
m_cmakeFiles.insert(cbpFile);
|
||||
|
||||
// Add CMakeCache.txt file:
|
||||
FileName cacheFile = m_parameters.buildDirectory;
|
||||
FileName cacheFile = m_parameters.workDirectory;
|
||||
cacheFile.appendPath(QLatin1String("CMakeCache.txt"));
|
||||
if (cacheFile.toFileInfo().exists())
|
||||
m_cmakeFiles.insert(cacheFile);
|
||||
@@ -460,11 +460,11 @@ void TeaLeafReader::startCMake(const QStringList &configurationArguments)
|
||||
{
|
||||
QTC_ASSERT(m_parameters.isValid() && m_parameters.cmakeTool, return);
|
||||
|
||||
const FileName buildDirectory = m_parameters.buildDirectory;
|
||||
const FileName workDirectory = m_parameters.workDirectory;
|
||||
QTC_ASSERT(!m_cmakeProcess, return);
|
||||
QTC_ASSERT(!m_parser, return);
|
||||
QTC_ASSERT(!m_future, return);
|
||||
QTC_ASSERT(buildDirectory.exists(), return);
|
||||
QTC_ASSERT(workDirectory.exists(), return);
|
||||
|
||||
const QString srcDir = m_parameters.sourceDirectory.toString();
|
||||
|
||||
@@ -485,7 +485,7 @@ void TeaLeafReader::startCMake(const QStringList &configurationArguments)
|
||||
// then we are racing against CMakeCache.txt also getting deleted.
|
||||
|
||||
m_cmakeProcess = new QtcProcess;
|
||||
m_cmakeProcess->setWorkingDirectory(buildDirectory.toString());
|
||||
m_cmakeProcess->setWorkingDirectory(workDirectory.toString());
|
||||
m_cmakeProcess->setEnvironment(m_parameters.environment);
|
||||
|
||||
connect(m_cmakeProcess, &QProcess::readyReadStandardOutput,
|
||||
@@ -505,7 +505,7 @@ void TeaLeafReader::startCMake(const QStringList &configurationArguments)
|
||||
MessageManager::write(tr("Running \"%1 %2\" in %3.")
|
||||
.arg(m_parameters.cmakeTool->cmakeExecutable().toUserOutput())
|
||||
.arg(args)
|
||||
.arg(buildDirectory.toUserOutput()));
|
||||
.arg(workDirectory.toUserOutput()));
|
||||
|
||||
m_future = new QFutureInterface<void>();
|
||||
m_future->setProgressRange(0, 1);
|
||||
|
||||
@@ -296,12 +296,10 @@ void HighlightScrollBarOverlay::paintEvent(QPaintEvent *paintEvent)
|
||||
const auto highlightEnd = highlights.cend();
|
||||
for (auto highlightIt = highlights.cbegin(); highlightIt != highlightEnd; ++highlightIt) {
|
||||
const QColor &color = creatorTheme()->color(highlightIt.key());
|
||||
for (int i = 0, total = highlightIt.value().size(); i < total; ++i) {
|
||||
const QRect rect = highlightIt.value().at(i);
|
||||
for (const QRect &rect : highlightIt.value())
|
||||
painter.fillRect(rect, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Highlight::Highlight(Id category_, int position_,
|
||||
Theme::Color color_, Highlight::Priority priority_)
|
||||
|
||||
@@ -211,6 +211,15 @@ GdbEngine::GdbEngine()
|
||||
connect(action(UseDynamicType), &SavedAction::valueChanged,
|
||||
this, &GdbEngine::reloadLocals);
|
||||
|
||||
connect(&m_gdbProc, &QProcess::errorOccurred,
|
||||
this, &GdbEngine::handleGdbError);
|
||||
connect(&m_gdbProc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, &GdbEngine::handleGdbFinished);
|
||||
connect(&m_gdbProc, &QtcProcess::readyReadStandardOutput,
|
||||
this, &GdbEngine::readGdbStandardOutput);
|
||||
connect(&m_gdbProc, &QtcProcess::readyReadStandardError,
|
||||
this, &GdbEngine::readGdbStandardError);
|
||||
|
||||
// Output
|
||||
connect(&m_outputCollector, &OutputCollector::byteDelivery,
|
||||
this, &GdbEngine::readDebuggeeOutput);
|
||||
@@ -3745,7 +3754,6 @@ void GdbEngine::setupEngine()
|
||||
foreach (int test, m_testCases)
|
||||
showMessage("ENABLING TEST CASE: " + QString::number(test));
|
||||
|
||||
m_gdbProc.disconnect(); // From any previous runs
|
||||
m_expectTerminalTrap = terminal();
|
||||
|
||||
const DebuggerRunParameters &rp = runParameters();
|
||||
@@ -3762,12 +3770,6 @@ void GdbEngine::setupEngine()
|
||||
if (!boolSetting(LoadGdbInit))
|
||||
gdbArgs << "-n";
|
||||
|
||||
connect(&m_gdbProc, &QProcess::errorOccurred, this, &GdbEngine::handleGdbError);
|
||||
connect(&m_gdbProc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, &GdbEngine::handleGdbFinished);
|
||||
connect(&m_gdbProc, &QtcProcess::readyReadStandardOutput, this, &GdbEngine::readGdbStandardOutput);
|
||||
connect(&m_gdbProc, &QtcProcess::readyReadStandardError, this, &GdbEngine::readGdbStandardError);
|
||||
|
||||
showMessage("STARTING " + rp.debugger.executable + " " + gdbArgs.join(' '));
|
||||
m_gdbProc.setCommand(rp.debugger.executable, QtcProcess::joinArgs(gdbArgs));
|
||||
if (QFileInfo(rp.debugger.workingDirectory).isDir())
|
||||
|
||||
@@ -95,6 +95,18 @@ LldbEngine::LldbEngine()
|
||||
this, &LldbEngine::updateLocals);
|
||||
connect(action(IntelFlavor), &SavedAction::valueChanged,
|
||||
this, &LldbEngine::updateAll);
|
||||
|
||||
connect(&m_lldbProc, &QProcess::errorOccurred,
|
||||
this, &LldbEngine::handleLldbError);
|
||||
connect(&m_lldbProc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, &LldbEngine::handleLldbFinished);
|
||||
connect(&m_lldbProc, &QProcess::readyReadStandardOutput,
|
||||
this, &LldbEngine::readLldbStandardOutput);
|
||||
connect(&m_lldbProc, &QProcess::readyReadStandardError,
|
||||
this, &LldbEngine::readLldbStandardError);
|
||||
|
||||
connect(this, &LldbEngine::outputReady,
|
||||
this, &LldbEngine::handleResponse, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
LldbEngine::~LldbEngine()
|
||||
@@ -166,22 +178,8 @@ void LldbEngine::abortDebuggerProcess()
|
||||
void LldbEngine::setupEngine()
|
||||
{
|
||||
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
|
||||
startLldb();
|
||||
}
|
||||
|
||||
void LldbEngine::startLldb()
|
||||
{
|
||||
QString lldbCmd = runParameters().debugger.executable;
|
||||
connect(&m_lldbProc, &QProcess::errorOccurred, this, &LldbEngine::handleLldbError);
|
||||
connect(&m_lldbProc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, &LldbEngine::handleLldbFinished);
|
||||
connect(&m_lldbProc, &QProcess::readyReadStandardOutput,
|
||||
this, &LldbEngine::readLldbStandardOutput);
|
||||
connect(&m_lldbProc, &QProcess::readyReadStandardError,
|
||||
this, &LldbEngine::readLldbStandardError);
|
||||
|
||||
connect(this, &LldbEngine::outputReady,
|
||||
this, &LldbEngine::handleResponse, Qt::QueuedConnection);
|
||||
|
||||
showMessage("STARTING LLDB: " + lldbCmd);
|
||||
m_lldbProc.setEnvironment(runParameters().debugger.environment);
|
||||
|
||||
@@ -72,7 +72,6 @@ private:
|
||||
void executeNextI() override;
|
||||
|
||||
void setupEngine() override;
|
||||
void startLldb();
|
||||
void startLldbStage2();
|
||||
void setupInferior() override;
|
||||
void runEngine() override;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
@@ -47,11 +47,16 @@
|
||||
#include <QFileInfo>
|
||||
#include <QFormLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QLoggingCategory>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
namespace {
|
||||
Q_LOGGING_CATEGORY(gccLog, "qtc.pe.toolchain.gcc");
|
||||
} // namespace
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace ProjectExplorer {
|
||||
@@ -70,102 +75,6 @@ static const char originalTargetTripleKeyC[] = "ProjectExplorer.GccToolChain.Ori
|
||||
static const char supportedAbisKeyC[] = "ProjectExplorer.GccToolChain.SupportedAbis";
|
||||
static const char binaryRegexp[] = "(?:^|-|\\b)(?:gcc|g\\+\\+)(?:-([\\d.]+))?$";
|
||||
|
||||
static const int CACHE_SIZE = 16;
|
||||
|
||||
HeaderPathsCache::HeaderPathsCache(const HeaderPathsCache &other)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_cache = other.cache();
|
||||
}
|
||||
|
||||
void HeaderPathsCache::insert(const QStringList &compilerCommand,
|
||||
const QList<HeaderPath> &headerPaths)
|
||||
{
|
||||
CacheItem runResults;
|
||||
runResults.first = compilerCommand;
|
||||
runResults.second = headerPaths;
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
bool cacheHit = false;
|
||||
check(compilerCommand, &cacheHit);
|
||||
if (!cacheHit) {
|
||||
m_cache.push_back(runResults);
|
||||
if (m_cache.size() > CACHE_SIZE)
|
||||
m_cache.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
QList<HeaderPath> HeaderPathsCache::check(const QStringList &compilerCommand,
|
||||
bool *cacheHit) const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it) {
|
||||
if (it->first == compilerCommand) {
|
||||
// Increase cached item priority
|
||||
CacheItem pair = *it;
|
||||
m_cache.erase(it);
|
||||
m_cache.push_back(pair);
|
||||
|
||||
*cacheHit = true;
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
*cacheHit = false;
|
||||
return QList<HeaderPath>();
|
||||
}
|
||||
|
||||
HeaderPathsCache::Cache HeaderPathsCache::cache() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
MacroCache::MacroCache() : m_mutex(QMutex::Recursive)
|
||||
{
|
||||
m_cache.reserve(CACHE_SIZE + 1);
|
||||
}
|
||||
|
||||
MacroCache::MacroCache(const MacroCache &other)
|
||||
: MacroCache()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_cache = other.cache();
|
||||
}
|
||||
|
||||
void MacroCache::insert(const QStringList &compilerCommand, const Macros ¯os)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (macros.isEmpty() || unlockedCheck(compilerCommand).isEmpty())
|
||||
return;
|
||||
|
||||
m_cache.push_back(qMakePair(compilerCommand, macros));
|
||||
if (m_cache.size() > CACHE_SIZE)
|
||||
m_cache.pop_front();
|
||||
}
|
||||
|
||||
Macros MacroCache::check(const QStringList &compilerCommand) const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return unlockedCheck(compilerCommand);
|
||||
}
|
||||
|
||||
MacroCache::Cache MacroCache::cache() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
Macros MacroCache::unlockedCheck(const QStringList &compilerCommand) const
|
||||
{
|
||||
auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) {
|
||||
return ci.first == compilerCommand;
|
||||
});
|
||||
if (it != m_cache.end())
|
||||
return it->second;
|
||||
return {};
|
||||
}
|
||||
|
||||
static QByteArray runGcc(const FileName &gcc, const QStringList &arguments, const QStringList &env)
|
||||
{
|
||||
if (gcc.isEmpty() || !gcc.toFileInfo().isExecutable())
|
||||
@@ -187,11 +96,16 @@ static QByteArray runGcc(const FileName &gcc, const QStringList &arguments, cons
|
||||
return response.allOutput().toUtf8();
|
||||
}
|
||||
|
||||
static const QStringList languageOption(Core::Id languageId)
|
||||
{
|
||||
if (languageId == Constants::C_LANGUAGE_ID)
|
||||
return {"-x", "c"};
|
||||
return {"-x", "c++"};
|
||||
}
|
||||
|
||||
static const QStringList gccPredefinedMacrosOptions(Core::Id languageId)
|
||||
{
|
||||
const QString langOption = languageId == Constants::CXX_LANGUAGE_ID
|
||||
? QLatin1String("-xc++") : QLatin1String("-xc");
|
||||
return QStringList({langOption, "-E", "-dM"});
|
||||
return languageOption(languageId) + QStringList({"-E", "-dM"});
|
||||
}
|
||||
|
||||
static ProjectExplorer::Macros gccPredefinedMacros(const FileName &gcc,
|
||||
@@ -251,7 +165,8 @@ QList<HeaderPath> GccToolChain::gccHeaderPaths(const FileName &gcc, const QStrin
|
||||
thisHeaderKind = HeaderPath::FrameworkHeaderPath;
|
||||
}
|
||||
|
||||
systemHeaderPaths.append(HeaderPath(QFile::decodeName(line), thisHeaderKind));
|
||||
const QString headerPath = QFileInfo(QFile::decodeName(line)).canonicalFilePath();
|
||||
systemHeaderPaths.append(HeaderPath(headerPath, thisHeaderKind));
|
||||
} else if (line.startsWith("End of search list.")) {
|
||||
break;
|
||||
} else {
|
||||
@@ -325,11 +240,13 @@ static QString gccVersion(const FileName &path, const QStringList &env)
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
GccToolChain::GccToolChain(Detection d) :
|
||||
ToolChain(Constants::GCC_TOOLCHAIN_TYPEID, d)
|
||||
GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID, d)
|
||||
{ }
|
||||
|
||||
GccToolChain::GccToolChain(Core::Id typeId, Detection d) :
|
||||
ToolChain(typeId, d)
|
||||
ToolChain(typeId, d),
|
||||
m_predefinedMacrosCache(std::make_shared<Cache<QVector<Macro>>>()),
|
||||
m_headerPathsCache(std::make_shared<Cache<QList<HeaderPath>>>())
|
||||
{ }
|
||||
|
||||
void GccToolChain::setCompilerCommand(const FileName &path)
|
||||
@@ -468,24 +385,24 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
|
||||
const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
|
||||
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
|
||||
QTC_CHECK(reinterpretOptions);
|
||||
MacroCache *macroCache = &m_predefinedMacrosCache;
|
||||
std::shared_ptr<Cache<QVector<Macro>>> macroCache = m_predefinedMacrosCache;
|
||||
Core::Id lang = language();
|
||||
|
||||
// This runner must be thread-safe!
|
||||
return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, macroCache, lang]
|
||||
(const QStringList &cxxflags) {
|
||||
QStringList allCxxflags = platformCodeGenFlags + cxxflags; // add only cxxflags is empty?
|
||||
(const QStringList &flags) {
|
||||
QStringList allFlags = platformCodeGenFlags + flags; // add only cxxflags is empty?
|
||||
QStringList arguments = gccPredefinedMacrosOptions(lang);
|
||||
for (int iArg = 0; iArg < allCxxflags.length(); ++iArg) {
|
||||
const QString &a = allCxxflags.at(iArg);
|
||||
for (int iArg = 0; iArg < allFlags.length(); ++iArg) {
|
||||
const QString &a = allFlags.at(iArg);
|
||||
if (a.startsWith("--gcc-toolchain=")) {
|
||||
arguments << a;
|
||||
} else if (a == "-arch") {
|
||||
if (++iArg < allCxxflags.length() && !arguments.contains(a))
|
||||
arguments << a << allCxxflags.at(iArg);
|
||||
if (++iArg < allFlags.length() && !arguments.contains(a))
|
||||
arguments << a << allFlags.at(iArg);
|
||||
} else if (a == "--sysroot" || a == "-isysroot" || a == "-D" ||a == "-U") {
|
||||
if (++iArg < allCxxflags.length())
|
||||
arguments << a << allCxxflags.at(iArg);
|
||||
if (++iArg < allFlags.length())
|
||||
arguments << a << allFlags.at(iArg);
|
||||
} else if (a == "-m128bit-long-double" || a == "-m32" || a == "-m3dnow" || a == "-m3dnowa"
|
||||
|| a == "-m64" || a == "-m96bit-long-double" || a == "-mabm" || a == "-maes"
|
||||
|| a.startsWith("-march=") || a == "-mavx" || a.startsWith("-masm=")
|
||||
@@ -508,15 +425,24 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
|
||||
}
|
||||
|
||||
arguments = reinterpretOptions(arguments);
|
||||
Macros macros = macroCache->check(arguments);
|
||||
if (!macros.isEmpty())
|
||||
return macros;
|
||||
const Utils::optional<QVector<Macro>> cachedMacros = macroCache->check(arguments);
|
||||
if (cachedMacros)
|
||||
return cachedMacros.value();
|
||||
|
||||
macros = gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
|
||||
const QVector<Macro> macros
|
||||
= gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
|
||||
arguments,
|
||||
env.toStringList());
|
||||
macroCache->insert(arguments, macros);
|
||||
|
||||
qCDebug(gccLog) << "Reporting macros to code model:";
|
||||
for (const Macro &m : macros) {
|
||||
qCDebug(gccLog) << compilerCommand.toUserOutput()
|
||||
<< (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
|
||||
<< arguments.join(", ") << "]"
|
||||
<< QString::fromUtf8(m.toByteArray());
|
||||
}
|
||||
|
||||
return macros;
|
||||
};
|
||||
}
|
||||
@@ -656,21 +582,22 @@ ToolChain::SystemHeaderPathsRunner GccToolChain::createSystemHeaderPathsRunner()
|
||||
const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
|
||||
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
|
||||
QTC_CHECK(reinterpretOptions);
|
||||
HeaderPathsCache *headerCache = &m_headerPathsCache;
|
||||
std::shared_ptr<Cache<QList<HeaderPath>>> headerCache = m_headerPathsCache;
|
||||
Core::Id languageId = language();
|
||||
|
||||
// This runner must be thread-safe!
|
||||
return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, headerCache]
|
||||
(const QStringList &cxxflags, const QString &sysRoot) {
|
||||
return [env, compilerCommand, platformCodeGenFlags, reinterpretOptions, headerCache, languageId]
|
||||
(const QStringList &flags, const QString &sysRoot) {
|
||||
// Prepare arguments
|
||||
QStringList arguments;
|
||||
const bool hasKitSysroot = !sysRoot.isEmpty();
|
||||
if (hasKitSysroot)
|
||||
arguments.append(QString::fromLatin1("--sysroot=%1").arg(sysRoot));
|
||||
|
||||
QStringList flags;
|
||||
flags << platformCodeGenFlags << cxxflags;
|
||||
for (int i = 0; i < flags.size(); ++i) {
|
||||
const QString &flag = flags.at(i);
|
||||
QStringList allFlags;
|
||||
allFlags << platformCodeGenFlags << flags;
|
||||
for (int i = 0; i < allFlags.size(); ++i) {
|
||||
const QString &flag = allFlags.at(i);
|
||||
if (flag.startsWith("-stdlib=") || flag.startsWith("--gcctoolchain=")) {
|
||||
arguments << flag;
|
||||
} else if (!hasKitSysroot) {
|
||||
@@ -679,33 +606,40 @@ ToolChain::SystemHeaderPathsRunner GccToolChain::createSystemHeaderPathsRunner()
|
||||
arguments << flag;
|
||||
} else if ((flag.startsWith("-isysroot") || flag.startsWith("--sysroot"))
|
||||
&& i < flags.size() - 1) {
|
||||
arguments << flag << flags.at(i + 1);
|
||||
arguments << flag << allFlags.at(i + 1);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arguments << "-xc++" << "-E" << "-v" << "-";
|
||||
arguments << languageOption(languageId) << "-E" << "-v" << "-";
|
||||
arguments = reinterpretOptions(arguments);
|
||||
|
||||
bool cacheHit = false;
|
||||
QList<HeaderPath> paths = headerCache->check(arguments, &cacheHit);
|
||||
if (cacheHit)
|
||||
return paths;
|
||||
const Utils::optional<QList<HeaderPath>> cachedPaths = headerCache->check(arguments);
|
||||
if (cachedPaths)
|
||||
return cachedPaths.value();
|
||||
|
||||
paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env),
|
||||
const QList<HeaderPath> paths = gccHeaderPaths(findLocalCompiler(compilerCommand, env),
|
||||
arguments,
|
||||
env.toStringList());
|
||||
headerCache->insert(arguments, paths);
|
||||
|
||||
qCDebug(gccLog) << "Reporting header paths to code model:";
|
||||
for (const HeaderPath &hp : paths) {
|
||||
qCDebug(gccLog) << compilerCommand.toUserOutput()
|
||||
<< (languageId == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
|
||||
<< arguments.join(", ") << "]"
|
||||
<< hp.path();
|
||||
}
|
||||
|
||||
return paths;
|
||||
};
|
||||
}
|
||||
|
||||
QList<HeaderPath> GccToolChain::systemHeaderPaths(const QStringList &cxxflags,
|
||||
QList<HeaderPath> GccToolChain::systemHeaderPaths(const QStringList &flags,
|
||||
const FileName &sysRoot) const
|
||||
{
|
||||
return createSystemHeaderPathsRunner()(cxxflags, sysRoot.toString());
|
||||
return createSystemHeaderPathsRunner()(flags, sysRoot.toString());
|
||||
}
|
||||
|
||||
void GccToolChain::addCommandPathToEnvironment(const FileName &command, Environment &env)
|
||||
@@ -1100,7 +1034,7 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const FileName &comp
|
||||
return result;
|
||||
|
||||
tc->setLanguage(language);
|
||||
tc->m_predefinedMacrosCache.insert(QStringList(), macros);
|
||||
tc->m_predefinedMacrosCache->insert(QStringList(), macros);
|
||||
tc->setCompilerCommand(compilerPath);
|
||||
tc->setSupportedAbis(detectedAbis.supportedAbis);
|
||||
tc->setTargetAbi(abi);
|
||||
@@ -1165,7 +1099,7 @@ void GccToolChainConfigWidget::applyImpl()
|
||||
tc->setDisplayName(displayName); // reset display name
|
||||
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));
|
||||
tc->setPlatformLinkerFlags(splitString(m_platformLinkerFlagsLineEdit->text()));
|
||||
tc->m_predefinedMacrosCache.insert(tc->platformCodeGenFlags(), m_macros);
|
||||
tc->m_predefinedMacrosCache->insert(tc->platformCodeGenFlags(), m_macros);
|
||||
}
|
||||
|
||||
void GccToolChainConfigWidget::setFromToolchain()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
@@ -32,10 +32,13 @@
|
||||
#include "headerpath.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <QMutex>
|
||||
#include <QStringList>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
@@ -51,42 +54,71 @@ class LinuxIccToolChainFactory;
|
||||
// GccToolChain
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
class HeaderPathsCache
|
||||
template<class T, int Size = 16>
|
||||
class Cache
|
||||
{
|
||||
public:
|
||||
HeaderPathsCache() : m_mutex(QMutex::Recursive) {}
|
||||
HeaderPathsCache(const HeaderPathsCache &other);
|
||||
void insert(const QStringList &compilerCommand, const QList<HeaderPath> &headerPaths);
|
||||
QList<HeaderPath> check(const QStringList &compilerCommand, bool *cacheHit) const;
|
||||
Cache() { m_cache.reserve(Size); }
|
||||
Cache(const Cache &other) = delete;
|
||||
Cache &operator =(const Cache &other) = delete;
|
||||
|
||||
protected:
|
||||
using CacheItem = QPair<QStringList, QList<HeaderPath>>;
|
||||
using Cache = QList<CacheItem>;
|
||||
Cache cache() const;
|
||||
|
||||
private:
|
||||
mutable QMutex m_mutex;
|
||||
mutable Cache m_cache;
|
||||
};
|
||||
|
||||
class MacroCache
|
||||
Cache(Cache &&other)
|
||||
{
|
||||
public:
|
||||
MacroCache();
|
||||
MacroCache(const MacroCache &other);
|
||||
void insert(const QStringList &compilerCommand, const Macros ¯os);
|
||||
Macros check(const QStringList &compilerCommand) const;
|
||||
using std::swap;
|
||||
|
||||
protected:
|
||||
using CacheItem = QPair<QStringList, Macros>;
|
||||
using Cache = QVector<CacheItem>;
|
||||
Cache cache() const;
|
||||
QMutexLocker otherLocker(&other.m_mutex);
|
||||
swap(m_cache, other.m_cache);
|
||||
}
|
||||
|
||||
Cache &operator =(Cache &&other)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QMutexLocker otherLocker(&other.m_mutex);
|
||||
auto temporay(std::move(other.m_cache)); // Make sure other.m_cache is empty!
|
||||
swap(m_cache, temporay);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void insert(const QStringList &compilerArguments, const T &values)
|
||||
{
|
||||
CacheItem runResults;
|
||||
runResults.first = compilerArguments;
|
||||
runResults.second = values;
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (!checkImpl(compilerArguments)) {
|
||||
if (m_cache.size() < Size) {
|
||||
m_cache.push_back(runResults);
|
||||
} else {
|
||||
std::rotate(m_cache.begin(), std::next(m_cache.begin()), m_cache.end());
|
||||
m_cache.back() = runResults;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Utils::optional<T> check(const QStringList &compilerArguments)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return checkImpl(compilerArguments);
|
||||
}
|
||||
|
||||
private:
|
||||
// Does not lock!
|
||||
Macros unlockedCheck(const QStringList &compilerCommand) const;
|
||||
mutable QMutex m_mutex;
|
||||
mutable Cache m_cache;
|
||||
Utils::optional<T> checkImpl(const QStringList &compilerArguments)
|
||||
{
|
||||
auto it = std::stable_partition(m_cache.begin(), m_cache.end(), [&](const CacheItem &ci) {
|
||||
return ci.first != compilerArguments;
|
||||
});
|
||||
if (it != m_cache.end())
|
||||
return m_cache.back().second;
|
||||
return {};
|
||||
}
|
||||
|
||||
using CacheItem = QPair<QStringList, T>;
|
||||
|
||||
QMutex m_mutex;
|
||||
QVector<CacheItem> m_cache;
|
||||
};
|
||||
|
||||
class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain
|
||||
@@ -109,7 +141,7 @@ public:
|
||||
Macros predefinedMacros(const QStringList &cxxflags) const override;
|
||||
|
||||
SystemHeaderPathsRunner createSystemHeaderPathsRunner() const override;
|
||||
QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags,
|
||||
QList<HeaderPath> systemHeaderPaths(const QStringList &flags,
|
||||
const Utils::FileName &sysRoot) const override;
|
||||
|
||||
void addToEnvironment(Utils::Environment &env) const override;
|
||||
@@ -203,8 +235,8 @@ private:
|
||||
mutable QList<HeaderPath> m_headerPaths;
|
||||
mutable QString m_version;
|
||||
|
||||
mutable MacroCache m_predefinedMacrosCache;
|
||||
mutable HeaderPathsCache m_headerPathsCache;
|
||||
mutable std::shared_ptr<Cache<QVector<Macro>>> m_predefinedMacrosCache;
|
||||
mutable std::shared_ptr<Cache<QList<HeaderPath>>> m_headerPathsCache;
|
||||
|
||||
friend class Internal::GccToolChainConfigWidget;
|
||||
friend class Internal::GccToolChainFactory;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/temporarydirectory.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
@@ -145,6 +146,33 @@ QDebug operator<<(QDebug d, const VisualStudioInstallation &i)
|
||||
return d;
|
||||
}
|
||||
|
||||
// Detect build tools introduced with MSVC2017
|
||||
static Utils::optional<VisualStudioInstallation> detectCppBuildTools2017()
|
||||
{
|
||||
#ifdef Q_OS_WIN64
|
||||
const char programFilesC[] = "ProgramFiles(x86)";
|
||||
#else
|
||||
const char programFilesC[] = "ProgramFiles";
|
||||
#endif
|
||||
|
||||
const QString installPath = QDir::fromNativeSeparators(QFile::decodeName(qgetenv(programFilesC)))
|
||||
+ "/Microsoft Visual Studio/2017/BuildTools";
|
||||
const QString vcVarsPath = installPath + "/VC/Auxiliary/Build";
|
||||
const QString vcVarsAllPath = vcVarsPath + "/vcvarsall.bat";
|
||||
|
||||
if (!QFileInfo::exists(vcVarsAllPath))
|
||||
return Utils::nullopt;
|
||||
|
||||
VisualStudioInstallation installation;
|
||||
installation.path = installPath;
|
||||
installation.vcVarsAll = vcVarsAllPath;
|
||||
installation.vcVarsPath = vcVarsPath;
|
||||
installation.version = QVersionNumber(15);
|
||||
installation.vsName = "15.0";
|
||||
|
||||
return installation;
|
||||
}
|
||||
|
||||
static QVector<VisualStudioInstallation> detectVisualStudio()
|
||||
{
|
||||
QVector<VisualStudioInstallation> result;
|
||||
@@ -185,6 +213,12 @@ static QVector<VisualStudioInstallation> detectVisualStudio()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Detect VS 2017 Build Tools
|
||||
auto installation = detectCppBuildTools2017();
|
||||
if (installation)
|
||||
result.append(*installation);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -836,7 +870,7 @@ static QList<ToolChain *> findOrCreateToolChain(
|
||||
}
|
||||
|
||||
// Detect build tools introduced with MSVC2015
|
||||
static void detectCppBuildTools(QList<ToolChain *> *list)
|
||||
static void detectCppBuildTools2015(QList<ToolChain *> *list)
|
||||
{
|
||||
struct Entry {
|
||||
const char *postFix;
|
||||
@@ -989,7 +1023,7 @@ QList<ToolChain *> MsvcToolChainFactory::autoDetect(const QList<ToolChain *> &al
|
||||
}
|
||||
}
|
||||
|
||||
detectCppBuildTools(&results);
|
||||
detectCppBuildTools2015(&results);
|
||||
|
||||
detectClangClToolChain(&results);
|
||||
|
||||
|
||||
@@ -562,7 +562,7 @@ public:
|
||||
|
||||
RunWorker *q;
|
||||
RunWorkerState state = RunWorkerState::Initialized;
|
||||
QPointer<RunControl> runControl;
|
||||
const QPointer<RunControl> runControl;
|
||||
QList<RunWorker *> startDependencies;
|
||||
QList<RunWorker *> stopDependencies;
|
||||
QString id;
|
||||
|
||||
@@ -128,7 +128,8 @@ public:
|
||||
virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0;
|
||||
|
||||
// A SystemHeaderPathsRunner is created in the ui thread and runs in another thread.
|
||||
using SystemHeaderPathsRunner = std::function<QList<HeaderPath>(const QStringList &cxxflags, const QString &sysRoot)>;
|
||||
using SystemHeaderPathsRunner = std::function<QList<HeaderPath>(const QStringList &cxxflags,
|
||||
const QString &sysRoot)>;
|
||||
virtual SystemHeaderPathsRunner createSystemHeaderPathsRunner() const = 0;
|
||||
virtual QList<HeaderPath> systemHeaderPaths(const QStringList &cxxflags,
|
||||
const Utils::FileName &sysRoot) const = 0;
|
||||
|
||||
@@ -263,7 +263,7 @@ void GenericProposalModel::filter(const QString &prefix)
|
||||
const QString lowerPrefix = prefix.toLower();
|
||||
foreach (const auto &item, m_originalItems) {
|
||||
const QString &text = item->text();
|
||||
if (regExp.match(text).hasMatch()) {
|
||||
if (regExp.match(text).capturedStart() == 0) {
|
||||
m_currentItems.append(item);
|
||||
if (text.startsWith(prefix)) {
|
||||
// Direct match
|
||||
|
||||
Submodule src/shared/qbs updated: 19abf216fd...47e4f740ca
@@ -14,6 +14,7 @@ SUBDIRS += \
|
||||
generichighlighter \
|
||||
profilewriter \
|
||||
treeviewfind \
|
||||
toolchaincache \
|
||||
qtcprocess \
|
||||
json \
|
||||
utils \
|
||||
|
||||
@@ -25,6 +25,7 @@ Project {
|
||||
"sdktool/sdktool.qbs",
|
||||
"timeline/timeline.qbs",
|
||||
"treeviewfind/treeviewfind.qbs",
|
||||
"toolchaincache/toolchaincache.qbs",
|
||||
"utils/utils.qbs",
|
||||
"valgrind/valgrind.qbs"
|
||||
].concat(project.additionalAutotests)
|
||||
|
||||
6
tests/auto/toolchaincache/toolchaincache.pro
Normal file
6
tests/auto/toolchaincache/toolchaincache.pro
Normal file
@@ -0,0 +1,6 @@
|
||||
QT -= gui
|
||||
|
||||
include(../qttest.pri)
|
||||
|
||||
SOURCES += \
|
||||
tst_toolchaincache.cpp
|
||||
10
tests/auto/toolchaincache/toolchaincache.qbs
Normal file
10
tests/auto/toolchaincache/toolchaincache.qbs
Normal file
@@ -0,0 +1,10 @@
|
||||
import qbs
|
||||
|
||||
QtcAutotest {
|
||||
name: "ToolChainCache autotest"
|
||||
Depends { name: "ProjectExplorer" }
|
||||
Group {
|
||||
name: "Test sources"
|
||||
files: "tst_toolchaincache.cpp"
|
||||
}
|
||||
}
|
||||
136
tests/auto/toolchaincache/tst_toolchaincache.cpp
Normal file
136
tests/auto/toolchaincache/tst_toolchaincache.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest>
|
||||
|
||||
#include <projectexplorer/gcctoolchain.h>
|
||||
|
||||
//////////////// the actual autotest
|
||||
|
||||
class tst_ToolChainCache : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void insertOne();
|
||||
void insertOneOne();
|
||||
void insertOneTwo();
|
||||
void insertOneTwoThree();
|
||||
void insertOneTwoOneThree();
|
||||
};
|
||||
|
||||
|
||||
void tst_ToolChainCache::insertOne()
|
||||
{
|
||||
const QStringList key1 = {"one"};
|
||||
const QString value1 = "value1";
|
||||
ProjectExplorer::Cache<QString, 2> cache;
|
||||
|
||||
cache.insert(key1, value1);
|
||||
|
||||
QVERIFY(bool(cache.check(key1)));
|
||||
QCOMPARE(cache.check(key1).value(), value1);
|
||||
QVERIFY(!cache.check({"other"}));
|
||||
}
|
||||
|
||||
void tst_ToolChainCache::insertOneOne()
|
||||
{
|
||||
const QStringList key1 = {"one"};
|
||||
const QString value1 = "value1";
|
||||
ProjectExplorer::Cache<QString, 2> cache;
|
||||
|
||||
cache.insert(key1, value1);
|
||||
cache.insert(key1, value1);
|
||||
|
||||
QVERIFY(bool(cache.check(key1)));
|
||||
QCOMPARE(cache.check(key1).value(), value1);
|
||||
QVERIFY(!cache.check({"other"}));
|
||||
}
|
||||
|
||||
void tst_ToolChainCache::insertOneTwo()
|
||||
{
|
||||
const QStringList key1 = {"one"};
|
||||
const QString value1 = "value1";
|
||||
const QStringList key2 = {"two"};
|
||||
const QString value2 = "value2";
|
||||
ProjectExplorer::Cache<QString, 2> cache;
|
||||
|
||||
cache.insert(key1, value1);
|
||||
cache.insert(key2, value2);
|
||||
|
||||
QVERIFY(bool(cache.check(key1)));
|
||||
QCOMPARE(cache.check(key1).value(), value1);
|
||||
QVERIFY(bool(cache.check(key2)));
|
||||
QCOMPARE(cache.check(key2).value(), value2);
|
||||
QVERIFY(!cache.check({"other"}));
|
||||
}
|
||||
|
||||
void tst_ToolChainCache::insertOneTwoThree()
|
||||
{
|
||||
const QStringList key1 = {"one"};
|
||||
const QString value1 = "value1";
|
||||
const QStringList key2 = {"two"};
|
||||
const QString value2 = "value2";
|
||||
const QStringList key3 = {"three"};
|
||||
const QString value3 = "value3";
|
||||
ProjectExplorer::Cache<QString, 2> cache;
|
||||
|
||||
cache.insert(key1, value1);
|
||||
cache.insert(key2, value2);
|
||||
cache.insert(key3, value3);
|
||||
|
||||
QVERIFY(!cache.check(key1)); // key1 was evicted
|
||||
QVERIFY(bool(cache.check(key2)));
|
||||
QCOMPARE(cache.check(key2).value(), value2);
|
||||
QVERIFY(bool(cache.check(key3)));
|
||||
QCOMPARE(cache.check(key3).value(), value3);
|
||||
QVERIFY(!cache.check({"other"}));
|
||||
}
|
||||
|
||||
void tst_ToolChainCache::insertOneTwoOneThree()
|
||||
{
|
||||
const QStringList key1 = {"one"};
|
||||
const QString value1 = "value1";
|
||||
const QStringList key2 = {"two"};
|
||||
const QString value2 = "value2";
|
||||
const QStringList key3 = {"three"};
|
||||
const QString value3 = "value3";
|
||||
ProjectExplorer::Cache<QString, 2> cache;
|
||||
|
||||
cache.insert(key1, value1);
|
||||
cache.insert(key2, value2);
|
||||
cache.insert(key1, value1);
|
||||
cache.insert(key3, value3);
|
||||
|
||||
QVERIFY(bool(cache.check(key1)));
|
||||
QCOMPARE(cache.check(key1).value(), value1);
|
||||
QVERIFY(!cache.check(key2)); // key2 was evicted
|
||||
QVERIFY(bool(cache.check(key3)));
|
||||
QCOMPARE(cache.check(key3).value(), value3);
|
||||
QVERIFY(!cache.check({"other"}));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_ToolChainCache)
|
||||
#include "tst_toolchaincache.moc"
|
||||
@@ -1,7 +1,6 @@
|
||||
import qbs
|
||||
import "../../autotest.qbs" as Autotest
|
||||
|
||||
Autotest {
|
||||
QtcAutotest {
|
||||
name: "CamelHumpMatcher autotest"
|
||||
Depends { name: "Utils" }
|
||||
files: "tst_camelhumpmatcher.cpp"
|
||||
|
||||
@@ -136,12 +136,14 @@ void tst_CamelHumpMatcher::highlighting_data()
|
||||
<< MatchStart{13} << MatchLength{1};
|
||||
QTest::newRow("humps-continued") << "LoCa" << "VeryLongCamelHump"
|
||||
<< MatchStart{4, 8} << MatchLength{2, 2};
|
||||
QTest::newRow("duplicate-match") << "som" << "SomeMatch"
|
||||
<< MatchStart{0} << MatchLength{3};
|
||||
QTest::newRow("numbers") << "4" << "TestJust4Fun"
|
||||
<< MatchStart{8} << MatchLength{1};
|
||||
QTest::newRow("wildcard-asterisk") << "Lo*Hu" << "VeryLongCamelHump"
|
||||
<< MatchStart{4, 13} << MatchLength{2, 2};
|
||||
<< MatchStart{4} << MatchLength{11};
|
||||
QTest::newRow("wildcard-question") << "Lo?g" << "VeryLongCamelHump"
|
||||
<< MatchStart{4, 7} << MatchLength{2, 1};
|
||||
<< MatchStart{4} << MatchLength{4};
|
||||
QTest::newRow("middle-no-hump") << "window" << "mainwindow.cpp"
|
||||
<< MatchStart{4} << MatchLength{6};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ Project {
|
||||
references: [
|
||||
"fileutils/fileutils.qbs",
|
||||
"ansiescapecodehandler/ansiescapecodehandler.qbs",
|
||||
"camelhumpmatcher/camelhumpmatcher.qbs",
|
||||
"stringutils/stringutils.qbs",
|
||||
"objectpool/objectpool.qbs",
|
||||
"templateengine/templateengine.qbs",
|
||||
|
||||
Reference in New Issue
Block a user