A few fixes for llvm-symbolizer on Windows.

Specifically, this patch correctly respects the -demangle option,
and additionally adds a hidden --relative-address option allows
input addresses to be relative to the module load address instead
of absolute addresses into the image.

llvm-svn: 236653
diff --git a/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp b/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
index 326cab5..afb7cc8 100644
--- a/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
+++ b/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp
@@ -29,6 +29,11 @@
 #include <sstream>
 #include <stdlib.h>
 
+#if defined(_MSC_VER)
+#include <Windows.h>
+#include <DbgHelp.h>
+#endif
+
 namespace llvm {
 namespace symbolize {
 
@@ -471,8 +476,10 @@
     std::unique_ptr<IPDBSession> Session;
     PDB_ErrorCode Error = loadDataForEXE(PDB_ReaderType::DIA,
                                          Objects.first->getFileName(), Session);
-    if (Error == PDB_ErrorCode::Success)
-      Context = new PDBContext(*CoffObject, std::move(Session));
+    if (Error == PDB_ErrorCode::Success) {
+      Context = new PDBContext(*CoffObject, std::move(Session),
+                               Opts.RelativeAddresses);
+    }
   }
   if (!Context)
     Context = new DWARFContextInMemory(*Objects.second);
@@ -522,7 +529,17 @@
   free(DemangledName);
   return Result;
 #else
-  return Name;
+  char DemangledName[1024] = {0};
+  DWORD result = ::UnDecorateSymbolName(
+      Name.c_str(), DemangledName, 1023,
+      UNDNAME_NO_ACCESS_SPECIFIERS |       // Strip public, private, protected
+          UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc
+          UNDNAME_NO_THROW_SIGNATURES |    // Strip throw() specifications
+          UNDNAME_NO_MEMBER_TYPE |      // Strip virtual, static, etc specifiers
+          UNDNAME_NO_MS_KEYWORDS |      // Strip all MS extension keywords
+          UNDNAME_NO_FUNCTION_RETURNS); // Strip function return types
+
+  return (result == 0) ? Name : std::string(DemangledName);
 #endif
 }
 
diff --git a/llvm/tools/llvm-symbolizer/LLVMSymbolize.h b/llvm/tools/llvm-symbolizer/LLVMSymbolize.h
index ff848fc..1c2006f 100644
--- a/llvm/tools/llvm-symbolizer/LLVMSymbolize.h
+++ b/llvm/tools/llvm-symbolizer/LLVMSymbolize.h
@@ -35,19 +35,20 @@
 class LLVMSymbolizer {
 public:
   struct Options {
-    bool UseSymbolTable : 1;
     FunctionNameKind PrintFunctions;
+    bool UseSymbolTable : 1;
     bool PrintInlining : 1;
     bool Demangle : 1;
+    bool RelativeAddresses : 1;
     std::string DefaultArch;
     std::vector<std::string> DsymHints;
-    Options(bool UseSymbolTable = true,
-            FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
-            bool PrintInlining = true, bool Demangle = true,
+    Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
+            bool UseSymbolTable = true, bool PrintInlining = true,
+            bool Demangle = true, bool RelativeAddresses = false,
             std::string DefaultArch = "")
-        : UseSymbolTable(UseSymbolTable),
-          PrintFunctions(PrintFunctions), PrintInlining(PrintInlining),
-          Demangle(Demangle), DefaultArch(DefaultArch) {}
+        : PrintFunctions(PrintFunctions), UseSymbolTable(UseSymbolTable),
+          PrintInlining(PrintInlining), Demangle(Demangle),
+          RelativeAddresses(RelativeAddresses), DefaultArch(DefaultArch) {}
   };
 
   LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 7a77a44..9c9f3ad 100644
--- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -49,8 +49,13 @@
                clEnumValEnd));
 
 static cl::opt<bool>
-ClPrintInlining("inlining", cl::init(true),
-                cl::desc("Print all inlined frames for a given address"));
+    ClUseRelativeAddress("relative-address", cl::init(false),
+                         cl::desc("Interpret addresses as relative addresses"),
+                         cl::ReallyHidden);
+
+static cl::opt<bool>
+    ClPrintInlining("inlining", cl::init(true),
+                    cl::desc("Print all inlined frames for a given address"));
 
 static cl::opt<bool>
 ClDemangle("demangle", cl::init(true), cl::desc("Demangle function names"));
@@ -127,8 +132,9 @@
   llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
 
   cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n");
-  LLVMSymbolizer::Options Opts(ClUseSymbolTable, ClPrintFunctions,
-                               ClPrintInlining, ClDemangle, ClDefaultArch);
+  LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable,
+                               ClPrintInlining, ClDemangle,
+                               ClUseRelativeAddress, ClDefaultArch);
   for (const auto &hint : ClDsymHint) {
     if (sys::path::extension(hint) == ".dSYM") {
       Opts.DsymHints.push_back(hint);