From 439d81de1b8092615a74e86fb3775461de618a1c Mon Sep 17 00:00:00 2001 From: Cyano Hao Date: Fri, 13 Dec 2024 12:07:12 +0800 Subject: [PATCH] Add initial support for GCC 15 `import std;` --- RedPandaIDE/compiler/compiler.cpp | 15 +++++++++++++++ RedPandaIDE/compiler/compiler.h | 1 + RedPandaIDE/compiler/compilerinfo.cpp | 7 +++++++ RedPandaIDE/compiler/compilerinfo.h | 1 + RedPandaIDE/compiler/filecompiler.cpp | 11 ++++++++++- RedPandaIDE/settings.cpp | 7 +++++++ 6 files changed, 41 insertions(+), 1 deletion(-) diff --git a/RedPandaIDE/compiler/compiler.cpp b/RedPandaIDE/compiler/compiler.cpp index d02871daa..488f34ed7 100644 --- a/RedPandaIDE/compiler/compiler.cpp +++ b/RedPandaIDE/compiler/compiler.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . */ #include "compiler.h" +#include "compiler/compilerinfo.h" #include "utils.h" #include "utils/escape.h" #include "utils/parsearg.h" @@ -412,6 +413,20 @@ QStringList Compiler::getCharsetArgument(const QByteArray& encoding,FileType fil return result; } +QStringList Compiler::getCppGccImportStdSources(bool checkSyntax) +{ + QStringList result; + if (!checkSyntax && compilerSet()->getCompileOptionValue(CC_CMD_OPT_ENABLE_GCC_IMPORT_STD) == COMPILER_OPTION_ON) { + // libstdc++ extends `import std` to C++20 + // FIXME: use robust method to check C++ standard version + const QString &std = compilerSet()->getCompileOptionValue(CC_CMD_OPT_STD); + if (std.startsWith("c++2") || std.startsWith("gnu++2")) { + result += {"-fsearch-include-path", "bits/std.cc", "bits/std.compat.cc"}; + } + } + return result; +} + QStringList Compiler::getCCompileArguments(bool checkSyntax) { QStringList result; diff --git a/RedPandaIDE/compiler/compiler.h b/RedPandaIDE/compiler/compiler.h index 54b280fef..f40180dc4 100644 --- a/RedPandaIDE/compiler/compiler.h +++ b/RedPandaIDE/compiler/compiler.h @@ -71,6 +71,7 @@ public slots: virtual bool prepareForRebuild() = 0; virtual bool beforeRunExtraCommand(int idx); virtual QStringList getCharsetArgument(const QByteArray& encoding, FileType fileType, bool onlyCheckSyntax); + virtual QStringList getCppGccImportStdSources(bool checkSyntax); virtual QStringList getCCompileArguments(bool checkSyntax); virtual QStringList getCppCompileArguments(bool checkSyntax); virtual QStringList getCIncludeArguments(); diff --git a/RedPandaIDE/compiler/compilerinfo.cpp b/RedPandaIDE/compiler/compilerinfo.cpp index b9ae7caff..17f3d3346 100644 --- a/RedPandaIDE/compiler/compilerinfo.cpp +++ b/RedPandaIDE/compiler/compilerinfo.cpp @@ -108,12 +108,14 @@ void CompilerInfo::prepareCompilerOptions() sl.append(QPair("ISO C++17","c++17")); sl.append(QPair("ISO C++20","c++2a")); sl.append(QPair("ISO C++23","c++2b")); + sl.append(QPair("ISO C++26","c++2c")); sl.append(QPair("GNU C++","gnu++98")); sl.append(QPair("GNU C++11","gnu++11")); sl.append(QPair("GNU C++14","gnu++14")); sl.append(QPair("GNU C++17","gnu++17")); sl.append(QPair("GNU C++20","gnu++2a")); sl.append(QPair("GNU C++23","gnu++2b")); + sl.append(QPair("GNU C++26","gnu++2c")); addOption(CC_CMD_OPT_STD, QObject::tr("C++ Language standard (-std)"), groupName, false, true, false, "-std=",CompilerOptionType::Choice, sl); sl.clear(); @@ -121,10 +123,14 @@ void CompilerInfo::prepareCompilerOptions() sl.append(QPair("ISO C99","c99")); sl.append(QPair("ISO C11","c11")); sl.append(QPair("ISO C17","c17")); + sl.append(QPair("ISO C23","c2x")); + sl.append(QPair("ISO C2Y","c2y")); sl.append(QPair("GNU C90","gnu90")); sl.append(QPair("GNU C99","gnu99")); sl.append(QPair("GNU C11","gnu11")); sl.append(QPair("GNU C17","gnu17")); + sl.append(QPair("GNU C23","gnu2x")); + sl.append(QPair("GNU C2Y","gnu2y")); addOption(C_CMD_OPT_STD, QObject::tr("C Language standard (-std)"), groupName, true, false, false, "-std=", CompilerOptionType::Choice, sl); // Optimization for cpu type @@ -187,6 +193,7 @@ void CompilerInfo::prepareCompilerOptions() addOption(CC_CMD_OPT_DEBUG_INFO, QObject::tr("Generate debugging information (-g3)"), groupName, true, true, false, "-g3"); addOption(CC_CMD_OPT_PROFILE_INFO, QObject::tr("Generate profiling info for analysis (-pg)"), groupName, true, true, true, "-pg"); addOption(CC_CMD_OPT_SYNTAX_ONLY, QObject::tr("Only check the code for syntax errors (-fsyntax-only)"), groupName, true, true, false, "-fsyntax-only"); + addOption(CC_CMD_OPT_ENABLE_GCC_IMPORT_STD, QObject::tr("Enable experimental support for GCC standard library modules (-fmodules)"), groupName, false, true, false, "-fmodules"); // Warnings groupName = QObject::tr("Warnings"); diff --git a/RedPandaIDE/compiler/compilerinfo.h b/RedPandaIDE/compiler/compilerinfo.h index 56a7a2894..153913227 100644 --- a/RedPandaIDE/compiler/compilerinfo.h +++ b/RedPandaIDE/compiler/compilerinfo.h @@ -31,6 +31,7 @@ #define CC_CMD_OPT_SYNTAX_ONLY "cc_cmd_opt_syntax_only" #define CC_CMD_OPT_WARNING_AS_ERROR "cc_cmd_opt_warning_as_error" #define CC_CMD_OPT_ABORT_ON_ERROR "cc_cmd_opt_abort_on_error" +#define CC_CMD_OPT_ENABLE_GCC_IMPORT_STD "cc_opt_enable_gcc_import_std" #define CC_CMD_OPT_PROFILE_INFO "cc_cmd_opt_profile_info" diff --git a/RedPandaIDE/compiler/filecompiler.cpp b/RedPandaIDE/compiler/filecompiler.cpp index c082ad580..455fc665a 100644 --- a/RedPandaIDE/compiler/filecompiler.cpp +++ b/RedPandaIDE/compiler/filecompiler.cpp @@ -65,8 +65,17 @@ bool FileCompiler::prepareForCompile() log(tr("- Filename: %1").arg(mFilename)); log(tr("- Compiler Set Name: %1").arg(compilerSet()->name())); log(""); + FileType fileType = getFileType(mFilename); - mArguments = QStringList{localizePath(mFilename)}; + CompilerType compilerType = compilerSet()->compilerType(); + + // GCC `import std;` sources should be added before the main file to generate GCM cache + if (fileType == FileType::CppSource && + (compilerType == CompilerType::GCC || compilerType == CompilerType::GCC_UTF8)) { + mArguments += getCppGccImportStdSources(mOnlyCheckSyntax); + } + + mArguments += QStringList{localizePath(mFilename)}; if (!mOnlyCheckSyntax) { switch(compilerSet()->compilationStage()) { case Settings::CompilerSet::CompilationStage::PreprocessingOnly: diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index fb198c99d..c262f39e6 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -17,6 +17,7 @@ #include "settings.h" #include #include +#include "compiler/compilerinfo.h" #include "utils.h" #include "utils/escape.h" #include "utils/font.h" @@ -1854,6 +1855,7 @@ Settings::CompilerSet::CompilerSet(const QJsonObject &set) : {CC_CMD_OPT_DEBUG_INFO, "ccCmdOptDebugInfo"}, {CC_CMD_OPT_PROFILE_INFO, "ccCmdOptProfileInfo"}, {CC_CMD_OPT_SYNTAX_ONLY, "ccCmdOptSyntaxOnly"}, + {CC_CMD_OPT_ENABLE_GCC_IMPORT_STD, "ccCmdOptEnableGccImportStd"}, {CC_CMD_OPT_INHIBIT_ALL_WARNING, "ccCmdOptInhibitAllWarning"}, {CC_CMD_OPT_WARNING_ALL, "ccCmdOptWarningAll"}, @@ -2481,6 +2483,10 @@ QStringList Settings::CompilerSet::defines(bool isCpp) { if (!mCompileOptions[key].isEmpty()) arguments.append(pOption->setting + mCompileOptions[key]); } + pOption = CompilerInfoManager::getCompilerOption(compilerType(), CC_CMD_OPT_ENABLE_GCC_IMPORT_STD); + if (pOption && mCompileOptions.contains(CC_CMD_OPT_ENABLE_GCC_IMPORT_STD)) { + arguments.append(pOption->setting); + } pOption = CompilerInfoManager::getCompilerOption(compilerType(), CC_CMD_OPT_DEBUG_INFO); if (pOption && mCompileOptions.contains(CC_CMD_OPT_DEBUG_INFO)) { arguments.append(pOption->setting); @@ -3679,6 +3685,7 @@ void Settings::CompilerSets::prepareCompatibleIndex() mCompilerCompatibleIndex.append(CC_CMD_OPT_SYNTAX_ONLY); mCompilerCompatibleIndex.append(CC_CMD_OPT_WARNING_AS_ERROR); mCompilerCompatibleIndex.append(CC_CMD_OPT_ABORT_ON_ERROR); + mCompilerCompatibleIndex.append(CC_CMD_OPT_ENABLE_GCC_IMPORT_STD); mCompilerCompatibleIndex.append(CC_CMD_OPT_PROFILE_INFO);