Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -569,6 +569,39 @@ MacroBuilder &Builder) const override { Builder.defineMacro("_WIN32"); } + void getMSCVersionDefines(uint32_t MSCVersion, MacroBuilder &Builder) const { + if (MSCVersion == 0) + return; + + // The MSC versioning scheme involves four versioning components: + // - Major + // - Minor + // - Build + // - Patch + // Ideally, the -fmsc-version would take a period delimited component of the + // form MM.mm.bbbbb.pp (e.g. 17.00.60610.1). Unfortunately, the current + // limitation of 32-bits prevents the encoding of Patch. Assume that patch + // is 0, and permit encodings of MMmmbbbbb or MMmm. + + unsigned Major, Minor, Build, Patch; + + if (MSCVersion <= 9999) { + Major = MSCVersion / 100; + Minor = MSCVersion % 100; + Build = 0; + Patch = 1; + } else { + Major = (MSCVersion / 100000) / 100; + Minor = (MSCVersion / 100000) % 100; + Build = (MSCVersion % 100000); + Patch = 1; + } + + Builder.defineMacro("_MSC_VER", Twine(Major * 100 + Minor)); + Builder.defineMacro("_MSC_FULL_VER", + Twine(Major * 10000000 + Minor * 100000 + Build)); + Builder.defineMacro("_MSC_BUILD", Twine(Patch)); + } void getVisualStudioDefines(const LangOptions &Opts, MacroBuilder &Builder) const { if (Opts.CPlusPlus) { @@ -587,8 +620,7 @@ if (Opts.POSIXThreads) Builder.defineMacro("_MT"); - if (Opts.MSCVersion != 0) - Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion)); + getMSCVersionDefines(Opts.MSCVersion, Builder); if (Opts.MicrosoftExt) { Builder.defineMacro("_MSC_EXTENSIONS"); Index: test/Driver/msc-version.c =================================================================== --- /dev/null +++ test/Driver/msc-version.c @@ -0,0 +1,18 @@ +// RUN: %clang -target i686-windows -fms-compatibility -dM -E -