Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -569,6 +569,32 @@ MacroBuilder &Builder) const override { Builder.defineMacro("_WIN32"); } + void getMSCVersionDefines(uint32_t MSCVersion, MacroBuilder &Builder) const { + assert(MSCVersion != 0 && "MSCVersion must be provided"); + + // 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; + unsigned ScalingFactor = MSCVersion > 100000 ? 100000 : 1; + + Major = (MSCVersion / ScalingFactor) / 100; + Minor = (MSCVersion / ScalingFactor) % 100; + Build = ScalingFactor == 1 ? 0 : MSCVersion % ScalingFactor; + Patch = 1; // FIXME We cannot encode the revision information into 32-bits + + 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) { @@ -588,7 +614,7 @@ 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 -