RunControl: Handle also ProjectInfo::CompilerCallData

...if it's available.

Change-Id: I41b8ab30e0c87ddd223f115e759bbd2a2c86cc68
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2014-10-30 11:57:09 +01:00
parent 36d306c5ba
commit 22003c8ea0
2 changed files with 107 additions and 55 deletions

View File

@@ -58,27 +58,103 @@ ClangStaticAnalyzerRunControl::ClangStaticAnalyzerRunControl(
{ {
} }
static QList<ClangStaticAnalyzerRunControl::SourceFileConfiguration> calculateFilesToProcess( // Removes (1) filePath (2) -o <somePath>
Project *project) static QStringList tweakedArguments(const QString &filePath, const QStringList &arguments)
{ {
typedef ClangStaticAnalyzerRunControl::SourceFileConfiguration SourceFileConfiguration; QStringList newArguments;
QTC_ASSERT(project, return QList<SourceFileConfiguration>());
ProjectInfo projectInfo = CppModelManager::instance()->projectInfo(project); bool skip = false;
QTC_ASSERT(projectInfo.isValid(), return QList<SourceFileConfiguration>()); 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<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyzeFromCompilerCallData(
const ProjectInfo::CompilerCallData &compilerCallData)
{
typedef ClangStaticAnalyzerRunControl::AnalyzeUnit AnalyzeUnit;
qCDebug(LOG) << "Taking arguments for analyzing from CompilerCallData.";
QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyze;
QHashIterator<QString, QList<QStringList> > it(compilerCallData);
while (it.hasNext()) {
it.next();
const QString file = it.key();
const QList<QStringList> compilerCalls = it.value();
foreach (const QStringList &options, compilerCalls) {
const QStringList arguments = tweakedArguments(file, options);
unitsToAnalyze << AnalyzeUnit(file, arguments);
}
}
return unitsToAnalyze;
}
static QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyzeFromProjectParts(
const QList<ProjectPart::Ptr> projectParts)
{
typedef ClangStaticAnalyzerRunControl::AnalyzeUnit AnalyzeUnit;
qCDebug(LOG) << "Taking arguments for analyzing from ProjectParts.";
QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyze;
QList<SourceFileConfiguration> files;
const QList<ProjectPart::Ptr> projectParts = projectInfo.projectParts();
foreach (const ProjectPart::Ptr &projectPart, projectParts) { foreach (const ProjectPart::Ptr &projectPart, projectParts) {
foreach (const ProjectFile &file, projectPart->files) { foreach (const ProjectFile &file, projectPart->files) {
if (file.path == CppModelManager::configurationFileName()) if (file.path == CppModelManager::configurationFileName())
continue; continue;
QTC_CHECK(file.kind != ProjectFile::Unclassified); QTC_CHECK(file.kind != ProjectFile::Unclassified);
if (ProjectFile::isSource(file.kind)) if (ProjectFile::isSource(file.kind)) {
files << SourceFileConfiguration(file, projectPart); const QStringList arguments = argumentsFromProjectPart(projectPart, file.kind);
unitsToAnalyze << AnalyzeUnit(file.path, arguments);
}
} }
} }
return files; return unitsToAnalyze;
}
static QList<ClangStaticAnalyzerRunControl::AnalyzeUnit> unitsToAnalyze(Project *project)
{
QTC_ASSERT(project, return QList<ClangStaticAnalyzerRunControl::AnalyzeUnit>());
ProjectInfo projectInfo = CppModelManager::instance()->projectInfo(project);
QTC_ASSERT(projectInfo.isValid(), return QList<ClangStaticAnalyzerRunControl::AnalyzeUnit>());
const ProjectInfo::CompilerCallData compilerCallData = projectInfo.compilerCallData();
if (!compilerCallData.isEmpty())
return unitsToAnalyzeFromCompilerCallData(compilerCallData);
return unitsToAnalyzeFromProjectParts(projectInfo.projectParts());
} }
bool ClangStaticAnalyzerRunControl::startEngine() bool ClangStaticAnalyzerRunControl::startEngine()
@@ -120,14 +196,12 @@ bool ClangStaticAnalyzerRunControl::startEngine()
m_clangLogFileDir = temporaryDir.path(); m_clangLogFileDir = temporaryDir.path();
// Collect files // Collect files
const QList<SourceFileConfiguration> filesToProcess = calculateFilesToProcess(project); const QList<AnalyzeUnit> filesToProcess = unitsToAnalyze(project);
qCDebug(LOG) << "Files to process:"; qCDebug(LOG) << "Files to process:";
foreach (const SourceFileConfiguration &fileConfig, filesToProcess) { foreach (const AnalyzeUnit &fileConfig, filesToProcess)
qCDebug(LOG) << fileConfig.file.path + QLatin1String(" [") qCDebug(LOG) << fileConfig.file;
+ fileConfig.projectPart->projectFile + QLatin1Char(']'); m_unitsToProcess = filesToProcess;
} m_initialFilesToProcessSize = m_unitsToProcess.count();
m_filesToProcess = filesToProcess;
m_initialFilesToProcessSize = m_filesToProcess.count();
m_filesAnalyzed = 0; m_filesAnalyzed = 0;
m_filesNotAnalyzed = 0; m_filesNotAnalyzed = 0;
@@ -145,7 +219,7 @@ bool ClangStaticAnalyzerRunControl::startEngine()
m_runners.clear(); m_runners.clear();
const int parallelRuns = ClangStaticAnalyzerSettings::instance()->simultaneousProcesses(); const int parallelRuns = ClangStaticAnalyzerSettings::instance()->simultaneousProcesses();
QTC_ASSERT(parallelRuns >= 1, emit finished(); return false); 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(); analyzeNextFile();
return true; return true;
} }
@@ -159,7 +233,7 @@ void ClangStaticAnalyzerRunControl::stopEngine()
delete runner; delete runner;
} }
m_runners.clear(); m_runners.clear();
m_filesToProcess.clear(); m_unitsToProcess.clear();
appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'), appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'),
Utils::NormalMessageFormat); Utils::NormalMessageFormat);
m_progress.reportFinished(); m_progress.reportFinished();
@@ -171,7 +245,7 @@ void ClangStaticAnalyzerRunControl::analyzeNextFile()
if (m_progress.isFinished()) if (m_progress.isFinished())
return; // The previous call already reported that we are finished. return; // The previous call already reported that we are finished.
if (m_filesToProcess.isEmpty()) { if (m_unitsToProcess.isEmpty()) {
if (m_runners.size() == 0) { if (m_runners.size() == 0) {
appendMessage(tr("Clang Static Analyzer finished: " appendMessage(tr("Clang Static Analyzer finished: "
"Processed %1 files successfully, %2 failed.") "Processed %1 files successfully, %2 failed.")
@@ -185,15 +259,14 @@ void ClangStaticAnalyzerRunControl::analyzeNextFile()
return; return;
} }
const SourceFileConfiguration config = m_filesToProcess.takeFirst(); const AnalyzeUnit unit = m_unitsToProcess.takeFirst();
const QString filePath = config.file.path; qCDebug(LOG) << "analyzeNextFile:" << unit.file;
const QStringList options = config.createClangOptions();
ClangStaticAnalyzerRunner *runner = createRunner(); ClangStaticAnalyzerRunner *runner = createRunner();
m_runners.insert(runner); m_runners.insert(runner);
qCDebug(LOG) << "analyzeNextFile:" << filePath; QTC_ASSERT(runner->run(unit.file, unit.arguments), return);
QTC_ASSERT(runner->run(filePath, options), return);
appendMessage(tr("Analyzing \"%1\".").arg(filePath) + QLatin1Char('\n'), appendMessage(tr("Analyzing \"%1\".").arg(unit.file) + QLatin1Char('\n'),
Utils::StdOutFormat); Utils::StdOutFormat);
} }
@@ -264,24 +337,7 @@ void ClangStaticAnalyzerRunControl::onProgressCanceled()
void ClangStaticAnalyzerRunControl::updateProgressValue() void ClangStaticAnalyzerRunControl::updateProgressValue()
{ {
m_progress.setProgressValue(m_initialFilesToProcessSize - m_filesToProcess.size()); m_progress.setProgressValue(m_initialFilesToProcessSize - m_unitsToProcess.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;
} }
} // namespace Internal } // namespace Internal

View File

@@ -36,16 +36,12 @@ class ClangStaticAnalyzerRunControl : public Analyzer::AnalyzerRunControl
Q_OBJECT Q_OBJECT
public: public:
struct SourceFileConfiguration { struct AnalyzeUnit {
SourceFileConfiguration(const CppTools::ProjectFile &projectFile, AnalyzeUnit(const QString &file, const QStringList &options)
const CppTools::ProjectPart::Ptr &projectPart) : file(file), arguments(options) {}
: file(projectFile)
, projectPart(projectPart) {}
QStringList createClangOptions() const; QString file;
QStringList arguments; // without file itself and "-o somePath"
CppTools::ProjectFile file;
CppTools::ProjectPart::Ptr projectPart;
}; };
public: public:
@@ -73,7 +69,7 @@ private:
QString m_clangExecutable; QString m_clangExecutable;
QString m_clangLogFileDir; QString m_clangLogFileDir;
QFutureInterface<void> m_progress; QFutureInterface<void> m_progress;
QList<SourceFileConfiguration> m_filesToProcess; QList<AnalyzeUnit> m_unitsToProcess;
QSet<ClangStaticAnalyzerRunner *> m_runners; QSet<ClangStaticAnalyzerRunner *> m_runners;
int m_initialFilesToProcessSize; int m_initialFilesToProcessSize;
int m_filesAnalyzed; int m_filesAnalyzed;