Merge pull request #19651 from compnerd/SKWin

SourceKit: handle Windows codepaths better
diff --git a/tools/SourceKit/tools/complete-test/complete-test.cpp b/tools/SourceKit/tools/complete-test/complete-test.cpp
index 30f46a2..872e083 100644
--- a/tools/SourceKit/tools/complete-test/complete-test.cpp
+++ b/tools/SourceKit/tools/complete-test/complete-test.cpp
@@ -21,14 +21,26 @@
 #include "llvm/Support/FileSystem.h"
 #include <fstream>
 #include <regex>
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 #include <unistd.h>
 #include <sys/param.h>
+#elif defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <Windows.h>
+#endif
 
 // FIXME: Platform compatibility.
 #include <dispatch/dispatch.h>
 
 using namespace llvm;
 
+#if defined(_WIN32)
+namespace {
+int STDOUT_FILENO = _fileno(stdout);
+}
+#endif
+
 namespace {
 struct TestOptions {
   StringRef sourceFile;
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index 17175f1..41be90c 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -27,8 +27,14 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormatVariadic.h"
 #include <fstream>
+#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
 #include <unistd.h>
 #include <sys/param.h>
+#elif defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <Windows.h>
+#endif
 
 // FIXME: Platform compatibility.
 #include <dispatch/dispatch.h>
@@ -37,6 +43,19 @@
 
 using namespace sourcekitd_test;
 
+#if defined(_WIN32)
+namespace {
+int STDOUT_FILENO = _fileno(stdout);
+const constexpr size_t MAXPATHLEN = MAX_PATH + 1;
+char *realpath(const char *path, const char *resolved_path) {
+  DWORD dwLength = GetFullPathNameA(path, 0, nullptr, nullptr);
+  if (resolved_path = malloc(dwLength + 1))
+    GetFullPathNameA(path, dwLength, resolved_path, nullptr);
+  return resolved_path;
+}
+}
+#endif
+
 static int handleTestInvocation(ArrayRef<const char *> Args, TestOptions &InitOpts);
 static bool handleResponse(sourcekitd_response_t Resp, const TestOptions &Opts,
                            const std::string &SourceFile,
diff --git a/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp b/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp
index be0a5d7..673411c 100644
--- a/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp
+++ b/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp
@@ -80,9 +80,16 @@
 }
 
 std::string sourcekitd::getRuntimeLibPath() {
-  // FIXME: Move to an LLVM API. Note that libclang does the same thing.
 #if defined(_WIN32)
-#error Not implemented
+  MEMORY_BASIC_INFORMATION mbi;
+  char path[MAX_PATH + 1];
+  if (!VirtualQuery(static_cast<void *>(sourcekitd_initialize), &mbi,
+                    sizeof(mbi)))
+    llvm_unreachable("call to VirtualQuery failed");
+  if (!GetModuleFileNameA(static_cast<HINSTANCE>(mbi.AllocationBase), path,
+                          MAX_PATH))
+    llvm_unreachable("call to GetModuleFileNameA failed");
+  return llvm::sys::path::parent_path(path);
 #else
   // This silly cast below avoids a C++ warning.
   Dl_info info;