diff options
| -rw-r--r-- | clang/lib/Basic/Targets.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 53 | ||||
| -rw-r--r-- | clang/lib/Frontend/TextDiagnostic.cpp | 2 | ||||
| -rw-r--r-- | clang/test/Driver/msc-version.c | 36 |
4 files changed, 95 insertions, 4 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index ae3e486d278..4fdbc244771 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -587,8 +587,12 @@ protected: 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"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 4647179d6f4..9174e4fb704 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/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" @@ -1194,6 +1195,56 @@ static Visibility parseVisibility(Arg *arg, ArgList &args, return DefaultVisibility; } +static unsigned parseMSCVersion(ArgList &Args, DiagnosticsEngine &Diags) { + auto Arg = Args.getLastArg(OPT_fmsc_version); + if (!Arg) + return 0; + + // 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. + + StringRef Value = Arg->getValue(); + + // parse the compatible old form of _MSC_VER or the newer _MSC_FULL_VER + if (Value.find('.') == StringRef::npos) { + unsigned Version = 0; + if (Value.getAsInteger(10, Version)) { + Diags.Report(diag::err_drv_invalid_value) + << Arg->getAsString(Args) << Value; + return 0; + } + return (Version < 100000) ? Version * 100000 : Version; + } + + // parse the dot-delimited component version + unsigned VC[4] = {0}; + SmallVector<StringRef, 4> Components; + + 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; + return 0; + } + } + + // FIXME we cannot encode the patch level + return VC[0] * 10000000 + VC[1] * 100000 + VC[2]; +} + static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags) { // FIXME: Cleanup per-file based stuff. @@ -1363,7 +1414,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, 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); + Opts.MSCVersion = parseMSCVersion(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); diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 4c90d01918c..7d39c74cea5 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -813,7 +813,7 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, if (DiagOpts->getFormat() == DiagnosticOptions::Msvc) { OS << ','; // Visual Studio 2010 or earlier expects column number to be off by one - if (LangOpts.MSCVersion && LangOpts.MSCVersion < 1700) + if (LangOpts.MSCVersion && LangOpts.MSCVersion < 170000000) ColNo--; } else OS << ':'; diff --git a/clang/test/Driver/msc-version.c b/clang/test/Driver/msc-version.c new file mode 100644 index 00000000000..09115c9fe93 --- /dev/null +++ b/clang/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 + |

