From 23136eb749b15daa9dc4be0b7e3d5aca949cd747 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 30 Oct 2014 17:35:52 +0100 Subject: RunControl: Show more status in Application Output pane Change-Id: I07e80e5a987612c19247a2d9a0628382b1136a06 Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzerruncontrol.cpp | 42 ++++++++++++++++++---- .../clangstaticanalyzerruncontrol.h | 2 ++ .../clangstaticanalyzerrunner.cpp | 10 ++++-- .../clangstaticanalyzerrunner.h | 3 ++ 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index e0c7b11e71..7c7e8a1554 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -53,6 +53,8 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl( ProjectExplorer::RunConfiguration *runConfiguration) : AnalyzerRunControl(startParams, runConfiguration) , m_initialFilesToProcessSize(0) + , m_filesAnalyzed(0) + , m_filesNotAnalyzed(0) { } @@ -126,6 +128,8 @@ bool ClangStaticAnalyzerRunControl::startEngine() } m_filesToProcess = filesToProcess; m_initialFilesToProcessSize = m_filesToProcess.count(); + m_filesAnalyzed = 0; + m_filesNotAnalyzed = 0; // Set up progress information using namespace Core; @@ -156,7 +160,10 @@ void ClangStaticAnalyzerRunControl::stopEngine() } m_runners.clear(); m_filesToProcess.clear(); - analyzeNextFile(); // emits finished + appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'), + Utils::NormalMessageFormat); + m_progress.reportFinished(); + emit finished(); } void ClangStaticAnalyzerRunControl::analyzeNextFile() @@ -166,7 +173,11 @@ void ClangStaticAnalyzerRunControl::analyzeNextFile() if (m_filesToProcess.isEmpty()) { if (m_runners.size() == 0) { - appendMessage(tr("Clang Static Analyzer finished.") + QLatin1Char('\n'), + appendMessage(tr("Clang Static Analyzer finished: " + "Processed %1 files successfully, %2 failed.") + .arg(m_filesAnalyzed) + .arg(m_filesNotAnalyzed) + + QLatin1Char('\n'), Utils::NormalMessageFormat); m_progress.reportFinished(); emit finished(); @@ -182,6 +193,8 @@ void ClangStaticAnalyzerRunControl::analyzeNextFile() m_runners.insert(runner); qCDebug(LOG) << "analyzeNextFile:" << filePath; QTC_ASSERT(runner->run(filePath, options), return); + appendMessage(tr("Analyzing \"%1\".").arg(filePath) + QLatin1Char('\n'), + Utils::StdOutFormat); } ClangStaticAnalyzerRunner *ClangStaticAnalyzerRunControl::createRunner() @@ -201,21 +214,36 @@ ClangStaticAnalyzerRunner *ClangStaticAnalyzerRunControl::createRunner() void ClangStaticAnalyzerRunControl::onRunnerFinishedWithSuccess(const QString &logFilePath) { qCDebug(LOG) << "onRunnerFinishedWithSuccess:" << logFilePath; - handleFinished(); QString errorMessage; const QList diagnostics = LogFileReader::read(logFilePath, &errorMessage); - QTC_CHECK(errorMessage.isEmpty()); - if (!errorMessage.isEmpty()) + if (!errorMessage.isEmpty()) { qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage; - if (!diagnostics.isEmpty()) - emit newDiagnosticsAvailable(diagnostics); + const QString filePath = qobject_cast(sender())->filePath(); + appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage) + + QLatin1Char('\n') + , Utils::StdErrFormat); + } else { + ++m_filesAnalyzed; + if (!diagnostics.isEmpty()) + emit newDiagnosticsAvailable(diagnostics); + } + + handleFinished(); } void ClangStaticAnalyzerRunControl::onRunnerFinishedWithFailure(const QString &errorMessage, const QString &errorDetails) { qCDebug(LOG) << "onRunnerFinishedWithFailure:" << errorMessage << errorDetails; + + ++m_filesNotAnalyzed; + const QString filePath = qobject_cast(sender())->filePath(); + appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage) + + QLatin1Char('\n') + , Utils::StdErrFormat); + appendMessage(errorDetails, Utils::StdErrFormat); + handleFinished(); } diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h index 661594bf11..0339751717 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h @@ -76,6 +76,8 @@ private: QList m_filesToProcess; QSet m_runners; int m_initialFilesToProcessSize; + int m_filesAnalyzed; + int m_filesNotAnalyzed; }; } // namespace Internal diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp index ed8efb93f8..1d4e5b527a 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp @@ -99,6 +99,7 @@ bool ClangStaticAnalyzerRunner::run(const QString &filePath, const QStringList & QTC_CHECK(!compilerOptions.contains(QLatin1String("-o"))); QTC_CHECK(!compilerOptions.contains(filePath)); + m_filePath = filePath; m_processOutput.clear(); m_logFile = createLogFile(filePath); @@ -112,6 +113,11 @@ bool ClangStaticAnalyzerRunner::run(const QString &filePath, const QStringList & return true; } +QString ClangStaticAnalyzerRunner::filePath() const +{ + return m_filePath; +} + void ClangStaticAnalyzerRunner::onProcessStarted() { emit started(); @@ -161,8 +167,8 @@ QString ClangStaticAnalyzerRunner::createLogFile(const QString &filePath) const QString ClangStaticAnalyzerRunner::processCommandlineAndOutput() const { return QObject::tr("Command line: \"%1\"\n" - "Process Error: \"%2\"\n" - "Output:\n\"%3\"") + "Process Error: %2\n" + "Output:\n%3") .arg(m_commandLine, QString::number(m_process.error()), QString::fromLocal8Bit(m_processOutput)); diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h index b535ec1077..461f694e2e 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.h @@ -45,6 +45,8 @@ public: // (2) -o output-file bool run(const QString &filePath, const QStringList &compilerOptions = QStringList()); + QString filePath() const; + signals: void started(); void finishedWithSuccess(const QString &logFilePath); @@ -62,6 +64,7 @@ private: private: QString m_clangExecutable; QString m_clangLogFileDir; + QString m_filePath; QString m_logFile; QString m_commandLine; QProcess m_process; -- cgit v1.2.3 From d61117e814d6f79064b239a7f6fee3afae043255 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 31 Oct 2014 10:37:11 +0100 Subject: Tool: Clear model already before building the project Change-Id: I507056c9a5ee950bd95541a9e3042e9af23c0731 Reviewed-by: Nikolai Kosjar --- plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index 143043d73f..bc7b60d7e6 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -144,15 +144,18 @@ void ClangStaticAnalyzerTool::startTool(StartMode mode) QTC_ASSERT(mode == Analyzer::StartLocal, return); AnalyzerManager::showMode(); - if (Project *pro = SessionManager::startupProject()) - ProjectExplorerPlugin::instance()->runProject(pro, runMode()); + + m_diagnosticModel->clear(); + setBusyCursor(true); + Project *pro = SessionManager::startupProject(); + QTC_ASSERT(pro, return); + ProjectExplorerPlugin::instance()->runProject(pro, runMode()); } void ClangStaticAnalyzerTool::onEngineIsStarting() { QTC_ASSERT(m_diagnosticModel, return); - m_diagnosticModel->clear(); - setBusyCursor(true); + } void ClangStaticAnalyzerTool::onNewDiagnosticsAvailable(const QList &diagnostics) -- cgit v1.2.3 From 1acf562612e0cf155e59572e3c919728ca0ea13e Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 31 Oct 2014 13:54:49 +0100 Subject: Runner: Use Utils::SynchronousProcess::stopProcess Change-Id: I77b0b039dae230c80a02f1692985c517bdd52023 Reviewed-by: Nikolai Kosjar --- plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp index 1d4e5b527a..5c469a07a2 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerrunner.cpp @@ -20,6 +20,8 @@ #include "clangstaticanalyzerconstants.h" +#include + #include #include #include @@ -83,14 +85,7 @@ ClangStaticAnalyzerRunner::ClangStaticAnalyzerRunner(const QString &clangExecuta ClangStaticAnalyzerRunner::~ClangStaticAnalyzerRunner() { - const QProcess::ProcessState processState = m_process.state(); - if (processState == QProcess::Starting || processState == QProcess::Running) { - m_process.terminate(); - if (!m_process.waitForFinished(500)) { - m_process.kill(); - m_process.waitForFinished(); - } - } + Utils::SynchronousProcess::stopProcess(m_process); } bool ClangStaticAnalyzerRunner::run(const QString &filePath, const QStringList &compilerOptions) -- cgit v1.2.3 From aa98ee27559dc79ac874755f190e2cbe9d817dfe Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 31 Oct 2014 15:55:32 +0100 Subject: Tool: Warn on run in Release mode Change-Id: I3443ccc8daf37a1b10b43df3736fcf24c7ae2fea Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzertool.cpp | 49 ++++++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index bc7b60d7e6..c2b663074e 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -24,10 +24,14 @@ #include #include +#include +#include #include #include #include +#include +#include #include #include @@ -139,23 +143,60 @@ AnalyzerRunControl *ClangStaticAnalyzerTool::createRunControl( return engine; } +static bool dontStartAfterHintForDebugMode() +{ + const Project *project = SessionManager::startupProject(); + BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown; + if (project) { + if (const Target *target = project->activeTarget()) { + if (const BuildConfiguration *buildConfig = target->activeBuildConfiguration()) + buildType = buildConfig->buildType(); + } + } + + if (buildType == BuildConfiguration::Release) { + const QString wrongMode = ClangStaticAnalyzerTool::tr("Release"); + const QString toolName = ClangStaticAnalyzerTool::tr("Clang Static Analyzer"); + const QString title = ClangStaticAnalyzerTool::tr("Run %1 in %2 Mode?").arg(toolName) + .arg(wrongMode); + const QString message = ClangStaticAnalyzerTool::tr( + "" + "

You are trying to run the tool \"%1\" on an application in %2 mode. The tool is " + "designed to be used in Debug mode since enabled assertions can reduce the number of " + "false positives.

" + "

Do you want to continue and run the tool in %2 mode?

" + "") + .arg(toolName).arg(wrongMode); + if (Utils::CheckableMessageBox::doNotAskAgainQuestion(Core::ICore::mainWindow(), + title, message, Core::ICore::settings(), + QLatin1String("ClangStaticAnalyzerCorrectModeWarning"), + QDialogButtonBox::Yes|QDialogButtonBox::Cancel, + QDialogButtonBox::Cancel, QDialogButtonBox::Yes) != QDialogButtonBox::Yes) + return true; + } + + return false; +} + void ClangStaticAnalyzerTool::startTool(StartMode mode) { QTC_ASSERT(mode == Analyzer::StartLocal, return); AnalyzerManager::showMode(); + if (dontStartAfterHintForDebugMode()) + return; + m_diagnosticModel->clear(); setBusyCursor(true); - Project *pro = SessionManager::startupProject(); - QTC_ASSERT(pro, return); - ProjectExplorerPlugin::instance()->runProject(pro, runMode()); + Project *project = SessionManager::startupProject(); + QTC_ASSERT(project, return); + ProjectExplorerPlugin::instance()->runProject(project, runMode()); } void ClangStaticAnalyzerTool::onEngineIsStarting() { QTC_ASSERT(m_diagnosticModel, return); - } void ClangStaticAnalyzerTool::onNewDiagnosticsAvailable(const QList &diagnostics) -- cgit v1.2.3 From 273f2b8c5df7232751bcf6999f549cf22417c23c Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 16 Oct 2014 13:14:45 +0200 Subject: Load the plugin only on Linux / OS X On these platforms clang and/or gcc are available and the QMakeProject and QbsProject can provide "enough" information. Windows/MinGW: Currently mingw 4.8.2 can't be used with clang 3.5. See https://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg09490.html Tests with mingw 4.9 are needed. Windows/MSVC: This needs more investigation. Observations so far: * Does not work at the moment calling clang.exe. * clang-cl.exe does not understand '--analyze'. Passing '-Xclang --analyze' in does not help either. Change-Id: I83afe4a186cba67faf7bd0ad6c1de42790e281b2 Reviewed-by: Eike Ziller --- plugins/clangstaticanalyzer/ClangStaticAnalyzer.json.in | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/clangstaticanalyzer/ClangStaticAnalyzer.json.in b/plugins/clangstaticanalyzer/ClangStaticAnalyzer.json.in index 77cc31b40d..13c2aa5b82 100644 --- a/plugins/clangstaticanalyzer/ClangStaticAnalyzer.json.in +++ b/plugins/clangstaticanalyzer/ClangStaticAnalyzer.json.in @@ -3,6 +3,7 @@ \"Version\" : \"$$QTCREATOR_VERSION\", \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\", \"Experimental\" : true, + \"Platform\" : \"(Linux.*)|(OS X.*)\", \"Vendor\" : \"Digia Plc\", \"Copyright\" : \"(C) 2014 Digia Plc\", \"License\" : [ \"Commercial Usage\", -- cgit v1.2.3 From 36d306c5ba384dfb0e8adf49aa3967b3f8c8cf01 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 7 Nov 2014 10:19:44 +0100 Subject: Adapt to qtcreator 3.3 changes / Compile fix Change-Id: I6074f163184b5287b4ba6b791cadbeeb47ae1e4e Reviewed-by: Nikolai Kosjar --- plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index 7c7e8a1554..7f794983f2 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -64,7 +64,7 @@ static QList calculateFi typedef ClangStaticAnalyzerRunControl::SourceFileConfiguration SourceFileConfiguration; QTC_ASSERT(project, return QList()); ProjectInfo projectInfo = CppModelManager::instance()->projectInfo(project); - QTC_ASSERT(projectInfo, return QList()); + QTC_ASSERT(projectInfo.isValid(), return QList()); QList files; const QList projectParts = projectInfo.projectParts(); -- cgit v1.2.3 From 22003c8ea05926ae1faa5497e60cacff9fadfbdd Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 30 Oct 2014 11:57:09 +0100 Subject: RunControl: Handle also ProjectInfo::CompilerCallData ...if it's available. Change-Id: I41b8ab30e0c87ddd223f115e759bbd2a2c86cc68 Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzerruncontrol.cpp | 146 ++++++++++++++------- .../clangstaticanalyzerruncontrol.h | 16 +-- 2 files changed, 107 insertions(+), 55 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index 7f794983f2..ba37140795 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -58,27 +58,103 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl( { } -static QList calculateFilesToProcess( - Project *project) +// Removes (1) filePath (2) -o +static QStringList tweakedArguments(const QString &filePath, const QStringList &arguments) { - typedef ClangStaticAnalyzerRunControl::SourceFileConfiguration SourceFileConfiguration; - QTC_ASSERT(project, return QList()); - ProjectInfo projectInfo = CppModelManager::instance()->projectInfo(project); - QTC_ASSERT(projectInfo.isValid(), return QList()); + QStringList newArguments; + + bool skip = false; + foreach (const QString &argument, arguments) { + if (skip) { + skip = false; + continue; + } else if (argument == QLatin1String("-o")) { + skip = true; + continue; + } else if (argument == filePath) { + continue; // TODO: Let it in? + } + + newArguments << argument; + } + QTC_CHECK(skip == false); + + return newArguments; +} + +static QStringList argumentsFromProjectPart(const CppTools::ProjectPart::Ptr &projectPart, + CppTools::ProjectFile::Kind fileKind) +{ + QStringList result; + + const bool objcExt = projectPart->languageExtensions & ProjectPart::ObjectiveCExtensions; + result += CppTools::CompilerOptionsBuilder::createLanguageOption(fileKind, objcExt); + result += CppTools::CompilerOptionsBuilder::createOptionsForLanguage( + projectPart->languageVersion, + projectPart->languageExtensions); + result += CppTools::CompilerOptionsBuilder::createDefineOptions(projectPart->toolchainDefines); + result += CppTools::CompilerOptionsBuilder::createDefineOptions(projectPart->projectDefines); + result += CppTools::CompilerOptionsBuilder::createHeaderPathOptions(projectPart->headerPaths); + result += QLatin1String("-fPIC"); // TODO: Remove? + + return result; +} + +static QList unitsToAnalyzeFromCompilerCallData( + const ProjectInfo::CompilerCallData &compilerCallData) +{ + typedef ClangStaticAnalyzerRunControl::AnalyzeUnit AnalyzeUnit; + qCDebug(LOG) << "Taking arguments for analyzing from CompilerCallData."; + + QList unitsToAnalyze; + + QHashIterator > it(compilerCallData); + while (it.hasNext()) { + it.next(); + const QString file = it.key(); + const QList compilerCalls = it.value(); + foreach (const QStringList &options, compilerCalls) { + const QStringList arguments = tweakedArguments(file, options); + unitsToAnalyze << AnalyzeUnit(file, arguments); + } + } + + return unitsToAnalyze; +} + +static QList unitsToAnalyzeFromProjectParts( + const QList projectParts) +{ + typedef ClangStaticAnalyzerRunControl::AnalyzeUnit AnalyzeUnit; + qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts."; + + QList unitsToAnalyze; - QList files; - const QList projectParts = projectInfo.projectParts(); foreach (const ProjectPart::Ptr &projectPart, projectParts) { foreach (const ProjectFile &file, projectPart->files) { if (file.path == CppModelManager::configurationFileName()) continue; QTC_CHECK(file.kind != ProjectFile::Unclassified); - if (ProjectFile::isSource(file.kind)) - files << SourceFileConfiguration(file, projectPart); + if (ProjectFile::isSource(file.kind)) { + const QStringList arguments = argumentsFromProjectPart(projectPart, file.kind); + unitsToAnalyze << AnalyzeUnit(file.path, arguments); + } } } - return files; + return unitsToAnalyze; +} + +static QList unitsToAnalyze(Project *project) +{ + QTC_ASSERT(project, return QList()); + ProjectInfo projectInfo = CppModelManager::instance()->projectInfo(project); + QTC_ASSERT(projectInfo.isValid(), return QList()); + + const ProjectInfo::CompilerCallData compilerCallData = projectInfo.compilerCallData(); + if (!compilerCallData.isEmpty()) + return unitsToAnalyzeFromCompilerCallData(compilerCallData); + return unitsToAnalyzeFromProjectParts(projectInfo.projectParts()); } bool ClangStaticAnalyzerRunControl::startEngine() @@ -120,14 +196,12 @@ bool ClangStaticAnalyzerRunControl::startEngine() m_clangLogFileDir = temporaryDir.path(); // Collect files - const QList filesToProcess = calculateFilesToProcess(project); + const QList filesToProcess = unitsToAnalyze(project); qCDebug(LOG) << "Files to process:"; - foreach (const SourceFileConfiguration &fileConfig, filesToProcess) { - qCDebug(LOG) << fileConfig.file.path + QLatin1String(" [") - + fileConfig.projectPart->projectFile + QLatin1Char(']'); - } - m_filesToProcess = filesToProcess; - m_initialFilesToProcessSize = m_filesToProcess.count(); + foreach (const AnalyzeUnit &fileConfig, filesToProcess) + qCDebug(LOG) << fileConfig.file; + m_unitsToProcess = filesToProcess; + m_initialFilesToProcessSize = m_unitsToProcess.count(); m_filesAnalyzed = 0; m_filesNotAnalyzed = 0; @@ -145,7 +219,7 @@ bool ClangStaticAnalyzerRunControl::startEngine() m_runners.clear(); const int parallelRuns = ClangStaticAnalyzerSettings::instance()->simultaneousProcesses(); QTC_ASSERT(parallelRuns >= 1, emit finished(); return false); - while (m_runners.size() < parallelRuns && !m_filesToProcess.isEmpty()) + while (m_runners.size() < parallelRuns && !m_unitsToProcess.isEmpty()) analyzeNextFile(); return true; } @@ -159,7 +233,7 @@ void ClangStaticAnalyzerRunControl::stopEngine() delete runner; } m_runners.clear(); - m_filesToProcess.clear(); + m_unitsToProcess.clear(); appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'), Utils::NormalMessageFormat); m_progress.reportFinished(); @@ -171,7 +245,7 @@ void ClangStaticAnalyzerRunControl::analyzeNextFile() if (m_progress.isFinished()) return; // The previous call already reported that we are finished. - if (m_filesToProcess.isEmpty()) { + if (m_unitsToProcess.isEmpty()) { if (m_runners.size() == 0) { appendMessage(tr("Clang Static Analyzer finished: " "Processed %1 files successfully, %2 failed.") @@ -185,15 +259,14 @@ void ClangStaticAnalyzerRunControl::analyzeNextFile() return; } - const SourceFileConfiguration config = m_filesToProcess.takeFirst(); - const QString filePath = config.file.path; - const QStringList options = config.createClangOptions(); + const AnalyzeUnit unit = m_unitsToProcess.takeFirst(); + qCDebug(LOG) << "analyzeNextFile:" << unit.file; ClangStaticAnalyzerRunner *runner = createRunner(); m_runners.insert(runner); - qCDebug(LOG) << "analyzeNextFile:" << filePath; - QTC_ASSERT(runner->run(filePath, options), return); - appendMessage(tr("Analyzing \"%1\".").arg(filePath) + QLatin1Char('\n'), + QTC_ASSERT(runner->run(unit.file, unit.arguments), return); + + appendMessage(tr("Analyzing \"%1\".").arg(unit.file) + QLatin1Char('\n'), Utils::StdOutFormat); } @@ -264,24 +337,7 @@ void ClangStaticAnalyzerRunControl::onProgressCanceled() void ClangStaticAnalyzerRunControl::updateProgressValue() { - m_progress.setProgressValue(m_initialFilesToProcessSize - m_filesToProcess.size()); -} - -QStringList ClangStaticAnalyzerRunControl::SourceFileConfiguration::createClangOptions() const -{ - QStringList result; - - const bool objcExt = projectPart->languageExtensions & ProjectPart::ObjectiveCExtensions; - result += CppTools::CompilerOptionsBuilder::createLanguageOption(file.kind, objcExt); - result += CppTools::CompilerOptionsBuilder::createOptionsForLanguage( - projectPart->languageVersion, - projectPart->languageExtensions); - result += CppTools::CompilerOptionsBuilder::createDefineOptions(projectPart->toolchainDefines); - result += CppTools::CompilerOptionsBuilder::createDefineOptions(projectPart->projectDefines); - result += CppTools::CompilerOptionsBuilder::createHeaderPathOptions(projectPart->headerPaths); - result += QLatin1String("-fPIC"); // TODO: Remove? - - return result; + m_progress.setProgressValue(m_initialFilesToProcessSize - m_unitsToProcess.size()); } } // namespace Internal diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h index 0339751717..8de898c23a 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h @@ -36,16 +36,12 @@ class ClangStaticAnalyzerRunControl : public Analyzer::AnalyzerRunControl Q_OBJECT public: - struct SourceFileConfiguration { - SourceFileConfiguration(const CppTools::ProjectFile &projectFile, - const CppTools::ProjectPart::Ptr &projectPart) - : file(projectFile) - , projectPart(projectPart) {} + struct AnalyzeUnit { + AnalyzeUnit(const QString &file, const QStringList &options) + : file(file), arguments(options) {} - QStringList createClangOptions() const; - - CppTools::ProjectFile file; - CppTools::ProjectPart::Ptr projectPart; + QString file; + QStringList arguments; // without file itself and "-o somePath" }; public: @@ -73,7 +69,7 @@ private: QString m_clangExecutable; QString m_clangLogFileDir; QFutureInterface m_progress; - QList m_filesToProcess; + QList m_unitsToProcess; QSet m_runners; int m_initialFilesToProcessSize; int m_filesAnalyzed; -- cgit v1.2.3 From 2f3666a3f05bfe5e71241b55ce72e913d547f2a4 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 5 Nov 2014 13:28:44 +0100 Subject: Ensure that project configuration did not change Otherwise we might try to analyze invalid or vanished files. Change-Id: I387dfb127618f2db21a538b07e1c152dbd026ca6 Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzerplugin.cpp | 5 ++-- .../clangstaticanalyzerruncontrol.cpp | 23 ++++++-------- .../clangstaticanalyzerruncontrol.h | 5 +++- .../clangstaticanalyzerruncontrolfactory.cpp | 35 ++++++++++++++++++++-- .../clangstaticanalyzerruncontrolfactory.h | 8 ++++- .../clangstaticanalyzertool.cpp | 23 ++++++++++++-- .../clangstaticanalyzer/clangstaticanalyzertool.h | 5 ++++ 7 files changed, 81 insertions(+), 23 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp index 0a321d64e8..e635305b97 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp @@ -121,10 +121,9 @@ bool ClangStaticAnalyzerPlugin::initializeEnterpriseFeatures(const QStringList & Q_UNUSED(arguments); Q_UNUSED(errorString); - addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage); - addAutoReleasedObject(new ClangStaticAnalyzerRunControlFactory); - m_analyzerTool = new ClangStaticAnalyzerTool(this); + addAutoReleasedObject(new ClangStaticAnalyzerRunControlFactory(m_analyzerTool)); + addAutoReleasedObject(new ClangStaticAnalyzerOptionsPage); const QString toolTip = tr("Clang Static Analyzer uses the analyzer from the clang project " "to find bugs."); diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index ba37140795..17a63f3a20 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -49,9 +49,11 @@ namespace ClangStaticAnalyzer { namespace Internal { ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl( - const Analyzer::AnalyzerStartParameters &startParams, - ProjectExplorer::RunConfiguration *runConfiguration) + const Analyzer::AnalyzerStartParameters &startParams, + ProjectExplorer::RunConfiguration *runConfiguration, + const ProjectInfo &projectInfo) : AnalyzerRunControl(startParams, runConfiguration) + , m_projectInfo(projectInfo) , m_initialFilesToProcessSize(0) , m_filesAnalyzed(0) , m_filesNotAnalyzed(0) @@ -145,10 +147,9 @@ static QList unitsToAnalyzeFromProje return unitsToAnalyze; } -static QList unitsToAnalyze(Project *project) +static QList unitsToAnalyze( + const CppTools::ProjectInfo &projectInfo) { - QTC_ASSERT(project, return QList()); - ProjectInfo projectInfo = CppModelManager::instance()->projectInfo(project); QTC_ASSERT(projectInfo.isValid(), return QList()); const ProjectInfo::CompilerCallData compilerCallData = projectInfo.compilerCallData(); @@ -161,14 +162,8 @@ bool ClangStaticAnalyzerRunControl::startEngine() { emit starting(this); - RunConfiguration *runConfig = runConfiguration(); - QTC_ASSERT(runConfig, emit finished(); return false); - Target *target = runConfig->target(); - QTC_ASSERT(target, emit finished(); return false); - Project *project = target->project(); - QTC_ASSERT(project, emit finished(); return false); - - const QString projectFile = project->projectFilePath().toString(); + QTC_ASSERT(m_projectInfo.isValid(), emit finished(); return false); + const QString projectFile = m_projectInfo.project()->projectFilePath().toString(); appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile) + QLatin1Char('\n'), Utils::NormalMessageFormat); @@ -196,7 +191,7 @@ bool ClangStaticAnalyzerRunControl::startEngine() m_clangLogFileDir = temporaryDir.path(); // Collect files - const QList filesToProcess = unitsToAnalyze(project); + const QList filesToProcess = unitsToAnalyze(m_projectInfo); qCDebug(LOG) << "Files to process:"; foreach (const AnalyzeUnit &fileConfig, filesToProcess) qCDebug(LOG) << fileConfig.file; diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h index 8de898c23a..cc56f107f6 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h @@ -46,7 +46,8 @@ public: public: explicit ClangStaticAnalyzerRunControl(const Analyzer::AnalyzerStartParameters &startParams, - ProjectExplorer::RunConfiguration *runConfiguration); + ProjectExplorer::RunConfiguration *runConfiguration, + const CppTools::ProjectInfo &projectInfo); bool startEngine(); void stopEngine(); @@ -66,6 +67,8 @@ private: void updateProgressValue(); private: + const CppTools::ProjectInfo m_projectInfo; + QString m_clangExecutable; QString m_clangLogFileDir; QFutureInterface m_progress; diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp index a8896b4565..df683464db 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp @@ -22,21 +22,31 @@ #include #include +#include +#include + #include #include #include +#include #include #include +#include + using namespace Analyzer; using namespace ProjectExplorer; namespace ClangStaticAnalyzer { namespace Internal { -ClangStaticAnalyzerRunControlFactory::ClangStaticAnalyzerRunControlFactory(QObject *parent) +ClangStaticAnalyzerRunControlFactory::ClangStaticAnalyzerRunControlFactory( + ClangStaticAnalyzerTool *tool, + QObject *parent) : IRunControlFactory(parent) + , m_tool(tool) { + QTC_CHECK(m_tool); } bool ClangStaticAnalyzerRunControlFactory::canRun(RunConfiguration *runConfiguration, @@ -58,9 +68,30 @@ RunControl *ClangStaticAnalyzerRunControlFactory::create(RunConfiguration *runCo RunMode runMode, QString *errorMessage) { - Q_UNUSED(errorMessage); Q_UNUSED(runMode); + using namespace CppTools; + const ProjectInfo projectInfoAtAnalyzerStart = m_tool->projectInfo(); + QTC_ASSERT(projectInfoAtAnalyzerStart.isValid(), return 0); + + Project *project = SessionManager::startupProject(); + QTC_ASSERT(project, return 0); + const ProjectInfo projectInfoNow = CppModelManager::instance()->projectInfo(project); + + if (projectInfoNow.configurationOrFilesChanged(projectInfoAtAnalyzerStart)) { + // If it's more than a release/debug build configuration change, e.g. + // a version control checkout, files might be not valid C++ anymore + // or even gone, so better stop here. + + m_tool->resetCursorAndProjectInfo(); + if (errorMessage) { + *errorMessage = tr( + "The project configuration changed since the start of the Clang Static Analyzer. " + "Please re-run with current configuration."); + } + return 0; + } + AnalyzerStartParameters sp; sp.runMode = runMode; sp.startMode = StartLocal; diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.h b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.h index ec3b2d8c9c..a325691972 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.h @@ -19,6 +19,8 @@ #ifndef CLANGSTATICANALYZERRUNCONTROLFACTORY_H #define CLANGSTATICANALYZERRUNCONTROLFACTORY_H +#include "clangstaticanalyzertool.h" + #include namespace ClangStaticAnalyzer { @@ -29,7 +31,8 @@ class ClangStaticAnalyzerRunControlFactory : public ProjectExplorer::IRunControl Q_OBJECT public: - explicit ClangStaticAnalyzerRunControlFactory(QObject *parent = 0); + explicit ClangStaticAnalyzerRunControlFactory(ClangStaticAnalyzerTool *tool, + QObject *parent = 0); bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, ProjectExplorer::RunMode runMode) const; @@ -37,6 +40,9 @@ public: ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, ProjectExplorer::RunMode runMode, QString *errorMessage); + +private: + ClangStaticAnalyzerTool *m_tool; }; } // namespace Internal diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index c2b663074e..591e8da4ce 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +134,11 @@ AnalyzerRunControl *ClangStaticAnalyzerTool::createRunControl( const AnalyzerStartParameters &sp, ProjectExplorer::RunConfiguration *runConfiguration) { - ClangStaticAnalyzerRunControl *engine = new ClangStaticAnalyzerRunControl(sp, runConfiguration); + QTC_ASSERT(runConfiguration, return 0); + QTC_ASSERT(m_projectInfo.isValid(), return 0); + + ClangStaticAnalyzerRunControl *engine = new ClangStaticAnalyzerRunControl(sp, runConfiguration, + m_projectInfo); connect(engine, &ClangStaticAnalyzerRunControl::starting, this, &ClangStaticAnalyzerTool::onEngineIsStarting); connect(engine, &ClangStaticAnalyzerRunControl::newDiagnosticsAvailable, @@ -192,6 +197,18 @@ void ClangStaticAnalyzerTool::startTool(StartMode mode) Project *project = SessionManager::startupProject(); QTC_ASSERT(project, return); ProjectExplorerPlugin::instance()->runProject(project, runMode()); + m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(project); +} + +CppTools::ProjectInfo ClangStaticAnalyzerTool::projectInfo() const +{ + return m_projectInfo; +} + +void ClangStaticAnalyzerTool::resetCursorAndProjectInfo() +{ + setBusyCursor(false); + m_projectInfo = CppTools::ProjectInfo(); } void ClangStaticAnalyzerTool::onEngineIsStarting() @@ -210,10 +227,12 @@ void ClangStaticAnalyzerTool::onEngineFinished() QTC_ASSERT(m_goBack, return); QTC_ASSERT(m_goNext, return); QTC_ASSERT(m_diagnosticModel, return); + + resetCursorAndProjectInfo(); + const int issuesFound = m_diagnosticModel->rowCount(); m_goBack->setEnabled(issuesFound > 1); m_goNext->setEnabled(issuesFound > 1); - setBusyCursor(false); AnalyzerManager::showStatusMessage(issuesFound > 0 ? AnalyzerManager::tr("Clang Static Analyzer finished, %n issues were found.", 0, issuesFound) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.h b/plugins/clangstaticanalyzer/clangstaticanalyzertool.h index 2cb1393a7a..f049740d89 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.h @@ -20,6 +20,7 @@ #define CLANGSTATICANALYZERTOOL_H #include +#include namespace Analyzer { class DetailedErrorView; } @@ -36,6 +37,8 @@ class ClangStaticAnalyzerTool : public Analyzer::IAnalyzerTool public: explicit ClangStaticAnalyzerTool(QObject *parent = 0); + CppTools::ProjectInfo projectInfo() const; + void resetCursorAndProjectInfo(); private: QWidget *createWidgets(); @@ -50,6 +53,8 @@ private: void setBusyCursor(bool busy); private: + CppTools::ProjectInfo m_projectInfo; + ClangStaticAnalyzerDiagnosticModel *m_diagnosticModel; Analyzer::DetailedErrorView *m_diagnosticView; -- cgit v1.2.3 From b6a50a1a4c46b6b935a2b56c0f7362f324f2f35f Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 7 Nov 2014 11:32:40 +0100 Subject: Use updated ProjectInfo ...that actually make us use the ProjectInfo with updated CompilerCallData. Change-Id: Ieee298b3db64159f3faa02231921275e4466bcb5 Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzerruncontrolfactory.cpp | 10 ++++---- .../clangstaticanalyzertool.cpp | 30 +++++++++++++++------- .../clangstaticanalyzer/clangstaticanalyzertool.h | 6 ++--- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp index df683464db..94f7f27163 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrolfactory.cpp @@ -71,19 +71,19 @@ RunControl *ClangStaticAnalyzerRunControlFactory::create(RunConfiguration *runCo Q_UNUSED(runMode); using namespace CppTools; - const ProjectInfo projectInfoAtAnalyzerStart = m_tool->projectInfo(); - QTC_ASSERT(projectInfoAtAnalyzerStart.isValid(), return 0); + const ProjectInfo projectInfoBeforeBuild = m_tool->projectInfoBeforeBuild(); + QTC_ASSERT(projectInfoBeforeBuild.isValid(), return 0); Project *project = SessionManager::startupProject(); QTC_ASSERT(project, return 0); - const ProjectInfo projectInfoNow = CppModelManager::instance()->projectInfo(project); + const ProjectInfo projectInfoAfterBuild = CppModelManager::instance()->projectInfo(project); - if (projectInfoNow.configurationOrFilesChanged(projectInfoAtAnalyzerStart)) { + if (projectInfoAfterBuild.configurationOrFilesChanged(projectInfoBeforeBuild)) { // If it's more than a release/debug build configuration change, e.g. // a version control checkout, files might be not valid C++ anymore // or even gone, so better stop here. - m_tool->resetCursorAndProjectInfo(); + m_tool->resetCursorAndProjectInfoBeforeBuild(); if (errorMessage) { *errorMessage = tr( "The project configuration changed since the start of the Clang Static Analyzer. " diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp index 591e8da4ce..5042267776 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp @@ -135,10 +135,21 @@ AnalyzerRunControl *ClangStaticAnalyzerTool::createRunControl( ProjectExplorer::RunConfiguration *runConfiguration) { QTC_ASSERT(runConfiguration, return 0); - QTC_ASSERT(m_projectInfo.isValid(), return 0); + QTC_ASSERT(m_projectInfoBeforeBuild.isValid(), return 0); - ClangStaticAnalyzerRunControl *engine = new ClangStaticAnalyzerRunControl(sp, runConfiguration, - m_projectInfo); + // Some projects provides CompilerCallData once a build is finished, + // so pass on the updated Project Info unless no configuration change + // (defines/includes/files) happened. + Project *project = SessionManager::startupProject(); + QTC_ASSERT(project, return 0); + const CppTools::ProjectInfo projectInfoAfterBuild + = CppTools::CppModelManager::instance()->projectInfo(project); + QTC_ASSERT(!projectInfoAfterBuild.configurationOrFilesChanged(m_projectInfoBeforeBuild), + return 0); + m_projectInfoBeforeBuild = CppTools::ProjectInfo(); + + ClangStaticAnalyzerRunControl *engine + = new ClangStaticAnalyzerRunControl(sp, runConfiguration, projectInfoAfterBuild); connect(engine, &ClangStaticAnalyzerRunControl::starting, this, &ClangStaticAnalyzerTool::onEngineIsStarting); connect(engine, &ClangStaticAnalyzerRunControl::newDiagnosticsAvailable, @@ -196,19 +207,20 @@ void ClangStaticAnalyzerTool::startTool(StartMode mode) setBusyCursor(true); Project *project = SessionManager::startupProject(); QTC_ASSERT(project, return); + m_projectInfoBeforeBuild = CppTools::CppModelManager::instance()->projectInfo(project); + QTC_ASSERT(m_projectInfoBeforeBuild.isValid(), return); ProjectExplorerPlugin::instance()->runProject(project, runMode()); - m_projectInfo = CppTools::CppModelManager::instance()->projectInfo(project); } -CppTools::ProjectInfo ClangStaticAnalyzerTool::projectInfo() const +CppTools::ProjectInfo ClangStaticAnalyzerTool::projectInfoBeforeBuild() const { - return m_projectInfo; + return m_projectInfoBeforeBuild; } -void ClangStaticAnalyzerTool::resetCursorAndProjectInfo() +void ClangStaticAnalyzerTool::resetCursorAndProjectInfoBeforeBuild() { setBusyCursor(false); - m_projectInfo = CppTools::ProjectInfo(); + m_projectInfoBeforeBuild = CppTools::ProjectInfo(); } void ClangStaticAnalyzerTool::onEngineIsStarting() @@ -228,7 +240,7 @@ void ClangStaticAnalyzerTool::onEngineFinished() QTC_ASSERT(m_goNext, return); QTC_ASSERT(m_diagnosticModel, return); - resetCursorAndProjectInfo(); + resetCursorAndProjectInfoBeforeBuild(); const int issuesFound = m_diagnosticModel->rowCount(); m_goBack->setEnabled(issuesFound > 1); diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.h b/plugins/clangstaticanalyzer/clangstaticanalyzertool.h index f049740d89..8f3bb1f196 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.h @@ -37,8 +37,8 @@ class ClangStaticAnalyzerTool : public Analyzer::IAnalyzerTool public: explicit ClangStaticAnalyzerTool(QObject *parent = 0); - CppTools::ProjectInfo projectInfo() const; - void resetCursorAndProjectInfo(); + CppTools::ProjectInfo projectInfoBeforeBuild() const; + void resetCursorAndProjectInfoBeforeBuild(); private: QWidget *createWidgets(); @@ -53,7 +53,7 @@ private: void setBusyCursor(bool busy); private: - CppTools::ProjectInfo m_projectInfo; + CppTools::ProjectInfo m_projectInfoBeforeBuild; ClangStaticAnalyzerDiagnosticModel *m_diagnosticModel; Analyzer::DetailedErrorView *m_diagnosticView; -- cgit v1.2.3 From 124311227de43b253852e8099475fd53e748c514 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 7 Nov 2014 12:15:13 +0100 Subject: Sort files to process Change-Id: Iac23e40c3154bf143b91d0262418f90907758276 Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index 17a63f3a20..b92150cc35 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -37,6 +37,8 @@ #include #include +#include + #include #include @@ -191,11 +193,15 @@ bool ClangStaticAnalyzerRunControl::startEngine() m_clangLogFileDir = temporaryDir.path(); // Collect files - const QList filesToProcess = unitsToAnalyze(m_projectInfo); + QList unitsToProcess = unitsToAnalyze(m_projectInfo); + Utils::sort(unitsToProcess, [](const AnalyzeUnit &a1, const AnalyzeUnit &a2) -> bool { + return a1.file < a2.file; + }); + qCDebug(LOG) << "Files to process:"; - foreach (const AnalyzeUnit &fileConfig, filesToProcess) + foreach (const AnalyzeUnit &fileConfig, unitsToProcess) qCDebug(LOG) << fileConfig.file; - m_unitsToProcess = filesToProcess; + m_unitsToProcess = unitsToProcess; m_initialFilesToProcessSize = m_unitsToProcess.count(); m_filesAnalyzed = 0; m_filesNotAnalyzed = 0; -- cgit v1.2.3 From e06c9ec09b9d882e2d0f791280f103f69aec6a09 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 3 Nov 2014 14:52:23 +0100 Subject: RunControl: Skip sub projects not selected for building Change-Id: I38e5a4f829484a7970fa4b6b06f00ec4cc92e8d0 Reviewed-by: Nikolai Kosjar --- plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp index b92150cc35..f9b3506102 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp @@ -135,6 +135,9 @@ static QList unitsToAnalyzeFromProje QList unitsToAnalyze; foreach (const ProjectPart::Ptr &projectPart, projectParts) { + if (!projectPart->selectedForBuilding) + continue; + foreach (const ProjectFile &file, projectPart->files) { if (file.path == CppModelManager::configurationFileName()) continue; -- cgit v1.2.3 From 33fd656641b36474f1f143d79bfbb6e17a45889a Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 14 Nov 2014 14:59:27 +0100 Subject: Check for valid Diagnostic Change-Id: Icfce44a373d56f008027330f9b1a2d446f4d2adb Reviewed-by: Nikolai Kosjar --- plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.cpp | 5 +++++ plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h | 2 ++ plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp | 3 +++ 3 files changed, 10 insertions(+) diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.cpp index e9152ffa47..09d810dfc9 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.cpp @@ -46,5 +46,10 @@ bool ExplainingStep::isValid() const return location.isValid() && !ranges.isEmpty() && !message.isEmpty(); } +bool Diagnostic::isValid() const +{ + return !description.isEmpty(); +} + } // namespace Internal } // namespace ClangStaticAnalyzer diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h index 3348cfa416..75df6218a9 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnostic.h @@ -56,6 +56,8 @@ public: class Diagnostic { public: + bool isValid() const; + QString description; QString category; QString type; diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp index fd9e216ed7..6d00968c86 100644 --- a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp +++ b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp @@ -168,6 +168,7 @@ DetailedErrorDelegate::SummaryLineInfo ClangStaticAnalyzerDiagnosticDelegate::su const QModelIndex &index) const { const Diagnostic diagnostic = index.data(Qt::UserRole).value(); + QTC_ASSERT(diagnostic.isValid(), return SummaryLineInfo()); DetailedErrorDelegate::SummaryLineInfo info; info.errorText = diagnostic.description; @@ -188,6 +189,8 @@ QWidget *ClangStaticAnalyzerDiagnosticDelegate::createDetailsWidget(const QFont QVBoxLayout *layout = new QVBoxLayout; const Diagnostic diagnostic = index.data(Qt::UserRole).value(); + if (!diagnostic.isValid()) + return widget; // Add summary label QLabel *summaryLineLabel = createSummaryLabel(diagnostic); -- cgit v1.2.3 From 37b8e7252e13a3b74c7e94a908f5818e60127c89 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 17 Nov 2014 14:08:07 +0100 Subject: Add qbs project file. Change-Id: I675c1f95d7a22dca4a6cfdc8bec3f815d2576884 Reviewed-by: Nikolai Kosjar --- .../clangstaticanalyzer/clangstaticanalyzer.qbs | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 plugins/clangstaticanalyzer/clangstaticanalyzer.qbs diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs b/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs new file mode 100644 index 0000000000..6c2612a69c --- /dev/null +++ b/plugins/clangstaticanalyzer/clangstaticanalyzer.qbs @@ -0,0 +1,47 @@ +import qbs + +QtcPlugin { + name: "ClangStaticAnalyzer" + + Depends { name: "AnalyzerBase" } + Depends { name: "Core" } + Depends { name: "CppTools" } + Depends { name: "ExtensionSystem" } + Depends { name: "LicenseChecker" } + Depends { name: "ProjectExplorer" } + Depends { name: "QtcSsh" } // TODO: export + recursive dependencies broken in qbs + Depends { name: "Utils" } + + Depends { name: "Qt.widgets" } + Depends { name: "Qt.network" } // TODO: See above + + files: [ + "clangstaticanalyzerconfigwidget.cpp", + "clangstaticanalyzerconfigwidget.h", + "clangstaticanalyzerconfigwidget.ui", + "clangstaticanalyzerconstants.h", + "clangstaticanalyzerdiagnostic.cpp", + "clangstaticanalyzerdiagnostic.h", + "clangstaticanalyzerdiagnosticmodel.cpp", + "clangstaticanalyzerdiagnosticmodel.h", + "clangstaticanalyzerdiagnosticview.cpp", + "clangstaticanalyzerdiagnosticview.h", + "clangstaticanalyzerlogfilereader.cpp", + "clangstaticanalyzerlogfilereader.h", + "clangstaticanalyzerplugin.cpp", + "clangstaticanalyzerplugin.h", + "clangstaticanalyzerruncontrol.cpp", + "clangstaticanalyzerruncontrol.h", + "clangstaticanalyzerruncontrolfactory.cpp", + "clangstaticanalyzerruncontrolfactory.h", + "clangstaticanalyzerrunner.cpp", + "clangstaticanalyzerrunner.h", + "clangstaticanalyzersettings.cpp", + "clangstaticanalyzersettings.h", + "clangstaticanalyzertool.cpp", + "clangstaticanalyzertool.h", + "clangstaticanalyzerutils.cpp", + "clangstaticanalyzerutils.h", + "clangstaticanalyzer_global.h", + ] +} -- cgit v1.2.3