ClangCodeModel: Support setting additional preprocessor directives

... for a document.
This was only ever implemented for the built-in code model.

Fixes: QTCREATORBUG-20423
Change-Id: Ia99d0136e9995a5626058ad06173ea077be024d8
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2022-09-08 15:27:55 +02:00
parent fbd4775f89
commit f7efefb6d4
7 changed files with 54 additions and 35 deletions

View File

@@ -335,7 +335,7 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
= CppEditor::ClangdSettings(d->settings).clangdIncludePath();
CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
*CppEditor::CppModelManager::instance()->fallbackProjectPart(),
warningsConfigForProject(nullptr), includeDir);
warningsConfigForProject(nullptr), includeDir, {});
const CppEditor::UsePrecompiledHeaders usePch = CppEditor::getPchUsage();
const QJsonArray projectPartOptions = fullProjectPartOptions(
optionsBuilder, globalClangOptions());
@@ -714,23 +714,26 @@ void ClangdClient::handleUiHeaderChange(const QString &fileName)
void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
const CppEditor::BaseEditorDocumentParser::Configuration &config)
{
if (config.preferredProjectPartId.isEmpty())
return;
CppEditor::BaseEditorDocumentParser::Configuration &cachedConfig = d->parserConfigs[filePath];
if (cachedConfig == config)
return;
cachedConfig = config;
// TODO: Also handle editorDefines (and usePrecompiledHeaders?)
const auto projectPart = CppEditor::CppModelManager::instance()
->projectPartForId(config.preferredProjectPartId);
// TODO: Also handle usePrecompiledHeaders?
const auto projectPart = !config.preferredProjectPartId.isEmpty()
? CppEditor::CppModelManager::instance()->projectPartForId(
config.preferredProjectPartId)
: projectPartForFile(filePath.toString());
if (!projectPart)
return;
CppEditor::BaseEditorDocumentParser::Configuration fullConfig = config;
fullConfig.preferredProjectPartId = projectPart->id();
CppEditor::BaseEditorDocumentParser::Configuration &cachedConfig = d->parserConfigs[filePath];
if (cachedConfig == fullConfig)
return;
cachedConfig = fullConfig;
QJsonObject cdbChanges;
const Utils::FilePath includeDir = CppEditor::ClangdSettings(d->settings).clangdIncludePath();
CppEditor::CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
*projectPart, warningsConfigForProject(project()), includeDir);
*projectPart, warningsConfigForProject(project()), includeDir,
ProjectExplorer::Macro::toMacros(config.editorDefines));
const CppEditor::ProjectFile file(filePath.toString(),
CppEditor::ProjectFile::classify(filePath.toString()));
const QJsonArray projectPartOptions = fullProjectPartOptions(
@@ -742,6 +745,7 @@ void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
DidChangeConfigurationParams configChangeParams;
configChangeParams.setSettings(settings);
sendMessage(DidChangeConfigurationNotification(configChangeParams));
emit configChanged();
}
void ClangdClient::switchIssuePaneEntries(const Utils::FilePath &filePath)

View File

@@ -114,6 +114,7 @@ signals:
const Utils::FilePath &file);
void proposalReady(TextEditor::IAssistProposal *proposal);
void textMarkCreated(const Utils::FilePath &file);
void configChanged();
private:
void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams &params) override;

View File

@@ -3,12 +3,10 @@
#include "clangeditordocumentprocessor.h"
#include "clangdiagnostictooltipwidget.h"
#include "clangfixitoperation.h"
#include "clangmodelmanagersupport.h"
#include "clangutils.h"
#include <cppeditor/builtincursorinfo.h>
#include <cppeditor/builtineditordocumentparser.h>
#include <cppeditor/clangdiagnosticconfigsmodel.h>
#include <cppeditor/compileroptionsbuilder.h>
#include <cppeditor/cppcodemodelsettings.h>
@@ -41,6 +39,11 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(TextEditor::TextDocum
{
connect(parser().data(), &CppEditor::BaseEditorDocumentParser::projectPartInfoUpdated,
this, &BaseEditorDocumentProcessor::projectPartInfoUpdated);
connect(static_cast<CppEditor::BuiltinEditorDocumentParser *>(parser().data()),
&CppEditor::BuiltinEditorDocumentParser::finished,
this, [this] {
emit parserConfigChanged(Utils::FilePath::fromString(filePath()), parserConfig());
});
setSemanticHighlightingChecker([this] {
return !ClangModelManagerSupport::clientForFile(m_document.filePath());
});

View File

@@ -171,7 +171,7 @@ GenerateCompilationDbResult generateCompilationDB(QList<ProjectInfo::ConstPtr> p
QTC_ASSERT(projectInfo, continue);
QStringList args;
const CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder(
*projectPart, warningsConfig, clangIncludeDir);
*projectPart, warningsConfig, clangIncludeDir, {});
QJsonArray ppOptions;
if (purpose == CompilationDbPurpose::Project) {
args = projectPartArguments(*projectPart);
@@ -328,7 +328,8 @@ QString textUntilPreviousStatement(TextEditor::TextDocumentManipulatorInterface
CompilerOptionsBuilder clangOptionsBuilder(const ProjectPart &projectPart,
const ClangDiagnosticConfig &warningsConfig,
const Utils::FilePath &clangIncludeDir)
const FilePath &clangIncludeDir,
const Macros &extraMacros)
{
const auto useBuildSystemWarnings = warningsConfig.useBuildSystemWarnings()
? UseBuildSystemWarnings::Yes
@@ -336,7 +337,9 @@ CompilerOptionsBuilder clangOptionsBuilder(const ProjectPart &projectPart,
CompilerOptionsBuilder optionsBuilder(projectPart, UseSystemHeader::No,
UseTweakedHeaderPaths::Yes, UseLanguageDefines::No,
useBuildSystemWarnings, clangIncludeDir);
optionsBuilder.provideAdditionalMacros({ProjectExplorer::Macro("Q_CREATOR_RUN", "1")});
Macros fullMacroList = extraMacros;
fullMacroList += Macro("Q_CREATOR_RUN", "1");
optionsBuilder.provideAdditionalMacros(fullMacroList);
optionsBuilder.build(ProjectFile::Unclassified, UsePrecompiledHeaders::No);
optionsBuilder.add("-fmessage-length=0", /*gccOnlyOption=*/true);
optionsBuilder.add("-fdiagnostics-show-note-include-stack", /*gccOnlyOption=*/true);

View File

@@ -35,7 +35,8 @@ const QStringList globalClangOptions();
CppEditor::CompilerOptionsBuilder clangOptionsBuilder(
const CppEditor::ProjectPart &projectPart,
const CppEditor::ClangDiagnosticConfig &warningsConfig,
const Utils::FilePath &clangIncludeDir);
const Utils::FilePath &clangIncludeDir,
const ProjectExplorer::Macros &extraMacros);
QJsonArray projectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder);
QJsonArray fullProjectPartOptions(const CppEditor::CompilerOptionsBuilder &optionsBuilder,
const QStringList &projectOptions);

View File

@@ -20,6 +20,7 @@
#include <projectexplorer/target.h>
#include <texteditor/codeassist/assistproposaliteminterface.h>
#include <texteditor/codeassist/textdocumentmanipulatorinterface.h>
#include <texteditor/textmark.h>
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/filepath.h>
@@ -2001,6 +2002,15 @@ ClangdTestExternalChanges::ClangdTestExternalChanges()
void ClangdTestExternalChanges::test()
{
ClangdClient * const oldClient = client();
QVERIFY(oldClient);
// Wait until things have settled.
while (true) {
if (!waitForSignalOrTimeout(oldClient, &ClangdClient::configChanged, timeOutInMs()))
break;
}
// Break a header file that is used, but not open in Creator.
// Neither we nor the server should notice, and no diagnostics should be shown for the
// source file that includes the now-broken header.
@@ -2008,14 +2018,15 @@ void ClangdTestExternalChanges::test()
QVERIFY(header.open(QIODevice::WriteOnly));
header.write("blubb");
header.close();
ClangdClient * const oldClient = client();
QVERIFY(oldClient);
waitForSignalOrTimeout(LanguageClientManager::instance(),
&LanguageClientManager::clientAdded, timeOutInMs());
QCOMPARE(client(), oldClient);
QCOMPARE(client(), ClangModelManagerSupport::clientForProject(project()));
const TextDocument * const curDoc = document("main.cpp");
QVERIFY(curDoc);
if (!curDoc->marks().isEmpty())
for (const auto &m : curDoc->marks())
qDebug() << m->lineAnnotation();
QVERIFY(curDoc->marks().isEmpty());
// Now trigger an external change in an open, but not currently visible file and

View File

@@ -507,8 +507,6 @@ void CppEditorWidget::finalizeInitialization()
// clang-format on
// Toolbar: '#' Button
// TODO: Make "Additional Preprocessor Directives" also useful with Clang Code Model.
if (!d->m_modelManager->isClangCodeModelActive()) {
d->m_preprocessorButton = new QToolButton(this);
d->m_preprocessorButton->setText(QLatin1String("#"));
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
@@ -517,9 +515,7 @@ void CppEditorWidget::finalizeInitialization()
updatePreprocessorButtonTooltip();
connect(d->m_preprocessorButton, &QAbstractButton::clicked,
this, &CppEditorWidget::showPreProcessorWidget);
insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
}
connect(this, &TextEditor::TextEditorWidget::toolbarOutlineChanged,
this, &CppEditorWidget::handleOutlineChanged);