Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1379,6 +1379,9 @@ Flags<[HelpHidden]>; def mglibc : Flag<["-"], "mglibc">, Group, Flags<[HelpHidden]>; def muclibc : Flag<["-"], "muclibc">, Group, Flags<[HelpHidden]>; +def mmin_libc_version_EQ : Joined<["-"], "mmin-libc-version=">, + Group, + Flags<[ DriverOption, CC1Option ]>; def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group; def mthumb : Flag<["-"], "mthumb">, Group; def mtune_EQ : Joined<["-"], "mtune=">, Group; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -162,6 +162,9 @@ /// The default TLS model to use. ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel) +/// minimum libc version +VALUE_CODEGENOPT(MinCLibVer, 32, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -372,6 +372,10 @@ getModule().addModuleFlag(llvm::Module::Warning, "Debug Info Version", llvm::DEBUG_METADATA_VERSION); + if (CodeGenOpts.MinCLibVer) + getModule().addModuleFlag(llvm::Module::Warning, "minimum libc version", + CodeGenOpts.MinCLibVer); + // We need to record the widths of enums and wchar_t, so that we can generate // the correct build attributes in the ARM backend. llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch(); Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -4121,6 +4121,12 @@ CmdArgs.push_back(Args.MakeArgString("-fms-compatibility-version=" + Ver)); } + // -mmin-libc-version + if (const Arg *A = Args.getLastArg(options::OPT_mmin_libc_version_EQ)) { + std::string Version = A->getValue(); + CmdArgs.push_back(Args.MakeArgString("-mmin-libc-version=" + Version)); + } + // -fno-borland-extensions is default. if (Args.hasFlag(options::OPT_fborland_extensions, options::OPT_fno_borland_extensions, false)) Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -565,6 +565,27 @@ } } + if (Arg *A = Args.getLastArg(OPT_mmin_libc_version_EQ)) { + StringRef Version = A->getValue(); + + unsigned VC[3] = {0}; + SmallVector Components; + + Version.split(Components, ".", llvm::array_lengthof(VC)); + for (unsigned CI = 0, + CE = std::min(Components.size(), llvm::array_lengthof(VC)); + CI < CE; ++CI) { + if (Components[CI].getAsInteger(10, VC[CI])) { + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) + << Version; + memset(VC, 0, sizeof(VC)); + break; + } + } + + Opts.MinCLibVer = VC[0] * 10000 + VC[1] * 100 + VC[2]; + } + if (Arg *A = Args.getLastArg(OPT_ffp_contract)) { StringRef Val = A->getValue(); if (Val == "fast") Index: test/CodeGen/libc-version.c =================================================================== --- /dev/null +++ test/CodeGen/libc-version.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple thumbv7-windows-itanium -mmin-libc-version=12.0 -emit-llvm -o - %s \ +// RUN: | FileCheck %s -check-prefix CHECK-WINDOWS +// RUN: %clang_cc1 -triple thumbv7-windows-itanium -emit-llvm -o - %s \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -triple i686-linux-gnu -mmin-libc-version=2.21.0 -emit-llvm -o - %s \ +// RUN: | FileCheck %s -check-prefix CHECK-LINUX +// RUN: %clang_cc1 -triple i686-linux-gnu -emit-llvm -o - %s \ +// RUN: | FileCheck %s + +// CHECK-LINUX: !"minimum libc version", i32 22100} +// CHECK-WINDOWS: !"minimum libc version", i32 120000} +// CHECK-NOT: !"minimum libc version" +