aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qbs/modules/libclang/functions.js5
-rw-r--r--qbs/modules/libclang/libclang.qbs3
-rw-r--r--src/plugins/clangcodemodel/clangcodemodel.qbs1
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager.qbs1
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring.qbs1
-rw-r--r--src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp69
-rw-r--r--src/plugins/clangtools/clangstaticanalyzerconfigwidget.h3
-rw-r--r--src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui31
-rw-r--r--src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp6
-rw-r--r--src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp1
-rw-r--r--src/plugins/clangtools/clangtoolruncontrol.cpp64
-rw-r--r--src/plugins/clangtools/clangtools.pro2
-rw-r--r--src/plugins/clangtools/clangtools.qbs14
-rw-r--r--src/plugins/clangtools/clangtoolssettings.cpp51
-rw-r--r--src/plugins/clangtools/clangtoolssettings.h10
-rw-r--r--src/plugins/clangtools/clangtoolsunittests.cpp5
-rw-r--r--src/plugins/clangtools/clangtoolsutils.cpp106
-rw-r--r--src/plugins/clangtools/clangtoolsutils.h29
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp17
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.h6
-rw-r--r--src/shared/clang/clang_defines.pri2
21 files changed, 87 insertions, 340 deletions
diff --git a/qbs/modules/libclang/functions.js b/qbs/modules/libclang/functions.js
index 7d5e4149fca..192473391ae 100644
--- a/qbs/modules/libclang/functions.js
+++ b/qbs/modules/libclang/functions.js
@@ -74,6 +74,11 @@ function libDir(llvmConfig)
return FileInfo.fromNativeSeparators(readOutput(llvmConfig, ["--libdir"]));
}
+function binDir(llvmConfig)
+{
+ return FileInfo.fromNativeSeparators(readOutput(llvmConfig, ["--bindir"]));
+}
+
function version(llvmConfig)
{
return readOutput(llvmConfig, ["--version"]).replace(/(\d+\.\d+\.\d+).*/, "$1")
diff --git a/qbs/modules/libclang/libclang.qbs b/qbs/modules/libclang/libclang.qbs
index 3b68faa0bb7..eeb233f12a9 100644
--- a/qbs/modules/libclang/libclang.qbs
+++ b/qbs/modules/libclang/libclang.qbs
@@ -16,6 +16,7 @@ Module {
property string llvmVersion
property string llvmIncludeDir
property string llvmLibDir
+ property string llvmBinDir
property stringList llvmLibs
property stringList llvmToolingLibs
property stringList llvmToolingDefines
@@ -28,6 +29,7 @@ Module {
llvmVersion = ClangFunctions.version(llvmConfig);
llvmIncludeDir = ClangFunctions.includeDir(llvmConfig);
llvmLibDir = ClangFunctions.libDir(llvmConfig);
+ llvmBinDir = ClangFunctions.binDir(llvmConfig);
llvmLibs = ClangFunctions.libraries(targetOS);
llvmToolingLibs = ClangFunctions.toolingLibs(llvmConfig, targetOS);
llvmBuildMode = ClangFunctions.buildMode(llvmConfig);
@@ -43,6 +45,7 @@ Module {
property string llvmVersion: clangProbe.llvmVersion
property string llvmIncludeDir: clangProbe.llvmIncludeDir
property string llvmLibDir: clangProbe.llvmLibDir
+ property string llvmBinDir: clangProbe.llvmBinDir
property stringList llvmLibs: clangProbe.llvmLibs
property stringList llvmToolingLibs: clangProbe.llvmToolingLibs
property string llvmBuildMode: clangProbe.llvmBuildMode
diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs
index 8950c6ed9b2..ce1cba0e1fa 100644
--- a/src/plugins/clangcodemodel/clangcodemodel.qbs
+++ b/src/plugins/clangcodemodel/clangcodemodel.qbs
@@ -27,6 +27,7 @@ QtcPlugin {
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
"include");
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
+ defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
return defines;
}
diff --git a/src/plugins/clangpchmanager/clangpchmanager.qbs b/src/plugins/clangpchmanager/clangpchmanager.qbs
index b8ade5b6ce1..8e7c5447a6c 100644
--- a/src/plugins/clangpchmanager/clangpchmanager.qbs
+++ b/src/plugins/clangpchmanager/clangpchmanager.qbs
@@ -23,6 +23,7 @@ QtcPlugin {
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
"include");
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
+ defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
return defines;
}
diff --git a/src/plugins/clangrefactoring/clangrefactoring.qbs b/src/plugins/clangrefactoring/clangrefactoring.qbs
index d76bca9f489..9778e1a3d04 100644
--- a/src/plugins/clangrefactoring/clangrefactoring.qbs
+++ b/src/plugins/clangrefactoring/clangrefactoring.qbs
@@ -25,6 +25,7 @@ QtcPlugin {
var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
"include");
defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
+ defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
return defines;
}
diff --git a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp
index 812984cafcf..9058774f596 100644
--- a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp
+++ b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.cpp
@@ -43,50 +43,7 @@ ClangStaticAnalyzerConfigWidget::ClangStaticAnalyzerConfigWidget(
{
m_ui->setupUi(this);
- Utils::PathChooser * const chooser = m_ui->clangExecutableChooser;
- chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
- chooser->setHistoryCompleter(QLatin1String("ClangStaticAnalyzer.ClangCommand.History"));
- chooser->setPromptDialogTitle(tr("Clang Command"));
- const auto validator = [chooser, this](Utils::FancyLineEdit *edit, QString *errorMessage) {
- const QString currentFilePath = chooser->fileName().toString();
- Utils::PathChooser pc;
- Utils::PathChooser *helperPathChooser;
- if (currentFilePath.isEmpty()) {
- pc.setExpectedKind(chooser->expectedKind());
- pc.setPath(edit->placeholderText());
- helperPathChooser = &pc;
- } else {
- helperPathChooser = chooser;
- }
-
- const bool isExecutableValid =
- chooser->defaultValidationFunction()(helperPathChooser->lineEdit(), errorMessage)
- && isClangExecutableUsable(helperPathChooser->fileName().toString(), errorMessage);
-
- const ClangExecutableVersion detectedVersion = isExecutableValid
- ? clangExecutableVersion(helperPathChooser->fileName().toString())
- : ClangExecutableVersion();
- updateDetectedVersionLabel(isExecutableValid, detectedVersion);
-
- return isExecutableValid;
- };
- chooser->setValidationFunction(validator);
- bool clangExeIsSet;
- const QString clangExe = settings->clangExecutable(&clangExeIsSet);
- chooser->lineEdit()->setPlaceholderText(QDir::toNativeSeparators(
- settings->defaultClangExecutable()));
- if (clangExeIsSet) {
- chooser->setPath(clangExe);
- } else {
- // Setting an empty string does not trigger the validator, as that is the initial value
- // in the line edit.
- chooser->setPath(QLatin1String(" "));
- chooser->lineEdit()->clear();
- }
- connect(m_ui->clangExecutableChooser, &Utils::PathChooser::rawPathChanged,
- [settings](const QString &path) { settings->setClangExecutable(path); });
-
- m_ui->simultaneousProccessesSpinBox->setValue(settings->simultaneousProcesses());
+ m_ui->simultaneousProccessesSpinBox->setValue(settings->savedSimultaneousProcesses());
m_ui->simultaneousProccessesSpinBox->setMinimum(1);
m_ui->simultaneousProccessesSpinBox->setMaximum(QThread::idealThreadCount());
connect(m_ui->simultaneousProccessesSpinBox,
@@ -99,29 +56,5 @@ ClangStaticAnalyzerConfigWidget::~ClangStaticAnalyzerConfigWidget()
delete m_ui;
}
-void ClangStaticAnalyzerConfigWidget::updateDetectedVersionLabel(
- bool isExecutableValid,
- const ClangExecutableVersion &providedVersion)
-{
- QLabel &label = *m_ui->detectedVersionLabel;
-
- if (isExecutableValid) {
- if (providedVersion.isValid()) {
- if (providedVersion.isSupportedVersion()) {
- label.setText(tr("Version: %1, supported.")
- .arg(providedVersion.toString()));
- } else {
- label.setText(tr("Version: %1, unsupported (supported version is %2).")
- .arg(providedVersion.toString())
- .arg(ClangExecutableVersion::supportedVersionAsString()));
- }
- } else {
- label.setText(tr("Version: Could not determine version."));
- }
- } else {
- label.setText(tr("Version: Set valid executable first."));
- }
-}
-
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h
index 629fe4d8192..7b23b35d5d0 100644
--- a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h
+++ b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.h
@@ -45,9 +45,6 @@ public:
QWidget *parent = 0);
~ClangStaticAnalyzerConfigWidget();
- void updateDetectedVersionLabel(bool executableIsValid,
- const ClangExecutableVersion &providedVersion);
-
private:
Ui::ClangStaticAnalyzerConfigWidget *m_ui;
ClangToolsSettings *m_settings;
diff --git a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui
index d4cb9c60e8d..69a9d28063b 100644
--- a/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui
+++ b/src/plugins/clangtools/clangstaticanalyzerconfigwidget.ui
@@ -21,34 +21,13 @@
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Clang executable:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="Utils::PathChooser" name="clangExecutableChooser" native="true"/>
- </item>
- </layout>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="detectedVersionLabel">
- <property name="text">
- <string>TextLabel</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Simultaneous processes:</string>
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="simultaneousProccessesSpinBox">
@@ -93,14 +72,6 @@
</item>
</layout>
</widget>
- <customwidgets>
- <customwidget>
- <class>Utils::PathChooser</class>
- <extends>QWidget</extends>
- <header location="global">utils/pathchooser.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp b/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp
index 392608e759c..31d9efb518f 100644
--- a/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp
+++ b/src/plugins/clangtools/clangstaticanalyzerpreconfiguredsessiontests.cpp
@@ -29,6 +29,7 @@
#include "clangstaticanalyzertool.h"
#include "clangtoolsutils.h"
+#include <cpptools/compileroptionsbuilder.h>
#include <cpptools/projectinfo.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
@@ -166,9 +167,8 @@ static QList<Target *> validTargets(Project *project)
const ToolChain * const toolchain = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID);
QTC_ASSERT(toolchain, return false);
- bool hasClangExecutable;
- clangExecutableFromSettings(&hasClangExecutable);
- if (!hasClangExecutable) {
+
+ if (CppTools::clangExecutable(CLANG_BINDIR).isEmpty()) {
qWarning("Project \"%s\": Skipping target \"%s\" since no suitable clang was found for the toolchain.",
qPrintable(projectFileName),
qPrintable(target->displayName()));
diff --git a/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp
index 5684ae875e6..e9585665337 100644
--- a/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp
+++ b/src/plugins/clangtools/clangstaticanalyzerruncontrol.cpp
@@ -147,7 +147,6 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl(RunControl *runCont
ClangToolRunner *ClangStaticAnalyzerRunControl::createRunner()
{
- QTC_ASSERT(!m_clangExecutable.isEmpty(), return 0);
QTC_ASSERT(!m_clangLogFileDir.isEmpty(), return 0);
auto runner = new ClangStaticAnalyzerRunner(m_clangExecutable,
diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp
index 4e0b609dd17..d2e03f48a47 100644
--- a/src/plugins/clangtools/clangtoolruncontrol.cpp
+++ b/src/plugins/clangtools/clangtoolruncontrol.cpp
@@ -145,18 +145,11 @@ static AnalyzeUnits unitsToAnalyzeFromProjectParts(const QVector<ProjectPart::Pt
return unitsToAnalyze;
}
-static QString clangResourceDir(const QString &clangExecutable, const QString &clangVersion)
-{
- QDir llvmDir = QFileInfo(clangExecutable).dir();
- llvmDir.cdUp();
- return llvmDir.absolutePath() + clangIncludePath(clangVersion);
-}
-
AnalyzeUnits ClangToolRunControl::sortedUnitsToAnalyze(const QString &clangVersion)
{
QTC_ASSERT(m_projectInfo.isValid(), return AnalyzeUnits());
- const QString clangResourceDirectory = clangResourceDir(m_clangExecutable, clangVersion);
+ const QString clangResourceDirectory = clangIncludeDirectory(m_clangExecutable, clangVersion);
AnalyzeUnits units = unitsToAnalyzeFromProjectParts(m_projectInfo.projectParts(), clangVersion,
clangResourceDirectory);
@@ -179,7 +172,9 @@ static QDebug operator<<(QDebug debug, const AnalyzeUnits &analyzeUnits)
}
ClangToolRunControl::ClangToolRunControl(RunControl *runControl, Target *target)
- : RunWorker(runControl), m_target(target)
+ : RunWorker(runControl)
+ , m_clangExecutable(CppTools::clangExecutable(CLANG_BINDIR))
+ , m_target(target)
{
}
@@ -208,9 +203,18 @@ void ClangToolRunControl::start()
return;
}
+ const QString &toolName = tool()->name();
+ if (m_clangExecutable.isEmpty()) {
+ const QString errorMessage = tr("%1 : Can't find clang executable, stop.").arg(toolName);
+ appendMessage(errorMessage, Utils::ErrorMessageFormat);
+ TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
+ TaskHub::requestPopup();
+ reportFailure();
+ return;
+ }
+
m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(m_target->project());
- const QString toolName = tool()->name();
// Some projects provides CompilerCallData once a build is finished,
if (m_projectInfo.configurationOrFilesChanged(m_projectInfoBeforeBuild)) {
// If it's more than a release/debug build configuration change, e.g.
@@ -225,42 +229,6 @@ void ClangToolRunControl::start()
appendMessage(tr("Running %1 on %2").arg(toolName).arg(projectFile.toUserOutput()),
Utils::NormalMessageFormat);
- // Check clang executable
- bool isValidClangExecutable;
- const QString executable = clangExecutableFromSettings(&isValidClangExecutable);
- if (!isValidClangExecutable) {
- const QString errorMessage = toolName
- + tr(": Invalid executable \"%1\", stop.").arg(executable);
- appendMessage(errorMessage, Utils::ErrorMessageFormat);
- TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
- TaskHub::requestPopup();
- reportFailure();
- return;
- }
-
- // Check clang version
- const ClangExecutableVersion version = clangExecutableVersion(executable);
- if (!version.isValid()) {
- const QString warningMessage
- = toolName + tr(": Running with possibly unsupported version, "
- "could not determine version from executable \"%1\".")
- .arg(executable);
- appendMessage(warningMessage, Utils::StdErrFormat);
- TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
- TaskHub::requestPopup();
- } else if (!version.isSupportedVersion()) {
- const QString warningMessage
- = toolName + tr(": Running with unsupported version %1, "
- "supported version is %2.")
- .arg(version.toString())
- .arg(ClangExecutableVersion::supportedVersionAsString());
- appendMessage(warningMessage, Utils::StdErrFormat);
- TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
- TaskHub::requestPopup();
- }
-
- m_clangExecutable = executable;
-
// Create log dir
Utils::TemporaryDirectory temporaryDir("qtc-clangtools-XXXXXX");
temporaryDir.setAutoRemove(false);
@@ -276,7 +244,7 @@ void ClangToolRunControl::start()
m_clangLogFileDir = temporaryDir.path();
// Collect files
- const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(version.toString());
+ const AnalyzeUnits unitsToProcess = sortedUnitsToAnalyze(CLANG_VERSION);
qCDebug(LOG) << "Files to process:" << unitsToProcess;
m_unitsToProcess = unitsToProcess;
m_initialFilesToProcessSize = m_unitsToProcess.count();
@@ -298,7 +266,7 @@ void ClangToolRunControl::start()
// Start process(es)
qCDebug(LOG) << "Environment:" << m_environment;
m_runners.clear();
- const int parallelRuns = ClangToolsSettings::instance()->simultaneousProcesses();
+ const int parallelRuns = ClangToolsSettings::instance()->savedSimultaneousProcesses();
QTC_ASSERT(parallelRuns >= 1, reportFailure(); return);
m_success = true;
diff --git a/src/plugins/clangtools/clangtools.pro b/src/plugins/clangtools/clangtools.pro
index 847f4bc9f46..505b01ebbeb 100644
--- a/src/plugins/clangtools/clangtools.pro
+++ b/src/plugins/clangtools/clangtools.pro
@@ -1,6 +1,8 @@
include(../../qtcreatorplugin.pri)
include(../../shared/clang/clang_installation.pri)
+include(../../shared/clang/clang_defines.pri)
+
requires(!isEmpty(LLVM_VERSION))
LIBS += $$LIBCLANG_LIBS
diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs
index 9601b3793b6..0875b052911 100644
--- a/src/plugins/clangtools/clangtools.qbs
+++ b/src/plugins/clangtools/clangtools.qbs
@@ -1,4 +1,5 @@
import qbs
+import qbs.FileInfo
QtcPlugin {
name: "ClangTools"
@@ -26,6 +27,19 @@ QtcPlugin {
cpp.dynamicLibraries: base.concat(libclang.llvmLibs)
cpp.rpaths: base.concat(libclang.llvmLibDir)
+ cpp.defines: {
+ var defines = base;
+ defines.push("CLANGPCHMANAGER_LIB");
+
+ // The following defines are used to determine the clang include path for intrinsics.
+ defines.push('CLANG_VERSION="' + libclang.llvmVersion + '"');
+ var resourceDir = FileInfo.joinPaths(libclang.llvmLibDir, "clang", libclang.llvmVersion,
+ "include");
+ defines.push('CLANG_RESOURCE_DIR="' + resourceDir + '"');
+ defines.push('CLANG_BINDIR="' + libclang.llvmBinDir + '"');
+ return defines;
+ }
+
files: [
"clangstaticanalyzerconfigwidget.cpp",
"clangstaticanalyzerconfigwidget.h",
diff --git a/src/plugins/clangtools/clangtoolssettings.cpp b/src/plugins/clangtools/clangtoolssettings.cpp
index 5c51ed84713..50bad3f82af 100644
--- a/src/plugins/clangtools/clangtoolssettings.cpp
+++ b/src/plugins/clangtools/clangtoolssettings.cpp
@@ -35,14 +35,12 @@
#include <QFileInfo>
#include <QThread>
-static const char clangExecutableKey[] = "clangExecutable";
static const char simultaneousProcessesKey[] = "simultaneousProcesses";
namespace ClangTools {
namespace Internal {
ClangToolsSettings::ClangToolsSettings()
- : m_simultaneousProcesses(-1)
{
readSettings();
}
@@ -53,36 +51,9 @@ ClangToolsSettings *ClangToolsSettings::instance()
return &instance;
}
-static QString clangExecutableFileName()
+int ClangToolsSettings::savedSimultaneousProcesses() const
{
- return QLatin1String("clang" QTC_HOST_EXE_SUFFIX);
-}
-
-QString ClangToolsSettings::defaultClangExecutable() const
-{
- const QString shippedBinary = Core::ICore::libexecPath()
- + QLatin1String("/clang/bin/")
- + clangExecutableFileName();
- if (QFileInfo(shippedBinary).isExecutable())
- return shippedBinary;
- return clangExecutableFileName();
-}
-
-QString ClangToolsSettings::clangExecutable(bool *isSet) const
-{
- if (m_clangExecutable.isEmpty()) {
- if (isSet)
- *isSet = false;
- return defaultClangExecutable();
- }
- if (isSet)
- *isSet = true;
- return m_clangExecutable;
-}
-
-void ClangToolsSettings::setClangExecutable(const QString &exectuable)
-{
- m_clangExecutable = exectuable;
+ return m_savedSimultaneousProcesses;
}
int ClangToolsSettings::simultaneousProcesses() const
@@ -92,7 +63,6 @@ int ClangToolsSettings::simultaneousProcesses() const
void ClangToolsSettings::setSimultaneousProcesses(int processes)
{
- QTC_ASSERT(processes >=1, return);
m_simultaneousProcesses = processes;
}
@@ -101,21 +71,22 @@ void ClangToolsSettings::readSettings()
QSettings *settings = Core::ICore::settings();
settings->beginGroup(QLatin1String(Constants::SETTINGS_ID));
- setClangExecutable(settings->value(QLatin1String(clangExecutableKey)).toString());
-
const int defaultSimultaneousProcesses = qMax(0, QThread::idealThreadCount() / 2);
- setSimultaneousProcesses(settings->value(QLatin1String(simultaneousProcessesKey),
- defaultSimultaneousProcesses).toInt());
+ m_savedSimultaneousProcesses = m_simultaneousProcesses
+ = settings->value(QString(simultaneousProcessesKey),
+ defaultSimultaneousProcesses).toInt();
settings->endGroup();
}
-void ClangToolsSettings::writeSettings() const
+void ClangToolsSettings::writeSettings()
{
QSettings *settings = Core::ICore::settings();
- settings->beginGroup(QLatin1String(Constants::SETTINGS_ID));
- settings->setValue(QLatin1String(clangExecutableKey), m_clangExecutable);
- settings->setValue(QLatin1String(simultaneousProcessesKey), simultaneousProcesses());
+ settings->beginGroup(QString(Constants::SETTINGS_ID));
+ settings->setValue(QString(simultaneousProcessesKey), m_simultaneousProcesses);
+
+ m_savedSimultaneousProcesses = m_simultaneousProcesses;
+
settings->endGroup();
}
diff --git a/src/plugins/clangtools/clangtoolssettings.h b/src/plugins/clangtools/clangtoolssettings.h
index 0739d630ec0..528407fe50b 100644
--- a/src/plugins/clangtools/clangtoolssettings.h
+++ b/src/plugins/clangtools/clangtoolssettings.h
@@ -35,11 +35,9 @@ class ClangToolsSettings
public:
static ClangToolsSettings *instance();
- void writeSettings() const;
+ void writeSettings();
- QString defaultClangExecutable() const;
- QString clangExecutable(bool *isSet = nullptr) const;
- void setClangExecutable(const QString &exectuable);
+ int savedSimultaneousProcesses() const;
int simultaneousProcesses() const;
void setSimultaneousProcesses(int processes);
@@ -48,8 +46,8 @@ private:
ClangToolsSettings();
void readSettings();
- QString m_clangExecutable;
- int m_simultaneousProcesses;
+ int m_simultaneousProcesses = -1;
+ int m_savedSimultaneousProcesses = -1;
};
} // namespace Internal
diff --git a/src/plugins/clangtools/clangtoolsunittests.cpp b/src/plugins/clangtools/clangtoolsunittests.cpp
index b98f9ff8feb..3c31d933700 100644
--- a/src/plugins/clangtools/clangtoolsunittests.cpp
+++ b/src/plugins/clangtools/clangtoolsunittests.cpp
@@ -62,9 +62,8 @@ void ClangToolsUnitTests::initTestCase()
Constants::CXX_LANGUAGE_ID);
if (!toolchain)
QSKIP("This test requires that there is a kit with a toolchain.");
- bool hasClangExecutable;
- clangExecutableFromSettings(&hasClangExecutable);
- if (!hasClangExecutable)
+
+ if (CppTools::clangExecutable(CLANG_BINDIR).isEmpty())
QSKIP("No clang suitable for analyzing found");
m_tmpDir = new CppTools::Tests::TemporaryCopiedDir(QLatin1String(":/unit-tests"));
diff --git a/src/plugins/clangtools/clangtoolsutils.cpp b/src/plugins/clangtools/clangtoolsutils.cpp
index cd43b397371..3e811500ac9 100644
--- a/src/plugins/clangtools/clangtoolsutils.cpp
+++ b/src/plugins/clangtools/clangtoolsutils.cpp
@@ -28,6 +28,8 @@
#include "clangtoolsdiagnostic.h"
#include "clangtoolssettings.h"
+#include <coreplugin/icore.h>
+
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/hostosinfo.h>
@@ -38,118 +40,14 @@
#include <QFileInfo>
#include <QRegularExpression>
-static bool isFileExecutable(const QString &executablePath)
-{
- if (executablePath.isEmpty())
- return false;
-
- const QFileInfo fileInfo(executablePath);
- return fileInfo.isFile() && fileInfo.isExecutable();
-}
-
namespace ClangTools {
namespace Internal {
-QString clangExecutableFromSettings(bool *isValid)
-{
- QString executable = ClangToolsSettings::instance()->clangExecutable();
- if (executable.isEmpty()) {
- *isValid = false;
- return executable;
- }
-
- const QString hostExeSuffix = QLatin1String(QTC_HOST_EXE_SUFFIX);
- const Qt::CaseSensitivity caseSensitivity = Utils::HostOsInfo::fileNameCaseSensitivity();
- const bool hasSuffix = executable.endsWith(hostExeSuffix, caseSensitivity);
-
- const QFileInfo fileInfo = QFileInfo(executable);
- if (fileInfo.isAbsolute()) {
- if (!hasSuffix)
- executable.append(hostExeSuffix);
- } else {
- const Utils::Environment &environment = Utils::Environment::systemEnvironment();
- const QString executableFromPath = environment.searchInPath(executable).toString();
- if (executableFromPath.isEmpty()) {
- *isValid = false;
- return executable;
- }
- executable = executableFromPath;
- }
-
- *isValid = isFileExecutable(executable) && isClangExecutableUsable(executable);
- return executable;
-}
-
QString createFullLocationString(const Debugger::DiagnosticLocation &location)
{
return location.filePath + QLatin1Char(':') + QString::number(location.line)
+ QLatin1Char(':') + QString::number(location.column);
}
-bool isClangExecutableUsable(const QString &filePath, QString *errorMessage)
-{
- const QFileInfo fi(filePath);
- if (fi.isSymLink() && fi.symLinkTarget().contains(QLatin1String("icecc"))) {
- if (errorMessage) {
- *errorMessage = QCoreApplication::translate("ClangTools",
- "The chosen file \"%1\" seems to point to an icecc binary not suitable "
- "for analyzing.\nPlease set a real Clang executable.")
- .arg(filePath);
- }
- return false;
- }
- return true;
-}
-
-ClangExecutableVersion clangExecutableVersion(const QString &executable)
-{
- const ClangExecutableVersion invalidVersion;
-
- // Sanity checks
- const QFileInfo fileInfo(executable);
- const bool isExecutableFile = fileInfo.isFile() && fileInfo.isExecutable();
- if (!isExecutableFile)
- return invalidVersion;
-
- // Get version output
- Utils::Environment environment = Utils::Environment::systemEnvironment();
- Utils::Environment::setupEnglishOutput(&environment);
- Utils::SynchronousProcess runner;
- runner.setEnvironment(environment.toStringList());
- runner.setTimeoutS(10);
- // We would prefer "-dumpversion", but that one is only there for GCC compatibility
- // and returns some static/old version.
- // See also https://bugs.llvm.org/show_bug.cgi?id=28597
- const QStringList arguments(QLatin1String(("--version")));
- const Utils::SynchronousProcessResponse response = runner.runBlocking(executable, arguments);
- if (response.result != Utils::SynchronousProcessResponse::Finished)
- return invalidVersion;
- const QString output = response.stdOut();
-
- // Parse version output
- const QRegularExpression re(QLatin1String("clang version (\\d+)\\.(\\d+)\\.(\\d+)"));
- const QRegularExpressionMatch reMatch = re.match(output);
- if (re.captureCount() != 3)
- return invalidVersion;
-
- const QString majorString = reMatch.captured(1);
- bool convertedSuccessfully = false;
- const int major = majorString.toInt(&convertedSuccessfully);
- if (!convertedSuccessfully)
- return invalidVersion;
-
- const QString minorString = reMatch.captured(2);
- const int minor = minorString.toInt(&convertedSuccessfully);
- if (!convertedSuccessfully)
- return invalidVersion;
-
- const QString patchString = reMatch.captured(3);
- const int patch = patchString.toInt(&convertedSuccessfully);
- if (!convertedSuccessfully)
- return invalidVersion;
-
- return ClangExecutableVersion(major, minor, patch);
-}
-
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolsutils.h b/src/plugins/clangtools/clangtoolsutils.h
index a63c9db3707..6d3a7a90caf 100644
--- a/src/plugins/clangtools/clangtoolsutils.h
+++ b/src/plugins/clangtools/clangtoolsutils.h
@@ -39,36 +39,7 @@ namespace Debugger { class DiagnosticLocation; }
namespace ClangTools {
namespace Internal {
-bool isClangExecutableUsable(const QString &filePath, QString *errorMessage = 0);
-
-QString clangExecutableFromSettings(bool *isValid);
-
QString createFullLocationString(const Debugger::DiagnosticLocation &location);
-// CLANG-UPGRADE-CHECK: Adapt minimum version numbers.
-class ClangExecutableVersion : public QVersionNumber {
-public:
- ClangExecutableVersion() : QVersionNumber(-1, -1, -1) {}
- ClangExecutableVersion(int major, int minor, int micro)
- : QVersionNumber(major, minor, micro) {}
-
- bool isValid() const
- {
- return majorVersion() >= 0 && minorVersion() >= 0 && microVersion() >= 0;
- }
-
- bool isSupportedVersion() const
- {
- return majorVersion() == 5 && minorVersion() == 0;
- }
-
- static QString supportedVersionAsString()
- {
- return QLatin1String("5.0");
- }
-};
-
-ClangExecutableVersion clangExecutableVersion(const QString &absolutePath);
-
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index 93e6ed3c10d..57f937fb18b 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -528,7 +528,7 @@ void CompilerOptionsBuilder::addClangIncludeFolder()
{
QTC_CHECK(!m_clangVersion.isEmpty());
add(SYSTEM_INCLUDE_PREFIX);
- add(clangIncludeDirectory());
+ add(clangIncludeDirectory(m_clangVersion, m_clangResourceDirectory));
}
void CompilerOptionsBuilder::addProjectConfigFileInclude()
@@ -548,14 +548,23 @@ static QString creatorLibexecPath()
#endif
}
-QString CompilerOptionsBuilder::clangIncludeDirectory() const
+QString clangIncludeDirectory(const QString &clangVersion, const QString &clangResourceDirectory)
{
- QDir dir(creatorLibexecPath() + "/clang" + clangIncludePath(m_clangVersion));
+ QDir dir(creatorLibexecPath() + "/clang" + clangIncludePath(clangVersion));
if (!dir.exists() || !QFileInfo(dir, "stdint.h").exists())
- dir = QDir(m_clangResourceDirectory);
+ dir = QDir(clangResourceDirectory);
return QDir::toNativeSeparators(dir.canonicalPath());
}
+QString clangExecutable(const QString &clangBinDirectory)
+{
+ const QString hostExeSuffix(QTC_HOST_EXE_SUFFIX);
+ QDir executable(creatorLibexecPath() + "/clang/bin/clang" + hostExeSuffix);
+ if (!executable.exists())
+ executable = QDir(clangBinDirectory + "/clang" + hostExeSuffix);
+ return QDir::toNativeSeparators(executable.canonicalPath());
+}
+
void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()
{
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h
index 2f860e510bd..87dc46ff26a 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.h
+++ b/src/plugins/cpptools/compileroptionsbuilder.h
@@ -90,7 +90,6 @@ private:
QByteArray macroOption(const ProjectExplorer::Macro &macro) const;
QByteArray toDefineOption(const ProjectExplorer::Macro &macro) const;
QString defineDirectiveToDefineOption(const ProjectExplorer::Macro &marco) const;
- QString clangIncludeDirectory() const;
void addClangIncludeFolder();
QStringList m_options;
@@ -98,6 +97,11 @@ private:
QString m_clangResourceDirectory;
};
+QString CPPTOOLS_EXPORT clangExecutable(const QString &clangBinDirectory);
+
+QString CPPTOOLS_EXPORT clangIncludeDirectory(const QString &clangVersion,
+ const QString &clangResourceDirectory);
+
template<class T>
T clangIncludePath(const T &clangVersion)
{
diff --git a/src/shared/clang/clang_defines.pri b/src/shared/clang/clang_defines.pri
index e1d219989f0..4453c8ba6de 100644
--- a/src/shared/clang/clang_defines.pri
+++ b/src/shared/clang/clang_defines.pri
@@ -1,3 +1,5 @@
DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
CLANG_RESOURCE_DIR=$$clean_path($${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include)
DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${CLANG_RESOURCE_DIR}\\\"\""
+CLANG_BINDIR=$$clean_path($${LLVM_BINDIR})
+DEFINES += "\"CLANG_BINDIR=\\\"$${CLANG_BINDIR}\\\"\""