2016-01-11 21:09:06 +01:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2016-01-11 21:09:06 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator.
|
|
|
|
|
**
|
|
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2016-01-11 21:09:06 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2016-01-11 21:09:06 +01:00
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "compileroptionsbuilder.h"
|
|
|
|
|
|
2017-09-27 10:32:52 +02:00
|
|
|
#include <coreplugin/icore.h>
|
|
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
2017-09-27 10:32:52 +02:00
|
|
|
|
2017-11-17 14:13:55 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2017-07-14 13:44:33 +02:00
|
|
|
#include <utils/qtcfallthrough.h>
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2016-07-01 15:07:32 +02:00
|
|
|
#include <QDir>
|
2016-10-10 17:31:19 +02:00
|
|
|
#include <QRegularExpression>
|
2016-07-01 15:07:32 +02:00
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
namespace CppTools {
|
|
|
|
|
|
2017-09-27 10:32:52 +02:00
|
|
|
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
|
|
|
|
|
const QString &clangVersion,
|
|
|
|
|
const QString &clangResourceDirectory)
|
2016-01-11 21:09:06 +01:00
|
|
|
: m_projectPart(projectPart)
|
2017-09-27 10:32:52 +02:00
|
|
|
, m_clangVersion(clangVersion)
|
|
|
|
|
, m_clangResourceDirectory(clangResourceDirectory)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList CompilerOptionsBuilder::build(CppTools::ProjectFile::Kind fileKind, PchUsage pchUsage)
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2017-09-27 10:32:52 +02:00
|
|
|
m_options.clear();
|
|
|
|
|
|
|
|
|
|
addWordWidth();
|
|
|
|
|
addTargetTriple();
|
2017-12-15 15:28:13 +01:00
|
|
|
addExtraCodeModelFlags();
|
2017-09-27 10:32:52 +02:00
|
|
|
addLanguageOption(fileKind);
|
|
|
|
|
addOptionsForLanguage(/*checkForBorlandExtensions*/ true);
|
|
|
|
|
enableExceptions();
|
|
|
|
|
|
|
|
|
|
addToolchainAndProjectMacros();
|
|
|
|
|
undefineClangVersionMacrosForMsvc();
|
|
|
|
|
undefineCppLanguageFeatureMacrosForMsvc2015();
|
2017-11-21 13:28:55 +01:00
|
|
|
addDefineFunctionMacrosMsvc();
|
2017-09-27 10:32:52 +02:00
|
|
|
|
|
|
|
|
addPredefinedHeaderPathsOptions();
|
|
|
|
|
addPrecompiledHeaderOptions(pchUsage);
|
|
|
|
|
addHeaderPathOptions();
|
|
|
|
|
addProjectConfigFileInclude();
|
|
|
|
|
|
|
|
|
|
addMsvcCompatibilityVersion();
|
|
|
|
|
|
|
|
|
|
addExtraOptions();
|
|
|
|
|
|
|
|
|
|
return options();
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList CompilerOptionsBuilder::options() const
|
|
|
|
|
{
|
|
|
|
|
return m_options;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::add(const QString &option)
|
|
|
|
|
{
|
|
|
|
|
m_options.append(option);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
void CompilerOptionsBuilder::addDefine(const ProjectExplorer::Macro ¯o)
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2017-02-07 15:00:38 +01:00
|
|
|
m_options.append(defineDirectiveToDefineOption(macro));
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-17 17:15:15 +02:00
|
|
|
void CompilerOptionsBuilder::addWordWidth()
|
|
|
|
|
{
|
|
|
|
|
const QString argument = m_projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit
|
|
|
|
|
? QLatin1String("-m64")
|
|
|
|
|
: QLatin1String("-m32");
|
|
|
|
|
add(argument);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-08 14:19:23 +02:00
|
|
|
void CompilerOptionsBuilder::addTargetTriple()
|
|
|
|
|
{
|
2016-12-05 16:08:01 +01:00
|
|
|
if (!m_projectPart.toolChainTargetTriple.isEmpty()) {
|
2016-04-08 14:19:23 +02:00
|
|
|
m_options.append(QLatin1String("-target"));
|
2016-12-05 16:08:01 +01:00
|
|
|
m_options.append(m_projectPart.toolChainTargetTriple);
|
2016-04-08 14:19:23 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-15 15:28:13 +01:00
|
|
|
void CompilerOptionsBuilder::addExtraCodeModelFlags()
|
|
|
|
|
{
|
|
|
|
|
// extraCodeModelFlags keep build architecture for cross-compilation.
|
|
|
|
|
// In case of iOS build target triple has aarch64 archtecture set which makes
|
|
|
|
|
// code model fail with CXError_Failure. To fix that we explicitly provide architecture.
|
|
|
|
|
m_options.append(m_projectPart.extraCodeModelFlags);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-12 13:11:01 +02:00
|
|
|
void CompilerOptionsBuilder::enableExceptions()
|
|
|
|
|
{
|
|
|
|
|
add(QLatin1String("-fcxx-exceptions"));
|
|
|
|
|
add(QLatin1String("-fexceptions"));
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-17 13:20:29 +02:00
|
|
|
void CompilerOptionsBuilder::addHeaderPathOptions()
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
|
|
|
|
typedef ProjectPartHeaderPath HeaderPath;
|
2016-11-02 12:21:54 +03:00
|
|
|
const QString defaultPrefix = includeDirOption();
|
2016-01-11 21:09:06 +01:00
|
|
|
|
|
|
|
|
QStringList result;
|
|
|
|
|
|
|
|
|
|
foreach (const HeaderPath &headerPath , m_projectPart.headerPaths) {
|
|
|
|
|
if (headerPath.path.isEmpty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (excludeHeaderPath(headerPath.path))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
QString prefix;
|
|
|
|
|
switch (headerPath.type) {
|
|
|
|
|
case HeaderPath::FrameworkPath:
|
|
|
|
|
prefix = QLatin1String("-F");
|
|
|
|
|
break;
|
|
|
|
|
default: // This shouldn't happen, but let's be nice..:
|
|
|
|
|
// intentional fall-through:
|
|
|
|
|
case HeaderPath::IncludePath:
|
|
|
|
|
prefix = defaultPrefix;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-14 12:49:26 +01:00
|
|
|
result.append(prefix);
|
|
|
|
|
result.append(QDir::toNativeSeparators(headerPath.path));
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_options.append(result);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-02 12:21:54 +03:00
|
|
|
void CompilerOptionsBuilder::addPrecompiledHeaderOptions(PchUsage pchUsage)
|
|
|
|
|
{
|
|
|
|
|
if (pchUsage == PchUsage::None)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QStringList result;
|
|
|
|
|
|
|
|
|
|
const QString includeOptionString = includeOption();
|
|
|
|
|
foreach (const QString &pchFile, m_projectPart.precompiledHeaders) {
|
|
|
|
|
if (QFile::exists(pchFile)) {
|
|
|
|
|
result += includeOptionString;
|
|
|
|
|
result += QDir::toNativeSeparators(pchFile);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_options.append(result);
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-11 14:08:00 +02:00
|
|
|
void CompilerOptionsBuilder::addToolchainAndProjectMacros()
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2017-02-07 15:00:38 +01:00
|
|
|
addMacros(m_projectPart.toolChainMacros);
|
|
|
|
|
addMacros(m_projectPart.projectMacros);
|
2016-07-07 11:45:46 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros ¯os)
|
2016-07-07 11:45:46 +02:00
|
|
|
{
|
2016-01-11 21:09:06 +01:00
|
|
|
QStringList result;
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
for (const ProjectExplorer::Macro ¯o : macros) {
|
|
|
|
|
if (excludeDefineDirective(macro))
|
2016-01-11 21:09:06 +01:00
|
|
|
continue;
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
const QString defineOption = defineDirectiveToDefineOption(macro);
|
2016-01-11 21:09:06 +01:00
|
|
|
if (!result.contains(defineOption))
|
|
|
|
|
result.append(defineOption);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_options.append(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
|
|
|
|
|
{
|
|
|
|
|
QStringList opts;
|
|
|
|
|
|
|
|
|
|
switch (fileKind) {
|
|
|
|
|
case ProjectFile::Unclassified:
|
2017-02-01 09:48:58 +01:00
|
|
|
case ProjectFile::Unsupported:
|
2016-01-11 21:09:06 +01:00
|
|
|
break;
|
|
|
|
|
case ProjectFile::CHeader:
|
|
|
|
|
if (objcExt)
|
|
|
|
|
opts += QLatin1String("objective-c-header");
|
|
|
|
|
else
|
|
|
|
|
opts += QLatin1String("c-header");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ProjectFile::CXXHeader:
|
|
|
|
|
default:
|
|
|
|
|
if (!objcExt) {
|
|
|
|
|
opts += QLatin1String("c++-header");
|
|
|
|
|
break;
|
2017-07-14 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
Q_FALLTHROUGH();
|
2016-01-11 21:09:06 +01:00
|
|
|
case ProjectFile::ObjCHeader:
|
|
|
|
|
case ProjectFile::ObjCXXHeader:
|
|
|
|
|
opts += QLatin1String("objective-c++-header");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ProjectFile::CSource:
|
|
|
|
|
if (!objcExt) {
|
|
|
|
|
opts += QLatin1String("c");
|
|
|
|
|
break;
|
2017-07-14 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
Q_FALLTHROUGH();
|
2016-01-11 21:09:06 +01:00
|
|
|
case ProjectFile::ObjCSource:
|
|
|
|
|
opts += QLatin1String("objective-c");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ProjectFile::CXXSource:
|
|
|
|
|
if (!objcExt) {
|
|
|
|
|
opts += QLatin1String("c++");
|
|
|
|
|
break;
|
2017-07-14 13:44:33 +02:00
|
|
|
}
|
|
|
|
|
Q_FALLTHROUGH();
|
2016-01-11 21:09:06 +01:00
|
|
|
case ProjectFile::ObjCXXSource:
|
|
|
|
|
opts += QLatin1String("objective-c++");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ProjectFile::OpenCLSource:
|
|
|
|
|
opts += QLatin1String("cl");
|
|
|
|
|
break;
|
|
|
|
|
case ProjectFile::CudaSource:
|
|
|
|
|
opts += QLatin1String("cuda");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!opts.isEmpty())
|
|
|
|
|
opts.prepend(QLatin1String("-x"));
|
|
|
|
|
|
|
|
|
|
return opts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::addLanguageOption(ProjectFile::Kind fileKind)
|
|
|
|
|
{
|
|
|
|
|
const bool objcExt = m_projectPart.languageExtensions & ProjectPart::ObjectiveCExtensions;
|
|
|
|
|
const QStringList options = createLanguageOptionGcc(fileKind, objcExt);
|
|
|
|
|
m_options.append(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtensions)
|
|
|
|
|
{
|
|
|
|
|
QStringList opts;
|
|
|
|
|
const ProjectPart::LanguageExtensions languageExtensions = m_projectPart.languageExtensions;
|
|
|
|
|
const bool gnuExtensions = languageExtensions & ProjectPart::GnuExtensions;
|
|
|
|
|
switch (m_projectPart.languageVersion) {
|
|
|
|
|
case ProjectPart::C89:
|
|
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89"));
|
|
|
|
|
break;
|
|
|
|
|
case ProjectPart::C99:
|
|
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99"));
|
|
|
|
|
break;
|
|
|
|
|
case ProjectPart::C11:
|
|
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
|
|
|
|
|
break;
|
|
|
|
|
case ProjectPart::CXX11:
|
|
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
|
|
|
|
|
break;
|
|
|
|
|
case ProjectPart::CXX98:
|
|
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98"));
|
|
|
|
|
break;
|
|
|
|
|
case ProjectPart::CXX03:
|
2017-09-29 13:46:53 +02:00
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03"));
|
2016-01-11 21:09:06 +01:00
|
|
|
break;
|
|
|
|
|
case ProjectPart::CXX14:
|
|
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14"));
|
|
|
|
|
break;
|
|
|
|
|
case ProjectPart::CXX17:
|
2017-09-29 13:46:53 +02:00
|
|
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
|
2016-01-11 21:09:06 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (languageExtensions & ProjectPart::MicrosoftExtensions)
|
|
|
|
|
opts << QLatin1String("-fms-extensions");
|
|
|
|
|
|
|
|
|
|
if (checkForBorlandExtensions && (languageExtensions & ProjectPart::BorlandExtensions))
|
|
|
|
|
opts << QLatin1String("-fborland-extensions");
|
|
|
|
|
|
|
|
|
|
m_options.append(opts);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 11:53:50 +02:00
|
|
|
static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer)
|
|
|
|
|
{
|
|
|
|
|
return mscFullVer.left(2)
|
|
|
|
|
+ QByteArray(".")
|
|
|
|
|
+ mscFullVer.mid(2, 2);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
static QByteArray msCompatibilityVersionFromDefines(const ProjectExplorer::Macros ¯os)
|
2016-04-11 11:53:50 +02:00
|
|
|
{
|
2017-02-07 15:00:38 +01:00
|
|
|
for (const ProjectExplorer::Macro ¯o : macros) {
|
|
|
|
|
if (macro.key == "_MSC_FULL_VER")
|
2016-04-11 11:53:50 +02:00
|
|
|
return toMsCompatibilityVersionFormat(macro.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QByteArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::addMsvcCompatibilityVersion()
|
|
|
|
|
{
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
2017-02-07 15:00:38 +01:00
|
|
|
const ProjectExplorer::Macros macros = m_projectPart.toolChainMacros + m_projectPart.projectMacros;
|
|
|
|
|
const QByteArray msvcVersion = msCompatibilityVersionFromDefines(macros);
|
2016-04-11 11:53:50 +02:00
|
|
|
|
|
|
|
|
if (!msvcVersion.isEmpty()) {
|
|
|
|
|
const QString option = QLatin1String("-fms-compatibility-version=")
|
|
|
|
|
+ QLatin1String(msvcVersion);
|
|
|
|
|
m_options.append(option);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 17:34:02 +02:00
|
|
|
static QStringList languageFeatureMacros()
|
|
|
|
|
{
|
2017-06-15 17:40:32 +02:00
|
|
|
// CLANG-UPGRADE-CHECK: Update known language features macros.
|
2017-09-29 13:46:53 +02:00
|
|
|
// 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_
|
2017-02-22 15:09:35 +01:00
|
|
|
static QStringList macros{
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_aggregate_bases"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_aggregate_nsdmi"),
|
|
|
|
|
QLatin1String("__cpp_alias_templates"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_aligned_new"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_attributes"),
|
|
|
|
|
QLatin1String("__cpp_binary_literals"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_capture_star_this"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_constexpr"),
|
|
|
|
|
QLatin1String("__cpp_decltype"),
|
|
|
|
|
QLatin1String("__cpp_decltype_auto"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_deduction_guides"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_delegating_constructors"),
|
|
|
|
|
QLatin1String("__cpp_digit_separators"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_enumerator_attributes"),
|
|
|
|
|
QLatin1String("__cpp_exceptions"),
|
|
|
|
|
QLatin1String("__cpp_fold_expressions"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_generic_lambdas"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_hex_float"),
|
|
|
|
|
QLatin1String("__cpp_if_constexpr"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_inheriting_constructors"),
|
|
|
|
|
QLatin1String("__cpp_init_captures"),
|
|
|
|
|
QLatin1String("__cpp_initializer_lists"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_inline_variables"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_lambdas"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_namespace_attributes"),
|
|
|
|
|
QLatin1String("__cpp_nested_namespace_definitions"),
|
|
|
|
|
QLatin1String("__cpp_noexcept_function_type"),
|
|
|
|
|
QLatin1String("__cpp_nontype_template_args"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_nsdmi"),
|
|
|
|
|
QLatin1String("__cpp_range_based_for"),
|
|
|
|
|
QLatin1String("__cpp_raw_strings"),
|
|
|
|
|
QLatin1String("__cpp_ref_qualifiers"),
|
|
|
|
|
QLatin1String("__cpp_return_type_deduction"),
|
|
|
|
|
QLatin1String("__cpp_rtti"),
|
|
|
|
|
QLatin1String("__cpp_rvalue_references"),
|
|
|
|
|
QLatin1String("__cpp_static_assert"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_structured_bindings"),
|
|
|
|
|
QLatin1String("__cpp_template_auto"),
|
|
|
|
|
QLatin1String("__cpp_threadsafe_static_init"),
|
2016-04-11 17:34:02 +02:00
|
|
|
QLatin1String("__cpp_unicode_characters"),
|
|
|
|
|
QLatin1String("__cpp_unicode_literals"),
|
|
|
|
|
QLatin1String("__cpp_user_defined_literals"),
|
|
|
|
|
QLatin1String("__cpp_variable_templates"),
|
|
|
|
|
QLatin1String("__cpp_variadic_templates"),
|
2017-09-29 13:46:53 +02:00
|
|
|
QLatin1String("__cpp_variadic_using"),
|
2016-04-11 17:34:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return macros;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::undefineCppLanguageFeatureMacrosForMsvc2015()
|
|
|
|
|
{
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
|
|
|
|
&& m_projectPart.isMsvc2015Toolchain) {
|
2017-09-29 13:46:53 +02:00
|
|
|
// Undefine the language feature macros that are pre-defined in clang-cl,
|
|
|
|
|
// but not in MSVC's cl.exe.
|
2016-04-11 17:34:02 +02:00
|
|
|
foreach (const QString ¯oName, languageFeatureMacros())
|
2016-10-17 15:12:05 +02:00
|
|
|
m_options.append(undefineOption() + macroName);
|
2016-04-11 17:34:02 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:18:28 +01:00
|
|
|
void CompilerOptionsBuilder::addDefineFunctionMacrosMsvc()
|
|
|
|
|
{
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
|
|
|
|
|
addMacros({{"__FUNCSIG__", "\"\""}, {"__FUNCTION__", "\"\""}, {"__FUNCDNAME__", "\"\""}});
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-02 12:21:54 +03:00
|
|
|
QString CompilerOptionsBuilder::includeDirOption() const
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2017-12-14 12:49:26 +01:00
|
|
|
return QLatin1String("-isystem");
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro ¯o) const
|
|
|
|
|
{
|
|
|
|
|
switch (macro.type) {
|
|
|
|
|
case ProjectExplorer::MacroType::Define: return defineOption().toUtf8();
|
|
|
|
|
case ProjectExplorer::MacroType::Undefine: return undefineOption().toUtf8();
|
|
|
|
|
default: return QByteArray();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray CompilerOptionsBuilder::toDefineOption(const ProjectExplorer::Macro ¯o) const
|
|
|
|
|
{
|
|
|
|
|
return macro.toKeyValue(macroOption(macro));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString CompilerOptionsBuilder::defineDirectiveToDefineOption(const ProjectExplorer::Macro ¯o) const
|
2016-04-11 11:53:50 +02:00
|
|
|
{
|
2017-02-07 15:00:38 +01:00
|
|
|
const QByteArray option = toDefineOption(macro);
|
2016-04-11 11:53:50 +02:00
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
return QString::fromUtf8(option);
|
2016-04-11 11:53:50 +02:00
|
|
|
}
|
|
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
QString CompilerOptionsBuilder::defineOption() const
|
|
|
|
|
{
|
|
|
|
|
return QLatin1String("-D");
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-17 15:12:05 +02:00
|
|
|
QString CompilerOptionsBuilder::undefineOption() const
|
|
|
|
|
{
|
|
|
|
|
return QLatin1String("-U");
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-02 12:21:54 +03:00
|
|
|
QString CompilerOptionsBuilder::includeOption() const
|
|
|
|
|
{
|
|
|
|
|
return QLatin1String("-include");
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
|
|
|
|
// This is a quick fix for QTCREATORBUG-11501.
|
|
|
|
|
// TODO: do a proper fix, see QTCREATORBUG-11709.
|
2017-02-07 15:00:38 +01:00
|
|
|
if (macro.key == "__cplusplus")
|
2016-01-11 21:09:06 +01:00
|
|
|
return true;
|
|
|
|
|
|
2017-11-06 16:00:25 +01:00
|
|
|
// 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"))
|
2016-01-11 21:09:06 +01:00
|
|
|
return true;
|
|
|
|
|
|
2016-10-31 15:25:59 +01:00
|
|
|
// If _FORTIFY_SOURCE is defined (typically in release mode), it will
|
|
|
|
|
// enable the inclusion of extra headers to help catching buffer overflows
|
|
|
|
|
// (e.g. wchar.h includes wchar2.h). These extra headers use
|
|
|
|
|
// __builtin_va_arg_pack, which clang does not support (yet), so avoid
|
|
|
|
|
// including those.
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
|
2017-02-07 15:00:38 +01:00
|
|
|
&& macro.key == "_FORTIFY_SOURCE") {
|
2016-10-31 15:25:59 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-01 14:37:57 +01:00
|
|
|
// MinGW 6 supports some fancy asm output flags and uses them in an
|
|
|
|
|
// intrinsics header pulled in by windows.h. Clang does not know them.
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID
|
2017-02-07 15:00:38 +01:00
|
|
|
&& macro.key == "__GCC_ASM_FLAG_OUTPUTS__") {
|
2016-11-01 14:37:57 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CompilerOptionsBuilder::excludeHeaderPath(const QString &headerPath) const
|
|
|
|
|
{
|
2018-01-02 15:26:08 +01:00
|
|
|
// Always exclude clang system includes (including intrinsics) which do not come with libclang
|
|
|
|
|
// that Qt Creator uses for code model.
|
|
|
|
|
// For example GCC on macOS uses system clang include path which makes clang code model
|
|
|
|
|
// include incorrect system headers.
|
|
|
|
|
static QRegularExpression clangIncludeDir(
|
|
|
|
|
QLatin1String("\\A.*/lib/clang/\\d+\\.\\d+(\\.\\d+)?/include\\z"));
|
|
|
|
|
return clangIncludeDir.match(headerPath).hasMatch();
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2017-09-27 10:32:52 +02:00
|
|
|
void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions()
|
|
|
|
|
{
|
|
|
|
|
add("-nostdinc");
|
|
|
|
|
add("-nostdlibinc");
|
|
|
|
|
|
2017-11-17 14:13:55 +01:00
|
|
|
// 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());
|
2017-12-14 12:49:26 +01:00
|
|
|
add(includeDirOption());
|
|
|
|
|
add(clangIncludeDirectory());
|
2017-09-27 10:32:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
2017-11-17 14:13:55 +01:00
|
|
|
QDir dir(creatorLibexecPath() + "/clang" + clangIncludePath(m_clangVersion));
|
2017-09-27 10:32:52 +02:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
} // namespace CppTools
|