forked from qt-creator/qt-creator
Clang: Support MSVC style of compiler flags
Clang has MSVC compatible mode which works with MSVC style command line flags. When possible use the same flags (-I, -D, -U, etc.) and in other cases either replace by MSVC analog (for example use /FI instead of -include) or pass the argument with '/clang:' prefix (requires https://reviews.llvm.org/D53457). Change-Id: I95f33bed5dc8d9493895ed8d4359cdd70fc774b8 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -50,14 +50,18 @@ static const char undefineOption[] = "-U";
|
||||
static const char includeUserPathOption[] = "-I";
|
||||
static const char includeSystemPathOption[] = "-isystem";
|
||||
|
||||
static const char includeFileOption[] = "-include";
|
||||
static const char includeFileOptionGcc[] = "-include";
|
||||
static const char includeFileOptionCl[] = "/FI";
|
||||
|
||||
static QByteArray macroOption(const ProjectExplorer::Macro ¯o)
|
||||
{
|
||||
switch (macro.type) {
|
||||
case ProjectExplorer::MacroType::Define: return defineOption;
|
||||
case ProjectExplorer::MacroType::Undefine: return undefineOption;
|
||||
default: return QByteArray();
|
||||
case ProjectExplorer::MacroType::Define:
|
||||
return defineOption;
|
||||
case ProjectExplorer::MacroType::Undefine:
|
||||
return undefineOption;
|
||||
default:
|
||||
return QByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +76,24 @@ static QString defineDirectiveToDefineOption(const ProjectExplorer::Macro ¯o
|
||||
return QString::fromUtf8(option);
|
||||
}
|
||||
|
||||
QStringList XclangArgs(const QStringList &args)
|
||||
{
|
||||
QStringList options;
|
||||
for (const QString &arg : args) {
|
||||
options.append("-Xclang");
|
||||
options.append(arg);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
QStringList clangArgsForCl(const QStringList &args)
|
||||
{
|
||||
QStringList options;
|
||||
for (const QString &arg : args)
|
||||
options.append("/clang:" + arg);
|
||||
return options;
|
||||
}
|
||||
|
||||
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
|
||||
UseSystemHeader useSystemHeader,
|
||||
UseToolchainMacros useToolchainMacros,
|
||||
@@ -105,8 +127,9 @@ QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
|
||||
return QStringList(););
|
||||
}
|
||||
|
||||
add("-c");
|
||||
addCompilerFlags();
|
||||
|
||||
addSyntaxOnly();
|
||||
addWordWidth();
|
||||
addTargetTriple();
|
||||
updateFileLanguage(fileKind);
|
||||
@@ -116,7 +139,6 @@ QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
|
||||
addProjectConfigFileInclude();
|
||||
|
||||
addExtraCodeModelFlags();
|
||||
addCompilerFlags();
|
||||
|
||||
addMsvcCompatibilityVersion();
|
||||
addToolchainAndProjectMacros();
|
||||
@@ -134,6 +156,21 @@ QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
|
||||
return options();
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::add(const QString &arg, bool gccOnlyOption)
|
||||
{
|
||||
add(QStringList{arg}, gccOnlyOption);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::add(const QStringList &args, bool gccOnlyOptions)
|
||||
{
|
||||
m_options.append((gccOnlyOptions && isClStyle()) ? clangArgsForCl(args) : args);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addSyntaxOnly()
|
||||
{
|
||||
isClStyle() ? add("/Zs") : add("-fsyntax-only");
|
||||
}
|
||||
|
||||
static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
|
||||
{
|
||||
QStringList options;
|
||||
@@ -202,10 +239,9 @@ void CompilerOptionsBuilder::addWordWidth()
|
||||
|
||||
void CompilerOptionsBuilder::addTargetTriple()
|
||||
{
|
||||
if (!m_projectPart.toolChainTargetTriple.isEmpty()) {
|
||||
add("-target");
|
||||
add(m_projectPart.toolChainTargetTriple);
|
||||
}
|
||||
// Only "--target=" style is accepted in both g++ and cl driver modes.
|
||||
if (!m_projectPart.toolChainTargetTriple.isEmpty())
|
||||
add("--target=" + m_projectPart.toolChainTargetTriple);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addExtraCodeModelFlags()
|
||||
@@ -213,13 +249,12 @@ 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);
|
||||
add(m_projectPart.extraCodeModelFlags);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addCompilerFlags()
|
||||
{
|
||||
if (m_compilerFlags.forward)
|
||||
m_options.append(m_compilerFlags.flags);
|
||||
add(m_compilerFlags.flags);
|
||||
}
|
||||
|
||||
static QString creatorResourcePath()
|
||||
@@ -241,7 +276,7 @@ void CompilerOptionsBuilder::insertWrappedQtHeaders()
|
||||
|
||||
const int index = m_options.indexOf(QRegularExpression("\\A-I.*\\z"));
|
||||
if (index < 0)
|
||||
m_options.append(wrappedQtHeaders);
|
||||
add(wrappedQtHeaders);
|
||||
else
|
||||
m_options = m_options.mid(0, index) + wrappedQtHeaders + m_options.mid(index);
|
||||
}
|
||||
@@ -260,7 +295,10 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
|
||||
|
||||
if (m_useTweakedHeaderPaths == UseTweakedHeaderPaths::Yes) {
|
||||
// Exclude all built-in includes except Clang resource directory.
|
||||
m_options.prepend("-nostdlibinc");
|
||||
|
||||
if (!isClStyle()) // MSVC does not have such include directories - ignore it for cl driver.
|
||||
m_options.prepend("-nostdlibinc");
|
||||
|
||||
if (!m_clangVersion.isEmpty()) {
|
||||
// Exclude all built-in includes and Clang resource directory.
|
||||
m_options.prepend("-nostdinc");
|
||||
@@ -268,20 +306,14 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
|
||||
}
|
||||
|
||||
|
||||
for (const HeaderPath &headerPath : filter.userHeaderPaths) {
|
||||
m_options.push_back(includeDirOptionForPath(headerPath.path));
|
||||
m_options.push_back(QDir::toNativeSeparators(headerPath.path));
|
||||
}
|
||||
for (const HeaderPath &headerPath : filter.userHeaderPaths)
|
||||
addIncludeDirOptionForPath(headerPath);
|
||||
|
||||
for (const HeaderPath &headerPath : filter.systemHeaderPaths) {
|
||||
m_options.push_back(includeDirOptionForSystemPath(headerPath.type));
|
||||
m_options.push_back(QDir::toNativeSeparators(headerPath.path));
|
||||
}
|
||||
for (const HeaderPath &headerPath : filter.systemHeaderPaths)
|
||||
addIncludeDirOptionForPath(headerPath);
|
||||
|
||||
for (const HeaderPath &headerPath : filter.builtInHeaderPaths) {
|
||||
m_options.push_back(includeSystemPathOption);
|
||||
m_options.push_back(QDir::toNativeSeparators(headerPath.path));
|
||||
}
|
||||
for (const HeaderPath &headerPath : filter.builtInHeaderPaths)
|
||||
addIncludeDirOptionForPath(headerPath);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addPrecompiledHeaderOptions(UsePrecompiledHeaders usePrecompiledHeaders)
|
||||
@@ -289,16 +321,13 @@ void CompilerOptionsBuilder::addPrecompiledHeaderOptions(UsePrecompiledHeaders u
|
||||
if (usePrecompiledHeaders == UsePrecompiledHeaders::No)
|
||||
return;
|
||||
|
||||
QStringList options;
|
||||
|
||||
for (const QString &pchFile : m_projectPart.precompiledHeaders) {
|
||||
if (QFile::exists(pchFile)) {
|
||||
options += includeFileOption;
|
||||
options += QDir::toNativeSeparators(pchFile);
|
||||
add({isClStyle() ? QLatin1String(includeFileOptionCl)
|
||||
: QLatin1String(includeFileOptionGcc),
|
||||
QDir::toNativeSeparators(pchFile)});
|
||||
}
|
||||
}
|
||||
|
||||
m_options.append(options);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addToolchainAndProjectMacros()
|
||||
@@ -321,11 +350,30 @@ void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros ¯os)
|
||||
options.append(defineOption);
|
||||
}
|
||||
|
||||
m_options.append(options);
|
||||
add(options);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::updateFileLanguage(ProjectFile::Kind fileKind)
|
||||
{
|
||||
if (isClStyle()) {
|
||||
QString option;
|
||||
if (ProjectFile::isC(fileKind))
|
||||
option = "/TC";
|
||||
else if (ProjectFile::isCxx(fileKind))
|
||||
option = "/TP";
|
||||
else
|
||||
QTC_ASSERT(false && "File kind not supported by cl driver mode", return;);
|
||||
|
||||
int langOptIndex = m_options.indexOf("/TC");
|
||||
if (langOptIndex == -1)
|
||||
langOptIndex = m_options.indexOf("/TP");
|
||||
if (langOptIndex == -1)
|
||||
add(option);
|
||||
else
|
||||
m_options[langOptIndex] = option;
|
||||
return;
|
||||
}
|
||||
|
||||
const bool objcExt = m_projectPart.languageExtensions
|
||||
& Utils::LanguageExtension::ObjectiveC;
|
||||
const QStringList options = createLanguageOptionGcc(fileKind, objcExt);
|
||||
@@ -335,7 +383,7 @@ void CompilerOptionsBuilder::updateFileLanguage(ProjectFile::Kind fileKind)
|
||||
QTC_ASSERT(options.size() == 2, return;);
|
||||
int langOptIndex = m_options.indexOf("-x");
|
||||
if (langOptIndex == -1)
|
||||
m_options.append(options);
|
||||
add(options);
|
||||
else
|
||||
m_options[langOptIndex + 1] = options[1];
|
||||
}
|
||||
@@ -345,59 +393,71 @@ void CompilerOptionsBuilder::addLanguageVersionAndExtensions()
|
||||
using Utils::LanguageExtension;
|
||||
using Utils::LanguageVersion;
|
||||
|
||||
QStringList options;
|
||||
if (m_compilerFlags.isLanguageVersionSpecified)
|
||||
return;
|
||||
|
||||
QString option;
|
||||
if (isClStyle()) {
|
||||
switch (m_projectPart.languageVersion) {
|
||||
default:
|
||||
break;
|
||||
case LanguageVersion::CXX14:
|
||||
option = "/std:c++14";
|
||||
break;
|
||||
case LanguageVersion::CXX17:
|
||||
option = "/std:c++17";
|
||||
break;
|
||||
case LanguageVersion::CXX2a:
|
||||
option = "/std:c++latest";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!option.isEmpty()) {
|
||||
add(option);
|
||||
return;
|
||||
}
|
||||
|
||||
// Continue in case no cl-style option could be chosen.
|
||||
}
|
||||
|
||||
const Utils::LanguageExtensions languageExtensions = m_projectPart.languageExtensions;
|
||||
const bool gnuExtensions = languageExtensions & LanguageExtension::Gnu;
|
||||
|
||||
if (!m_compilerFlags.forward
|
||||
|| (m_compilerFlags.forward && !m_compilerFlags.isLanguageVersionSpecified)) {
|
||||
switch (m_projectPart.languageVersion) {
|
||||
case LanguageVersion::C89:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89"));
|
||||
break;
|
||||
case LanguageVersion::C99:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99"));
|
||||
break;
|
||||
case LanguageVersion::C11:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
|
||||
break;
|
||||
case LanguageVersion::C18:
|
||||
// Clang 6, 7 and current trunk do not accept "gnu18"/"c18", so use the "*17" variants.
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu17") : QLatin1String("-std=c17"));
|
||||
break;
|
||||
case LanguageVersion::CXX11:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
|
||||
break;
|
||||
case LanguageVersion::CXX98:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98"));
|
||||
break;
|
||||
case LanguageVersion::CXX03:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03"));
|
||||
break;
|
||||
case LanguageVersion::CXX14:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14"));
|
||||
break;
|
||||
case LanguageVersion::CXX17:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
|
||||
break;
|
||||
case LanguageVersion::CXX2a:
|
||||
options << (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a"));
|
||||
break;
|
||||
}
|
||||
switch (m_projectPart.languageVersion) {
|
||||
case LanguageVersion::C89:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89"));
|
||||
break;
|
||||
case LanguageVersion::C99:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99"));
|
||||
break;
|
||||
case LanguageVersion::C11:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
|
||||
break;
|
||||
case LanguageVersion::C18:
|
||||
// Clang 6, 7 and current trunk do not accept "gnu18"/"c18", so use the "*17" variants.
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu17") : QLatin1String("-std=c17"));
|
||||
break;
|
||||
case LanguageVersion::CXX11:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
|
||||
break;
|
||||
case LanguageVersion::CXX98:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98"));
|
||||
break;
|
||||
case LanguageVersion::CXX03:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03"));
|
||||
break;
|
||||
case LanguageVersion::CXX14:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14"));
|
||||
break;
|
||||
case LanguageVersion::CXX17:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
|
||||
break;
|
||||
case LanguageVersion::CXX2a:
|
||||
option = (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_compilerFlags.forward) {
|
||||
if (languageExtensions & LanguageExtension::Microsoft)
|
||||
options << "-fms-extensions";
|
||||
|
||||
if (languageExtensions & LanguageExtension::OpenMP)
|
||||
options << "-fopenmp";
|
||||
|
||||
if (languageExtensions & LanguageExtension::Borland)
|
||||
options << "-fborland-extensions";
|
||||
}
|
||||
|
||||
m_options.append(options);
|
||||
add(option, /*gccOnlyOption=*/true);
|
||||
}
|
||||
|
||||
static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer)
|
||||
@@ -515,14 +575,34 @@ void CompilerOptionsBuilder::addDefineFunctionMacrosMsvc()
|
||||
}
|
||||
}
|
||||
|
||||
QString CompilerOptionsBuilder::includeDirOptionForPath(const QString &path) const
|
||||
void CompilerOptionsBuilder::addIncludeDirOptionForPath(const ProjectExplorer::HeaderPath &path)
|
||||
{
|
||||
if (m_useSystemHeader == UseSystemHeader::No
|
||||
|| path.startsWith(m_projectPart.project->rootProjectDirectory().toString())) {
|
||||
return QLatin1String(includeUserPathOption);
|
||||
if (path.type == ProjectExplorer::HeaderPathType::Framework) {
|
||||
QTC_ASSERT(isClStyle(), return;);
|
||||
add({"-F", QDir::toNativeSeparators(path.path)});
|
||||
return;
|
||||
}
|
||||
|
||||
return QLatin1String(includeSystemPathOption);
|
||||
bool systemPath = false;
|
||||
if (path.type == ProjectExplorer::HeaderPathType::BuiltIn) {
|
||||
systemPath = true;
|
||||
} else if (path.type == ProjectExplorer::HeaderPathType::System) {
|
||||
if (m_useSystemHeader == UseSystemHeader::Yes)
|
||||
systemPath = true;
|
||||
} else {
|
||||
// ProjectExplorer::HeaderPathType::User
|
||||
if (m_useSystemHeader == UseSystemHeader::Yes
|
||||
&& !path.path.startsWith(m_projectPart.project->rootProjectDirectory().toString())) {
|
||||
systemPath = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (systemPath) {
|
||||
add({includeSystemPathOption, QDir::toNativeSeparators(path.path)}, true);
|
||||
return;
|
||||
}
|
||||
|
||||
add({includeUserPathOption, QDir::toNativeSeparators(path.path)});
|
||||
}
|
||||
|
||||
bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const
|
||||
@@ -575,41 +655,28 @@ void CompilerOptionsBuilder::addWrappedQtHeadersIncludePath(QStringList &list) c
|
||||
|
||||
if (m_projectPart.qtVersion != ProjectPart::NoQt) {
|
||||
const QString wrappedQtCoreHeaderPath = wrappedQtHeadersPath + "/QtCore";
|
||||
list.append(includeDirOptionForPath(wrappedQtHeadersPath));
|
||||
list.append(QDir::toNativeSeparators(wrappedQtHeadersPath));
|
||||
list.append(includeDirOptionForPath(wrappedQtHeadersPath));
|
||||
list.append(QDir::toNativeSeparators(wrappedQtCoreHeaderPath));
|
||||
list.append({includeUserPathOption,
|
||||
QDir::toNativeSeparators(wrappedQtHeadersPath),
|
||||
includeUserPathOption,
|
||||
QDir::toNativeSeparators(wrappedQtCoreHeaderPath)});
|
||||
}
|
||||
}
|
||||
|
||||
QString CompilerOptionsBuilder::includeDirOptionForSystemPath(ProjectExplorer::HeaderPathType type) const
|
||||
{
|
||||
if (type == ProjectExplorer::HeaderPathType::Framework)
|
||||
return QString("-F");
|
||||
|
||||
if (m_useSystemHeader == UseSystemHeader::Yes)
|
||||
return QString(includeSystemPathOption);
|
||||
|
||||
return QString(includeUserPathOption);
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addToolchainFlags()
|
||||
{
|
||||
// In case of MSVC we need builtin clang defines to correctly handle clang includes
|
||||
if (m_projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
||||
&& m_projectPart.toolchainType != ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
|
||||
&& m_projectPart.toolchainType != ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
|
||||
if (m_useToolchainMacros == UseToolchainMacros::Yes)
|
||||
add("-undef");
|
||||
else if (!m_compilerFlags.forward)
|
||||
add("-fPIC");
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addProjectConfigFileInclude()
|
||||
{
|
||||
if (!m_projectPart.projectConfigFile.isEmpty()) {
|
||||
add(includeFileOption);
|
||||
add(QDir::toNativeSeparators(m_projectPart.projectConfigFile));
|
||||
add({isClStyle() ? QLatin1String(includeFileOptionCl) : QLatin1String(includeFileOptionGcc),
|
||||
QDir::toNativeSeparators(m_projectPart.projectConfigFile)});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,31 +718,53 @@ void CompilerOptionsBuilder::reset()
|
||||
// QMakeProject: -pipe -Whello -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC
|
||||
void CompilerOptionsBuilder::evaluateCompilerFlags()
|
||||
{
|
||||
const Core::Id &toolChain = m_projectPart.toolchainType;
|
||||
if (toolChain == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
|
||||
|| toolChain == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) {
|
||||
m_compilerFlags.forward = true;
|
||||
|
||||
for (const QString &option : m_projectPart.compilerFlags) {
|
||||
// Ignore warning flags as these interfere with ouser user-configured diagnostics.
|
||||
// Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows.
|
||||
if (option.startsWith("-w", Qt::CaseInsensitive) // -w, -W...
|
||||
|| option.startsWith("-pedantic")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check whether a language version is already used.
|
||||
// Modify if needed as clang accepts c18/gnu18, but not c17/gnu17.
|
||||
QString theOption = option;
|
||||
if (theOption.startsWith("-std=")) {
|
||||
m_compilerFlags.isLanguageVersionSpecified = true;
|
||||
theOption.replace("=c18", "=c17");
|
||||
theOption.replace("=gnu18", "=gnu17");
|
||||
}
|
||||
|
||||
m_compilerFlags.flags.append(theOption);
|
||||
bool containsDriverMode = false;
|
||||
for (const QString &option : m_projectPart.compilerFlags) {
|
||||
// Ignore warning flags as these interfere with ouser user-configured diagnostics.
|
||||
// Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows.
|
||||
if (option.startsWith("-w", Qt::CaseInsensitive)
|
||||
|| option.startsWith("/w", Qt::CaseInsensitive) || option.startsWith("-pedantic")) {
|
||||
// -w, -W, /w, /W...
|
||||
continue;
|
||||
}
|
||||
|
||||
if (option.startsWith("-O", Qt::CaseSensitive) || option.startsWith("/O", Qt::CaseSensitive)
|
||||
|| option.startsWith("/M", Qt::CaseSensitive)) {
|
||||
// Optimization and run-time flags.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check whether a language version is already used.
|
||||
QString theOption = option;
|
||||
if (theOption.startsWith("-std=")) {
|
||||
m_compilerFlags.isLanguageVersionSpecified = true;
|
||||
theOption.replace("=c18", "=c17");
|
||||
theOption.replace("=gnu18", "=gnu17");
|
||||
} else if (theOption.startsWith("/std:") || theOption.startsWith("-std:")) {
|
||||
m_compilerFlags.isLanguageVersionSpecified = true;
|
||||
}
|
||||
|
||||
if (theOption.startsWith("--driver-mode=")) {
|
||||
if (theOption.endsWith("cl"))
|
||||
m_clStyle = true;
|
||||
containsDriverMode = true;
|
||||
}
|
||||
|
||||
m_compilerFlags.flags.append(theOption);
|
||||
}
|
||||
|
||||
const Core::Id &toolChain = m_projectPart.toolchainType;
|
||||
if (!containsDriverMode
|
||||
&& (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
||||
|| toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)) {
|
||||
m_clStyle = true;
|
||||
m_compilerFlags.flags.prepend("--driver-mode=cl");
|
||||
}
|
||||
}
|
||||
|
||||
bool CompilerOptionsBuilder::isClStyle() const
|
||||
{
|
||||
return m_clStyle;
|
||||
}
|
||||
|
||||
} // namespace CppTools
|
||||
|
||||
@@ -37,6 +37,9 @@ enum class UseTweakedHeaderPaths : char { Yes, No };
|
||||
enum class UseToolchainMacros : char { Yes, No };
|
||||
enum class UseLanguageDefines : char { Yes, No };
|
||||
|
||||
CPPTOOLS_EXPORT QStringList XclangArgs(const QStringList &args);
|
||||
CPPTOOLS_EXPORT QStringList clangArgsForCl(const QStringList &args);
|
||||
|
||||
class CPPTOOLS_EXPORT CompilerOptionsBuilder
|
||||
{
|
||||
public:
|
||||
@@ -53,6 +56,7 @@ public:
|
||||
|
||||
// Add options based on project part
|
||||
virtual void addToolchainAndProjectMacros();
|
||||
void addSyntaxOnly();
|
||||
void addWordWidth();
|
||||
void addToolchainFlags();
|
||||
void addHeaderPathOptions();
|
||||
@@ -74,18 +78,20 @@ public:
|
||||
void undefineClangVersionMacrosForMsvc();
|
||||
|
||||
// Add custom options
|
||||
void add(const QString &option) { m_options.append(option); }
|
||||
void add(const QString &arg, bool gccOnlyOption = false);
|
||||
void add(const QStringList &args, bool gccOnlyOptions = false);
|
||||
virtual void addExtraOptions() {}
|
||||
|
||||
static UseToolchainMacros useToolChainMacros();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
void evaluateCompilerFlags();
|
||||
bool isClStyle() const;
|
||||
|
||||
private:
|
||||
void addIncludeDirOptionForPath(const ProjectExplorer::HeaderPath &path);
|
||||
bool excludeDefineDirective(const ProjectExplorer::Macro ¯o) const;
|
||||
QString includeDirOptionForPath(const QString &path) const;
|
||||
void addWrappedQtHeadersIncludePath(QStringList &list) const;
|
||||
QString includeDirOptionForSystemPath(ProjectExplorer::HeaderPathType type) const;
|
||||
QByteArray msvcVersion() const;
|
||||
|
||||
private:
|
||||
@@ -100,12 +106,12 @@ private:
|
||||
const QString m_clangResourceDirectory;
|
||||
|
||||
struct {
|
||||
bool forward = false;
|
||||
QStringList flags;
|
||||
bool isLanguageVersionSpecified = false;
|
||||
} m_compilerFlags;
|
||||
|
||||
QStringList m_options;
|
||||
bool m_clStyle = false;
|
||||
};
|
||||
|
||||
} // namespace CppTools
|
||||
|
||||
@@ -118,6 +118,42 @@ bool ProjectFile::isSource() const
|
||||
return isSource(kind);
|
||||
}
|
||||
|
||||
bool ProjectFile::isC(ProjectFile::Kind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case ProjectFile::CHeader:
|
||||
case ProjectFile::CSource:
|
||||
case ProjectFile::ObjCHeader:
|
||||
case ProjectFile::ObjCSource:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectFile::isCxx(ProjectFile::Kind kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case ProjectFile::CXXHeader:
|
||||
case ProjectFile::CXXSource:
|
||||
case ProjectFile::ObjCXXHeader:
|
||||
case ProjectFile::ObjCXXSource:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectFile::isC() const
|
||||
{
|
||||
return isC(kind);
|
||||
}
|
||||
|
||||
bool ProjectFile::isCxx() const
|
||||
{
|
||||
return isCxx(kind);
|
||||
}
|
||||
|
||||
#define RETURN_TEXT_FOR_CASE(enumValue) case ProjectFile::enumValue: return #enumValue
|
||||
const char *projectFileKindToText(ProjectFile::Kind kind)
|
||||
{
|
||||
|
||||
@@ -54,11 +54,16 @@ public:
|
||||
|
||||
static bool isSource(Kind kind);
|
||||
static bool isHeader(Kind kind);
|
||||
static bool isC(Kind kind);
|
||||
static bool isCxx(Kind kind);
|
||||
static bool isAmbiguousHeader(const QString &filePath);
|
||||
|
||||
bool isHeader() const;
|
||||
bool isSource() const;
|
||||
|
||||
bool isC() const;
|
||||
bool isCxx() const;
|
||||
|
||||
public:
|
||||
ProjectFile() = default;
|
||||
ProjectFile(const QString &filePath, Kind kind, bool active = true);
|
||||
|
||||
Reference in New Issue
Block a user