From d400dce35d817afd719ffadf8c8f43c8814c05c1 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 30 Jun 2020 15:11:15 +0200 Subject: [PATCH] Require GCC 7 and enable C++17 Fix MSVC2019 - result type of conditional expression is ambiguous: types 'const char [1]' and 'QByteArray' can be converted to multiple common types Fix MinGW 8.1 - undefined reference to SemanticHighlightNotification::methodName Fix Utils::transform with std::vector for GCC & MSVC Unfortunately we cannot get rid of the special variant and optional implementations, because Apple Clang requires deployment target >= 10.14 for the functions that can throw std::bad_optional_access. Fixes: QTCREATORBUG-20520 Change-Id: I5c36a70f21f8b0215d2f4fc5c0653a022778d928 Reviewed-by: Christian Kandeler Reviewed-by: Marco Bubke Reviewed-by: David Schulz --- CMakeLists.txt | 2 +- README.md | 4 +- qbs/imports/QtcProduct.qbs | 2 +- qtcreator.pri | 2 +- .../languagefeatures.cpp | 4 ++ .../languageserverprotocol/languagefeatures.h | 2 + src/libs/utils/algorithm.h | 13 ++++++ src/libs/utils/optional.h | 40 ++++++++++++++++++- src/libs/utils/variant.h | 5 ++- src/plugins/projectexplorer/gcctoolchain.cpp | 10 ++--- src/plugins/texteditor/codestylepool.cpp | 2 +- tests/unit/unittest/unittest.pro | 2 +- tests/unit/unittest/unittest.qbs | 2 +- 13 files changed, 75 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f76ce0a1519..76773e3e5d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ mark_as_advanced(IDE_REVISION IDE_REVISION_STR IDE_REVISION_URL) project(QtCreator VERSION ${IDE_VERSION}) # Force C++ standard, do not fall back, do not use compiler extensions -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/README.md b/README.md index 6daded0a4fd..41438e0153e 100644 --- a/README.md +++ b/README.md @@ -31,11 +31,11 @@ Prerequisites: * Qt WebEngine module for QtWebEngine based help viewer * On Windows: * ActiveState Active Perl - * MinGW with g++ 5.3 or Visual Studio 2017 or later + * MinGW with GCC 7 or Visual Studio 2017 or later * jom * Python 3.5 or later (optional, needed for the python enabled debug helper) * On Mac OS X: latest Xcode -* On Linux: g++ 5.3 or later +* On Linux: GCC 7 or later * LLVM/Clang 8.0.0 or later (optional, needed for the Clang Code Model, Clang Tools, ClangFormat, Clang PCH Manager and Clang Refactoring plugins, see the section "Get LLVM/Clang for the Clang Code Model". The LLVM C++ API provides no compatibility garantee, diff --git a/qbs/imports/QtcProduct.qbs b/qbs/imports/QtcProduct.qbs index be3653ffe06..c6d1a26e90f 100644 --- a/qbs/imports/QtcProduct.qbs +++ b/qbs/imports/QtcProduct.qbs @@ -52,7 +52,7 @@ Product { return flags; } - cpp.cxxLanguageVersion: "c++14" + cpp.cxxLanguageVersion: "c++17" cpp.defines: qtc.generalDefines cpp.minimumWindowsVersion: "6.1" cpp.useCxxPrecompiledHeader: useNonGuiPchFile || useGuiPchFile diff --git a/qtcreator.pri b/qtcreator.pri index cc0a0b658cb..af9b96bca19 100644 --- a/qtcreator.pri +++ b/qtcreator.pri @@ -7,7 +7,7 @@ include($$PWD/qtcreator_ide_branding.pri) PRODUCT_BUNDLE_IDENTIFIER=$${PRODUCT_BUNDLE_ORGANIZATION}.$${IDE_ID} VERSION = $$QTCREATOR_VERSION -CONFIG += c++14 +CONFIG += c++17 defineReplace(qtLibraryTargetName) { unset(LIBRARY_NAME) diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp index e960296dc80..bffa0df284f 100644 --- a/src/libs/languageserverprotocol/languagefeatures.cpp +++ b/src/libs/languageserverprotocol/languagefeatures.cpp @@ -547,4 +547,8 @@ PrepareRenameResult::PrepareRenameResult(const QJsonValue &val) } } +SemanticHighlightNotification::SemanticHighlightNotification(const SemanticHighlightingParams ¶ms) + : Notification(methodName, params) +{} + } // namespace LanguageServerProtocol diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h index 074f6440af5..bc4eaa61ab7 100644 --- a/src/libs/languageserverprotocol/languagefeatures.h +++ b/src/libs/languageserverprotocol/languagefeatures.h @@ -898,6 +898,8 @@ class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification : public Notification { public: + SemanticHighlightNotification( + const SemanticHighlightingParams ¶ms = SemanticHighlightingParams()); using Notification::Notification; constexpr static const char methodName[] = "textDocument/semanticHighlighting"; }; diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h index 212840eeab5..5a3c4edee66 100644 --- a/src/libs/utils/algorithm.h +++ b/src/libs/utils/algorithm.h @@ -280,6 +280,16 @@ template class C, // result container type typename Result = std::decay_t>, typename ResultContainer = C> Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function); +#ifdef Q_CC_CLANG +// "Matching of template template-arguments excludes compatible templates" +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0522r0.html (P0522R0) +// in C++17 makes the above match e.g. C=std::vector even though that takes two +// template parameters. Unfortunately the following one matches too, and there is no additional +// partial ordering rule, resulting in an ambiguous call for this previously valid code. +// GCC and MSVC ignore that issue and follow the standard to the letter, but Clang only +// enables the new behavior when given -frelaxed-template-template-args . +// To avoid requiring everyone using this header to enable that feature, keep the old implementation +// for Clang. template class C, // result container type typename SC, // input container type typename F, // function type @@ -287,6 +297,7 @@ template class C, // result container type typename Result = std::decay_t>, typename ResultContainer = C>> Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function); +#endif // member function without result type deduction: template class C, // result container type @@ -709,6 +720,7 @@ Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function) return transform(std::forward(container), function); } +#ifdef Q_CC_CLANG template class C, // result container type typename SC, // input container type typename F, // function type @@ -719,6 +731,7 @@ Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function) { return transform(std::forward(container), function); } +#endif // member function without result type deduction: template class C, // result container type diff --git a/src/libs/utils/optional.h b/src/libs/utils/optional.h index a9f58334b70..9450b308ede 100644 --- a/src/libs/utils/optional.h +++ b/src/libs/utils/optional.h @@ -32,7 +32,43 @@ See std(::experimental)::optional. */ -// TODO: replace by #include <(experimental/)optional> depending on compiler and C++ version +// std::optional from Apple's Clang supports methods that throw std::bad_optional_access only +// with deployment target >= macOS 10.14 +// TODO: Use std::optional everywhere when we can require macOS 10.14 +#if !defined(__apple_build_version__) + +#include + +namespace Utils { + +using std::optional; +using std::nullopt; +using std::nullopt_t; +using std::in_place; + +// make_optional is a copy, since there is no sensible way to import functions in C++ +template +constexpr optional> make_optional(T &&v) +{ + return optional>(std::forward(v)); +} + +template +optional make_optional(Args &&... args) +{ + return optional(in_place, std::forward(args)...); +} + +template +constexpr optional make_optional(std::initializer_list il, Args &&... args) +{ + return optional(in_place, il, std::forward(args)...); +} + +} // namespace Utils + +#else + #include <3rdparty/optional/optional.hpp> namespace Utils { @@ -59,3 +95,5 @@ constexpr optional make_optional(std::reference_wrapper v) } } // Utils + +#endif diff --git a/src/libs/utils/variant.h b/src/libs/utils/variant.h index 24637c7d488..aebef568dce 100644 --- a/src/libs/utils/variant.h +++ b/src/libs/utils/variant.h @@ -29,7 +29,10 @@ See std(::experimental)::variant. */ -#if __cplusplus >= 201703L +// std::variant from Apple's Clang supports methods that throw std::bad_optional_access only +// with deployment target >= macOS 10.14 +// TODO: Use std::variant everywhere when we can require macOS 10.14 +#if !defined(__apple_build_version__) #include namespace Utils { diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index e4ea036d77f..89ae6b17483 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -1426,7 +1426,7 @@ void ClangToolChain::syncAutodetectedWithParentToolchains() if (!mingwToolChainFromId(m_parentToolChainId)) { const QList mingwTCs = mingwToolChains(); - m_parentToolChainId = mingwTCs.isEmpty() ? "" : mingwTCs.front()->id(); + m_parentToolChainId = mingwTCs.isEmpty() ? QByteArray() : mingwTCs.front()->id(); } // Subscribe only autodetected toolchains. @@ -1445,7 +1445,7 @@ void ClangToolChain::syncAutodetectedWithParentToolchains() QObject::disconnect(m_mingwToolchainAddedConnection); } else if (m_parentToolChainId == tc->id()) { const QList mingwTCs = mingwToolChains(); - m_parentToolChainId = mingwTCs.isEmpty() ? "" : mingwTCs.front()->id(); + m_parentToolChainId = mingwTCs.isEmpty() ? QByteArray() : mingwTCs.front()->id(); } }); } @@ -1713,8 +1713,8 @@ void ClangToolChainConfigWidget::updateParentToolChainComboBox() const MingwToolChain *parentTC = mingwToolChainFromId(parentId); m_parentToolchainCombo->clear(); - m_parentToolchainCombo->addItem(parentTC ? parentTC->displayName() : "", - parentTC ? parentId : ""); + m_parentToolchainCombo->addItem(parentTC ? parentTC->displayName() : QString(), + parentTC ? parentId : QByteArray()); if (tc->isAutoDetected()) return; @@ -1766,7 +1766,7 @@ bool ClangToolChainConfigWidget::isDirtyImpl() const auto tc = static_cast(toolChain()); Q_ASSERT(tc); const MingwToolChain *parentTC = mingwToolChainFromId(tc->m_parentToolChainId); - const QByteArray parentId = parentTC ? parentTC->id() : ""; + const QByteArray parentId = parentTC ? parentTC->id() : QByteArray(); return parentId != m_parentToolchainCombo->currentData(); } diff --git a/src/plugins/texteditor/codestylepool.cpp b/src/plugins/texteditor/codestylepool.cpp index 9523364dfd0..55377eceae8 100644 --- a/src/plugins/texteditor/codestylepool.cpp +++ b/src/plugins/texteditor/codestylepool.cpp @@ -81,7 +81,7 @@ QByteArray CodeStylePoolPrivate::generateUniqueId(const QByteArray &id) const } const QByteArray baseName = id.left(idx); - QByteArray newName = baseName.isEmpty() ? "codestyle" : baseName; + QByteArray newName = baseName.isEmpty() ? QByteArray("codestyle") : baseName; int i = 2; while (m_idToCodeStyle.contains(newName)) newName = baseName + QByteArray::number(i++); diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 3917237d0bf..dbe272985d0 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -2,7 +2,7 @@ INCLUDEPATH += ../mockup INCLUDEPATH += ../mockup/qmldesigner/designercore/include QT += core network testlib widgets -CONFIG += console c++14 testcase +CONFIG += console c++17 testcase CONFIG -= app_bundle shared QTC_UNITTEST_BUILD_CPP_PARSER = $$(QTC_UNITTEST_BUILD_CPP_PARSER) diff --git a/tests/unit/unittest/unittest.qbs b/tests/unit/unittest/unittest.qbs index de84177ba15..d364b7ea512 100644 --- a/tests/unit/unittest/unittest.qbs +++ b/tests/unit/unittest/unittest.qbs @@ -71,7 +71,7 @@ CppApplication { flags = flags.concat(libclang.llvmToolingCxxFlags); return flags; } - cpp.cxxLanguageVersion: "c++14" + cpp.cxxLanguageVersion: "c++17" cpp.dynamicLibraries: { var libs = []; if (libclang.present) {