summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsproject.cpp6
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.cpp6
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp2
-rw-r--r--src/plugins/cppcheck/cppchecktool.cpp4
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp12
-rw-r--r--src/plugins/cpptools/cppcodemodelinspectordumper.cpp5
-rw-r--r--src/plugins/cpptools/cppprojectinfogenerator.cpp67
-rw-r--r--src/plugins/cpptools/cppprojectinfogenerator.h4
-rw-r--r--src/plugins/cpptools/projectinfo.cpp2
-rw-r--r--src/plugins/cpptools/projectinfo.h2
-rw-r--r--src/plugins/cpptools/projectpart.h10
-rw-r--r--src/plugins/genericprojectmanager/genericproject.cpp6
-rw-r--r--src/plugins/nim/project/nimtoolchain.cpp4
-rw-r--r--src/plugins/nim/project/nimtoolchain.h2
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.cpp104
-rw-r--r--src/plugins/projectexplorer/abstractmsvctoolchain.h5
-rw-r--r--src/plugins/projectexplorer/customtoolchain.cpp14
-rw-r--r--src/plugins/projectexplorer/customtoolchain.h2
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.cpp92
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.h4
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp1
-rw-r--r--src/plugins/projectexplorer/toolchain.cpp73
-rw-r--r--src/plugins/projectexplorer/toolchain.h39
-rw-r--r--src/plugins/projectexplorer/toolchainsettingsaccessor.cpp2
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp6
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp6
-rw-r--r--tests/unit/mockup/projectexplorer/toolchain.h31
-rw-r--r--tests/unit/unittest/cppprojectinfogenerator-test.cpp14
28 files changed, 317 insertions, 208 deletions
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
index c211fcc471..fc4850b84f 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
@@ -276,10 +276,8 @@ void AutotoolsProject::updateCppCodeModel()
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
- if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
- activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder;
- else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
- activeQtVersion = CppTools::ProjectPart::Qt4Latest;
+ if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
+ activeQtVersion = CppTools::ProjectPart::Qt4;
else
activeQtVersion = CppTools::ProjectPart::Qt5;
}
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index ddf9ba6d89..598a0f7b4a 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -286,10 +286,8 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc)
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
- if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
- activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder;
- else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
- activeQtVersion = CppTools::ProjectPart::Qt4Latest;
+ if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
+ activeQtVersion = CppTools::ProjectPart::Qt4;
else
activeQtVersion = CppTools::ProjectPart::Qt5;
}
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
index 487652aeb9..47c66df91a 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp
@@ -253,7 +253,7 @@ CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FileName &pr
tcInfo.targetTriple = tc->originalTargetTriple();
tcInfo.sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
tcInfo.headerPathsRunner = tc->createBuiltInHeaderPathsRunner();
- tcInfo.predefinedMacrosRunner = tc->createPredefinedMacrosRunner();
+ tcInfo.macroInspectionRunner = tc->createMacroInspectionRunner();
m_cppCodeModelUpdater->update({this, tcInfo, tcInfo, rpps});
diff --git a/src/plugins/cppcheck/cppchecktool.cpp b/src/plugins/cppcheck/cppchecktool.cpp
index 28111cd3f6..5288e0f4c1 100644
--- a/src/plugins/cppcheck/cppchecktool.cpp
+++ b/src/plugins/cppcheck/cppchecktool.cpp
@@ -148,6 +148,9 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
case Version::C11:
result.push_back("--std=c11 --language=c");
break;
+ case Version::C18:
+ result.push_back("--language=c");
+ break;
case Version::CXX03:
result.push_back("--std=c++03 --language=c++");
break;
@@ -159,6 +162,7 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
break;
case Version::CXX98:
case Version::CXX17:
+ case Version::CXX2a:
result.push_back("--language=c++");
break;
}
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index e722722e25..b05bd09d1f 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -408,6 +408,10 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension
case ProjectPart::C11:
opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
break;
+ case ProjectPart::C18:
+ // Clang 6, 7 and current trunk do not accept "gnu18"/"c18", so use the "*17" variants.
+ opts << (gnuExtensions ? QLatin1String("-std=gnu17") : QLatin1String("-std=c17"));
+ break;
case ProjectPart::CXX11:
opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
break;
@@ -423,6 +427,9 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension
case ProjectPart::CXX17:
opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
break;
+ case ProjectPart::CXX2a:
+ opts << (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a"));
+ break;
}
if (languageExtensions & ProjectPart::MicrosoftExtensions)
@@ -588,6 +595,11 @@ QString CompilerOptionsBuilder::includeOption() const
bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro &macro) const
{
+ // Avoid setting __cplusplus & co as this might conflict with other command line flags.
+ // Clang should set __cplusplus based on -std= and -fms-compatibility-version version.
+ QTC_ASSERT(macro.key != "__cplusplus", return true);
+ QTC_ASSERT(macro.key != "__STDC_VERSION__", return true);
+
// 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"))
diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
index 6a0c1fe124..540ac99104 100644
--- a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
+++ b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp
@@ -110,11 +110,13 @@ QString Utils::toString(ProjectPart::LanguageVersion languageVersion)
CASE_LANGUAGEVERSION(C89);
CASE_LANGUAGEVERSION(C99);
CASE_LANGUAGEVERSION(C11);
+ CASE_LANGUAGEVERSION(C18);
CASE_LANGUAGEVERSION(CXX98);
CASE_LANGUAGEVERSION(CXX03);
CASE_LANGUAGEVERSION(CXX11);
CASE_LANGUAGEVERSION(CXX14);
CASE_LANGUAGEVERSION(CXX17);
+ CASE_LANGUAGEVERSION(CXX2a);
// no default to get a compiler warning if anything is added
}
#undef CASE_LANGUAGEVERSION
@@ -146,8 +148,7 @@ QString Utils::toString(ProjectPart::QtVersion qtVersion)
switch (qtVersion) {
CASE_QTVERSION(UnknownQt);
CASE_QTVERSION(NoQt);
- CASE_QTVERSION(Qt4_8_6AndOlder);
- CASE_QTVERSION(Qt4Latest);
+ CASE_QTVERSION(Qt4);
CASE_QTVERSION(Qt5);
// no default to get a compiler warning if anything is added
}
diff --git a/src/plugins/cpptools/cppprojectinfogenerator.cpp b/src/plugins/cpptools/cppprojectinfogenerator.cpp
index fd1c928090..8d04f2429e 100644
--- a/src/plugins/cpptools/cppprojectinfogenerator.cpp
+++ b/src/plugins/cpptools/cppprojectinfogenerator.cpp
@@ -30,6 +30,8 @@
#include <projectexplorer/headerpath.h>
#include <projectexplorer/projectexplorerconstants.h>
+#include <utils/qtcassert.h>
+
namespace CppTools {
namespace Internal {
@@ -39,9 +41,11 @@ class ToolChainEvaluator
{
public:
ToolChainEvaluator(ProjectPart &projectPart,
+ Language language,
const RawProjectPartFlags &flags,
const ToolChainInfo &tcInfo)
: m_projectPart(projectPart)
+ , m_language(language)
, m_flags(flags)
, m_tcInfo(tcInfo)
{
@@ -61,11 +65,20 @@ public:
if (m_projectPart.toolchainType == ProjectExplorer::Constants::COMPILATION_DATABASE_TOOLCHAIN_TYPEID)
m_projectPart.extraCodeModelFlags = m_flags.commandLineFlags;
- mapLanguageVersion();
- mapLanguageExtensions();
+ if (m_tcInfo.macroInspectionRunner) {
+ auto macroInspectionReport = m_tcInfo.macroInspectionRunner(m_flags.commandLineFlags);
+ m_projectPart.toolChainMacros = macroInspectionReport.macros;
+ m_projectPart.languageVersion = static_cast<ProjectPart::LanguageVersion>(
+ macroInspectionReport.languageVersion);
+ } else { // No compiler set in kit.
+ if (m_language == Language::C)
+ m_projectPart.languageVersion = ProjectPart::LanguageVersion::LatestCVersion;
+ if (m_language == Language::CXX)
+ m_projectPart.languageVersion = ProjectPart::LanguageVersion::LatestCxxVersion;
+ }
+ mapLanguageExtensions();
addHeaderPaths();
- addDefines();
}
private:
@@ -76,27 +89,6 @@ private:
: ProjectPart::WordWidth32Bit;
}
- void mapLanguageVersion()
- {
- using namespace ProjectExplorer;
-
- const ToolChain::CompilerFlags &compilerFlags = m_flags.compilerFlags;
- ProjectPart::LanguageVersion &languageVersion = m_projectPart.languageVersion;
-
- if (compilerFlags & ToolChain::StandardC11)
- languageVersion = ProjectPart::C11;
- else if (compilerFlags & ToolChain::StandardC99)
- languageVersion = ProjectPart::C99;
- else if (compilerFlags & ToolChain::StandardCxx17)
- languageVersion = ProjectPart::CXX17;
- else if (compilerFlags & ToolChain::StandardCxx14)
- languageVersion = ProjectPart::CXX14;
- else if (compilerFlags & ToolChain::StandardCxx11)
- languageVersion = ProjectPart::CXX11;
- else if (compilerFlags & ToolChain::StandardCxx98)
- languageVersion = ProjectPart::CXX98;
- }
-
void mapLanguageExtensions()
{
using namespace ProjectExplorer;
@@ -133,16 +125,9 @@ private:
}
}
- void addDefines()
- {
- if (!m_tcInfo.predefinedMacrosRunner)
- return; // No compiler set in kit.
-
- m_projectPart.toolChainMacros = m_tcInfo.predefinedMacrosRunner(m_flags.commandLineFlags);
- }
-
private:
ProjectPart &m_projectPart;
+ const Language m_language;
const RawProjectPartFlags &m_flags;
const ToolChainInfo &m_tcInfo;
};
@@ -205,15 +190,12 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart,
m_projectUpdateInfo.project);
- ProjectPart::LanguageVersion defaultVersion = ProjectPart::LatestCxxVersion;
- if (rawProjectPart.qtVersion == ProjectPart::Qt4_8_6AndOlder)
- defaultVersion = ProjectPart::CXX11;
if (cat.hasCxxSources()) {
result << createProjectPart(rawProjectPart,
part,
cat.cxxSources(),
cat.partName("C++"),
- defaultVersion,
+ Language::CXX,
ProjectPart::NoExtensions);
}
@@ -222,7 +204,7 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
part,
cat.objcxxSources(),
cat.partName("Obj-C++"),
- defaultVersion,
+ Language::CXX,
ProjectPart::ObjectiveCExtensions);
}
@@ -231,7 +213,7 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
part,
cat.cSources(),
cat.partName("C"),
- ProjectPart::LatestCVersion,
+ Language::C,
ProjectPart::NoExtensions);
}
@@ -240,7 +222,7 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
part,
cat.objcSources(),
cat.partName("Obj-C"),
- ProjectPart::LatestCVersion,
+ Language::C,
ProjectPart::ObjectiveCExtensions);
}
}
@@ -251,17 +233,16 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &r
const ProjectPart::Ptr &templateProjectPart,
const ProjectFiles &projectFiles,
const QString &partName,
- ProjectPart::LanguageVersion languageVersion,
+ Language language,
ProjectPart::LanguageExtensions languageExtensions)
{
ProjectPart::Ptr part(templateProjectPart->copy());
part->displayName = partName;
part->files = projectFiles;
- part->languageVersion = languageVersion;
RawProjectPartFlags flags;
ToolChainInfo tcInfo;
- if (languageVersion <= ProjectPart::LatestCVersion) {
+ if (language == Language::C) {
flags = rawProjectPart.flagsForC;
tcInfo = m_projectUpdateInfo.cToolChainInfo;
}
@@ -271,7 +252,7 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &r
tcInfo = m_projectUpdateInfo.cxxToolChainInfo;
}
// TODO: If no toolchain is set, show a warning
- ToolChainEvaluator evaluator(*part.data(), flags, tcInfo);
+ ToolChainEvaluator evaluator(*part.data(), language, flags, tcInfo);
evaluator.evaluate();
part->languageExtensions |= languageExtensions;
diff --git a/src/plugins/cpptools/cppprojectinfogenerator.h b/src/plugins/cpptools/cppprojectinfogenerator.h
index 6f81eaf85f..963c9a748b 100644
--- a/src/plugins/cpptools/cppprojectinfogenerator.h
+++ b/src/plugins/cpptools/cppprojectinfogenerator.h
@@ -32,6 +32,8 @@
namespace CppTools {
namespace Internal {
+enum class Language { C, CXX };
+
class ProjectInfoGenerator
{
public:
@@ -46,7 +48,7 @@ private:
const ProjectPart::Ptr &templateProjectPart,
const ProjectFiles &projectFiles,
const QString &partName,
- ProjectPart::LanguageVersion languageVersion,
+ Language language,
ProjectPart::LanguageExtensions languageExtensions);
private:
diff --git a/src/plugins/cpptools/projectinfo.cpp b/src/plugins/cpptools/projectinfo.cpp
index a51caebe11..c39449fef7 100644
--- a/src/plugins/cpptools/projectinfo.cpp
+++ b/src/plugins/cpptools/projectinfo.cpp
@@ -48,7 +48,7 @@ ToolChainInfo::ToolChainInfo(const ProjectExplorer::ToolChain *toolChain,
// they can be run from a worker thread.
sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner();
- predefinedMacrosRunner = toolChain->createPredefinedMacrosRunner();
+ macroInspectionRunner = toolChain->createMacroInspectionRunner();
}
}
diff --git a/src/plugins/cpptools/projectinfo.h b/src/plugins/cpptools/projectinfo.h
index 38bf509cba..a69ffd8fdf 100644
--- a/src/plugins/cpptools/projectinfo.h
+++ b/src/plugins/cpptools/projectinfo.h
@@ -58,7 +58,7 @@ public:
QString sysRootPath; // For headerPathsRunner.
ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner;
- ProjectExplorer::ToolChain::PredefinedMacrosRunner predefinedMacrosRunner;
+ ProjectExplorer::ToolChain::MacroInspectionRunner macroInspectionRunner;
};
class CPPTOOLS_EXPORT ProjectUpdateInfo
diff --git a/src/plugins/cpptools/projectpart.h b/src/plugins/cpptools/projectpart.h
index ce017abc79..8d04e71ff3 100644
--- a/src/plugins/cpptools/projectpart.h
+++ b/src/plugins/cpptools/projectpart.h
@@ -49,17 +49,20 @@ namespace CppTools {
class CPPTOOLS_EXPORT ProjectPart
{
public:
+ // Keep in sync with Toolchain::LanguageVersion!
enum LanguageVersion {
C89,
C99,
C11,
- LatestCVersion = C11,
+ C18,
+ LatestCVersion = C18,
CXX98,
CXX03,
CXX11,
CXX14,
CXX17,
- LatestCxxVersion = CXX17,
+ CXX2a,
+ LatestCxxVersion = CXX2a,
};
enum LanguageExtension {
@@ -81,8 +84,7 @@ public:
enum QtVersion {
UnknownQt = -1,
NoQt,
- Qt4_8_6AndOlder,
- Qt4Latest,
+ Qt4,
Qt5
};
diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp
index edeac3eec4..b99d037e65 100644
--- a/src/plugins/genericprojectmanager/genericproject.cpp
+++ b/src/plugins/genericprojectmanager/genericproject.cpp
@@ -436,10 +436,8 @@ void GenericProject::refreshCppCodeModel()
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
if (QtSupport::BaseQtVersion *qtVersion =
QtSupport::QtKitInformation::qtVersion(activeTarget()->kit())) {
- if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
- activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder;
- else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
- activeQtVersion = CppTools::ProjectPart::Qt4Latest;
+ if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
+ activeQtVersion = CppTools::ProjectPart::Qt4;
else
activeQtVersion = CppTools::ProjectPart::Qt5;
}
diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp
index 01147f4fa1..ec1651a682 100644
--- a/src/plugins/nim/project/nimtoolchain.cpp
+++ b/src/plugins/nim/project/nimtoolchain.cpp
@@ -77,9 +77,9 @@ bool NimToolChain::isValid() const
return fi.isExecutable();
}
-ToolChain::PredefinedMacrosRunner NimToolChain::createPredefinedMacrosRunner() const
+ToolChain::MacroInspectionRunner NimToolChain::createMacroInspectionRunner() const
{
- return ToolChain::PredefinedMacrosRunner();
+ return ToolChain::MacroInspectionRunner();
}
Macros NimToolChain::predefinedMacros(const QStringList &) const
diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h
index 7b25e993de..4f866d5f27 100644
--- a/src/plugins/nim/project/nimtoolchain.h
+++ b/src/plugins/nim/project/nimtoolchain.h
@@ -40,7 +40,7 @@ public:
ProjectExplorer::Abi targetAbi() const override;
bool isValid() const override;
- PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
+ MacroInspectionRunner createMacroInspectionRunner() const override;
ProjectExplorer::Macros predefinedMacros(const QStringList &flags) const final;
CompilerFlags compilerFlags(const QStringList &flags) const final;
ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final;
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
index 4bd77d1462..151c4400ef 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp
@@ -99,23 +99,88 @@ QString AbstractMsvcToolChain::originalTargetTriple() const
: QLatin1String("i686-pc-windows-msvc");
}
-ToolChain::PredefinedMacrosRunner AbstractMsvcToolChain::createPredefinedMacrosRunner() const
+//
+// We want to detect the language version based on the predefined macros.
+// Unfortunately MSVC does not conform to standard when it comes to the predefined
+// __cplusplus macro - it reports "199711L", even for newer language versions.
+//
+// However:
+// * For >= Visual Studio 2015 Update 3 predefines _MSVC_LANG which has the proper value
+// of __cplusplus.
+// See https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2017
+// * For >= Visual Studio 2017 Version 15.7 __cplusplus is correct once /Zc:__cplusplus
+// is provided on the command line. Then __cplusplus == _MSVC_LANG.
+// See https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus
+//
+// We rely on _MSVC_LANG if possible, otherwise on some hard coded language versions
+// depending on _MSC_VER.
+//
+// For _MSV_VER values, see https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2017.
+//
+ToolChain::LanguageVersion static languageVersionForMsvc(const Core::Id &language,
+ const Macros &macros)
+{
+ using LanguageVersion = ToolChain::LanguageVersion;
+
+ int mscVer = -1;
+ QByteArray msvcLang;
+ for (const ProjectExplorer::Macro &macro : macros) {
+ if (macro.key == "_MSVC_LANG")
+ msvcLang = macro.value;
+ if (macro.key == "_MSC_VER")
+ mscVer = macro.value.toInt(nullptr);
+ }
+ QTC_CHECK(mscVer > 0);
+
+ if (language == Constants::CXX_LANGUAGE_ID) {
+ if (!msvcLang.isEmpty()) // >= Visual Studio 2015 Update 3
+ return ToolChain::cxxLanguageVersion(msvcLang);
+ if (mscVer >= 1800) // >= Visual Studio 2013 (12.0)
+ return LanguageVersion::CXX14;
+ if (mscVer >= 1600) // >= Visual Studio 2010 (10.0)
+ return LanguageVersion::CXX11;
+ return LanguageVersion::CXX98;
+ } else if (language == Constants::C_LANGUAGE_ID) {
+ if (mscVer >= 1910) // >= Visual Studio 2017 RTW (15.0)
+ return LanguageVersion::C11;
+ return LanguageVersion::C99;
+ } else {
+ QTC_CHECK(false && "Unexpected toolchain language, assuming latest C++ we support.");
+ return LanguageVersion::LatestCxxVersion;
+ }
+}
+
+Q_GLOBAL_STATIC_WITH_ARGS(const QVector<QByteArray>, unwantedMacrosMsvc,
+ ({"_MSVC_LANG",
+ "_MSC_BUILD",
+ "_MSC_FULL_VER",
+ "_MSC_VER"}))
+
+ToolChain::MacroInspectionRunner AbstractMsvcToolChain::createMacroInspectionRunner() const
{
Utils::Environment env(m_lastEnvironment);
addToEnvironment(env);
+ const Core::Id lang = language();
// This runner must be thread-safe!
- return [this, env](const QStringList &cxxflags) {
+ return [this, env, lang](const QStringList &cxxflags) {
QMutexLocker locker(m_predefinedMacrosMutex);
- if (m_predefinedMacros.isEmpty())
+ if (m_predefinedMacros.isEmpty() || m_cxxFlags != cxxflags) {
m_predefinedMacros = msvcPredefinedMacros(cxxflags, env);
- return m_predefinedMacros;
+ m_cxxFlags = cxxflags;
+ }
+
+ const QVector<Macro> filteredMacros = Utils::filtered(m_predefinedMacros, [](const Macro &m) {
+ return !ToolChain::isUnwantedMacro(m) && !unwantedMacrosMsvc->contains(m.key);
+ });
+ return MacroInspectionReport{filteredMacros,
+ languageVersionForMsvc(lang, m_predefinedMacros)};
};
}
ProjectExplorer::Macros AbstractMsvcToolChain::predefinedMacros(const QStringList &cxxflags) const
{
- return createPredefinedMacrosRunner()(cxxflags);
+ return createMacroInspectionRunner()(cxxflags).macros;
}
ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList &cxxflags) const
@@ -128,35 +193,6 @@ ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList
if (cxxflags.contains(QLatin1String("/Za")))
flags &= ~MicrosoftExtensions;
- bool cLanguage = (language() == ProjectExplorer::Constants::C_LANGUAGE_ID);
-
- switch (m_abi.osFlavor()) {
- case Abi::WindowsMsvc2010Flavor:
- case Abi::WindowsMsvc2012Flavor:
- if (cLanguage)
- flags |= StandardC99;
- else
- flags |= StandardCxx11;
- break;
- case Abi::WindowsMsvc2013Flavor:
- case Abi::WindowsMsvc2015Flavor:
- if (cLanguage)
- flags |= StandardC99;
- else
- flags |= StandardCxx14;
- break;
- case Abi::WindowsMsvc2017Flavor:
- if (cLanguage)
- flags |= StandardC11;
- else if (cxxflags.contains("/std:c++17") || cxxflags.contains("/std:c++latest"))
- flags |= StandardCxx17;
- else
- flags |= StandardCxx14;
- break;
- default:
- break;
- }
-
return flags;
}
diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.h b/src/plugins/projectexplorer/abstractmsvctoolchain.h
index 2979e728cc..d949073f46 100644
--- a/src/plugins/projectexplorer/abstractmsvctoolchain.h
+++ b/src/plugins/projectexplorer/abstractmsvctoolchain.h
@@ -53,7 +53,7 @@ public:
QString originalTargetTriple() const override;
- PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
+ MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) const override;
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
WarningFlags warningFlags(const QStringList &cflags) const override;
@@ -99,8 +99,11 @@ protected:
Utils::FileName m_debuggerCommand;
+
mutable QMutex *m_predefinedMacrosMutex = nullptr;
mutable Macros m_predefinedMacros;
+ mutable QStringList m_cxxFlags;
+
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
mutable QMutex *m_headerPathsMutex = nullptr;
diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp
index f9cb0a81a7..7b952e0fe2 100644
--- a/src/plugins/projectexplorer/customtoolchain.cpp
+++ b/src/plugins/projectexplorer/customtoolchain.cpp
@@ -116,12 +116,13 @@ bool CustomToolChain::isValid() const
return true;
}
-ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner() const
+ToolChain::MacroInspectionRunner CustomToolChain::createMacroInspectionRunner() const
{
const Macros theMacros = m_predefinedMacros;
+ const Core::Id lang = language();
// This runner must be thread-safe!
- return [theMacros](const QStringList &cxxflags){
+ return [theMacros, lang](const QStringList &cxxflags){
Macros macros = theMacros;
for (const QString &cxxFlag : cxxflags) {
if (cxxFlag.startsWith(QLatin1String("-D")))
@@ -130,20 +131,17 @@ ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner(
macros.append({cxxFlag.mid(2).trimmed().toUtf8(), MacroType::Undefine});
}
- return macros;
+ return MacroInspectionReport{macros, ToolChain::languageVersion(lang, macros)};
};
}
Macros CustomToolChain::predefinedMacros(const QStringList &cxxflags) const
{
- return createPredefinedMacrosRunner()(cxxflags);
+ return createMacroInspectionRunner()(cxxflags).macros;
}
-ToolChain::CompilerFlags CustomToolChain::compilerFlags(const QStringList &cxxflags) const
+ToolChain::CompilerFlags CustomToolChain::compilerFlags(const QStringList &) const
{
- for (const QString &cxx11Flag : m_cxx11Flags)
- if (cxxflags.contains(cxx11Flag))
- return StandardCxx11;
return NoFlags;
}
diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h
index 23abb2e730..28fd7a1828 100644
--- a/src/plugins/projectexplorer/customtoolchain.h
+++ b/src/plugins/projectexplorer/customtoolchain.h
@@ -71,7 +71,7 @@ public:
bool isValid() const override;
- PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
+ MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) const override;
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
WarningFlags warningFlags(const QStringList &cxxflags) const override;
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index 622b477ca2..2fa6de6737 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -254,7 +254,7 @@ GccToolChain::GccToolChain(Detection d) :
GccToolChain::GccToolChain(Core::Id typeId, Detection d) :
ToolChain(typeId, d),
- m_predefinedMacrosCache(std::make_shared<Cache<QVector<Macro>, 64>>()),
+ m_predefinedMacrosCache(std::make_shared<Cache<MacroInspectionReport, 64>>()),
m_headerPathsCache(std::make_shared<Cache<HeaderPaths>>())
{ }
@@ -385,9 +385,7 @@ static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath,
return path.isEmpty() ? compilerPath : path;
}
-Q_GLOBAL_STATIC_WITH_ARGS(const QVector<QByteArray>, unwantedMacros, ({"__cplusplus"}))
-
-ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() const
+ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() const
{
// Using a clean environment breaks ccache/distcc/etc.
Environment env = Environment::systemEnvironment();
@@ -396,7 +394,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
QTC_CHECK(reinterpretOptions);
- std::shared_ptr<Cache<QVector<Macro>, 64>> macroCache = m_predefinedMacrosCache;
+ std::shared_ptr<Cache<MacroInspectionReport, 64>> macroCache = m_predefinedMacrosCache;
Core::Id lang = language();
// This runner must be thread-safe!
@@ -436,20 +434,22 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
}
arguments = reinterpretOptions(arguments);
- const Utils::optional<QVector<Macro>> cachedMacros = macroCache->check(arguments);
+ const Utils::optional<MacroInspectionReport> cachedMacros = macroCache->check(arguments);
if (cachedMacros)
return cachedMacros.value();
- const QVector<Macro> macros
- = gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
- arguments,
- env.toStringList());
+ const Macros macros = gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
+ arguments,
+ env.toStringList());
const QVector<Macro> filteredMacros = Utils::filtered(macros, [](const Macro &m) {
- return !unwantedMacros->contains(m.key);
+ return !isUnwantedMacro(m);
});
- macroCache->insert(arguments, filteredMacros);
- qCDebug(gccLog) << "Reporting macros to code model:";
+ const auto report = MacroInspectionReport{filteredMacros, languageVersion(lang, macros)};
+ macroCache->insert(arguments, report);
+
+ qCDebug(gccLog) << "MacroInspectionReport for code model:";
+ qCDebug(gccLog) << "Language version:" << report.languageVersion;
for (const Macro &m : filteredMacros) {
qCDebug(gccLog) << compilerCommand.toUserOutput()
<< (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
@@ -457,7 +457,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
<< QString::fromUtf8(m.toByteArray());
}
- return filteredMacros;
+ return report;
};
}
@@ -472,7 +472,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
*/
ProjectExplorer::Macros GccToolChain::predefinedMacros(const QStringList &cxxflags) const
{
- return createPredefinedMacrosRunner()(cxxflags);
+ return createMacroInspectionRunner()(cxxflags).macros;
}
/**
@@ -487,55 +487,14 @@ ToolChain::CompilerFlags GccToolChain::compilerFlags(const QStringList &cxxflags
foreach (const QString &flag, allCxxflags) {
if (flag.startsWith("-std=")) {
const QByteArray std = flag.mid(5).toLatin1();
- if (std == "c++98" || std == "c++03") {
- flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | StandardCxx17 | GnuExtensions);
- flags |= StandardCxx98;
- } else if (std == "gnu++98" || std == "gnu++03") {
- flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | StandardCxx17);
- flags |= GnuExtensions;
- } else if (std == "c++0x" || std == "c++11") {
- flags |= StandardCxx11;
- flags &= ~CompilerFlags(StandardCxx14 | StandardCxx17 | GnuExtensions);
- } else if (std == "c++14" || std == "c++1y") {
- flags |= StandardCxx14;
- flags &= ~CompilerFlags(StandardCxx11 | StandardCxx17 | GnuExtensions);
- } else if (std == "c++17" || std == "c++1z") {
- flags |= StandardCxx17;
- flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | GnuExtensions);
- } else if (std == "gnu++0x" || std == "gnu++11") {
- flags |= CompilerFlags(StandardCxx11 | GnuExtensions);
- flags &= ~CompilerFlags(StandardCxx14 | StandardCxx17);
- } else if (std== "gnu++14" || std == "gnu++1y") {
- flags |= CompilerFlags(StandardCxx14 | GnuExtensions);
- flags &= ~CompilerFlags(StandardCxx11 | StandardCxx17);
- } else if (std== "gnu++17" || std == "gnu++1z") {
- flags |= CompilerFlags(StandardCxx17 | GnuExtensions);
- flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14);
- } else if (std == "c89" || std == "c90"
- || std == "iso9899:1990" || std == "iso9899:199409") {
- flags &= ~CompilerFlags(StandardC99 | StandardC11);
- } else if (std == "gnu89" || std == "gnu90") {
- flags &= ~CompilerFlags(StandardC99 | StandardC11);
- flags |= GnuExtensions;
- } else if (std == "c99" || std == "c9x"
- || std == "iso9899:1999" || std == "iso9899:199x") {
- flags |= StandardC99;
- flags &= ~StandardC11;
- } else if (std == "gnu99" || std == "gnu9x") {
- flags |= CompilerFlags(StandardC99 | GnuExtensions);
- flags &= ~StandardC11;
- } else if (std == "c11" || std == "c1x" || std == "iso9899:2011") {
- flags |= CompilerFlags(StandardC99 | StandardC11);
- } else if (std == "gnu11" || std == "gnu1x") {
- flags |= CompilerFlags(StandardC99 | StandardC11 | GnuExtensions);
- }
+ if (std.startsWith("gnu"))
+ flags |= CompilerFlags(GnuExtensions);
+ else
+ flags &= ~CompilerFlags(GnuExtensions);
} else if (flag == "-fopenmp") {
flags |= OpenMP;
} else if (flag == "-fms-extensions") {
flags |= MicrosoftExtensions;
- } else if (flag == "-ansi") {
- flags &= ~CompilerFlags(StandardCxx11 | GnuExtensions
- | StandardC99 | StandardC11);
}
}
@@ -1069,7 +1028,10 @@ QList<ToolChain *> GccToolChainFactory::autoDetectToolChain(const FileName &comp
return result;
tc->setLanguage(language);
- tc->m_predefinedMacrosCache->insert(QStringList(), macros);
+ tc->m_predefinedMacrosCache
+ ->insert(QStringList(),
+ ToolChain::MacroInspectionReport{macros,
+ ToolChain::languageVersion(language, macros)});
tc->setCompilerCommand(compilerPath);
tc->setSupportedAbis(detectedAbis.supportedAbis);
tc->setTargetAbi(abi);
@@ -1134,7 +1096,11 @@ void GccToolChainConfigWidget::applyImpl()
tc->setDisplayName(displayName); // reset display name
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));
tc->setPlatformLinkerFlags(splitString(m_platformLinkerFlagsLineEdit->text()));
- tc->m_predefinedMacrosCache->insert(tc->platformCodeGenFlags(), m_macros);
+ tc->m_predefinedMacrosCache
+ ->insert(tc->platformCodeGenFlags(),
+ ToolChain::MacroInspectionReport{m_macros,
+ ToolChain::languageVersion(tc->language(),
+ m_macros)});
}
void GccToolChainConfigWidget::setFromToolchain()
@@ -1319,7 +1285,7 @@ void ClangToolChain::addToEnvironment(Environment &env) const
ToolChain::CompilerFlags ClangToolChain::defaultCompilerFlags() const
{
- return CompilerFlags(GnuExtensions | StandardCxx11);
+ return CompilerFlags(GnuExtensions);
}
IOutputParser *ClangToolChain::outputParser() const
diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h
index 3458f63414..64e2acbe51 100644
--- a/src/plugins/projectexplorer/gcctoolchain.h
+++ b/src/plugins/projectexplorer/gcctoolchain.h
@@ -143,7 +143,7 @@ public:
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
WarningFlags warningFlags(const QStringList &cflags) const override;
- PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
+ MacroInspectionRunner createMacroInspectionRunner() const override;
Macros predefinedMacros(const QStringList &cxxflags) const override;
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
@@ -253,7 +253,7 @@ private:
mutable HeaderPaths m_headerPaths;
mutable QString m_version;
- mutable std::shared_ptr<Cache<QVector<Macro>, 64>> m_predefinedMacrosCache;
+ mutable std::shared_ptr<Cache<MacroInspectionReport, 64>> m_predefinedMacrosCache;
mutable std::shared_ptr<Cache<HeaderPaths>> m_headerPathsCache;
mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {};
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 765dc86d38..7fb74661ec 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -334,6 +334,7 @@ static QByteArray msvcCompilationFile()
"__CLR_VER",
"_CMMN_INTRIN_FUNC",
"_CONTROL_FLOW_GUARD",
+ "__cplusplus",
"__cplusplus_cli",
"__cplusplus_winrt",
"_CPPLIB_VER",
diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp
index e0c1b113a8..e11481d06f 100644
--- a/src/plugins/projectexplorer/toolchain.cpp
+++ b/src/plugins/projectexplorer/toolchain.cpp
@@ -286,6 +286,79 @@ bool ToolChain::fromMap(const QVariantMap &data)
return true;
}
+static long toLanguageVersionAsLong(QByteArray dateAsByteArray)
+{
+ dateAsByteArray.chop(1); // Strip 'L'.
+ return dateAsByteArray.toLong(nullptr);
+}
+
+ToolChain::LanguageVersion ToolChain::cxxLanguageVersion(const QByteArray &cplusplusMacroValue)
+{
+ const long version = toLanguageVersionAsLong(cplusplusMacroValue);
+
+ if (version > 201703L)
+ return LanguageVersion::LatestCxxVersion;
+
+ switch (version) {
+ case 201703L: return LanguageVersion::CXX17;
+ case 201403L: Q_FALLTHROUGH();
+ case 201402L: return LanguageVersion::CXX14;
+ case 201103L: return LanguageVersion::CXX11;
+ case 199711L: return LanguageVersion::CXX03;
+ default:
+ QTC_CHECK(false && "Unexpected __cplusplus value, assuming latest C++ we support.");
+ return LanguageVersion::LatestCxxVersion;
+ }
+}
+
+ToolChain::LanguageVersion ToolChain::languageVersion(const Core::Id &language, const Macros &macros)
+{
+ if (language == Constants::CXX_LANGUAGE_ID) {
+ for (const ProjectExplorer::Macro &macro : macros) {
+ if (macro.key == "__cplusplus") // Check for the C++ identifying macro
+ return cxxLanguageVersion(macro.value);
+ }
+
+ QTC_CHECK(false && "__cplusplus is not predefined, assuming latest C++ we support.");
+ return LanguageVersion::LatestCxxVersion;
+ } else if (language == Constants::C_LANGUAGE_ID) {
+ for (const ProjectExplorer::Macro &macro : macros) {
+ if (macro.key == "__STDC_VERSION__") {
+ const long version = toLanguageVersionAsLong(macro.value);
+
+ if (version > 201710L)
+ return LanguageVersion::LatestCVersion;
+
+ switch (version) {
+ case 201710L: return LanguageVersion::C18;
+ case 201112L: return LanguageVersion::C11;
+ case 199901L: return LanguageVersion::C99;
+ case 199409L: return LanguageVersion::C89; // C89 as amended in 1994
+ default:
+ QTC_CHECK(false && "Unexpected __STDC_VERSION__ value, "
+ "assuming latest C version we support.");
+ return LanguageVersion::LatestCVersion;
+ }
+ }
+ }
+
+ // The __STDC_VERSION__ macro was introduced after C89.
+ // We haven't seen it, so it must be C89.
+ return LanguageVersion::C89;
+ } else {
+ QTC_CHECK(false && "Unexpected toolchain language, assuming latest C++ we support.");
+ return LanguageVersion::LatestCxxVersion;
+ }
+}
+
+Q_GLOBAL_STATIC_WITH_ARGS(const QVector<QByteArray>, unwantedMacros,
+ ({"__cplusplus", "__STDC_VERSION__"}))
+
+bool ToolChain::isUnwantedMacro(const Macro &macro)
+{
+ return unwantedMacros->contains(macro.key);
+}
+
/*!
Used by the tool chain kit information to validate the kit.
*/
diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h
index fcc7e93d06..89bbab09b4 100644
--- a/src/plugins/projectexplorer/toolchain.h
+++ b/src/plugins/projectexplorer/toolchain.h
@@ -109,26 +109,44 @@ public:
enum CompilerFlag {
NoFlags = 0,
- StandardCxx11 = 0x1,
- StandardC99 = 0x2,
- StandardC11 = 0x4,
GnuExtensions = 0x8,
MicrosoftExtensions = 0x10,
BorlandExtensions = 0x20,
OpenMP = 0x40,
ObjectiveC = 0x80,
- StandardCxx14 = 0x100,
- StandardCxx17 = 0x200,
- StandardCxx98 = 0x400,
};
+
+ // Keep in sync with ProjectPart::LanguageVersion!
+ enum LanguageVersion {
+ C89,
+ C99,
+ C11,
+ C18,
+ LatestCVersion = C18,
+ CXX98,
+ CXX03,
+ CXX11,
+ CXX14,
+ CXX17,
+ CXX2a,
+ LatestCxxVersion = CXX2a,
+ };
+
Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag)
virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0;
virtual WarningFlags warningFlags(const QStringList &cflags) const = 0;
- // A PredefinedMacrosRunner is created in the ui thread and runs in another thread.
- using PredefinedMacrosRunner = std::function<Macros(const QStringList &cxxflags)>;
- virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const = 0;
+ class MacroInspectionReport
+ {
+ public:
+ Macros macros;
+ LanguageVersion languageVersion;
+ };
+
+ // A MacroInspectionRunner is created in the ui thread and runs in another thread.
+ using MacroInspectionRunner = std::function<MacroInspectionReport(const QStringList &cxxflags)>;
+ virtual MacroInspectionRunner createMacroInspectionRunner() const = 0;
virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0;
// A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread.
@@ -157,6 +175,9 @@ public:
virtual QList<Task> validateKit(const Kit *k) const;
void setLanguage(Core::Id language);
+ static LanguageVersion cxxLanguageVersion(const QByteArray &cplusplusMacroValue);
+ static LanguageVersion languageVersion(const Core::Id &language, const Macros &macros);
+ static bool isUnwantedMacro(const Macro &macro);
protected:
explicit ToolChain(Core::Id typeId, Detection d);
diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp
index 409812440f..e0055bfe81 100644
--- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp
+++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp
@@ -308,7 +308,7 @@ public:
QString typeDisplayName() const override { return QString("Test Tool Chain"); }
Abi targetAbi() const override { return Abi::hostAbi(); }
bool isValid() const override { return m_valid; }
- PredefinedMacrosRunner createPredefinedMacrosRunner() const override { return PredefinedMacrosRunner(); }
+ MacroInspectionRunner createMacroInspectionRunner() const override { return MacroInspectionRunner(); }
Macros predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return Macros(); }
CompilerFlags compilerFlags(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return NoFlags; }
WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags); return WarningFlags::NoWarnings; }
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index 1e07625be3..7981547ab3 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -915,10 +915,8 @@ void QbsProject::updateCppCodeModel()
CppTools::ProjectPart::QtVersion qtVersionFromKit = CppTools::ProjectPart::NoQt;
if (qtVersion) {
- if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
- qtVersionFromKit = CppTools::ProjectPart::Qt4_8_6AndOlder;
- else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
- qtVersionFromKit = CppTools::ProjectPart::Qt4Latest;
+ if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
+ qtVersionFromKit = CppTools::ProjectPart::Qt4;
else
qtVersionFromKit = CppTools::ProjectPart::Qt5;
}
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index e825d600a2..2547797780 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -277,10 +277,8 @@ void QmakeProject::updateCppCodeModel()
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt;
if (qtVersion) {
- if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
- qtVersionForPart = ProjectPart::Qt4_8_6AndOlder;
- else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
- qtVersionForPart = ProjectPart::Qt4Latest;
+ if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
+ qtVersionForPart = ProjectPart::Qt4;
else
qtVersionForPart = ProjectPart::Qt5;
}
diff --git a/tests/unit/mockup/projectexplorer/toolchain.h b/tests/unit/mockup/projectexplorer/toolchain.h
index 93cb630c4c..3ce5ad8902 100644
--- a/tests/unit/mockup/projectexplorer/toolchain.h
+++ b/tests/unit/mockup/projectexplorer/toolchain.h
@@ -41,17 +41,11 @@ public:
enum CompilerFlag {
NoFlags = 0,
- StandardCxx11 = 0x1,
- StandardC99 = 0x2,
- StandardC11 = 0x4,
GnuExtensions = 0x8,
MicrosoftExtensions = 0x10,
BorlandExtensions = 0x20,
OpenMP = 0x40,
ObjectiveC = 0x80,
- StandardCxx14 = 0x100,
- StandardCxx17 = 0x200,
- StandardCxx98 = 0x400,
};
Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag)
@@ -60,8 +54,29 @@ public:
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(const QStringList &cxxflags, const QString &sysRoot)>;
virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const { return BuiltInHeaderPathsRunner(); }
- using PredefinedMacrosRunner = std::function<Macros(const QStringList &cxxflags)>;
- virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const { return PredefinedMacrosRunner(); }
+ enum LanguageVersion {
+ C89,
+ C99,
+ C11,
+ C18,
+ LatestCVersion = C18,
+ CXX98,
+ CXX03,
+ CXX11,
+ CXX14,
+ CXX17,
+ CXX2a,
+ LatestCxxVersion = CXX2a,
+ };
+
+ class MacroInspectionReport
+ {
+ public:
+ Macros macros;
+ LanguageVersion languageVersion; // Derived from macros.
+ };
+ using MacroInspectionRunner = std::function<MacroInspectionReport(const QStringList &cxxflags)>;
+ virtual MacroInspectionRunner createMacroInspectionRunner() const = 0;
virtual QString originalTargetTriple() const { return QString(); }
virtual QStringList extraCodeModelFlags() const { return QStringList(); }
diff --git a/tests/unit/unittest/cppprojectinfogenerator-test.cpp b/tests/unit/unittest/cppprojectinfogenerator-test.cpp
index 9a991a7520..b93ab46a73 100644
--- a/tests/unit/unittest/cppprojectinfogenerator-test.cpp
+++ b/tests/unit/unittest/cppprojectinfogenerator-test.cpp
@@ -39,6 +39,7 @@ using CppTools::ProjectUpdateInfo;
using CppTools::ProjectPart;
using CppTools::RawProjectPart;
+using ProjectExplorer::Macros;
using ProjectExplorer::ToolChain;
using testing::Eq;
@@ -65,6 +66,7 @@ protected:
ProjectInfo generate();
protected:
+ ProjectUpdateInfo projectUpdateInfo;
RawProjectPart rawProjectPart;
};
@@ -115,19 +117,21 @@ TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault)
ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::LatestCxxVersion));
}
-TEST_F(ProjectInfoGenerator, UseCompilerFlagsForLanguageVersion)
+TEST_F(ProjectInfoGenerator, UseMacroInspectionReportForLanguageVersion)
{
+ projectUpdateInfo.cxxToolChainInfo.macroInspectionRunner = [](const QStringList &) {
+ return ToolChain::MacroInspectionReport{Macros(), ToolChain::LanguageVersion::CXX17};
+ };
rawProjectPart.files = QStringList{ "foo.cpp" };
- rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::StandardCxx98;
const ProjectInfo projectInfo = generate();
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
- ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::CXX98));
+ ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::CXX17));
}
-TEST_F(ProjectInfoGenerator, UseCompilerFlagsForLangaugeExtensions)
+TEST_F(ProjectInfoGenerator, UseCompilerFlagsForLanguageExtensions)
{
rawProjectPart.files = QStringList{ "foo.cpp" };
rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::MicrosoftExtensions;
@@ -160,7 +164,7 @@ void ProjectInfoGenerator::SetUp()
ProjectInfo ProjectInfoGenerator::generate()
{
QFutureInterface<void> fi;
- ProjectUpdateInfo projectUpdateInfo;
+
projectUpdateInfo.rawProjectParts += rawProjectPart;
::ProjectInfoGenerator generator(fi, projectUpdateInfo);