diff options
Diffstat (limited to 'src/plugins/cpptools/compileroptionsbuilder.cpp')
-rw-r--r-- | src/plugins/cpptools/compileroptionsbuilder.cpp | 163 |
1 files changed, 128 insertions, 35 deletions
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index 43a4146218..8164009bf1 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -25,7 +25,11 @@ #include "compileroptionsbuilder.h" +#include <coreplugin/icore.h> + #include <projectexplorer/projectexplorerconstants.h> + +#include <utils/qtcassert.h> #include <utils/qtcfallthrough.h> #include <QDir> @@ -33,9 +37,40 @@ namespace CppTools { -CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart) +CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart, + const QString &clangVersion, + const QString &clangResourceDirectory) : m_projectPart(projectPart) + , m_clangVersion(clangVersion) + , m_clangResourceDirectory(clangResourceDirectory) +{ +} + +QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind, PchUsage pchUsage) { + m_options.clear(); + + addWordWidth(); + addTargetTriple(); + addLanguageOption(fileKind); + addOptionsForLanguage(/*checkForBorlandExtensions*/ true); + enableExceptions(); + + addToolchainAndProjectMacros(); + undefineClangVersionMacrosForMsvc(); + undefineCppLanguageFeatureMacrosForMsvc2015(); + addDefineFunctionMacrosMsvc(); + + addPredefinedHeaderPathsOptions(); + addPrecompiledHeaderOptions(pchUsage); + addHeaderPathOptions(); + addProjectConfigFileInclude(); + + addMsvcCompatibilityVersion(); + + addExtraOptions(); + + return options(); } QStringList CompilerOptionsBuilder::options() const @@ -101,7 +136,8 @@ void CompilerOptionsBuilder::addHeaderPathOptions() break; } - result.append(prefix + QDir::toNativeSeparators(headerPath.path)); + result.append(prefix); + result.append(QDir::toNativeSeparators(headerPath.path)); } m_options.append(result); @@ -237,15 +273,13 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension opts << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98")); break; case ProjectPart::CXX03: - // Clang 3.6 does not know -std=gnu++03. - opts << QLatin1String("-std=c++03"); + opts << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03")); break; case ProjectPart::CXX14: opts << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14")); break; case ProjectPart::CXX17: - // TODO: Change to (probably) "gnu++17"/"c++17" at some point in the future. - opts << (gnuExtensions ? QLatin1String("-std=gnu++1z") : QLatin1String("-std=c++1z")); + opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17")); break; } @@ -292,24 +326,39 @@ void CompilerOptionsBuilder::addMsvcCompatibilityVersion() static QStringList languageFeatureMacros() { // CLANG-UPGRADE-CHECK: Update known language features macros. - // Collected with: - // $ CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 - // $ D:\usr\llvm-3.8.0\bin\clang++.exe -fms-compatibility-version=19 -std=c++1y -dM -E D:\empty.cpp | grep __cpp_ + // Collected with the following command line. + // * Use latest -fms-compatibility-version and -std possible. + // * Compatibility version 19 vs 1910 did not matter. + // $ clang++ -fms-compatibility-version=19 -std=c++1z -dM -E D:\empty.cpp | grep __cpp_ static QStringList macros{ + QLatin1String("__cpp_aggregate_bases"), QLatin1String("__cpp_aggregate_nsdmi"), QLatin1String("__cpp_alias_templates"), + QLatin1String("__cpp_aligned_new"), QLatin1String("__cpp_attributes"), QLatin1String("__cpp_binary_literals"), + QLatin1String("__cpp_capture_star_this"), QLatin1String("__cpp_constexpr"), QLatin1String("__cpp_decltype"), QLatin1String("__cpp_decltype_auto"), + QLatin1String("__cpp_deduction_guides"), QLatin1String("__cpp_delegating_constructors"), QLatin1String("__cpp_digit_separators"), + QLatin1String("__cpp_enumerator_attributes"), + QLatin1String("__cpp_exceptions"), + QLatin1String("__cpp_fold_expressions"), QLatin1String("__cpp_generic_lambdas"), + QLatin1String("__cpp_hex_float"), + QLatin1String("__cpp_if_constexpr"), QLatin1String("__cpp_inheriting_constructors"), QLatin1String("__cpp_init_captures"), QLatin1String("__cpp_initializer_lists"), + QLatin1String("__cpp_inline_variables"), QLatin1String("__cpp_lambdas"), + QLatin1String("__cpp_namespace_attributes"), + QLatin1String("__cpp_nested_namespace_definitions"), + QLatin1String("__cpp_noexcept_function_type"), + QLatin1String("__cpp_nontype_template_args"), QLatin1String("__cpp_nsdmi"), QLatin1String("__cpp_range_based_for"), QLatin1String("__cpp_raw_strings"), @@ -318,11 +367,15 @@ static QStringList languageFeatureMacros() QLatin1String("__cpp_rtti"), QLatin1String("__cpp_rvalue_references"), QLatin1String("__cpp_static_assert"), + QLatin1String("__cpp_structured_bindings"), + QLatin1String("__cpp_template_auto"), + QLatin1String("__cpp_threadsafe_static_init"), QLatin1String("__cpp_unicode_characters"), QLatin1String("__cpp_unicode_literals"), QLatin1String("__cpp_user_defined_literals"), QLatin1String("__cpp_variable_templates"), QLatin1String("__cpp_variadic_templates"), + QLatin1String("__cpp_variadic_using"), }; return macros; @@ -332,8 +385,8 @@ void CompilerOptionsBuilder::undefineCppLanguageFeatureMacrosForMsvc2015() { if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID && m_projectPart.isMsvc2015Toolchain) { - // Undefine the language feature macros that are pre-defined in clang-cl 3.8.0, - // but not in MSVC2015's cl.exe. + // Undefine the language feature macros that are pre-defined in clang-cl, + // but not in MSVC's cl.exe. foreach (const QString ¯oName, languageFeatureMacros()) m_options.append(undefineOption() + macroName); } @@ -345,17 +398,9 @@ void CompilerOptionsBuilder::addDefineFunctionMacrosMsvc() addMacros({{"__FUNCSIG__", "\"\""}, {"__FUNCTION__", "\"\""}, {"__FUNCDNAME__", "\"\""}}); } -void CompilerOptionsBuilder::addDefineFloat128ForMingw() -{ - // CLANG-UPGRADE-CHECK: Workaround still needed? - // https://llvm.org/bugs/show_bug.cgi?id=30685 - if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) - addDefine({"__float128", "short", ProjectExplorer::MacroType::Define}); -} - QString CompilerOptionsBuilder::includeDirOption() const { - return QLatin1String("-I"); + return QLatin1String("-isystem"); } QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro ¯o) const @@ -394,12 +439,6 @@ QString CompilerOptionsBuilder::includeOption() const return QLatin1String("-include"); } -static bool isGccOrMinGwToolchain(const Core::Id &toolchainType) -{ - return toolchainType == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID - || toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID; -} - bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const { // This is a quick fix for QTCREATORBUG-11501. @@ -407,16 +446,10 @@ bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro if (macro.key == "__cplusplus") return true; - // gcc 4.9 has: - // #define __has_include(STR) __has_include__(STR) - // #define __has_include_next(STR) __has_include_next__(STR) - // The right-hand sides are gcc built-ins that clang does not understand, and they'd - // override clang's own (non-macro, it seems) definitions of the symbols on the left-hand - // side. - if (isGccOrMinGwToolchain(m_projectPart.toolchainType) - && macro.key.contains("has_include")) { + // Ignore for all compiler toolchains since LLVM has it's own implementation for + // __has_include(STR) and __has_include_next(STR) + if (macro.key.startsWith("__has_include")) return true; - } // If _FORTIFY_SOURCE is defined (typically in release mode), it will // enable the inclusion of extra headers to help catching buffer overflows @@ -449,4 +482,64 @@ bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const return clangIncludeDir.match(headerPath).hasMatch(); } +void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions() +{ + add("-nostdinc"); + add("-nostdlibinc"); + + // In case of MSVC we need builtin clang defines to correctly handle clang includes + if (m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) + add("-undef"); + + addClangIncludeFolder(); +} + +void CompilerOptionsBuilder::addClangIncludeFolder() +{ + QTC_CHECK(!m_clangVersion.isEmpty()); + add(includeDirOption()); + add(clangIncludeDirectory()); +} + +void CompilerOptionsBuilder::addProjectConfigFileInclude() +{ + if (!m_projectPart.projectConfigFile.isEmpty()) { + add("-include"); + add(QDir::toNativeSeparators(m_projectPart.projectConfigFile)); + } +} + +static QString creatorLibexecPath() +{ +#ifndef UNIT_TESTS + return Core::ICore::instance()->libexecPath(); +#else + return QString(); +#endif +} + +QString CompilerOptionsBuilder::clangIncludeDirectory() const +{ + QDir dir(creatorLibexecPath() + "/clang" + clangIncludePath(m_clangVersion)); + if (!dir.exists() || !QFileInfo(dir, "stdint.h").exists()) + dir = QDir(m_clangResourceDirectory); + return QDir::toNativeSeparators(dir.canonicalPath()); +} + +void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc() +{ + if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) { + static QStringList macroNames { + "__clang__", + "__clang_major__", + "__clang_minor__", + "__clang_patchlevel__", + "__clang_version__" + }; + + foreach (const QString ¯oName, macroNames) + add(undefineOption() + macroName); + } +} + } // namespace CppTools |