Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp	(revision 79556)
+++ lib/Basic/Targets.cpp	(working copy)
@@ -337,12 +337,6 @@
 };
 } // end anonymous namespace. 
 
-/// GetWindowsLanguageOptions - Set the default language options for Windows.
-static void GetWindowsLanguageOptions(LangOptions &Opts,
-                                     const char *Triple) {
-  Opts.Microsoft = true;
-}
-
 //===----------------------------------------------------------------------===//
 // Specific target implementations.
 //===----------------------------------------------------------------------===//
@@ -918,17 +912,88 @@
     DefineStd(Defines, "WIN32", Opts);
     DefineStd(Defines, "WINNT", Opts);
     Define(Defines, "_X86_");
-    Define(Defines, "__MSVCRT__");
   }
+};
+} // end anonymous namespace
 
+/// GetWindowsVisualStudioLanguageOptions - Set the default language options for Windows.
+static void GetWindowsVisualStudioLanguageOptions(LangOptions &Opts,
+                                     const char *Triple) {
+  Opts.Microsoft = true;
+}
+
+namespace {
+// x86-32 Windows Visual Studio target
+class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
+public:
+  VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
+    : WindowsX86_32TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                std::vector<char> &Defines) const {
+    WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
+    const char* TT = getTargetTriple();
+    // The value of the following reflects processor type.
+    // 300=386, 400=486, 500=Pentium, 600=Blend (default)
+    char processorTypeCode[4];
+    if ((strlen(TT) >= 5) && (TT[0] == 'i') && (TT[2] == '8') &&
+            (TT[3] == '6') && (TT[4] == '-') && ((TT[1] - '3') < 6))
+        processorTypeCode[0] = TT[1];
+    else
+        processorTypeCode[0] = '6';
+    processorTypeCode[1] = '0';
+    processorTypeCode[2] = '0';
+    processorTypeCode[3] = '\0';
+    Define(Defines, "_M_IX86", processorTypeCode);
+  }
   virtual void getDefaultLangOptions(LangOptions &Opts) {
-    X86_32TargetInfo::getDefaultLangOptions(Opts);
-    GetWindowsLanguageOptions(Opts, getTargetTriple());
+    WindowsX86_32TargetInfo::getDefaultLangOptions(Opts);
+    GetWindowsVisualStudioLanguageOptions(Opts, getTargetTriple());
   }
 };
 } // end anonymous namespace
 
 namespace {
+// x86-32 MinGW target
+class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
+public:
+  MinGWX86_32TargetInfo(const std::string& triple)
+    : WindowsX86_32TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                std::vector<char> &Defines) const {
+    WindowsX86_32TargetInfo::getTargetDefines(Opts, Defines);
+    Define(Defines, "__MSVCRT__");
+    Define(Defines, "__MINGW32__");
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-32 Cygwin target
+class CygwinX86_32TargetInfo : public X86_32TargetInfo {
+public:
+  CygwinX86_32TargetInfo(const std::string& triple)
+    : X86_32TargetInfo(triple) {
+    TLSSupported = false;
+    WCharType = UnsignedShort;
+    WCharWidth = WCharAlign = 16;
+    DoubleAlign = LongLongAlign = 64;
+    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
+                        "a0:0:64-f80:32:32";
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                std::vector<char> &Defines) const {
+    X86_32TargetInfo::getTargetDefines(Opts, Defines);
+    Define(Defines, "__CYGWIN__");
+    Define(Defines, "__CYGWIN32__");
+    DefineStd(Defines, "unix", Opts);
+  }
+};
+} // end anonymous namespace
+
+namespace {
 // x86-64 generic target
 class X86_64TargetInfo : public X86TargetInfo {
 public:
@@ -980,6 +1045,60 @@
 } // end anonymous namespace
 
 namespace {
+// x86-64 Windows target
+class WindowsX86_64TargetInfo : public X86_64TargetInfo {
+public:
+  WindowsX86_64TargetInfo(const std::string& triple)
+    : X86_64TargetInfo(triple) {
+    TLSSupported = false;
+    WCharType = UnsignedShort;
+    WCharWidth = WCharAlign = 16;
+    DoubleAlign = LongLongAlign = 64;
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                std::vector<char> &Defines) const {
+    X86_64TargetInfo::getTargetDefines(Opts, Defines);
+    Define(Defines, "_WIN64");
+    DefineStd(Defines, "WIN64", Opts);
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-64 Windows Visual Studio target
+class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
+public:
+  VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
+    : WindowsX86_64TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                std::vector<char> &Defines) const {
+    WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
+    Define(Defines, "_M_X64");
+  }
+  virtual const char *getVAListDeclaration() const {
+    return "typedef char* va_list;";
+  }
+};
+} // end anonymous namespace
+
+namespace {
+// x86-64 MinGW target
+class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
+public:
+  MinGWX86_64TargetInfo(const std::string& triple)
+    : WindowsX86_64TargetInfo(triple) {
+  }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                std::vector<char> &Defines) const {
+    WindowsX86_64TargetInfo::getTargetDefines(Opts, Defines);
+    Define(Defines, "__MSVCRT__");
+    Define(Defines, "__MINGW64__");
+  }
+};
+} // end anonymous namespace
+
+namespace {
 class ARMTargetInfo : public TargetInfo {
   enum {
     Armv4t,
@@ -1561,6 +1680,7 @@
 TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
   llvm::Triple Triple(T);
   llvm::Triple::OSType os = Triple.getOS();
+  llvm::Triple::EnvironmentType env = Triple.getEnvironment();
 
   switch (Triple.getArch()) {
   default:
@@ -1623,10 +1743,16 @@
     case llvm::Triple::Solaris:
       return new SolarisTargetInfo<X86_32TargetInfo>(T);
     case llvm::Triple::Cygwin:
+      return new CygwinX86_32TargetInfo(T);
     case llvm::Triple::MinGW32:
-    case llvm::Triple::MinGW64:
+      return new MinGWX86_32TargetInfo(T);
     case llvm::Triple::Win32:
-      return new WindowsX86_32TargetInfo(T);
+      switch (env) {
+        case llvm::Triple::VisualStudio:
+          return new VisualStudioWindowsX86_32TargetInfo(T);
+        default:
+          return new WindowsX86_32TargetInfo(T);
+      }
     default:
       return new X86_32TargetInfo(T);
     }
@@ -1645,6 +1771,16 @@
       return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
     case llvm::Triple::Solaris:
       return new SolarisTargetInfo<X86_64TargetInfo>(T);
+    case llvm::Triple::MinGW64:
+      return new MinGWX86_64TargetInfo(T);
+    case llvm::Triple::Win32:   // Allow old use of x86_64-pc-win32.
+    case llvm::Triple::Win64:
+      switch (env) {
+        case llvm::Triple::VisualStudio:
+          return new VisualStudioWindowsX86_64TargetInfo(T);
+        default:
+          return new WindowsX86_64TargetInfo(T);
+      }
     default:
       return new X86_64TargetInfo(T);
     }
