forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.0'
Change-Id: Ied609608f6b12aa923c67777bc5a273c4d8fbcbb
This commit is contained in:
@@ -44,16 +44,39 @@ void CompilerOptionsBuilder::add(const QString &option)
|
||||
m_options.append(option);
|
||||
}
|
||||
|
||||
QString CompilerOptionsBuilder::defineLineToDefineOption(const QByteArray &defineLine)
|
||||
struct Macro {
|
||||
static Macro fromDefineDirective(const QByteArray &defineDirective);
|
||||
QByteArray toDefineOption(const QByteArray &option) const;
|
||||
|
||||
QByteArray name;
|
||||
QByteArray value;
|
||||
};
|
||||
|
||||
Macro Macro::fromDefineDirective(const QByteArray &defineDirective)
|
||||
{
|
||||
QByteArray str = defineLine.mid(8);
|
||||
int spaceIdx = str.indexOf(' ');
|
||||
const QString option = defineOption();
|
||||
const QByteArray str = defineDirective.mid(8);
|
||||
const int spaceIdx = str.indexOf(' ');
|
||||
const bool hasValue = spaceIdx != -1;
|
||||
QString arg = option + QLatin1String(str.left(hasValue ? spaceIdx : str.size()) + '=');
|
||||
|
||||
Macro macro;
|
||||
macro.name = str.left(hasValue ? spaceIdx : str.size());
|
||||
if (hasValue)
|
||||
arg += QLatin1String(str.mid(spaceIdx + 1));
|
||||
return arg;
|
||||
macro.value = str.mid(spaceIdx + 1);
|
||||
|
||||
return macro;
|
||||
}
|
||||
|
||||
QByteArray Macro::toDefineOption(const QByteArray &option) const
|
||||
{
|
||||
QByteArray result;
|
||||
|
||||
result.append(option);
|
||||
result.append(name);
|
||||
result.append('=');
|
||||
if (!value.isEmpty())
|
||||
result.append(value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addDefine(const QByteArray &defineLine)
|
||||
@@ -69,6 +92,12 @@ void CompilerOptionsBuilder::addTargetTriple()
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::enableExceptions()
|
||||
{
|
||||
add(QLatin1String("-fcxx-exceptions"));
|
||||
add(QLatin1String("-fexceptions"));
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addHeaderPathOptions()
|
||||
{
|
||||
typedef ProjectPartHeaderPath HeaderPath;
|
||||
@@ -225,11 +254,103 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension
|
||||
m_options.append(opts);
|
||||
}
|
||||
|
||||
static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer)
|
||||
{
|
||||
return mscFullVer.left(2)
|
||||
+ QByteArray(".")
|
||||
+ mscFullVer.mid(2, 2);
|
||||
}
|
||||
|
||||
static QByteArray msCompatibilityVersionFromDefines(const QByteArray &defineDirectives)
|
||||
{
|
||||
foreach (QByteArray defineDirective, defineDirectives.split('\n')) {
|
||||
if (defineDirective.isEmpty())
|
||||
continue;
|
||||
|
||||
const Macro macro = Macro::fromDefineDirective(defineDirective);
|
||||
if (macro.name == "_MSC_FULL_VER")
|
||||
return toMsCompatibilityVersionFormat(macro.value);
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::addMsvcCompatibilityVersion()
|
||||
{
|
||||
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
||||
const QByteArray defines = m_projectPart.toolchainDefines + m_projectPart.projectDefines;
|
||||
const QByteArray msvcVersion = msCompatibilityVersionFromDefines(defines);
|
||||
|
||||
if (!msvcVersion.isEmpty()) {
|
||||
const QString option = QLatin1String("-fms-compatibility-version=")
|
||||
+ QLatin1String(msvcVersion);
|
||||
m_options.append(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList languageFeatureMacros()
|
||||
{
|
||||
// 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_
|
||||
static QStringList macros {
|
||||
QLatin1String("__cpp_aggregate_nsdmi"),
|
||||
QLatin1String("__cpp_alias_templates"),
|
||||
QLatin1String("__cpp_attributes"),
|
||||
QLatin1String("__cpp_binary_literals"),
|
||||
QLatin1String("__cpp_constexpr"),
|
||||
QLatin1String("__cpp_decltype"),
|
||||
QLatin1String("__cpp_decltype_auto"),
|
||||
QLatin1String("__cpp_delegating_constructors"),
|
||||
QLatin1String("__cpp_digit_separators"),
|
||||
QLatin1String("__cpp_generic_lambdas"),
|
||||
QLatin1String("__cpp_inheriting_constructors"),
|
||||
QLatin1String("__cpp_init_captures"),
|
||||
QLatin1String("__cpp_initializer_lists"),
|
||||
QLatin1String("__cpp_lambdas"),
|
||||
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"),
|
||||
QLatin1String("__cpp_unicode_characters"),
|
||||
QLatin1String("__cpp_unicode_literals"),
|
||||
QLatin1String("__cpp_user_defined_literals"),
|
||||
QLatin1String("__cpp_variable_templates"),
|
||||
QLatin1String("__cpp_variadic_templates"),
|
||||
};
|
||||
|
||||
return macros;
|
||||
}
|
||||
|
||||
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.
|
||||
foreach (const QString ¯oName, languageFeatureMacros())
|
||||
m_options.append(QLatin1String("/U") + macroName);
|
||||
}
|
||||
}
|
||||
|
||||
QString CompilerOptionsBuilder::includeOption() const
|
||||
{
|
||||
return QLatin1String("-I");
|
||||
}
|
||||
|
||||
QString CompilerOptionsBuilder::defineLineToDefineOption(const QByteArray &defineLine)
|
||||
{
|
||||
const Macro macro = Macro::fromDefineDirective(defineLine);
|
||||
const QByteArray option = macro.toDefineOption(defineOption().toLatin1());
|
||||
|
||||
return QString::fromLatin1(option);
|
||||
}
|
||||
|
||||
QString CompilerOptionsBuilder::defineOption() const
|
||||
{
|
||||
return QLatin1String("-D");
|
||||
|
||||
@@ -45,11 +45,15 @@ public:
|
||||
|
||||
// Add options based on project part
|
||||
virtual void addTargetTriple();
|
||||
virtual void enableExceptions();
|
||||
void addHeaderPathOptions();
|
||||
void addToolchainAndProjectDefines();
|
||||
virtual void addLanguageOption(ProjectFile::Kind fileKind);
|
||||
virtual void addOptionsForLanguage(bool checkForBorlandExtensions = true);
|
||||
|
||||
void addMsvcCompatibilityVersion();
|
||||
void undefineCppLanguageFeatureMacrosForMsvc2015();
|
||||
|
||||
protected:
|
||||
virtual bool excludeDefineLine(const QByteArray &defineLine) const;
|
||||
virtual bool excludeHeaderPath(const QString &headerPath) const;
|
||||
|
||||
@@ -36,6 +36,13 @@ ProjectInfo::ProjectInfo(QPointer<ProjectExplorer::Project> project)
|
||||
: m_project(project)
|
||||
{}
|
||||
|
||||
static bool operator==(const ProjectInfo::CompilerCallGroup &first,
|
||||
const ProjectInfo::CompilerCallGroup &second)
|
||||
{
|
||||
return first.groupId == second.groupId
|
||||
&& first.callsPerSourceFile == second.callsPerSourceFile;
|
||||
}
|
||||
|
||||
bool ProjectInfo::operator ==(const ProjectInfo &other) const
|
||||
{
|
||||
return m_project == other.m_project
|
||||
|
||||
@@ -59,8 +59,13 @@ public:
|
||||
const QSet<QString> sourceFiles() const;
|
||||
const QByteArray defines() const;
|
||||
|
||||
// Source file --> List of compiler calls
|
||||
typedef QHash<QString, QList<QStringList>> CompilerCallData;
|
||||
struct CompilerCallGroup {
|
||||
using CallsPerSourceFile = QHash<QString, QList<QStringList>>;
|
||||
|
||||
QString groupId;
|
||||
CallsPerSourceFile callsPerSourceFile;
|
||||
};
|
||||
using CompilerCallData = QVector<CompilerCallGroup>;
|
||||
void setCompilerCallData(const CompilerCallData &data);
|
||||
CompilerCallData compilerCallData() const;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace CppTools {
|
||||
|
||||
ProjectPart::ProjectPart()
|
||||
: project(0)
|
||||
, isMsvc2015Toolchain(false)
|
||||
, languageVersion(CXX14)
|
||||
, languageExtensions(NoExtensions)
|
||||
, qtVersion(UnknownQt)
|
||||
|
||||
@@ -103,6 +103,7 @@ public: // fields
|
||||
QByteArray projectDefines;
|
||||
QByteArray toolchainDefines;
|
||||
Core::Id toolchainType;
|
||||
bool isMsvc2015Toolchain;
|
||||
QString targetTriple;
|
||||
ProjectPartHeaderPaths headerPaths;
|
||||
QStringList precompiledHeaders;
|
||||
|
||||
@@ -28,10 +28,12 @@
|
||||
#include "cppprojectfile.h"
|
||||
#include "cpptoolsconstants.h"
|
||||
|
||||
#include <projectexplorer/abi.h>
|
||||
#include <projectexplorer/headerpath.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
|
||||
@@ -279,6 +281,18 @@ QString targetTriple(ProjectExplorer::Project *project, const Core::Id &toolchai
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool projectHasMsvc2015Toolchain(ProjectExplorer::Project *project)
|
||||
{
|
||||
if (project) {
|
||||
if (ProjectExplorer::Target *target = project->activeTarget()) {
|
||||
if (ProjectExplorer::RunConfiguration *runConfig = target->activeRunConfiguration())
|
||||
return runConfig->abi().osFlavor() == ProjectExplorer::Abi::WindowsMsvc2015Flavor;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -341,6 +355,7 @@ void ProjectPartBuilder::evaluateProjectPartToolchain(
|
||||
|
||||
projectPart->toolchainDefines = toolChain->predefinedMacros(commandLineFlags);
|
||||
projectPart->toolchainType = toolChain->typeId();
|
||||
projectPart->isMsvc2015Toolchain = projectHasMsvc2015Toolchain(projectPart->project);
|
||||
projectPart->targetTriple = targetTriple(projectPart->project, toolChain->typeId());
|
||||
projectPart->updateLanguageFeatures();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user