forked from qt-creator/qt-creator
Clang: turn off delayed template parsing
Fix templates highlight and completion on Windows Add UI to turn on/off delayed parsing (off by default) Task-number: QTCREATORBUG-17222 Change-Id: I0cd5e0bcfff2789cd938e4096829f777ff15957a Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -419,16 +419,24 @@ static QStringList warningOptions(CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
if (projectPart && projectPart->project) {
|
||||
ClangProjectSettings projectSettings(projectPart->project);
|
||||
if (!projectSettings.useGlobalWarningConfig()) {
|
||||
if (!projectSettings.useGlobalConfig()) {
|
||||
const Core::Id warningConfigId = projectSettings.warningConfigId();
|
||||
const CppTools::ClangDiagnosticConfigsModel configsModel(
|
||||
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
|
||||
if (configsModel.hasConfigWithId(warningConfigId))
|
||||
return configsModel.configWithId(warningConfigId).commandLineOptions();
|
||||
return configsModel.configWithId(warningConfigId).commandLineWarnings();
|
||||
}
|
||||
}
|
||||
|
||||
return CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineOptions();
|
||||
return CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings();
|
||||
}
|
||||
|
||||
static QStringList commandLineOptions(CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
if (!projectPart || !projectPart->project)
|
||||
return ClangProjectSettings::globalCommandLineOptions();
|
||||
|
||||
return ClangProjectSettings{projectPart->project}.commandLineOptions();
|
||||
}
|
||||
|
||||
static QStringList precompiledHeaderOptions(
|
||||
@@ -454,6 +462,7 @@ static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart
|
||||
{
|
||||
return languageOptions(filePath, projectPart)
|
||||
+ warningOptions(projectPart)
|
||||
+ commandLineOptions(projectPart)
|
||||
+ precompiledHeaderOptions(filePath, projectPart);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,15 +25,23 @@
|
||||
|
||||
#include "clangprojectsettings.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
static QString useGlobalWarningConfigKey()
|
||||
{ return QStringLiteral("ClangCodeModel.UseGlobalWarningConfig"); }
|
||||
static QString useGlobalConfigKey()
|
||||
{ return QStringLiteral("ClangCodeModel.UseGlobalConfig"); }
|
||||
|
||||
static QString warningConfigIdKey()
|
||||
{ return QStringLiteral("ClangCodeModel.WarningConfigId"); }
|
||||
|
||||
static QString customCommandLineKey()
|
||||
{ return QLatin1String("ClangCodeModel.CustomCommandLineKey"); }
|
||||
|
||||
ClangProjectSettings::ClangProjectSettings(ProjectExplorer::Project *project)
|
||||
: m_project(project)
|
||||
{
|
||||
@@ -55,31 +63,55 @@ void ClangProjectSettings::setWarningConfigId(const Core::Id &customConfigId)
|
||||
m_warningConfigId = customConfigId;
|
||||
}
|
||||
|
||||
bool ClangProjectSettings::useGlobalWarningConfig() const
|
||||
bool ClangProjectSettings::useGlobalConfig() const
|
||||
{
|
||||
return m_useGlobalWarningConfig;
|
||||
return m_useGlobalConfig;
|
||||
}
|
||||
|
||||
void ClangProjectSettings::setUseGlobalWarningConfig(bool useGlobalWarningConfig)
|
||||
void ClangProjectSettings::setUseGlobalConfig(bool useGlobalConfig)
|
||||
{
|
||||
m_useGlobalWarningConfig = useGlobalWarningConfig;
|
||||
m_useGlobalConfig = useGlobalConfig;
|
||||
}
|
||||
|
||||
QStringList ClangProjectSettings::commandLineOptions() const
|
||||
{
|
||||
return m_useGlobalConfig ? globalCommandLineOptions()
|
||||
: m_customCommandLineOptions;
|
||||
}
|
||||
|
||||
void ClangProjectSettings::setCommandLineOptions(const QStringList &options)
|
||||
{
|
||||
QTC_ASSERT(!m_useGlobalConfig, qDebug()
|
||||
<< "setCommandLineOptions was called while using global project config");
|
||||
m_customCommandLineOptions = options;
|
||||
}
|
||||
|
||||
void ClangProjectSettings::load()
|
||||
{
|
||||
const QVariant useGlobalConfigVariant = m_project->namedSettings(useGlobalWarningConfigKey());
|
||||
const QVariant useGlobalConfigVariant = m_project->namedSettings(useGlobalConfigKey());
|
||||
const bool useGlobalConfig = useGlobalConfigVariant.isValid()
|
||||
? useGlobalConfigVariant.toBool()
|
||||
: true;
|
||||
|
||||
setUseGlobalWarningConfig(useGlobalConfig);
|
||||
setUseGlobalConfig(useGlobalConfig);
|
||||
setWarningConfigId(Core::Id::fromSetting(m_project->namedSettings(warningConfigIdKey())));
|
||||
m_customCommandLineOptions = m_project->namedSettings(customCommandLineKey()).toStringList();
|
||||
if (m_customCommandLineOptions.empty())
|
||||
m_customCommandLineOptions = globalCommandLineOptions();
|
||||
}
|
||||
|
||||
void ClangProjectSettings::store()
|
||||
{
|
||||
m_project->setNamedSettings(useGlobalWarningConfigKey(), useGlobalWarningConfig());
|
||||
m_project->setNamedSettings(useGlobalConfigKey(), useGlobalConfig());
|
||||
m_project->setNamedSettings(warningConfigIdKey(), warningConfigId().toSetting());
|
||||
m_project->setNamedSettings(customCommandLineKey(), m_customCommandLineOptions);
|
||||
}
|
||||
|
||||
QStringList ClangProjectSettings::globalCommandLineOptions()
|
||||
{
|
||||
if (Utils::HostOsInfo::isWindowsHost())
|
||||
return {QLatin1String{GlobalWindowsCmdOptions}};
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -39,21 +39,32 @@ class ClangProjectSettings: public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
constexpr static const char* DelayedTemplateParsing = "-fdelayed-template-parsing";
|
||||
constexpr static const char* NoDelayedTemplateParsing = "-fno-delayed-template-parsing";
|
||||
constexpr static const char* GlobalWindowsCmdOptions = NoDelayedTemplateParsing;
|
||||
|
||||
ClangProjectSettings(ProjectExplorer::Project *project);
|
||||
|
||||
bool useGlobalWarningConfig() const;
|
||||
void setUseGlobalWarningConfig(bool useGlobalWarningConfig);
|
||||
bool useGlobalConfig() const;
|
||||
void setUseGlobalConfig(bool useGlobalConfig);
|
||||
|
||||
Core::Id warningConfigId() const;
|
||||
void setWarningConfigId(const Core::Id &warningConfigId);
|
||||
|
||||
QStringList commandLineOptions() const;
|
||||
void setCommandLineOptions(const QStringList &options);
|
||||
|
||||
void load();
|
||||
void store();
|
||||
|
||||
static QStringList globalCommandLineOptions();
|
||||
|
||||
private:
|
||||
ProjectExplorer::Project *m_project;
|
||||
bool m_useGlobalWarningConfig = true;
|
||||
bool m_useGlobalConfig = true;
|
||||
Core::Id m_warningConfigId;
|
||||
|
||||
QStringList m_customCommandLineOptions;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -34,60 +34,21 @@
|
||||
#include <cpptools/cppcodemodelsettings.h>
|
||||
#include <cpptools/cpptoolsreuse.h>
|
||||
|
||||
static const char GLOBAL_PROXY_CONFIG_ID[] = "globalProxyConfig";
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
namespace ClangCodeModel {
|
||||
namespace Internal {
|
||||
|
||||
static CppTools::ClangDiagnosticConfig
|
||||
createConfigRepresentingGlobalSetting(const CppTools::ClangDiagnosticConfig &baseConfig)
|
||||
static Core::Id configIdForProject(ClangProjectSettings &projectSettings)
|
||||
{
|
||||
CppTools::ClangDiagnosticConfig config = baseConfig;
|
||||
config.setId(GLOBAL_PROXY_CONFIG_ID);
|
||||
|
||||
QString displayName = config.displayName();
|
||||
if (config.isReadOnly())
|
||||
displayName = CppTools::ClangDiagnosticConfigsModel::displayNameWithBuiltinIndication(config);
|
||||
displayName = ClangProjectSettingsWidget::tr("Global setting (%1)").arg(displayName);
|
||||
|
||||
config.setDisplayName(displayName);
|
||||
config.setIsReadOnly(true);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
static Core::Id globalConfigId(const CppTools::CppCodeModelSettings &settings,
|
||||
const CppTools::ClangDiagnosticConfigsModel &model)
|
||||
{
|
||||
const Core::Id configId = settings.clangDiagnosticConfigId();
|
||||
|
||||
if (model.hasConfigWithId(configId))
|
||||
return configId;
|
||||
|
||||
return model.at(0).id(); // Config saved in the settings was removed, fallback to first.
|
||||
}
|
||||
|
||||
static CppTools::ClangDiagnosticConfigsModel
|
||||
createConfigsModelWithGlobalProxyConfig(const CppTools::CppCodeModelSettings &settings)
|
||||
{
|
||||
using namespace CppTools;
|
||||
ClangDiagnosticConfigsModel configsModel(settings.clangCustomDiagnosticConfigs());
|
||||
|
||||
const Core::Id globalId = globalConfigId(settings, configsModel);
|
||||
const ClangDiagnosticConfig globalConfig = configsModel.configWithId(globalId);
|
||||
const ClangDiagnosticConfig globalProxy
|
||||
= createConfigRepresentingGlobalSetting(globalConfig);
|
||||
|
||||
configsModel.prepend(globalProxy);
|
||||
|
||||
return configsModel;
|
||||
}
|
||||
|
||||
static Core::Id configIdForProject(const ClangProjectSettings &projectSettings)
|
||||
{
|
||||
return projectSettings.useGlobalWarningConfig()
|
||||
? Core::Id(GLOBAL_PROXY_CONFIG_ID)
|
||||
: projectSettings.warningConfigId();
|
||||
if (projectSettings.useGlobalConfig())
|
||||
return CppTools::codeModelSettings()->clangDiagnosticConfigId();
|
||||
Core::Id configId = projectSettings.warningConfigId();
|
||||
if (!configId.isValid()) {
|
||||
configId = CppTools::codeModelSettings()->clangDiagnosticConfigId();
|
||||
projectSettings.setWarningConfigId(configId);
|
||||
}
|
||||
return configId;
|
||||
}
|
||||
|
||||
ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project *project)
|
||||
@@ -98,24 +59,33 @@ ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project
|
||||
using namespace CppTools;
|
||||
|
||||
m_diagnosticConfigWidget = new ClangDiagnosticConfigsWidget;
|
||||
m_diagnosticConfigWidget->setConfigWithUndecoratedDisplayName(Core::Id(GLOBAL_PROXY_CONFIG_ID));
|
||||
refreshDiagnosticConfigsWidgetFromSettings();
|
||||
|
||||
m_ui.generalConfigurationGroupBox->setVisible(Utils::HostOsInfo::isWindowsHost());
|
||||
|
||||
m_ui.clangSettings->setCurrentIndex(m_projectSettings.useGlobalConfig() ? 0 : 1);
|
||||
syncOtherWidgetsToComboBox();
|
||||
|
||||
connectToCppCodeModelSettingsChanged();
|
||||
connect(m_diagnosticConfigWidget.data(), &ClangDiagnosticConfigsWidget::currentConfigChanged,
|
||||
this, &ClangProjectSettingsWidget::onCurrentWarningConfigChanged);
|
||||
connect(m_diagnosticConfigWidget.data(), &ClangDiagnosticConfigsWidget::customConfigsChanged,
|
||||
this, &ClangProjectSettingsWidget::onCustomWarningConfigsChanged);
|
||||
connect(m_ui.delayedTemplateParse, &QCheckBox::toggled,
|
||||
this, &ClangProjectSettingsWidget::onDelayedTemplateParseClicked);
|
||||
connect(m_ui.clangSettings,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &ClangProjectSettingsWidget::onClangSettingsChanged);
|
||||
|
||||
m_ui.diagnosticConfigurationGroupBox->layout()->addWidget(m_diagnosticConfigWidget);
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::onCurrentWarningConfigChanged(const Core::Id ¤tConfigId)
|
||||
{
|
||||
const bool useGlobalConfig = currentConfigId == Core::Id(GLOBAL_PROXY_CONFIG_ID);
|
||||
|
||||
m_projectSettings.setUseGlobalWarningConfig(useGlobalConfig);
|
||||
// Don't save it when we reset the global config in code
|
||||
if (m_projectSettings.useGlobalConfig())
|
||||
return;
|
||||
m_projectSettings.setWarningConfigId(currentConfigId);
|
||||
|
||||
m_projectSettings.store();
|
||||
}
|
||||
|
||||
@@ -132,11 +102,48 @@ void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
|
||||
connectToCppCodeModelSettingsChanged();
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::onDelayedTemplateParseClicked(bool checked)
|
||||
{
|
||||
// Don't save it when we reset the global config in code
|
||||
if (m_projectSettings.useGlobalConfig())
|
||||
return;
|
||||
|
||||
const QLatin1String extraFlag{checked ? ClangProjectSettings::DelayedTemplateParsing
|
||||
: ClangProjectSettings::NoDelayedTemplateParsing};
|
||||
QStringList options = m_projectSettings.commandLineOptions();
|
||||
options.removeAll(QLatin1String{ClangProjectSettings::DelayedTemplateParsing});
|
||||
options.removeAll(QLatin1String{ClangProjectSettings::NoDelayedTemplateParsing});
|
||||
options.append(extraFlag);
|
||||
m_projectSettings.setCommandLineOptions(options);
|
||||
m_projectSettings.store();
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::onClangSettingsChanged(int index)
|
||||
{
|
||||
m_projectSettings.setUseGlobalConfig(index == 0 ? true : false);
|
||||
m_projectSettings.store();
|
||||
syncOtherWidgetsToComboBox();
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::syncOtherWidgetsToComboBox()
|
||||
{
|
||||
const QStringList options = m_projectSettings.commandLineOptions();
|
||||
m_ui.delayedTemplateParse->setChecked(
|
||||
options.contains(QLatin1String{ClangProjectSettings::DelayedTemplateParsing}));
|
||||
|
||||
const bool isCustom = !m_projectSettings.useGlobalConfig();
|
||||
m_ui.generalConfigurationGroupBox->setEnabled(isCustom);
|
||||
m_ui.diagnosticConfigurationGroupBox->setEnabled(isCustom);
|
||||
|
||||
refreshDiagnosticConfigsWidgetFromSettings();
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::refreshDiagnosticConfigsWidgetFromSettings()
|
||||
{
|
||||
m_diagnosticConfigWidget->refresh(
|
||||
createConfigsModelWithGlobalProxyConfig(*CppTools::codeModelSettings()),
|
||||
configIdForProject(m_projectSettings));
|
||||
CppTools::ClangDiagnosticConfigsModel configsModel(
|
||||
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
|
||||
m_diagnosticConfigWidget->refresh(configsModel,
|
||||
configIdForProject(m_projectSettings));
|
||||
}
|
||||
|
||||
void ClangProjectSettingsWidget::connectToCppCodeModelSettingsChanged()
|
||||
|
||||
@@ -49,9 +49,12 @@ public:
|
||||
private:
|
||||
void onCurrentWarningConfigChanged(const Core::Id ¤tConfigId);
|
||||
void onCustomWarningConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
|
||||
void onDelayedTemplateParseClicked(bool);
|
||||
void onClangSettingsChanged(int index);
|
||||
void refreshDiagnosticConfigsWidgetFromSettings();
|
||||
void connectToCppCodeModelSettingsChanged();
|
||||
void disconnectFromCppCodeModelSettingsChanged();
|
||||
void syncOtherWidgetsToComboBox();
|
||||
|
||||
private:
|
||||
Ui::ClangProjectSettingsWidget m_ui;
|
||||
|
||||
@@ -14,6 +14,52 @@
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="clangSettings">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Global</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Custom</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="generalConfigurationGroupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>General</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="delayedTemplateParse">
|
||||
<property name="toolTip">
|
||||
<string>Parse templates in a MSVC-compliant way. This helps to parse headers for example from Active Template Library (ATL) or Windows Runtime Library (WRL).
|
||||
However, using the relaxed and extended rules means also that no highlighting/completion can be provided within template functions.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable MSVC-compliant template parsing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="diagnosticConfigurationGroupBox">
|
||||
<property name="title">
|
||||
|
||||
Reference in New Issue
Block a user