Define InitLLVM to do common initialization all at once.

We have a few functions that virtually all command wants to run on
process startup/shutdown. This patch adds InitLLVM class to do that
all at once, so that we don't need to copy-n-paste boilerplate code
to each llvm command's main() function.

Differential Revision: https://reviews.llvm.org/D45602

llvm-svn: 330046
diff --git a/llvm/lib/Support/InitLLVM.cpp b/llvm/lib/Support/InitLLVM.cpp
new file mode 100644
index 0000000..c76b1bd
--- /dev/null
+++ b/llvm/lib/Support/InitLLVM.cpp
@@ -0,0 +1,48 @@
+//===-- InitLLVM.cpp -----------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include <string>
+
+using namespace llvm;
+
+InitLLVM::InitLLVM(int &Argc, const char **&Argv) : StackPrinter(Argc, Argv) {
+  sys::PrintStackTraceOnErrorSignal(Argv[0]);
+
+#ifdef _WIN32
+  // We use UTF-8 as the internal character encoding. On Windows,
+  // arguments passed to main() may not be encoded in UTF-8. In order
+  // to reliably detect encoding of command line arguments, we use an
+  // Windows API to obtain arguments, convert them to UTF-8, and then
+  // write them back to the Argv vector.
+  //
+  // There's probably other way to do the same thing (e.g. using
+  // wmain() instead of main()), but this way seems less intrusive
+  // than that.
+  std::string Banner = std::string(Argv[0]) + ": ";
+  ExitOnError ExitOnErr(Banner);
+
+  ExitOnErr(errorCodeToError(
+      sys::Process::GetArgumentVector(Args, makeArrayRef(Argv, Argc), Alloc)));
+
+  // GetArgumentVector doesn't terminate the vector with a nullptr.
+  // Do it to make it compatible with the real argv.
+  Args.push_back(nullptr);
+
+  Argc = Args.size() - 1;
+  Argv = Args.data();
+#endif
+}
+
+InitLLVM::~InitLLVM() { llvm_shutdown(); }