forked from qt-creator/qt-creator
ClangTools: Use compilation database when running clang-tidy and clazy
Fixes: QTCREATORBUG-29529 Change-Id: I917c53352e448dfd9e58e7a6e4dabb71e8f79491 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -21,6 +21,7 @@ add_qtc_plugin(ClangTools
|
|||||||
clangtool.cpp clangtool.h
|
clangtool.cpp clangtool.h
|
||||||
clangtoolrunner.cpp clangtoolrunner.h
|
clangtoolrunner.cpp clangtoolrunner.h
|
||||||
clangtools_global.h
|
clangtools_global.h
|
||||||
|
clangtoolscompilationdb.cpp clangtoolscompilationdb.h
|
||||||
clangtoolstr.h
|
clangtoolstr.h
|
||||||
clangtoolsconstants.h
|
clangtoolsconstants.h
|
||||||
clangtoolsdiagnostic.cpp clangtoolsdiagnostic.h
|
clangtoolsdiagnostic.cpp clangtoolsdiagnostic.h
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "clangselectablefilesdialog.h"
|
#include "clangselectablefilesdialog.h"
|
||||||
#include "clangtoolrunner.h"
|
#include "clangtoolrunner.h"
|
||||||
|
#include "clangtoolscompilationdb.h"
|
||||||
#include "clangtoolsconstants.h"
|
#include "clangtoolsconstants.h"
|
||||||
#include "clangtoolsdiagnosticview.h"
|
#include "clangtoolsdiagnosticview.h"
|
||||||
#include "clangtoolsprojectsettings.h"
|
#include "clangtoolsprojectsettings.h"
|
||||||
@@ -753,7 +754,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings,
|
|||||||
for (const FileInfo &fileInfo : fileInfos) {
|
for (const FileInfo &fileInfo : fileInfos) {
|
||||||
if (diagnosticConfig.isEnabled(tool)
|
if (diagnosticConfig.isEnabled(tool)
|
||||||
|| runSettings.hasConfigFileForSourceFile(fileInfo.file)) {
|
|| runSettings.hasConfigFileForSourceFile(fileInfo.file)) {
|
||||||
unitsToProcess.append({fileInfo, includeDir, clangVersion});
|
unitsToProcess.append({fileInfo, tool});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qCDebug(LOG) << Q_FUNC_INFO << executable << includeDir << clangVersion;
|
qCDebug(LOG) << Q_FUNC_INFO << executable << includeDir << clangVersion;
|
||||||
@@ -798,7 +799,8 @@ Group ClangTool::runRecipe(const RunSettings &runSettings,
|
|||||||
const AnalyzeInputData input{tool, runSettings, diagnosticConfig, tempDir->path(),
|
const AnalyzeInputData input{tool, runSettings, diagnosticConfig, tempDir->path(),
|
||||||
environment};
|
environment};
|
||||||
|
|
||||||
taskTree.setRecipe({clangToolTask(unitsToProcess, input, setupHandler, outputHandler)});
|
taskTree.setRecipe(
|
||||||
|
{clangToolTask(tool, unitsToProcess, input, setupHandler, outputHandler)});
|
||||||
return SetupResult::Continue;
|
return SetupResult::Continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -830,6 +832,9 @@ Group ClangTool::runRecipe(const RunSettings &runSettings,
|
|||||||
void ClangTool::startTool(FileSelection fileSelection, const RunSettings &runSettings,
|
void ClangTool::startTool(FileSelection fileSelection, const RunSettings &runSettings,
|
||||||
const ClangDiagnosticConfig &diagnosticConfig)
|
const ClangDiagnosticConfig &diagnosticConfig)
|
||||||
{
|
{
|
||||||
|
ClangToolsCompilationDb &db = ClangToolsCompilationDb::getDb(m_type);
|
||||||
|
db.disconnect(this);
|
||||||
|
|
||||||
Project *project = ProjectManager::startupProject();
|
Project *project = ProjectManager::startupProject();
|
||||||
QTC_ASSERT(project, return);
|
QTC_ASSERT(project, return);
|
||||||
QTC_ASSERT(project->activeTarget(), return);
|
QTC_ASSERT(project->activeTarget(), return);
|
||||||
@@ -841,6 +846,14 @@ void ClangTool::startTool(FileSelection fileSelection, const RunSettings &runSet
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (db.generateIfNecessary()) {
|
||||||
|
connect(&db, &ClangToolsCompilationDb::generated, this, [=, this](bool success) {
|
||||||
|
if (success)
|
||||||
|
startTool(fileSelection, runSettings, diagnosticConfig);
|
||||||
|
}, Qt::SingleShotConnection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TaskHub::clearTasks(taskCategory());
|
TaskHub::clearTasks(taskCategory());
|
||||||
|
|
||||||
// Collect files to analyze
|
// Collect files to analyze
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "clangtoolrunner.h"
|
#include "clangtoolrunner.h"
|
||||||
|
|
||||||
|
#include "clangtoolscompilationdb.h"
|
||||||
#include "clangtoolslogfilereader.h"
|
#include "clangtoolslogfilereader.h"
|
||||||
#include "clangtoolstr.h"
|
#include "clangtoolstr.h"
|
||||||
#include "clangtoolsutils.h"
|
#include "clangtoolsutils.h"
|
||||||
@@ -34,31 +35,6 @@ using namespace Tasking;
|
|||||||
namespace ClangTools {
|
namespace ClangTools {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
AnalyzeUnit::AnalyzeUnit(const FileInfo &fileInfo,
|
|
||||||
const FilePath &clangIncludeDir,
|
|
||||||
const QString &clangVersion)
|
|
||||||
{
|
|
||||||
const FilePath actualClangIncludeDir = Core::ICore::clangIncludeDirectory(
|
|
||||||
clangVersion, clangIncludeDir);
|
|
||||||
CompilerOptionsBuilder optionsBuilder(*fileInfo.projectPart,
|
|
||||||
UseSystemHeader::No,
|
|
||||||
UseTweakedHeaderPaths::Tools,
|
|
||||||
UseLanguageDefines::No,
|
|
||||||
UseBuildSystemWarnings::No,
|
|
||||||
actualClangIncludeDir);
|
|
||||||
file = fileInfo.file;
|
|
||||||
arguments = extraClangToolsPrependOptions();
|
|
||||||
arguments.append(
|
|
||||||
optionsBuilder.build(fileInfo.kind,
|
|
||||||
CppCodeModelSettings(fileInfo.settings).usePrecompiledHeaders()));
|
|
||||||
arguments.append(extraClangToolsAppendOptions());
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isClMode(const QStringList &options)
|
|
||||||
{
|
|
||||||
return options.contains("--driver-mode=cl");
|
|
||||||
}
|
|
||||||
|
|
||||||
static QStringList checksArguments(const AnalyzeUnit &unit, const AnalyzeInputData &input)
|
static QStringList checksArguments(const AnalyzeUnit &unit, const AnalyzeInputData &input)
|
||||||
{
|
{
|
||||||
if (input.tool == ClangToolType::Tidy) {
|
if (input.tool == ClangToolType::Tidy) {
|
||||||
@@ -78,24 +54,6 @@ static QStringList checksArguments(const AnalyzeUnit &unit, const AnalyzeInputDa
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static QStringList clangArguments(const AnalyzeUnit &unit, const AnalyzeInputData &input)
|
|
||||||
{
|
|
||||||
QStringList arguments;
|
|
||||||
const ClangDiagnosticConfig &diagnosticConfig = input.config;
|
|
||||||
const QStringList &baseOptions = unit.arguments;
|
|
||||||
arguments << ClangDiagnosticConfigsModel::globalDiagnosticOptions()
|
|
||||||
<< (isClMode(baseOptions) ? clangArgsForCl(diagnosticConfig.clangOptions())
|
|
||||||
: diagnosticConfig.clangOptions())
|
|
||||||
<< baseOptions;
|
|
||||||
if (ProjectFile::isHeader(unit.file))
|
|
||||||
arguments << "-Wno-pragma-once-outside-header";
|
|
||||||
|
|
||||||
if (LOG().isDebugEnabled())
|
|
||||||
arguments << QLatin1String("-v");
|
|
||||||
|
|
||||||
return arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FilePath createOutputFilePath(const FilePath &dirPath, const FilePath &fileToAnalyze)
|
static FilePath createOutputFilePath(const FilePath &dirPath, const FilePath &fileToAnalyze)
|
||||||
{
|
{
|
||||||
const QString fileName = fileToAnalyze.fileName();
|
const QString fileName = fileToAnalyze.fileName();
|
||||||
@@ -111,7 +69,8 @@ static FilePath createOutputFilePath(const FilePath &dirPath, const FilePath &fi
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupItem clangToolTask(const AnalyzeUnits &units,
|
GroupItem clangToolTask(CppEditor::ClangToolType toolType,
|
||||||
|
const AnalyzeUnits &units,
|
||||||
const AnalyzeInputData &input,
|
const AnalyzeInputData &input,
|
||||||
const AnalyzeSetupHandler &setupHandler,
|
const AnalyzeSetupHandler &setupHandler,
|
||||||
const AnalyzeOutputHandler &outputHandler)
|
const AnalyzeOutputHandler &outputHandler)
|
||||||
@@ -124,8 +83,9 @@ GroupItem clangToolTask(const AnalyzeUnits &units,
|
|||||||
const Storage<ClangToolStorage> storage;
|
const Storage<ClangToolStorage> storage;
|
||||||
const LoopList iterator(units);
|
const LoopList iterator(units);
|
||||||
|
|
||||||
const auto mainToolArguments = [input, iterator](const ClangToolStorage &data) {
|
const auto mainToolArguments = [input, iterator, toolType](const ClangToolStorage &data) {
|
||||||
QStringList result;
|
QStringList result;
|
||||||
|
result << "-p" << ClangToolsCompilationDb::getDb(toolType).parentDir().nativePath();
|
||||||
result << "-export-fixes=" + data.outputFilePath.nativePath();
|
result << "-export-fixes=" + data.outputFilePath.nativePath();
|
||||||
if (!input.overlayFilePath.isEmpty() && isVFSOverlaySupported(data.executable))
|
if (!input.overlayFilePath.isEmpty() && isVFSOverlaySupported(data.executable))
|
||||||
result << "--vfsoverlay=" + input.overlayFilePath;
|
result << "--vfsoverlay=" + input.overlayFilePath;
|
||||||
@@ -146,8 +106,6 @@ GroupItem clangToolTask(const AnalyzeUnits &units,
|
|||||||
return SetupResult::StopWithError;
|
return SetupResult::StopWithError;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTC_CHECK(!unit.arguments.contains(QLatin1String("-o")));
|
|
||||||
QTC_CHECK(!unit.arguments.contains(unit.file.nativePath()));
|
|
||||||
QTC_ASSERT(unit.file.exists(), return SetupResult::StopWithError);
|
QTC_ASSERT(unit.file.exists(), return SetupResult::StopWithError);
|
||||||
data->outputFilePath = createOutputFilePath(input.outputDirPath, unit.file);
|
data->outputFilePath = createOutputFilePath(input.outputDirPath, unit.file);
|
||||||
QTC_ASSERT(!data->outputFilePath.isEmpty(), return SetupResult::StopWithError);
|
QTC_ASSERT(!data->outputFilePath.isEmpty(), return SetupResult::StopWithError);
|
||||||
@@ -163,8 +121,7 @@ GroupItem clangToolTask(const AnalyzeUnits &units,
|
|||||||
|
|
||||||
const ClangToolStorage &data = *storage;
|
const ClangToolStorage &data = *storage;
|
||||||
const CommandLine commandLine{data.executable, {checksArguments(unit, input),
|
const CommandLine commandLine{data.executable, {checksArguments(unit, input),
|
||||||
mainToolArguments(data), "--",
|
mainToolArguments(data)}};
|
||||||
clangArguments(unit, input)}};
|
|
||||||
qCDebug(LOG).noquote() << "Starting" << commandLine.toUserOutput();
|
qCDebug(LOG).noquote() << "Starting" << commandLine.toUserOutput();
|
||||||
process.setCommand(commandLine);
|
process.setCommand(commandLine);
|
||||||
};
|
};
|
||||||
|
@@ -19,12 +19,14 @@ namespace Internal {
|
|||||||
|
|
||||||
struct AnalyzeUnit
|
struct AnalyzeUnit
|
||||||
{
|
{
|
||||||
AnalyzeUnit(const FileInfo &fileInfo,
|
AnalyzeUnit(const FileInfo &fileInfo, CppEditor::ClangToolType toolType)
|
||||||
const Utils::FilePath &clangResourceDir,
|
: file(fileInfo.file)
|
||||||
const QString &clangVersion);
|
, toolType(toolType)
|
||||||
|
{}
|
||||||
|
|
||||||
Utils::FilePath file;
|
Utils::FilePath file;
|
||||||
QStringList arguments; // without file itself and "-o somePath"
|
CppEditor::ClangToolType toolType;
|
||||||
|
|
||||||
};
|
};
|
||||||
using AnalyzeUnits = QList<AnalyzeUnit>;
|
using AnalyzeUnits = QList<AnalyzeUnit>;
|
||||||
|
|
||||||
@@ -53,7 +55,8 @@ struct AnalyzeOutputData
|
|||||||
using AnalyzeSetupHandler = std::function<bool(const AnalyzeUnit &)>;
|
using AnalyzeSetupHandler = std::function<bool(const AnalyzeUnit &)>;
|
||||||
using AnalyzeOutputHandler = std::function<void(const AnalyzeOutputData &)>;
|
using AnalyzeOutputHandler = std::function<void(const AnalyzeOutputData &)>;
|
||||||
|
|
||||||
Tasking::GroupItem clangToolTask(const AnalyzeUnits &units,
|
Tasking::GroupItem clangToolTask(CppEditor::ClangToolType toolType,
|
||||||
|
const AnalyzeUnits &units,
|
||||||
const AnalyzeInputData &input,
|
const AnalyzeInputData &input,
|
||||||
const AnalyzeSetupHandler &setupHandler,
|
const AnalyzeSetupHandler &setupHandler,
|
||||||
const AnalyzeOutputHandler &outputHandler);
|
const AnalyzeOutputHandler &outputHandler);
|
||||||
|
@@ -33,6 +33,8 @@ QtcPlugin {
|
|||||||
"clangtoolrunner.cpp",
|
"clangtoolrunner.cpp",
|
||||||
"clangtoolrunner.h",
|
"clangtoolrunner.h",
|
||||||
"clangtools_global.h",
|
"clangtools_global.h",
|
||||||
|
"clangtoolscompilationdb.cpp",
|
||||||
|
"clangtoolscompilationdb.h",
|
||||||
"clangtoolstr.h",
|
"clangtoolstr.h",
|
||||||
"clangtoolsconstants.h",
|
"clangtoolsconstants.h",
|
||||||
"clangtoolsdiagnostic.cpp",
|
"clangtoolsdiagnostic.cpp",
|
||||||
|
162
src/plugins/clangtools/clangtoolscompilationdb.cpp
Normal file
162
src/plugins/clangtools/clangtoolscompilationdb.cpp
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "clangtoolscompilationdb.h"
|
||||||
|
|
||||||
|
#include "clangtoolsprojectsettings.h"
|
||||||
|
#include "clangtoolstr.h"
|
||||||
|
#include "clangtoolsutils.h"
|
||||||
|
#include "executableinfo.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/messagemanager.h>
|
||||||
|
#include <cppeditor/clangdiagnosticconfigsmodel.h>
|
||||||
|
#include <cppeditor/compilationdb.h>
|
||||||
|
#include <cppeditor/cppmodelmanager.h>
|
||||||
|
#include <utils/async.h>
|
||||||
|
#include <utils/futuresynchronizer.h>
|
||||||
|
#include <utils/temporarydirectory.h>
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace CppEditor;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
namespace ClangTools::Internal {
|
||||||
|
|
||||||
|
class ClangToolsCompilationDb::Private
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Private(ClangToolType toolType, ClangToolsCompilationDb *q) : q(q), toolType(toolType) {}
|
||||||
|
|
||||||
|
void generate();
|
||||||
|
QString toolName() const { return clangToolName(toolType); }
|
||||||
|
|
||||||
|
static inline std::unique_ptr<ClangToolsCompilationDb> clangTidyDb;
|
||||||
|
static inline std::unique_ptr<ClangToolsCompilationDb> clazyDb;
|
||||||
|
|
||||||
|
ClangToolsCompilationDb * const q;
|
||||||
|
const ClangToolType toolType;
|
||||||
|
TemporaryDirectory dir{toolName()};
|
||||||
|
QFutureWatcher<GenerateCompilationDbResult> generatorWatcher;
|
||||||
|
FutureSynchronizer generatorSynchronizer;
|
||||||
|
bool readyAndUpToDate = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
ClangToolsCompilationDb::ClangToolsCompilationDb(ClangToolType toolType)
|
||||||
|
: d(new Private(toolType, this))
|
||||||
|
{
|
||||||
|
connect(&d->generatorWatcher, &QFutureWatcher<GenerateCompilationDbResult>::finished,
|
||||||
|
this, [this] {
|
||||||
|
const auto result = d->generatorWatcher.result();
|
||||||
|
const bool success = result.has_value();
|
||||||
|
QTC_CHECK(!d->readyAndUpToDate);
|
||||||
|
d->readyAndUpToDate = success;
|
||||||
|
if (success) {
|
||||||
|
Core::MessageManager::writeSilently(
|
||||||
|
Tr::tr("Compilation database for %1 successfully generated at %2.")
|
||||||
|
.arg(d->toolName(), d->dir.path().toUserOutput()));
|
||||||
|
} else {
|
||||||
|
Core::MessageManager::writeDisrupting(
|
||||||
|
Tr::tr("Generating compilation database for %1 failed: %2")
|
||||||
|
.arg(d->toolName(), result.error()));
|
||||||
|
}
|
||||||
|
emit generated(success);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ClangToolsSettings::instance(), &BaseAspect::changed,
|
||||||
|
this, &ClangToolsCompilationDb::invalidate);
|
||||||
|
connect(CppModelManager::instance(), &CppModelManager::projectPartsUpdated,
|
||||||
|
this, &ClangToolsCompilationDb::invalidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClangToolsCompilationDb::~ClangToolsCompilationDb() { delete d; }
|
||||||
|
|
||||||
|
void ClangToolsCompilationDb::invalidate() { d->readyAndUpToDate = false; }
|
||||||
|
|
||||||
|
FilePath ClangToolsCompilationDb::parentDir() const { return d->dir.path(); }
|
||||||
|
|
||||||
|
bool ClangToolsCompilationDb::generateIfNecessary()
|
||||||
|
{
|
||||||
|
if (d->readyAndUpToDate)
|
||||||
|
return false;
|
||||||
|
d->generate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClangToolsCompilationDb &ClangToolsCompilationDb::getDb(ClangToolType toolType)
|
||||||
|
{
|
||||||
|
if (toolType == ClangToolType::Tidy) {
|
||||||
|
if (!Private::clangTidyDb)
|
||||||
|
Private::clangTidyDb.reset(new ClangToolsCompilationDb(toolType));
|
||||||
|
return *Private::clangTidyDb;
|
||||||
|
}
|
||||||
|
if (!Private::clazyDb)
|
||||||
|
Private::clazyDb.reset(new ClangToolsCompilationDb(toolType));
|
||||||
|
return *Private::clazyDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClangToolsCompilationDb::Private::generate()
|
||||||
|
{
|
||||||
|
QTC_CHECK(!readyAndUpToDate);
|
||||||
|
|
||||||
|
if (generatorWatcher.isRunning())
|
||||||
|
generatorWatcher.cancel();
|
||||||
|
|
||||||
|
Core::MessageManager::writeSilently(
|
||||||
|
Tr::tr("Generating compilation database for %1 at %2 ...")
|
||||||
|
.arg(clangToolName(toolType), dir.path().toUserOutput()));
|
||||||
|
|
||||||
|
const auto getCompilerOptionsBuilder = [this](const ProjectPart &pp) {
|
||||||
|
const auto projectSettings = ClangToolsProjectSettings::getSettings(pp.project());
|
||||||
|
QTC_ASSERT(projectSettings, return CompilerOptionsBuilder(pp));
|
||||||
|
connect(projectSettings.get(), &ClangToolsProjectSettings::changed,
|
||||||
|
q, &ClangToolsCompilationDb::invalidate);
|
||||||
|
const Id configId = projectSettings->runSettings().diagnosticConfigId();
|
||||||
|
const ClangDiagnosticConfig config = Utils::findOrDefault(
|
||||||
|
ClangToolsSettings::instance()->diagnosticConfigs(),
|
||||||
|
[configId](const ClangDiagnosticConfig &c) { return c.id() == configId; });
|
||||||
|
const auto useBuildSystemWarnings = config.useBuildSystemWarnings()
|
||||||
|
? UseBuildSystemWarnings::Yes
|
||||||
|
: UseBuildSystemWarnings::No;
|
||||||
|
|
||||||
|
const FilePath executable = toolExecutable(toolType);
|
||||||
|
const auto [includeDir, clangVersion] = getClangIncludeDirAndVersion(executable);
|
||||||
|
const FilePath actualClangIncludeDir = Core::ICore::clangIncludeDirectory(
|
||||||
|
clangVersion, includeDir);
|
||||||
|
|
||||||
|
CompilerOptionsBuilder optionsBuilder(pp,
|
||||||
|
UseSystemHeader::No,
|
||||||
|
UseTweakedHeaderPaths::Tools,
|
||||||
|
UseLanguageDefines::No,
|
||||||
|
useBuildSystemWarnings,
|
||||||
|
actualClangIncludeDir);
|
||||||
|
optionsBuilder.build(ProjectFile::Unclassified, UsePrecompiledHeaders::No);
|
||||||
|
if (useBuildSystemWarnings == UseBuildSystemWarnings::No) {
|
||||||
|
for (const QString &opt : config.clangOptions())
|
||||||
|
optionsBuilder.add(opt, true);
|
||||||
|
}
|
||||||
|
const QStringList extraArgsToPrepend = extraClangToolsPrependOptions();
|
||||||
|
for (const QString &arg : extraArgsToPrepend)
|
||||||
|
optionsBuilder.prepend(arg);
|
||||||
|
const QStringList extraArgsToAppend = extraClangToolsAppendOptions();
|
||||||
|
for (const QString &arg : extraArgsToAppend)
|
||||||
|
optionsBuilder.add(arg);
|
||||||
|
|
||||||
|
return optionsBuilder;
|
||||||
|
};
|
||||||
|
|
||||||
|
generatorWatcher.setFuture(
|
||||||
|
Utils::asyncRun(
|
||||||
|
&generateCompilationDB,
|
||||||
|
CppModelManager::projectInfos(),
|
||||||
|
dir.path(),
|
||||||
|
CompilationDbPurpose::Analysis,
|
||||||
|
ClangDiagnosticConfigsModel::globalDiagnosticOptions(),
|
||||||
|
getCompilerOptionsBuilder));
|
||||||
|
generatorSynchronizer.addFuture(generatorWatcher.future());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ClangTools::Internal
|
33
src/plugins/clangtools/clangtoolscompilationdb.h
Normal file
33
src/plugins/clangtools/clangtoolscompilationdb.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cppeditor/clangdiagnosticconfig.h>
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace ClangTools::Internal {
|
||||||
|
class ClangToolsCompilationDb : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
~ClangToolsCompilationDb();
|
||||||
|
|
||||||
|
bool generateIfNecessary();
|
||||||
|
Utils::FilePath parentDir() const;
|
||||||
|
|
||||||
|
static ClangToolsCompilationDb &getDb(CppEditor::ClangToolType toolType);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void generated(bool success);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit ClangToolsCompilationDb(CppEditor::ClangToolType toolType);
|
||||||
|
void invalidate();
|
||||||
|
|
||||||
|
class Private;
|
||||||
|
Private * const d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ClangTools::Internal
|
@@ -205,7 +205,7 @@ void DocumentClangToolRunner::run()
|
|||||||
const auto [includeDir, clangVersion] = getClangIncludeDirAndVersion(executable);
|
const auto [includeDir, clangVersion] = getClangIncludeDirAndVersion(executable);
|
||||||
if (includeDir.isEmpty() || clangVersion.isEmpty())
|
if (includeDir.isEmpty() || clangVersion.isEmpty())
|
||||||
return;
|
return;
|
||||||
const AnalyzeUnits units{{m_fileInfo, includeDir, clangVersion}};
|
const AnalyzeUnits units{{m_fileInfo, tool}};
|
||||||
const auto diagnosticFilter = [mappedPath = vfso().autoSavedFilePath(m_document)](
|
const auto diagnosticFilter = [mappedPath = vfso().autoSavedFilePath(m_document)](
|
||||||
const FilePath &path) { return path == mappedPath; };
|
const FilePath &path) { return path == mappedPath; };
|
||||||
const AnalyzeInputData input{tool,
|
const AnalyzeInputData input{tool,
|
||||||
@@ -219,7 +219,8 @@ void DocumentClangToolRunner::run()
|
|||||||
return !m_document->isModified() || isVFSOverlaySupported(executable);
|
return !m_document->isModified() || isVFSOverlaySupported(executable);
|
||||||
};
|
};
|
||||||
const auto outputHandler = [this](const AnalyzeOutputData &output) { onDone(output); };
|
const auto outputHandler = [this](const AnalyzeOutputData &output) { onDone(output); };
|
||||||
tasks.append(Group{finishAllAndSuccess, clangToolTask(units, input, setupHandler, outputHandler)});
|
tasks.append(Group{finishAllAndSuccess,
|
||||||
|
clangToolTask(tool, units, input, setupHandler, outputHandler)});
|
||||||
};
|
};
|
||||||
addClangTool(ClangToolType::Tidy);
|
addClangTool(ClangToolType::Tidy);
|
||||||
addClangTool(ClangToolType::Clazy);
|
addClangTool(ClangToolType::Clazy);
|
||||||
|
@@ -135,6 +135,8 @@ static QJsonObject createFileObject(const FilePath &buildDir,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
args = clangOptionsForFile(projFile, projectPart, projectPartOptions, usePch, clStyle);
|
args = clangOptionsForFile(projFile, projectPart, projectPartOptions, usePch, clStyle);
|
||||||
|
if (purpose == CompilationDbPurpose::Analysis && projFile.isHeader())
|
||||||
|
args << "-Wno-pragma-once-outside-header";
|
||||||
args.prepend("clang"); // TODO: clang-cl for MSVC targets? Does it matter at all what we put here?
|
args.prepend("clang"); // TODO: clang-cl for MSVC targets? Does it matter at all what we put here?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ class ClangDiagnosticConfig;
|
|||||||
|
|
||||||
using GenerateCompilationDbResult = Utils::expected_str<Utils::FilePath>;
|
using GenerateCompilationDbResult = Utils::expected_str<Utils::FilePath>;
|
||||||
using GetOptionsBuilder = std::function<CompilerOptionsBuilder(const ProjectPart &)>;
|
using GetOptionsBuilder = std::function<CompilerOptionsBuilder(const ProjectPart &)>;
|
||||||
enum class CompilationDbPurpose { Project, CodeModel };
|
enum class CompilationDbPurpose { Project, CodeModel, Analysis };
|
||||||
|
|
||||||
QJsonArray CPPEDITOR_EXPORT fullProjectPartOptions(
|
QJsonArray CPPEDITOR_EXPORT fullProjectPartOptions(
|
||||||
const CppEditor::CompilerOptionsBuilder &optionsBuilder,
|
const CppEditor::CompilerOptionsBuilder &optionsBuilder,
|
||||||
|
Reference in New Issue
Block a user