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:
		@@ -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 ¯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
 | 
			
		||||
    // __has_include(STR) and __has_include_next(STR)
 | 
			
		||||
    if (macro.key.startsWith("__has_include"))
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user