summaryrefslogtreecommitdiff
path: root/src/plugins/clangstaticanalyzer
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2016-07-22 15:17:36 +0300
committerOrgad Shaneh <orgad.shaneh@audiocodes.com>2016-07-22 15:18:00 +0300
commit1b34f2a4b8bc0b1f883a96c59eeb10fd34dee2bd (patch)
treef42b406d6f69451d9a0940d6e18742b5ad0729cc /src/plugins/clangstaticanalyzer
parent9ab6228ba06f738684538aeb8b9ad6f17bb89875 (diff)
parentd8c18de93c3113743121cfcee4df1269d3127c2f (diff)
downloadqt-creator-1b34f2a4b8bc0b1f883a96c59eeb10fd34dee2bd.tar.gz
Merge remote-tracking branch 'origin/4.1'
Change-Id: Ia90424d479936a898705c433e5810c77ae088b2c
Diffstat (limited to 'src/plugins/clangstaticanalyzer')
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp37
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.h5
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui11
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp22
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp50
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h35
6 files changed, 156 insertions, 4 deletions
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp
index f65a8a6931..dd3e59d2c4 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.cpp
@@ -47,7 +47,7 @@ ClangStaticAnalyzerConfigWidget::ClangStaticAnalyzerConfigWidget(
chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
chooser->setHistoryCompleter(QLatin1String("ClangStaticAnalyzer.ClangCommand.History"));
chooser->setPromptDialogTitle(tr("Clang Command"));
- const auto validator = [chooser](Utils::FancyLineEdit *edit, QString *errorMessage) {
+ const auto validator = [chooser, this](Utils::FancyLineEdit *edit, QString *errorMessage) {
const QString currentFilePath = chooser->fileName().toString();
Utils::PathChooser pc;
Utils::PathChooser *helperPathChooser;
@@ -58,8 +58,17 @@ ClangStaticAnalyzerConfigWidget::ClangStaticAnalyzerConfigWidget(
} else {
helperPathChooser = chooser;
}
- return chooser->defaultValidationFunction()(helperPathChooser->lineEdit(), errorMessage)
+
+ 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;
@@ -90,5 +99,29 @@ 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 ClangStaticAnalyzer
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.h
index f410670e50..6cc4e39eaf 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.h
@@ -34,6 +34,8 @@ namespace Internal {
namespace Ui { class ClangStaticAnalyzerConfigWidget; }
+class ClangExecutableVersion;
+
class ClangStaticAnalyzerConfigWidget : public QWidget
{
Q_OBJECT
@@ -43,6 +45,9 @@ public:
QWidget *parent = 0);
~ClangStaticAnalyzerConfigWidget();
+ void updateDetectedVersionLabel(bool executableIsValid,
+ const ClangExecutableVersion &providedVersion);
+
private:
Ui::ClangStaticAnalyzerConfigWidget *m_ui;
ClangStaticAnalyzerSettings *m_settings;
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui b/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui
index 800733a331..3f4d3762ec 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerconfigwidget.ui
@@ -34,14 +34,21 @@
</item>
</layout>
</item>
- <item row="1" column="0">
+ <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="1" column="1">
+ <item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="simultaneousProccessesSpinBox">
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
index 1fa42fa11b..f140907a66 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
@@ -469,6 +469,28 @@ void ClangStaticAnalyzerRunControl::start()
emit finished();
return;
}
+
+ // Check clang version
+ const ClangExecutableVersion version = clangExecutableVersion(executable);
+ if (!version.isValid()) {
+ const QString warningMessage
+ = tr("Clang Static Analyzer: Running with possibly unsupported version, "
+ "could not determine version from executable \"%1\".")
+ .arg(executable);
+ appendMessage(warningMessage + QLatin1Char('\n'), Utils::StdErrFormat);
+ TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
+ TaskHub::requestPopup();
+ } else if (!version.isSupportedVersion()) {
+ const QString warningMessage
+ = tr("Clang Static Analyzer: Running with unsupported version %1, "
+ "supported version is %2.")
+ .arg(version.toString())
+ .arg(ClangExecutableVersion::supportedVersionAsString());
+ appendMessage(warningMessage + QLatin1Char('\n'), Utils::StdErrFormat);
+ TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
+ TaskHub::requestPopup();
+ }
+
m_clangExecutable = executable;
// Create log dir
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
index 0b7bc0f230..a1a1bee67a 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.cpp
@@ -32,9 +32,11 @@
#include <utils/hostosinfo.h>
#include <utils/environment.h>
+#include <utils/synchronousprocess.h>
#include <QCoreApplication>
#include <QFileInfo>
+#include <QRegularExpression>
static bool isFileExecutable(const QString &executablePath)
{
@@ -108,5 +110,53 @@ bool isClangExecutableUsable(const QString &filePath, QString *errorMessage)
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 returns some old version number.
+ 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 ClangStaticAnalyzer
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
index 6b0880fc67..fb86bc1f94 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerutils.h
@@ -44,5 +44,40 @@ QString clangExecutableFromSettings(Core::Id toolchainType, bool *isValid);
QString createFullLocationString(const Debugger::DiagnosticLocation &location);
+// TODO: Use QVersionNumber once we can use >= Qt 5.6.0
+class ClangExecutableVersion {
+public:
+ ClangExecutableVersion() : majorNumber(-1) , minorNumber(-1) , patchNumber(-1) {}
+ ClangExecutableVersion(int major, int minor, int patch)
+ : majorNumber(major) , minorNumber(minor) , patchNumber(patch) {}
+
+ bool isValid() const
+ {
+ return majorNumber >= 0 && minorNumber >= 0 && patchNumber >= 0;
+ }
+
+ bool isSupportedVersion() const
+ {
+ return majorNumber == 3 && minorNumber == 8;
+ }
+
+ static QString supportedVersionAsString()
+ {
+ return QLatin1String("3.8");
+ }
+
+ QString toString() const
+ {
+ return QString::fromLatin1("%1.%2.%3").arg(majorNumber).arg(minorNumber).arg(patchNumber);
+ }
+
+public:
+ int majorNumber;
+ int minorNumber;
+ int patchNumber;
+};
+
+ClangExecutableVersion clangExecutableVersion(const QString &absolutePath);
+
} // namespace Internal
} // namespace ClangStaticAnalyzer