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 <christian.kandeler@qt.io>
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2020-06-30 15:11:15 +02:00
parent e210bcf3eb
commit d400dce35d
13 changed files with 75 additions and 15 deletions

View File

@@ -17,7 +17,7 @@ mark_as_advanced(IDE_REVISION IDE_REVISION_STR IDE_REVISION_URL)
project(QtCreator VERSION ${IDE_VERSION}) project(QtCreator VERSION ${IDE_VERSION})
# Force C++ standard, do not fall back, do not use compiler extensions # 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_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)

View File

@@ -31,11 +31,11 @@ Prerequisites:
* Qt WebEngine module for QtWebEngine based help viewer * Qt WebEngine module for QtWebEngine based help viewer
* On Windows: * On Windows:
* ActiveState Active Perl * 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 * jom
* Python 3.5 or later (optional, needed for the python enabled debug helper) * Python 3.5 or later (optional, needed for the python enabled debug helper)
* On Mac OS X: latest Xcode * 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, * 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 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, "Get LLVM/Clang for the Clang Code Model". The LLVM C++ API provides no compatibility garantee,

View File

@@ -52,7 +52,7 @@ Product {
return flags; return flags;
} }
cpp.cxxLanguageVersion: "c++14" cpp.cxxLanguageVersion: "c++17"
cpp.defines: qtc.generalDefines cpp.defines: qtc.generalDefines
cpp.minimumWindowsVersion: "6.1" cpp.minimumWindowsVersion: "6.1"
cpp.useCxxPrecompiledHeader: useNonGuiPchFile || useGuiPchFile cpp.useCxxPrecompiledHeader: useNonGuiPchFile || useGuiPchFile

View File

@@ -7,7 +7,7 @@ include($$PWD/qtcreator_ide_branding.pri)
PRODUCT_BUNDLE_IDENTIFIER=$${PRODUCT_BUNDLE_ORGANIZATION}.$${IDE_ID} PRODUCT_BUNDLE_IDENTIFIER=$${PRODUCT_BUNDLE_ORGANIZATION}.$${IDE_ID}
VERSION = $$QTCREATOR_VERSION VERSION = $$QTCREATOR_VERSION
CONFIG += c++14 CONFIG += c++17
defineReplace(qtLibraryTargetName) { defineReplace(qtLibraryTargetName) {
unset(LIBRARY_NAME) unset(LIBRARY_NAME)

View File

@@ -547,4 +547,8 @@ PrepareRenameResult::PrepareRenameResult(const QJsonValue &val)
} }
} }
SemanticHighlightNotification::SemanticHighlightNotification(const SemanticHighlightingParams &params)
: Notification(methodName, params)
{}
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -898,6 +898,8 @@ class LANGUAGESERVERPROTOCOL_EXPORT SemanticHighlightNotification
: public Notification<SemanticHighlightingParams> : public Notification<SemanticHighlightingParams>
{ {
public: public:
SemanticHighlightNotification(
const SemanticHighlightingParams &params = SemanticHighlightingParams());
using Notification::Notification; using Notification::Notification;
constexpr static const char methodName[] = "textDocument/semanticHighlighting"; constexpr static const char methodName[] = "textDocument/semanticHighlighting";
}; };

View File

@@ -280,6 +280,16 @@ template<template<typename> class C, // result container type
typename Result = std::decay_t<std::result_of_t<F(Value &)>>, typename Result = std::decay_t<std::result_of_t<F(Value &)>>,
typename ResultContainer = C<Result>> typename ResultContainer = C<Result>>
Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function); 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<template<typename, typename> class C, // result container type template<template<typename, typename> class C, // result container type
typename SC, // input container type typename SC, // input container type
typename F, // function type typename F, // function type
@@ -287,6 +297,7 @@ template<template<typename, typename> class C, // result container type
typename Result = std::decay_t<std::result_of_t<F(Value &)>>, typename Result = std::decay_t<std::result_of_t<F(Value &)>>,
typename ResultContainer = C<Result, std::allocator<Result>>> typename ResultContainer = C<Result, std::allocator<Result>>>
Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function); Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
#endif
// member function without result type deduction: // member function without result type deduction:
template<template<typename...> class C, // result container type template<template<typename...> class C, // result container type
@@ -709,6 +720,7 @@ Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function)
return transform<ResultContainer>(std::forward<SC>(container), function); return transform<ResultContainer>(std::forward<SC>(container), function);
} }
#ifdef Q_CC_CLANG
template<template<typename, typename> class C, // result container type template<template<typename, typename> class C, // result container type
typename SC, // input container type typename SC, // input container type
typename F, // function type typename F, // function type
@@ -719,6 +731,7 @@ Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function)
{ {
return transform<ResultContainer>(std::forward<SC>(container), function); return transform<ResultContainer>(std::forward<SC>(container), function);
} }
#endif
// member function without result type deduction: // member function without result type deduction:
template<template<typename...> class C, // result container type template<template<typename...> class C, // result container type

View File

@@ -32,7 +32,43 @@
See std(::experimental)::optional. 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 <optional>
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<class T>
constexpr optional<std::decay_t<T>> make_optional(T &&v)
{
return optional<std::decay_t<T>>(std::forward<T>(v));
}
template<class T, class... Args>
optional<T> make_optional(Args &&... args)
{
return optional<T>(in_place, std::forward<Args>(args)...);
}
template<class T, class Up, class... Args>
constexpr optional<T> make_optional(std::initializer_list<Up> il, Args &&... args)
{
return optional<T>(in_place, il, std::forward<Args>(args)...);
}
} // namespace Utils
#else
#include <3rdparty/optional/optional.hpp> #include <3rdparty/optional/optional.hpp>
namespace Utils { namespace Utils {
@@ -59,3 +95,5 @@ constexpr optional<X&> make_optional(std::reference_wrapper<X> v)
} }
} // Utils } // Utils
#endif

View File

@@ -29,7 +29,10 @@
See std(::experimental)::variant. 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 <variant> #include <variant>
namespace Utils { namespace Utils {

View File

@@ -1426,7 +1426,7 @@ void ClangToolChain::syncAutodetectedWithParentToolchains()
if (!mingwToolChainFromId(m_parentToolChainId)) { if (!mingwToolChainFromId(m_parentToolChainId)) {
const QList<ToolChain *> mingwTCs = mingwToolChains(); const QList<ToolChain *> mingwTCs = mingwToolChains();
m_parentToolChainId = mingwTCs.isEmpty() ? "" : mingwTCs.front()->id(); m_parentToolChainId = mingwTCs.isEmpty() ? QByteArray() : mingwTCs.front()->id();
} }
// Subscribe only autodetected toolchains. // Subscribe only autodetected toolchains.
@@ -1445,7 +1445,7 @@ void ClangToolChain::syncAutodetectedWithParentToolchains()
QObject::disconnect(m_mingwToolchainAddedConnection); QObject::disconnect(m_mingwToolchainAddedConnection);
} else if (m_parentToolChainId == tc->id()) { } else if (m_parentToolChainId == tc->id()) {
const QList<ToolChain *> mingwTCs = mingwToolChains(); const QList<ToolChain *> 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); const MingwToolChain *parentTC = mingwToolChainFromId(parentId);
m_parentToolchainCombo->clear(); m_parentToolchainCombo->clear();
m_parentToolchainCombo->addItem(parentTC ? parentTC->displayName() : "", m_parentToolchainCombo->addItem(parentTC ? parentTC->displayName() : QString(),
parentTC ? parentId : ""); parentTC ? parentId : QByteArray());
if (tc->isAutoDetected()) if (tc->isAutoDetected())
return; return;
@@ -1766,7 +1766,7 @@ bool ClangToolChainConfigWidget::isDirtyImpl() const
auto tc = static_cast<ClangToolChain *>(toolChain()); auto tc = static_cast<ClangToolChain *>(toolChain());
Q_ASSERT(tc); Q_ASSERT(tc);
const MingwToolChain *parentTC = mingwToolChainFromId(tc->m_parentToolChainId); 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(); return parentId != m_parentToolchainCombo->currentData();
} }

View File

@@ -81,7 +81,7 @@ QByteArray CodeStylePoolPrivate::generateUniqueId(const QByteArray &id) const
} }
const QByteArray baseName = id.left(idx); const QByteArray baseName = id.left(idx);
QByteArray newName = baseName.isEmpty() ? "codestyle" : baseName; QByteArray newName = baseName.isEmpty() ? QByteArray("codestyle") : baseName;
int i = 2; int i = 2;
while (m_idToCodeStyle.contains(newName)) while (m_idToCodeStyle.contains(newName))
newName = baseName + QByteArray::number(i++); newName = baseName + QByteArray::number(i++);

View File

@@ -2,7 +2,7 @@ INCLUDEPATH += ../mockup
INCLUDEPATH += ../mockup/qmldesigner/designercore/include INCLUDEPATH += ../mockup/qmldesigner/designercore/include
QT += core network testlib widgets QT += core network testlib widgets
CONFIG += console c++14 testcase CONFIG += console c++17 testcase
CONFIG -= app_bundle shared CONFIG -= app_bundle shared
QTC_UNITTEST_BUILD_CPP_PARSER = $$(QTC_UNITTEST_BUILD_CPP_PARSER) QTC_UNITTEST_BUILD_CPP_PARSER = $$(QTC_UNITTEST_BUILD_CPP_PARSER)

View File

@@ -71,7 +71,7 @@ CppApplication {
flags = flags.concat(libclang.llvmToolingCxxFlags); flags = flags.concat(libclang.llvmToolingCxxFlags);
return flags; return flags;
} }
cpp.cxxLanguageVersion: "c++14" cpp.cxxLanguageVersion: "c++17"
cpp.dynamicLibraries: { cpp.dynamicLibraries: {
var libs = []; var libs = [];
if (libclang.present) { if (libclang.present) {