Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,9 @@ def warn_hlsl_langstd_minimal :
"recommend using %1 instead">,
InGroup<HLSLDXCCompat>;

def err_unknown_crtdll : Error<"unknown Windows/MinGW C runtime library '%0'">,
DefaultFatal;

// ClangIR frontend errors
def err_cir_to_cir_transform_failed : Error<
"CIR-to-CIR transformation failed">, DefaultFatal;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,9 @@ LANGOPT(BoundsSafety, 1, 0, NotCompatible, "Bounds safety extension for C")

LANGOPT(PreserveVec3Type, 1, 0, NotCompatible, "Preserve 3-component vector type")

ENUM_LANGOPT(MinGWCRTDll, WindowsCRTDLLVersion, 4, WindowsCRTDLLVersion::CRTDLL_Default, NotCompatible,
"MinGW specific. Controls the __MSVCRT_VERSION and related preprocessor defines.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo, __MSVCRT_VERSION__ with two trailing underscores.


#undef LANGOPT
#undef ENUM_LANGOPT
#undef VALUE_LANGOPT
17 changes: 17 additions & 0 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,23 @@ class LangOptionsBase {
MSVC2022_9 = 1939,
};

enum WindowsCRTDLLVersion {
CRTDLL_Default,
CRTDLL,
MSVCRT10,
MSVCRT20,
MSVCRT40,
MSVCRTD,
MSVCR70,
MSVCR71,
MSVCR80,
MSVCR90,
MSVCR100,
MSVCR110,
MSVCR120,
UCRT
};

enum SYCLMajorVersion {
SYCL_None,
SYCL_2017,
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,12 @@ defm auto_import : BoolFOption<"auto-import",
PosFlag<SetTrue, [], [], "MinGW specific. Enable code generation support for "
"automatic dllimport, and enable support for it in the linker. "
"Enabled by default.">>;
def mcrtdll_EQ : Joined<["-"], "mcrtdll=">,
Group<m_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"MinGW specific. Changes preprocessor flags and "
"linker options to use the"
"specified C runtime library.">;
} // let Flags = [TargetSpecific]

// In the future this option will be supported by other offloading
Expand Down
48 changes: 47 additions & 1 deletion clang/lib/Basic/Targets/OSTargets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,54 @@ static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts,
DefineStd(Builder, "WIN64", Opts);
Builder.defineMacro("__MINGW64__");
}
Builder.defineMacro("__MSVCRT__");
Builder.defineMacro("__MINGW32__");
if (Opts.getMinGWCRTDll() == LangOptions::WindowsCRTDLLVersion::CRTDLL) {
Builder.defineMacro("__CRTDLL__");
} else {
Builder.defineMacro("__MSVCRT__");
switch (Opts.getMinGWCRTDll()) {
case LangOptions::WindowsCRTDLLVersion::CRTDLL_Default:
break;
case LangOptions::WindowsCRTDLLVersion::MSVCRT10:
Builder.defineMacro("__MSVCRT_VERSION__", "0x100");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCRT20:
Builder.defineMacro("__MSVCRT_VERSION__", "0x200");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCRT40:
Builder.defineMacro("__MSVCRT_VERSION__", "0x400");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCRTD:
Builder.defineMacro("__MSVCRT_VERSION__", "0x600");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCR70:
Builder.defineMacro("__MSVCRT_VERSION__", "0x700");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCR71:
Builder.defineMacro("__MSVCRT_VERSION__", "0x701");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCR80:
Builder.defineMacro("__MSVCRT_VERSION__", "0x800");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCR90:
Builder.defineMacro("__MSVCRT_VERSION__", "0x900");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCR100:
Builder.defineMacro("__MSVCRT_VERSION__", "0xA00");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCR110:
Builder.defineMacro("__MSVCRT_VERSION__", "0xB00");
break;
case LangOptions::WindowsCRTDLLVersion::MSVCR120:
Builder.defineMacro("__MSVCRT_VERSION__", "0xC00");
break;
case LangOptions::WindowsCRTDLLVersion::UCRT:
Builder.defineMacro("_UCRT");
break;
default:
llvm_unreachable("Unknown MinGW CRT version");
}
}
addCygMingDefines(Opts, Builder);
}

Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5970,6 +5970,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Triple.isWindowsGNUEnvironment()) {
Args.addOptOutFlag(CmdArgs, options::OPT_fauto_import,
options::OPT_fno_auto_import);
Args.addLastArg(CmdArgs, options::OPT_mcrtdll_EQ);
}

if (Args.hasFlag(options::OPT_fms_volatile, options::OPT_fno_ms_volatile,
Expand Down
29 changes: 17 additions & 12 deletions clang/lib/Driver/ToolChains/MinGW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,24 @@ void tools::MinGW::Linker::AddLibGCC(const ArgList &Args,

CmdArgs.push_back("-lmoldname");
CmdArgs.push_back("-lmingwex");
for (auto Lib : Args.getAllArgValues(options::OPT_l)) {
if (StringRef(Lib).starts_with("msvcr") ||
StringRef(Lib).starts_with("ucrt") ||
StringRef(Lib).starts_with("crtdll")) {
Lib = (llvm::Twine("-l") + Lib).str();
// Respect the user's chosen crt variant, but still provide it
// again as the last linker argument, because some of the libraries
// we added above may depend on it.
CmdArgs.push_back(Args.MakeArgStringRef(Lib));
return;
}

if (Arg *A = Args.getLastArg(options::OPT_mcrtdll_EQ)) {
std::string mcrtdll = (Twine("-l") + A->getValue()).str();
CmdArgs.push_back(Args.MakeArgStringRef(mcrtdll));
} else {
for (auto Lib : Args.getAllArgValues(options::OPT_l))
if (StringRef(Lib).starts_with("msvcr") ||
StringRef(Lib).starts_with("ucrt") ||
StringRef(Lib).starts_with("crtdll")) {
Lib = (llvm::Twine("-l") + Lib).str();
// Respect the user's chosen crt variant, but still provide it
// again as the last linker argument, because some of the libraries
// we added above may depend on it.
CmdArgs.push_back(Args.MakeArgStringRef(Lib));
return;
}
CmdArgs.push_back("-lmsvcrt");
}
CmdArgs.push_back("-lmsvcrt");
}

void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Expand Down
38 changes: 38 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4705,6 +4705,44 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
}
}

// Process MinGW -mcrtdll option
if (Arg *A = Args.getLastArg(OPT_mcrtdll_EQ)) {
Opts.MinGWCRTDll =
llvm::StringSwitch<enum LangOptions::WindowsCRTDLLVersion>(
A->getValue())
.StartsWithLower("crtdll",
LangOptions::WindowsCRTDLLVersion::CRTDLL)
.StartsWithLower("msvcrt10",
LangOptions::WindowsCRTDLLVersion::MSVCRT10)
.StartsWithLower("msvcrt20",
LangOptions::WindowsCRTDLLVersion::MSVCRT20)
.StartsWithLower("msvcrt40",
LangOptions::WindowsCRTDLLVersion::MSVCRT40)
.StartsWithLower("msvcr40",
LangOptions::WindowsCRTDLLVersion::MSVCRT40)
.StartsWithLower("msvcrtd",
LangOptions::WindowsCRTDLLVersion::MSVCRTD)
.StartsWithLower("msvcr70",
LangOptions::WindowsCRTDLLVersion::MSVCR70)
.StartsWithLower("msvcr71",
LangOptions::WindowsCRTDLLVersion::MSVCR71)
.StartsWithLower("msvcr80",
LangOptions::WindowsCRTDLLVersion::MSVCR80)
.StartsWithLower("msvcr90",
LangOptions::WindowsCRTDLLVersion::MSVCR90)
.StartsWithLower("msvcr100",
LangOptions::WindowsCRTDLLVersion::MSVCR100)
.StartsWithLower("msvcr110",
LangOptions::WindowsCRTDLLVersion::MSVCR110)
.StartsWithLower("msvcr120",
LangOptions::WindowsCRTDLLVersion::MSVCR120)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're missing a case (and enum) for msvcrt-os, if this is to mimic the GCC implementation.

.StartsWithLower("ucrt", LangOptions::WindowsCRTDLLVersion::UCRT)
.Default(LangOptions::WindowsCRTDLLVersion::CRTDLL_Default);
if (Opts.MinGWCRTDll == LangOptions::WindowsCRTDLLVersion::CRTDLL_Default) {
Diags.Report(diag::err_unknown_crtdll) << A->getValue();
}
}

return Diags.getNumErrors() == NumErrorsBefore;
}

Expand Down
30 changes: 30 additions & 0 deletions clang/test/Driver/mingw-mcrtdll.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RUN: %clang -v --target=x86_64-w64-mingw32 -### %s 2>&1 | FileCheck -check-prefix=DEFAULT %s
// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=msvcr90 -### %s 2>&1 | FileCheck -check-prefix=MSVCR90 %s
// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=msvcr90_suffix -### %s 2>&1 | FileCheck -check-prefix=MSVCR90_SUFFIX %s
// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=ucrt -### %s 2>&1 | FileCheck -check-prefix=UCRT %s
// RUN: %clang -v --target=x86_64-w64-mingw32 -mcrtdll=ucrtbase -### %s 2>&1 | FileCheck -check-prefix=UCRTBASE %s

// RUN: %clang -dM -E --target=x86_64-w64-mingw32 %s 2>&1 | FileCheck -check-prefix=DEFINE_DEFAULT %s
// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=msvcr90 %s 2>&1 | FileCheck -check-prefix=DEFINE_MSVCR90 %s
// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=msvcr90_suffix %s 2>&1 | FileCheck -check-prefix=DEFINE_MSVCR90 %s
// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=ucrt %s 2>&1 | FileCheck -check-prefix=DEFINE_UCRT %s
// RUN: %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=ucrtbase %s 2>&1 | FileCheck -check-prefix=DEFINE_UCRT %s
// RUN: not %clang -dM -E --target=x86_64-w64-mingw32 -mcrtdll=bad %s 2>&1 | FileCheck -check-prefix=BAD %s

// DEFAULT: "-lmingwex" "-lmsvcrt"
// DEFINE_DEFAULT: #define __MSVCRT__
// MSVCR90: "-lmingwex" "-lmsvcr90"
// DEFINE_MSVCR90: #define __MSVCRT_VERSION__ 0x900
// DEFINE_MSVCR90: #define __MSVCRT__
// MSVCR90-NOT: "-lmsvcrt"
// MSVCR90_SUFFIX: "-lmingwex" "-lmsvcr90_suffix"
// MSVCR90_SUFFIX-NOT: "-lmsvcrt"
// UCRT: "-lmingwex" "-lucrt"
// DEFINE_UCRT: #define _UCRT
// DEFINE_UCRT-NOT: #define __MSVCRT_VERSION__
// UCRT-NOT: "-lmsvcrt"
// UCRTBASE: "-lmingwex" "-lucrtbase"
// UCRTBASE-NOT: "-lmsvcrt"
// DEFINE_CRTDLL: #define __CRTDLL__
// DEFINE_CRTDLL-NOT: #define __MSVCRT__
// BAD: error: unknown Windows/MinGW C runtime library 'bad'
Loading