Address additional review comments.

http://reviews.llvm.org/D4233

Files:
  lib/Basic/Targets.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/Driver/msc-version.c
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -587,8 +587,12 @@
     if (Opts.POSIXThreads)
       Builder.defineMacro("_MT");
 
-    if (Opts.MSCVersion != 0)
-      Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
+    if (Opts.MSCVersion != 0) {
+      Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion / 100000));
+      Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCVersion));
+      // FIXME We cannot encode the revision information into 32-bits
+      Builder.defineMacro("_MSC_BUILD", Twine(1));
+    }
 
     if (Opts.MicrosoftExt) {
       Builder.defineMacro("_MSC_EXTENSIONS");
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -20,6 +20,7 @@
 #include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
@@ -1191,6 +1192,55 @@
   return DefaultVisibility;
 }
 
+static void parseMSCVersion(LangOptions &Opts, ArgList &Args,
+                            DiagnosticsEngine &Diags) {
+  decltype(Opts.MSCVersion) Version = 0;
+
+  if (auto Arg = Args.getLastArg(OPT_fmsc_version)) {
+    StringRef Value = Arg->getValue();
+
+    // The MSC versioning scheme involves four versioning components:
+    //  - Major
+    //  - Minor
+    //  - Build
+    //  - Patch
+    // We accept either the old style (_MSC_VER) value, or a _MSC_FULL_VER
+    // value.  Additionally, the value may be provided in the form of a more
+    // readable MM.mm.bbbbb.pp version.
+    //
+    // Unfortunately, due to the bit-width limitations, we cannot currently
+    // encode the value for the patch level.
+
+    if (Value.find('.') == StringRef::npos) {
+      if (Value.getAsInteger(10, Version))
+        Diags.Report(diag::err_drv_invalid_value)
+          << Arg->getAsString(Args) << Value;
+    } else {
+      bool Valid = true;
+      SmallVector<StringRef, 4> Components;
+      decltype(Opts.MSCVersion) VC[4] = {0};  // MM.mm.bbbbb.pp
+
+      Value.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)
+            << Arg->getAsString(Args) << Value;
+          Valid = false;
+          break;
+        }
+      }
+
+      // FIXME we cannot encode the patch level
+      if (Valid)
+        Version = VC[0] * 10000000 + VC[1] * 100000 + VC[2];
+    }
+  }
+
+  Opts.MSCVersion = (Version < 100000) ? Version * 100000 : Version;
+}
+
 static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
                           DiagnosticsEngine &Diags) {
   // FIXME: Cleanup per-file based stuff.
@@ -1360,7 +1410,7 @@
   Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility);
   Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions);
   Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt;
-  Opts.MSCVersion = getLastArgIntValue(Args, OPT_fmsc_version, 0, Diags);
+  parseMSCVersion(Opts, Args, Diags);
   Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags);
   Opts.Borland = Args.hasArg(OPT_fborland_extensions);
   Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
Index: test/Driver/msc-version.c
===================================================================
--- /dev/null
+++ test/Driver/msc-version.c
@@ -0,0 +1,36 @@
+// RUN: %clang -target i686-windows -fms-compatibility -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-NO-MSC-VERSION
+
+// CHECK-NO-MSC-VERSION: _MSC_BUILD 1
+// CHECK-NO-MSC-VERSION: _MSC_FULL_VER 170000000
+// CHECK-NO-MSC-VERSION: _MSC_VER 1700
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=1600 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION
+
+// CHECK-MSC-VERSION: _MSC_BUILD 1
+// CHECK-MSC-VERSION: _MSC_FULL_VER 160000000
+// CHECK-MSC-VERSION: _MSC_VER 1600
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=160030319 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-EXT
+
+// CHECK-MSC-VERSION-EXT: _MSC_BUILD 1
+// CHECK-MSC-VERSION-EXT: _MSC_FULL_VER 160030319
+// CHECK-MSC-VERSION-EXT: _MSC_VER 1600
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=17.00 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR
+
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_FULL_VER 170000000
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_VER 1700
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=15.00.20706 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR-BUILD
+
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_FULL_VER 150020706
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_VER 1500
+
+// RUN: %clang -target i686-windows -fms-compatibility -fmsc-version=15.00.20706.01 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH
+
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_FULL_VER 150020706
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_VER 1500
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to