forked from qt-creator/qt-creator
Toolchains: Detect unspecified language version
We checked the command line from the project manager for "-std=X" and friends to figure out the language version to use. However, if such a flag was not provided, we assumed the latest version we support. This could conflict with the actual version of the compiler and its predefined macros. Figure out the version by inspecting __cplusplus/__STDC_VERSION__ in the predefined macros of the toolchain. The MSVC compiler is an exception to this, as it does not seem to properly set the value - check for _MSVC_LANG if possible, otherwise simply assume some versions as before. While at it, add also support for C17/C18 and the upcoming C++2a. Task-number: QTCREATORBUG-20884 Task-number: QTCREATORBUG-21188 Change-Id: I464ffcd52d2120c0208275a050e82efda44fae1c Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -276,10 +276,8 @@ void AutotoolsProject::updateCppCodeModel()
|
|||||||
|
|
||||||
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
|
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
|
||||||
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
|
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
|
||||||
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
|
if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder;
|
activeQtVersion = CppTools::ProjectPart::Qt4;
|
||||||
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt4Latest;
|
|
||||||
else
|
else
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt5;
|
activeQtVersion = CppTools::ProjectPart::Qt5;
|
||||||
}
|
}
|
||||||
|
@@ -286,10 +286,8 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc)
|
|||||||
|
|
||||||
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
|
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
|
||||||
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
|
if (QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k)) {
|
||||||
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
|
if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder;
|
activeQtVersion = CppTools::ProjectPart::Qt4;
|
||||||
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt4Latest;
|
|
||||||
else
|
else
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt5;
|
activeQtVersion = CppTools::ProjectPart::Qt5;
|
||||||
}
|
}
|
||||||
|
@@ -253,7 +253,7 @@ CompilationDatabaseProject::CompilationDatabaseProject(const Utils::FileName &pr
|
|||||||
tcInfo.targetTriple = tc->originalTargetTriple();
|
tcInfo.targetTriple = tc->originalTargetTriple();
|
||||||
tcInfo.sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
|
tcInfo.sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
|
||||||
tcInfo.headerPathsRunner = tc->createBuiltInHeaderPathsRunner();
|
tcInfo.headerPathsRunner = tc->createBuiltInHeaderPathsRunner();
|
||||||
tcInfo.predefinedMacrosRunner = tc->createPredefinedMacrosRunner();
|
tcInfo.macroInspectionRunner = tc->createMacroInspectionRunner();
|
||||||
|
|
||||||
m_cppCodeModelUpdater->update({this, tcInfo, tcInfo, rpps});
|
m_cppCodeModelUpdater->update({this, tcInfo, tcInfo, rpps});
|
||||||
|
|
||||||
|
@@ -148,6 +148,9 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
|
|||||||
case Version::C11:
|
case Version::C11:
|
||||||
result.push_back("--std=c11 --language=c");
|
result.push_back("--std=c11 --language=c");
|
||||||
break;
|
break;
|
||||||
|
case Version::C18:
|
||||||
|
result.push_back("--language=c");
|
||||||
|
break;
|
||||||
case Version::CXX03:
|
case Version::CXX03:
|
||||||
result.push_back("--std=c++03 --language=c++");
|
result.push_back("--std=c++03 --language=c++");
|
||||||
break;
|
break;
|
||||||
@@ -159,6 +162,7 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part)
|
|||||||
break;
|
break;
|
||||||
case Version::CXX98:
|
case Version::CXX98:
|
||||||
case Version::CXX17:
|
case Version::CXX17:
|
||||||
|
case Version::CXX2a:
|
||||||
result.push_back("--language=c++");
|
result.push_back("--language=c++");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -408,6 +408,10 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension
|
|||||||
case ProjectPart::C11:
|
case ProjectPart::C11:
|
||||||
opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
|
opts << (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
|
||||||
break;
|
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:
|
case ProjectPart::CXX11:
|
||||||
opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
|
||||||
break;
|
break;
|
||||||
@@ -423,6 +427,9 @@ void CompilerOptionsBuilder::addOptionsForLanguage(bool checkForBorlandExtension
|
|||||||
case ProjectPart::CXX17:
|
case ProjectPart::CXX17:
|
||||||
opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
|
||||||
break;
|
break;
|
||||||
|
case ProjectPart::CXX2a:
|
||||||
|
opts << (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a"));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (languageExtensions & ProjectPart::MicrosoftExtensions)
|
if (languageExtensions & ProjectPart::MicrosoftExtensions)
|
||||||
@@ -588,6 +595,11 @@ QString CompilerOptionsBuilder::includeOption() const
|
|||||||
|
|
||||||
bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const
|
bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) 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
|
// Ignore for all compiler toolchains since LLVM has it's own implementation for
|
||||||
// __has_include(STR) and __has_include_next(STR)
|
// __has_include(STR) and __has_include_next(STR)
|
||||||
if (macro.key.startsWith("__has_include"))
|
if (macro.key.startsWith("__has_include"))
|
||||||
|
@@ -110,11 +110,13 @@ QString Utils::toString(ProjectPart::LanguageVersion languageVersion)
|
|||||||
CASE_LANGUAGEVERSION(C89);
|
CASE_LANGUAGEVERSION(C89);
|
||||||
CASE_LANGUAGEVERSION(C99);
|
CASE_LANGUAGEVERSION(C99);
|
||||||
CASE_LANGUAGEVERSION(C11);
|
CASE_LANGUAGEVERSION(C11);
|
||||||
|
CASE_LANGUAGEVERSION(C18);
|
||||||
CASE_LANGUAGEVERSION(CXX98);
|
CASE_LANGUAGEVERSION(CXX98);
|
||||||
CASE_LANGUAGEVERSION(CXX03);
|
CASE_LANGUAGEVERSION(CXX03);
|
||||||
CASE_LANGUAGEVERSION(CXX11);
|
CASE_LANGUAGEVERSION(CXX11);
|
||||||
CASE_LANGUAGEVERSION(CXX14);
|
CASE_LANGUAGEVERSION(CXX14);
|
||||||
CASE_LANGUAGEVERSION(CXX17);
|
CASE_LANGUAGEVERSION(CXX17);
|
||||||
|
CASE_LANGUAGEVERSION(CXX2a);
|
||||||
// no default to get a compiler warning if anything is added
|
// no default to get a compiler warning if anything is added
|
||||||
}
|
}
|
||||||
#undef CASE_LANGUAGEVERSION
|
#undef CASE_LANGUAGEVERSION
|
||||||
@@ -146,8 +148,7 @@ QString Utils::toString(ProjectPart::QtVersion qtVersion)
|
|||||||
switch (qtVersion) {
|
switch (qtVersion) {
|
||||||
CASE_QTVERSION(UnknownQt);
|
CASE_QTVERSION(UnknownQt);
|
||||||
CASE_QTVERSION(NoQt);
|
CASE_QTVERSION(NoQt);
|
||||||
CASE_QTVERSION(Qt4_8_6AndOlder);
|
CASE_QTVERSION(Qt4);
|
||||||
CASE_QTVERSION(Qt4Latest);
|
|
||||||
CASE_QTVERSION(Qt5);
|
CASE_QTVERSION(Qt5);
|
||||||
// no default to get a compiler warning if anything is added
|
// no default to get a compiler warning if anything is added
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,8 @@
|
|||||||
#include <projectexplorer/headerpath.h>
|
#include <projectexplorer/headerpath.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -39,9 +41,11 @@ class ToolChainEvaluator
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ToolChainEvaluator(ProjectPart &projectPart,
|
ToolChainEvaluator(ProjectPart &projectPart,
|
||||||
|
Language language,
|
||||||
const RawProjectPartFlags &flags,
|
const RawProjectPartFlags &flags,
|
||||||
const ToolChainInfo &tcInfo)
|
const ToolChainInfo &tcInfo)
|
||||||
: m_projectPart(projectPart)
|
: m_projectPart(projectPart)
|
||||||
|
, m_language(language)
|
||||||
, m_flags(flags)
|
, m_flags(flags)
|
||||||
, m_tcInfo(tcInfo)
|
, m_tcInfo(tcInfo)
|
||||||
{
|
{
|
||||||
@@ -61,11 +65,20 @@ public:
|
|||||||
if (m_projectPart.toolchainType == ProjectExplorer::Constants::COMPILATION_DATABASE_TOOLCHAIN_TYPEID)
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::COMPILATION_DATABASE_TOOLCHAIN_TYPEID)
|
||||||
m_projectPart.extraCodeModelFlags = m_flags.commandLineFlags;
|
m_projectPart.extraCodeModelFlags = m_flags.commandLineFlags;
|
||||||
|
|
||||||
mapLanguageVersion();
|
if (m_tcInfo.macroInspectionRunner) {
|
||||||
mapLanguageExtensions();
|
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();
|
addHeaderPaths();
|
||||||
addDefines();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -76,27 +89,6 @@ private:
|
|||||||
: ProjectPart::WordWidth32Bit;
|
: 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()
|
void mapLanguageExtensions()
|
||||||
{
|
{
|
||||||
using namespace ProjectExplorer;
|
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:
|
private:
|
||||||
ProjectPart &m_projectPart;
|
ProjectPart &m_projectPart;
|
||||||
|
const Language m_language;
|
||||||
const RawProjectPartFlags &m_flags;
|
const RawProjectPartFlags &m_flags;
|
||||||
const ToolChainInfo &m_tcInfo;
|
const ToolChainInfo &m_tcInfo;
|
||||||
};
|
};
|
||||||
@@ -205,15 +190,12 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
|
|||||||
const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart,
|
const ProjectPart::Ptr part = projectPartFromRawProjectPart(rawProjectPart,
|
||||||
m_projectUpdateInfo.project);
|
m_projectUpdateInfo.project);
|
||||||
|
|
||||||
ProjectPart::LanguageVersion defaultVersion = ProjectPart::LatestCxxVersion;
|
|
||||||
if (rawProjectPart.qtVersion == ProjectPart::Qt4_8_6AndOlder)
|
|
||||||
defaultVersion = ProjectPart::CXX11;
|
|
||||||
if (cat.hasCxxSources()) {
|
if (cat.hasCxxSources()) {
|
||||||
result << createProjectPart(rawProjectPart,
|
result << createProjectPart(rawProjectPart,
|
||||||
part,
|
part,
|
||||||
cat.cxxSources(),
|
cat.cxxSources(),
|
||||||
cat.partName("C++"),
|
cat.partName("C++"),
|
||||||
defaultVersion,
|
Language::CXX,
|
||||||
ProjectPart::NoExtensions);
|
ProjectPart::NoExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +204,7 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
|
|||||||
part,
|
part,
|
||||||
cat.objcxxSources(),
|
cat.objcxxSources(),
|
||||||
cat.partName("Obj-C++"),
|
cat.partName("Obj-C++"),
|
||||||
defaultVersion,
|
Language::CXX,
|
||||||
ProjectPart::ObjectiveCExtensions);
|
ProjectPart::ObjectiveCExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +213,7 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
|
|||||||
part,
|
part,
|
||||||
cat.cSources(),
|
cat.cSources(),
|
||||||
cat.partName("C"),
|
cat.partName("C"),
|
||||||
ProjectPart::LatestCVersion,
|
Language::C,
|
||||||
ProjectPart::NoExtensions);
|
ProjectPart::NoExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +222,7 @@ QVector<ProjectPart::Ptr> ProjectInfoGenerator::createProjectParts(const RawProj
|
|||||||
part,
|
part,
|
||||||
cat.objcSources(),
|
cat.objcSources(),
|
||||||
cat.partName("Obj-C"),
|
cat.partName("Obj-C"),
|
||||||
ProjectPart::LatestCVersion,
|
Language::C,
|
||||||
ProjectPart::ObjectiveCExtensions);
|
ProjectPart::ObjectiveCExtensions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,17 +233,16 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &r
|
|||||||
const ProjectPart::Ptr &templateProjectPart,
|
const ProjectPart::Ptr &templateProjectPart,
|
||||||
const ProjectFiles &projectFiles,
|
const ProjectFiles &projectFiles,
|
||||||
const QString &partName,
|
const QString &partName,
|
||||||
ProjectPart::LanguageVersion languageVersion,
|
Language language,
|
||||||
ProjectPart::LanguageExtensions languageExtensions)
|
ProjectPart::LanguageExtensions languageExtensions)
|
||||||
{
|
{
|
||||||
ProjectPart::Ptr part(templateProjectPart->copy());
|
ProjectPart::Ptr part(templateProjectPart->copy());
|
||||||
part->displayName = partName;
|
part->displayName = partName;
|
||||||
part->files = projectFiles;
|
part->files = projectFiles;
|
||||||
part->languageVersion = languageVersion;
|
|
||||||
|
|
||||||
RawProjectPartFlags flags;
|
RawProjectPartFlags flags;
|
||||||
ToolChainInfo tcInfo;
|
ToolChainInfo tcInfo;
|
||||||
if (languageVersion <= ProjectPart::LatestCVersion) {
|
if (language == Language::C) {
|
||||||
flags = rawProjectPart.flagsForC;
|
flags = rawProjectPart.flagsForC;
|
||||||
tcInfo = m_projectUpdateInfo.cToolChainInfo;
|
tcInfo = m_projectUpdateInfo.cToolChainInfo;
|
||||||
}
|
}
|
||||||
@@ -271,7 +252,7 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(const RawProjectPart &r
|
|||||||
tcInfo = m_projectUpdateInfo.cxxToolChainInfo;
|
tcInfo = m_projectUpdateInfo.cxxToolChainInfo;
|
||||||
}
|
}
|
||||||
// TODO: If no toolchain is set, show a warning
|
// TODO: If no toolchain is set, show a warning
|
||||||
ToolChainEvaluator evaluator(*part.data(), flags, tcInfo);
|
ToolChainEvaluator evaluator(*part.data(), language, flags, tcInfo);
|
||||||
evaluator.evaluate();
|
evaluator.evaluate();
|
||||||
|
|
||||||
part->languageExtensions |= languageExtensions;
|
part->languageExtensions |= languageExtensions;
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
enum class Language { C, CXX };
|
||||||
|
|
||||||
class ProjectInfoGenerator
|
class ProjectInfoGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -46,7 +48,7 @@ private:
|
|||||||
const ProjectPart::Ptr &templateProjectPart,
|
const ProjectPart::Ptr &templateProjectPart,
|
||||||
const ProjectFiles &projectFiles,
|
const ProjectFiles &projectFiles,
|
||||||
const QString &partName,
|
const QString &partName,
|
||||||
ProjectPart::LanguageVersion languageVersion,
|
Language language,
|
||||||
ProjectPart::LanguageExtensions languageExtensions);
|
ProjectPart::LanguageExtensions languageExtensions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -48,7 +48,7 @@ ToolChainInfo::ToolChainInfo(const ProjectExplorer::ToolChain *toolChain,
|
|||||||
// they can be run from a worker thread.
|
// they can be run from a worker thread.
|
||||||
sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
|
sysRootPath = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString();
|
||||||
headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner();
|
headerPathsRunner = toolChain->createBuiltInHeaderPathsRunner();
|
||||||
predefinedMacrosRunner = toolChain->createPredefinedMacrosRunner();
|
macroInspectionRunner = toolChain->createMacroInspectionRunner();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
QString sysRootPath; // For headerPathsRunner.
|
QString sysRootPath; // For headerPathsRunner.
|
||||||
ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner;
|
ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner;
|
||||||
ProjectExplorer::ToolChain::PredefinedMacrosRunner predefinedMacrosRunner;
|
ProjectExplorer::ToolChain::MacroInspectionRunner macroInspectionRunner;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPPTOOLS_EXPORT ProjectUpdateInfo
|
class CPPTOOLS_EXPORT ProjectUpdateInfo
|
||||||
|
@@ -49,17 +49,20 @@ namespace CppTools {
|
|||||||
class CPPTOOLS_EXPORT ProjectPart
|
class CPPTOOLS_EXPORT ProjectPart
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Keep in sync with Toolchain::LanguageVersion!
|
||||||
enum LanguageVersion {
|
enum LanguageVersion {
|
||||||
C89,
|
C89,
|
||||||
C99,
|
C99,
|
||||||
C11,
|
C11,
|
||||||
LatestCVersion = C11,
|
C18,
|
||||||
|
LatestCVersion = C18,
|
||||||
CXX98,
|
CXX98,
|
||||||
CXX03,
|
CXX03,
|
||||||
CXX11,
|
CXX11,
|
||||||
CXX14,
|
CXX14,
|
||||||
CXX17,
|
CXX17,
|
||||||
LatestCxxVersion = CXX17,
|
CXX2a,
|
||||||
|
LatestCxxVersion = CXX2a,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LanguageExtension {
|
enum LanguageExtension {
|
||||||
@@ -81,8 +84,7 @@ public:
|
|||||||
enum QtVersion {
|
enum QtVersion {
|
||||||
UnknownQt = -1,
|
UnknownQt = -1,
|
||||||
NoQt,
|
NoQt,
|
||||||
Qt4_8_6AndOlder,
|
Qt4,
|
||||||
Qt4Latest,
|
|
||||||
Qt5
|
Qt5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -436,10 +436,8 @@ void GenericProject::refreshCppCodeModel()
|
|||||||
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
|
CppTools::ProjectPart::QtVersion activeQtVersion = CppTools::ProjectPart::NoQt;
|
||||||
if (QtSupport::BaseQtVersion *qtVersion =
|
if (QtSupport::BaseQtVersion *qtVersion =
|
||||||
QtSupport::QtKitInformation::qtVersion(activeTarget()->kit())) {
|
QtSupport::QtKitInformation::qtVersion(activeTarget()->kit())) {
|
||||||
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
|
if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt4_8_6AndOlder;
|
activeQtVersion = CppTools::ProjectPart::Qt4;
|
||||||
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt4Latest;
|
|
||||||
else
|
else
|
||||||
activeQtVersion = CppTools::ProjectPart::Qt5;
|
activeQtVersion = CppTools::ProjectPart::Qt5;
|
||||||
}
|
}
|
||||||
|
@@ -77,9 +77,9 @@ bool NimToolChain::isValid() const
|
|||||||
return fi.isExecutable();
|
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
|
Macros NimToolChain::predefinedMacros(const QStringList &) const
|
||||||
|
@@ -40,7 +40,7 @@ public:
|
|||||||
ProjectExplorer::Abi targetAbi() const override;
|
ProjectExplorer::Abi targetAbi() const override;
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
|
|
||||||
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
|
MacroInspectionRunner createMacroInspectionRunner() const override;
|
||||||
ProjectExplorer::Macros predefinedMacros(const QStringList &flags) const final;
|
ProjectExplorer::Macros predefinedMacros(const QStringList &flags) const final;
|
||||||
CompilerFlags compilerFlags(const QStringList &flags) const final;
|
CompilerFlags compilerFlags(const QStringList &flags) const final;
|
||||||
ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final;
|
ProjectExplorer::WarningFlags warningFlags(const QStringList &flags) const final;
|
||||||
|
@@ -99,23 +99,88 @@ QString AbstractMsvcToolChain::originalTargetTriple() const
|
|||||||
: QLatin1String("i686-pc-windows-msvc");
|
: 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 ¯os)
|
||||||
|
{
|
||||||
|
using LanguageVersion = ToolChain::LanguageVersion;
|
||||||
|
|
||||||
|
int mscVer = -1;
|
||||||
|
QByteArray msvcLang;
|
||||||
|
for (const ProjectExplorer::Macro ¯o : 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);
|
Utils::Environment env(m_lastEnvironment);
|
||||||
addToEnvironment(env);
|
addToEnvironment(env);
|
||||||
|
const Core::Id lang = language();
|
||||||
|
|
||||||
// This runner must be thread-safe!
|
// This runner must be thread-safe!
|
||||||
return [this, env](const QStringList &cxxflags) {
|
return [this, env, lang](const QStringList &cxxflags) {
|
||||||
QMutexLocker locker(m_predefinedMacrosMutex);
|
QMutexLocker locker(m_predefinedMacrosMutex);
|
||||||
if (m_predefinedMacros.isEmpty())
|
if (m_predefinedMacros.isEmpty() || m_cxxFlags != cxxflags) {
|
||||||
m_predefinedMacros = msvcPredefinedMacros(cxxflags, env);
|
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
|
ProjectExplorer::Macros AbstractMsvcToolChain::predefinedMacros(const QStringList &cxxflags) const
|
||||||
{
|
{
|
||||||
return createPredefinedMacrosRunner()(cxxflags);
|
return createMacroInspectionRunner()(cxxflags).macros;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList &cxxflags) const
|
ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList &cxxflags) const
|
||||||
@@ -128,35 +193,6 @@ ToolChain::CompilerFlags AbstractMsvcToolChain::compilerFlags(const QStringList
|
|||||||
if (cxxflags.contains(QLatin1String("/Za")))
|
if (cxxflags.contains(QLatin1String("/Za")))
|
||||||
flags &= ~MicrosoftExtensions;
|
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;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,7 +53,7 @@ public:
|
|||||||
|
|
||||||
QString originalTargetTriple() const override;
|
QString originalTargetTriple() const override;
|
||||||
|
|
||||||
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
|
MacroInspectionRunner createMacroInspectionRunner() const override;
|
||||||
Macros predefinedMacros(const QStringList &cxxflags) const override;
|
Macros predefinedMacros(const QStringList &cxxflags) const override;
|
||||||
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
|
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
|
||||||
WarningFlags warningFlags(const QStringList &cflags) const override;
|
WarningFlags warningFlags(const QStringList &cflags) const override;
|
||||||
@@ -99,8 +99,11 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
Utils::FileName m_debuggerCommand;
|
Utils::FileName m_debuggerCommand;
|
||||||
|
|
||||||
mutable QMutex *m_predefinedMacrosMutex = nullptr;
|
mutable QMutex *m_predefinedMacrosMutex = nullptr;
|
||||||
mutable Macros m_predefinedMacros;
|
mutable Macros m_predefinedMacros;
|
||||||
|
mutable QStringList m_cxxFlags;
|
||||||
|
|
||||||
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
|
mutable Utils::Environment m_lastEnvironment; // Last checked 'incoming' environment.
|
||||||
mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
|
mutable Utils::Environment m_resultEnvironment; // Resulting environment for VC
|
||||||
mutable QMutex *m_headerPathsMutex = nullptr;
|
mutable QMutex *m_headerPathsMutex = nullptr;
|
||||||
|
@@ -116,12 +116,13 @@ bool CustomToolChain::isValid() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner() const
|
ToolChain::MacroInspectionRunner CustomToolChain::createMacroInspectionRunner() const
|
||||||
{
|
{
|
||||||
const Macros theMacros = m_predefinedMacros;
|
const Macros theMacros = m_predefinedMacros;
|
||||||
|
const Core::Id lang = language();
|
||||||
|
|
||||||
// This runner must be thread-safe!
|
// This runner must be thread-safe!
|
||||||
return [theMacros](const QStringList &cxxflags){
|
return [theMacros, lang](const QStringList &cxxflags){
|
||||||
Macros macros = theMacros;
|
Macros macros = theMacros;
|
||||||
for (const QString &cxxFlag : cxxflags) {
|
for (const QString &cxxFlag : cxxflags) {
|
||||||
if (cxxFlag.startsWith(QLatin1String("-D")))
|
if (cxxFlag.startsWith(QLatin1String("-D")))
|
||||||
@@ -130,20 +131,17 @@ ToolChain::PredefinedMacrosRunner CustomToolChain::createPredefinedMacrosRunner(
|
|||||||
macros.append({cxxFlag.mid(2).trimmed().toUtf8(), MacroType::Undefine});
|
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
|
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;
|
return NoFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,7 +71,7 @@ public:
|
|||||||
|
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
|
|
||||||
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
|
MacroInspectionRunner createMacroInspectionRunner() const override;
|
||||||
Macros predefinedMacros(const QStringList &cxxflags) const override;
|
Macros predefinedMacros(const QStringList &cxxflags) const override;
|
||||||
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
|
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
|
||||||
WarningFlags warningFlags(const QStringList &cxxflags) const override;
|
WarningFlags warningFlags(const QStringList &cxxflags) const override;
|
||||||
|
@@ -254,7 +254,7 @@ GccToolChain::GccToolChain(Detection d) :
|
|||||||
|
|
||||||
GccToolChain::GccToolChain(Core::Id typeId, Detection d) :
|
GccToolChain::GccToolChain(Core::Id typeId, Detection d) :
|
||||||
ToolChain(typeId, 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>>())
|
m_headerPathsCache(std::make_shared<Cache<HeaderPaths>>())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@@ -385,9 +385,7 @@ static Utils::FileName findLocalCompiler(const Utils::FileName &compilerPath,
|
|||||||
return path.isEmpty() ? compilerPath : path;
|
return path.isEmpty() ? compilerPath : path;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(const QVector<QByteArray>, unwantedMacros, ({"__cplusplus"}))
|
ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() const
|
||||||
|
|
||||||
ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() const
|
|
||||||
{
|
{
|
||||||
// Using a clean environment breaks ccache/distcc/etc.
|
// Using a clean environment breaks ccache/distcc/etc.
|
||||||
Environment env = Environment::systemEnvironment();
|
Environment env = Environment::systemEnvironment();
|
||||||
@@ -396,7 +394,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
|
|||||||
const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
|
const QStringList platformCodeGenFlags = m_platformCodeGenFlags;
|
||||||
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
|
OptionsReinterpreter reinterpretOptions = m_optionsReinterpreter;
|
||||||
QTC_CHECK(reinterpretOptions);
|
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();
|
Core::Id lang = language();
|
||||||
|
|
||||||
// This runner must be thread-safe!
|
// This runner must be thread-safe!
|
||||||
@@ -436,20 +434,22 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
|
|||||||
}
|
}
|
||||||
|
|
||||||
arguments = reinterpretOptions(arguments);
|
arguments = reinterpretOptions(arguments);
|
||||||
const Utils::optional<QVector<Macro>> cachedMacros = macroCache->check(arguments);
|
const Utils::optional<MacroInspectionReport> cachedMacros = macroCache->check(arguments);
|
||||||
if (cachedMacros)
|
if (cachedMacros)
|
||||||
return cachedMacros.value();
|
return cachedMacros.value();
|
||||||
|
|
||||||
const QVector<Macro> macros
|
const Macros macros = gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
|
||||||
= gccPredefinedMacros(findLocalCompiler(compilerCommand, env),
|
arguments,
|
||||||
arguments,
|
env.toStringList());
|
||||||
env.toStringList());
|
|
||||||
const QVector<Macro> filteredMacros = Utils::filtered(macros, [](const Macro &m) {
|
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) {
|
for (const Macro &m : filteredMacros) {
|
||||||
qCDebug(gccLog) << compilerCommand.toUserOutput()
|
qCDebug(gccLog) << compilerCommand.toUserOutput()
|
||||||
<< (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
|
<< (lang == Constants::CXX_LANGUAGE_ID ? ": C++ [" : ": C [")
|
||||||
@@ -457,7 +457,7 @@ ToolChain::PredefinedMacrosRunner GccToolChain::createPredefinedMacrosRunner() c
|
|||||||
<< QString::fromUtf8(m.toByteArray());
|
<< 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
|
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) {
|
foreach (const QString &flag, allCxxflags) {
|
||||||
if (flag.startsWith("-std=")) {
|
if (flag.startsWith("-std=")) {
|
||||||
const QByteArray std = flag.mid(5).toLatin1();
|
const QByteArray std = flag.mid(5).toLatin1();
|
||||||
if (std == "c++98" || std == "c++03") {
|
if (std.startsWith("gnu"))
|
||||||
flags &= ~CompilerFlags(StandardCxx11 | StandardCxx14 | StandardCxx17 | GnuExtensions);
|
flags |= CompilerFlags(GnuExtensions);
|
||||||
flags |= StandardCxx98;
|
else
|
||||||
} else if (std == "gnu++98" || std == "gnu++03") {
|
flags &= ~CompilerFlags(GnuExtensions);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else if (flag == "-fopenmp") {
|
} else if (flag == "-fopenmp") {
|
||||||
flags |= OpenMP;
|
flags |= OpenMP;
|
||||||
} else if (flag == "-fms-extensions") {
|
} else if (flag == "-fms-extensions") {
|
||||||
flags |= MicrosoftExtensions;
|
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;
|
return result;
|
||||||
|
|
||||||
tc->setLanguage(language);
|
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->setCompilerCommand(compilerPath);
|
||||||
tc->setSupportedAbis(detectedAbis.supportedAbis);
|
tc->setSupportedAbis(detectedAbis.supportedAbis);
|
||||||
tc->setTargetAbi(abi);
|
tc->setTargetAbi(abi);
|
||||||
@@ -1134,7 +1096,11 @@ void GccToolChainConfigWidget::applyImpl()
|
|||||||
tc->setDisplayName(displayName); // reset display name
|
tc->setDisplayName(displayName); // reset display name
|
||||||
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));
|
tc->setPlatformCodeGenFlags(splitString(m_platformCodeGenFlagsLineEdit->text()));
|
||||||
tc->setPlatformLinkerFlags(splitString(m_platformLinkerFlagsLineEdit->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()
|
void GccToolChainConfigWidget::setFromToolchain()
|
||||||
@@ -1319,7 +1285,7 @@ void ClangToolChain::addToEnvironment(Environment &env) const
|
|||||||
|
|
||||||
ToolChain::CompilerFlags ClangToolChain::defaultCompilerFlags() const
|
ToolChain::CompilerFlags ClangToolChain::defaultCompilerFlags() const
|
||||||
{
|
{
|
||||||
return CompilerFlags(GnuExtensions | StandardCxx11);
|
return CompilerFlags(GnuExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOutputParser *ClangToolChain::outputParser() const
|
IOutputParser *ClangToolChain::outputParser() const
|
||||||
|
@@ -143,7 +143,7 @@ public:
|
|||||||
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
|
CompilerFlags compilerFlags(const QStringList &cxxflags) const override;
|
||||||
WarningFlags warningFlags(const QStringList &cflags) const override;
|
WarningFlags warningFlags(const QStringList &cflags) const override;
|
||||||
|
|
||||||
PredefinedMacrosRunner createPredefinedMacrosRunner() const override;
|
MacroInspectionRunner createMacroInspectionRunner() const override;
|
||||||
Macros predefinedMacros(const QStringList &cxxflags) const override;
|
Macros predefinedMacros(const QStringList &cxxflags) const override;
|
||||||
|
|
||||||
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
|
BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const override;
|
||||||
@@ -253,7 +253,7 @@ private:
|
|||||||
mutable HeaderPaths m_headerPaths;
|
mutable HeaderPaths m_headerPaths;
|
||||||
mutable QString m_version;
|
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 std::shared_ptr<Cache<HeaderPaths>> m_headerPathsCache;
|
||||||
mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {};
|
mutable ExtraHeaderPathsFunction m_extraHeaderPathsFunction = [](HeaderPaths &) {};
|
||||||
|
|
||||||
|
@@ -334,6 +334,7 @@ static QByteArray msvcCompilationFile()
|
|||||||
"__CLR_VER",
|
"__CLR_VER",
|
||||||
"_CMMN_INTRIN_FUNC",
|
"_CMMN_INTRIN_FUNC",
|
||||||
"_CONTROL_FLOW_GUARD",
|
"_CONTROL_FLOW_GUARD",
|
||||||
|
"__cplusplus",
|
||||||
"__cplusplus_cli",
|
"__cplusplus_cli",
|
||||||
"__cplusplus_winrt",
|
"__cplusplus_winrt",
|
||||||
"_CPPLIB_VER",
|
"_CPPLIB_VER",
|
||||||
|
@@ -286,6 +286,79 @@ bool ToolChain::fromMap(const QVariantMap &data)
|
|||||||
return true;
|
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 ¯os)
|
||||||
|
{
|
||||||
|
if (language == Constants::CXX_LANGUAGE_ID) {
|
||||||
|
for (const ProjectExplorer::Macro ¯o : 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 ¯o : 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 ¯o)
|
||||||
|
{
|
||||||
|
return unwantedMacros->contains(macro.key);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Used by the tool chain kit information to validate the kit.
|
Used by the tool chain kit information to validate the kit.
|
||||||
*/
|
*/
|
||||||
|
@@ -109,26 +109,44 @@ public:
|
|||||||
|
|
||||||
enum CompilerFlag {
|
enum CompilerFlag {
|
||||||
NoFlags = 0,
|
NoFlags = 0,
|
||||||
StandardCxx11 = 0x1,
|
|
||||||
StandardC99 = 0x2,
|
|
||||||
StandardC11 = 0x4,
|
|
||||||
GnuExtensions = 0x8,
|
GnuExtensions = 0x8,
|
||||||
MicrosoftExtensions = 0x10,
|
MicrosoftExtensions = 0x10,
|
||||||
BorlandExtensions = 0x20,
|
BorlandExtensions = 0x20,
|
||||||
OpenMP = 0x40,
|
OpenMP = 0x40,
|
||||||
ObjectiveC = 0x80,
|
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)
|
Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag)
|
||||||
|
|
||||||
virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0;
|
virtual CompilerFlags compilerFlags(const QStringList &cxxflags) const = 0;
|
||||||
virtual WarningFlags warningFlags(const QStringList &cflags) const = 0;
|
virtual WarningFlags warningFlags(const QStringList &cflags) const = 0;
|
||||||
|
|
||||||
// A PredefinedMacrosRunner is created in the ui thread and runs in another thread.
|
class MacroInspectionReport
|
||||||
using PredefinedMacrosRunner = std::function<Macros(const QStringList &cxxflags)>;
|
{
|
||||||
virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const = 0;
|
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;
|
virtual Macros predefinedMacros(const QStringList &cxxflags) const = 0;
|
||||||
|
|
||||||
// A BuiltInHeaderPathsRunner is created in the ui thread and runs in another thread.
|
// 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;
|
virtual QList<Task> validateKit(const Kit *k) const;
|
||||||
|
|
||||||
void setLanguage(Core::Id language);
|
void setLanguage(Core::Id language);
|
||||||
|
static LanguageVersion cxxLanguageVersion(const QByteArray &cplusplusMacroValue);
|
||||||
|
static LanguageVersion languageVersion(const Core::Id &language, const Macros ¯os);
|
||||||
|
static bool isUnwantedMacro(const Macro ¯o);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ToolChain(Core::Id typeId, Detection d);
|
explicit ToolChain(Core::Id typeId, Detection d);
|
||||||
|
@@ -308,7 +308,7 @@ public:
|
|||||||
QString typeDisplayName() const override { return QString("Test Tool Chain"); }
|
QString typeDisplayName() const override { return QString("Test Tool Chain"); }
|
||||||
Abi targetAbi() const override { return Abi::hostAbi(); }
|
Abi targetAbi() const override { return Abi::hostAbi(); }
|
||||||
bool isValid() const override { return m_valid; }
|
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(); }
|
Macros predefinedMacros(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return Macros(); }
|
||||||
CompilerFlags compilerFlags(const QStringList &cxxflags) const override { Q_UNUSED(cxxflags); return NoFlags; }
|
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; }
|
WarningFlags warningFlags(const QStringList &cflags) const override { Q_UNUSED(cflags); return WarningFlags::NoWarnings; }
|
||||||
|
@@ -915,10 +915,8 @@ void QbsProject::updateCppCodeModel()
|
|||||||
|
|
||||||
CppTools::ProjectPart::QtVersion qtVersionFromKit = CppTools::ProjectPart::NoQt;
|
CppTools::ProjectPart::QtVersion qtVersionFromKit = CppTools::ProjectPart::NoQt;
|
||||||
if (qtVersion) {
|
if (qtVersion) {
|
||||||
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
|
if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
||||||
qtVersionFromKit = CppTools::ProjectPart::Qt4_8_6AndOlder;
|
qtVersionFromKit = CppTools::ProjectPart::Qt4;
|
||||||
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
|
||||||
qtVersionFromKit = CppTools::ProjectPart::Qt4Latest;
|
|
||||||
else
|
else
|
||||||
qtVersionFromKit = CppTools::ProjectPart::Qt5;
|
qtVersionFromKit = CppTools::ProjectPart::Qt5;
|
||||||
}
|
}
|
||||||
|
@@ -277,10 +277,8 @@ void QmakeProject::updateCppCodeModel()
|
|||||||
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
|
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
|
||||||
ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt;
|
ProjectPart::QtVersion qtVersionForPart = ProjectPart::NoQt;
|
||||||
if (qtVersion) {
|
if (qtVersion) {
|
||||||
if (qtVersion->qtVersion() <= QtSupport::QtVersionNumber(4,8,6))
|
if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
||||||
qtVersionForPart = ProjectPart::Qt4_8_6AndOlder;
|
qtVersionForPart = ProjectPart::Qt4;
|
||||||
else if (qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0))
|
|
||||||
qtVersionForPart = ProjectPart::Qt4Latest;
|
|
||||||
else
|
else
|
||||||
qtVersionForPart = ProjectPart::Qt5;
|
qtVersionForPart = ProjectPart::Qt5;
|
||||||
}
|
}
|
||||||
|
@@ -41,17 +41,11 @@ public:
|
|||||||
|
|
||||||
enum CompilerFlag {
|
enum CompilerFlag {
|
||||||
NoFlags = 0,
|
NoFlags = 0,
|
||||||
StandardCxx11 = 0x1,
|
|
||||||
StandardC99 = 0x2,
|
|
||||||
StandardC11 = 0x4,
|
|
||||||
GnuExtensions = 0x8,
|
GnuExtensions = 0x8,
|
||||||
MicrosoftExtensions = 0x10,
|
MicrosoftExtensions = 0x10,
|
||||||
BorlandExtensions = 0x20,
|
BorlandExtensions = 0x20,
|
||||||
OpenMP = 0x40,
|
OpenMP = 0x40,
|
||||||
ObjectiveC = 0x80,
|
ObjectiveC = 0x80,
|
||||||
StandardCxx14 = 0x100,
|
|
||||||
StandardCxx17 = 0x200,
|
|
||||||
StandardCxx98 = 0x400,
|
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag)
|
Q_DECLARE_FLAGS(CompilerFlags, CompilerFlag)
|
||||||
|
|
||||||
@@ -60,8 +54,29 @@ public:
|
|||||||
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(const QStringList &cxxflags, const QString &sysRoot)>;
|
using BuiltInHeaderPathsRunner = std::function<HeaderPaths(const QStringList &cxxflags, const QString &sysRoot)>;
|
||||||
virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const { return BuiltInHeaderPathsRunner(); }
|
virtual BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner() const { return BuiltInHeaderPathsRunner(); }
|
||||||
|
|
||||||
using PredefinedMacrosRunner = std::function<Macros(const QStringList &cxxflags)>;
|
enum LanguageVersion {
|
||||||
virtual PredefinedMacrosRunner createPredefinedMacrosRunner() const { return PredefinedMacrosRunner(); }
|
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 QString originalTargetTriple() const { return QString(); }
|
||||||
virtual QStringList extraCodeModelFlags() const { return QStringList(); }
|
virtual QStringList extraCodeModelFlags() const { return QStringList(); }
|
||||||
|
@@ -39,6 +39,7 @@ using CppTools::ProjectUpdateInfo;
|
|||||||
using CppTools::ProjectPart;
|
using CppTools::ProjectPart;
|
||||||
using CppTools::RawProjectPart;
|
using CppTools::RawProjectPart;
|
||||||
|
|
||||||
|
using ProjectExplorer::Macros;
|
||||||
using ProjectExplorer::ToolChain;
|
using ProjectExplorer::ToolChain;
|
||||||
|
|
||||||
using testing::Eq;
|
using testing::Eq;
|
||||||
@@ -65,6 +66,7 @@ protected:
|
|||||||
ProjectInfo generate();
|
ProjectInfo generate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
ProjectUpdateInfo projectUpdateInfo;
|
||||||
RawProjectPart rawProjectPart;
|
RawProjectPart rawProjectPart;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,19 +117,21 @@ TEST_F(ProjectInfoGenerator, ProjectPartHasLatestLanguageVersionByDefault)
|
|||||||
ASSERT_THAT(projectPart.languageVersion, Eq(ProjectPart::LatestCxxVersion));
|
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.files = QStringList{ "foo.cpp" };
|
||||||
rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::StandardCxx98;
|
|
||||||
|
|
||||||
const ProjectInfo projectInfo = generate();
|
const ProjectInfo projectInfo = generate();
|
||||||
|
|
||||||
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
|
ASSERT_THAT(projectInfo.projectParts().size(), Eq(1));
|
||||||
const ProjectPart &projectPart = *projectInfo.projectParts().at(0);
|
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.files = QStringList{ "foo.cpp" };
|
||||||
rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::MicrosoftExtensions;
|
rawProjectPart.flagsForCxx.compilerFlags = ToolChain::CompilerFlag::MicrosoftExtensions;
|
||||||
@@ -160,7 +164,7 @@ void ProjectInfoGenerator::SetUp()
|
|||||||
ProjectInfo ProjectInfoGenerator::generate()
|
ProjectInfo ProjectInfoGenerator::generate()
|
||||||
{
|
{
|
||||||
QFutureInterface<void> fi;
|
QFutureInterface<void> fi;
|
||||||
ProjectUpdateInfo projectUpdateInfo;
|
|
||||||
projectUpdateInfo.rawProjectParts += rawProjectPart;
|
projectUpdateInfo.rawProjectParts += rawProjectPart;
|
||||||
::ProjectInfoGenerator generator(fi, projectUpdateInfo);
|
::ProjectInfoGenerator generator(fi, projectUpdateInfo);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user