From 1834b17c91e2a4ea8800151bedc798933b4b6496 Mon Sep 17 00:00:00 2001
From: Frederich Munch <marsupial@users.noreply.github.com>
Date: Fri, 16 Dec 2016 13:33:42 -0500
Subject: [PATCH] Add platform::Demangle function.

---
 .../cling/include/cling/Utils/Platform.h      |  6 +++++
 .../lib/Interpreter/IncrementalExecutor.cpp   | 26 ++-----------------
 interpreter/cling/lib/Utils/PlatformPosix.cpp | 14 ++++++++++
 interpreter/cling/lib/Utils/PlatformWin.cpp   | 14 ++++++++++
 4 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/interpreter/cling/include/cling/Utils/Platform.h b/interpreter/cling/include/cling/Utils/Platform.h
index df46b84d165..07f34e2fc11 100644
--- a/interpreter/cling/include/cling/Utils/Platform.h
+++ b/interpreter/cling/include/cling/Utils/Platform.h
@@ -44,6 +44,12 @@ namespace platform {
   ///
   const void* DLSym(const std::string& Name, std::string* Err = nullptr);
 
+  ///\brief Demangle the given symbol name
+  ///
+  /// \returns The demangled name or an empty string
+  ///
+  std::string Demangle(const std::string& Symbol);
+
   ///\brief Close a handle to a shared library.
   ///
   /// \param [in] Lib - Handle to library from previous call to DLOpen
diff --git a/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp b/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
index 237c9c64f7d..da1e59221a9 100644
--- a/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
+++ b/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp
@@ -15,6 +15,7 @@
 #include "cling/Interpreter/Transaction.h"
 #include "cling/Utils/AST.h"
 #include "cling/Utils/Output.h"
+#include "cling/Utils/Platform.h"
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Frontend/CodeGenOptions.h"
@@ -31,15 +32,6 @@
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Target/TargetMachine.h"
 
-#ifdef LLVM_ON_WIN32
-extern "C"
-char *__unDName(char *demangled, const char *mangled, int out_len,
-                void * (* pAlloc )(size_t), void (* pFree )(void *),
-                unsigned short int flags);
-#else
-#include <cxxabi.h>
-#endif
-
 using namespace llvm;
 
 namespace cling {
@@ -406,21 +398,7 @@ bool IncrementalExecutor::diagnoseUnresolvedSymbols(llvm::StringRef trigger,
     cling::errs() << "!\n";
 
     // Be helpful, demangle!
-    std::string demangledName;
-    {
-#ifndef LLVM_ON_WIN32
-      int status = 0;
-      char *demang = abi::__cxa_demangle(i->c_str(), 0, 0, &status);
-      if (status == 0)
-        demangledName = demang;
-      free(demang);
-#else
-      if (char* demang = __unDName(0, i->c_str(), 0, malloc, free, 0)) {
-        demangledName = demang;
-        free(demang);
-      }
-#endif
-    }
+    std::string demangledName = platform::Demangle(*i);
     if (!demangledName.empty()) {
        cling::errs()
           << "You are probably missing the definition of "
diff --git a/interpreter/cling/lib/Utils/PlatformPosix.cpp b/interpreter/cling/lib/Utils/PlatformPosix.cpp
index 20d8881b813..61d2e518f37 100644
--- a/interpreter/cling/lib/Utils/PlatformPosix.cpp
+++ b/interpreter/cling/lib/Utils/PlatformPosix.cpp
@@ -17,6 +17,7 @@
 #include <array>
 #include <atomic>
 #include <string>
+#include <cxxabi.h>
 #include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -199,6 +200,19 @@ bool GetSystemLibraryPaths(llvm::SmallVectorImpl<std::string>& Paths) {
   return true;
 }
 
+std::string Demangle(const std::string& Symbol) {
+  struct AutoFree {
+    char* Str;
+    AutoFree(char* Ptr) : Str(Ptr) {}
+    ~AutoFree() { ::free(Str); };
+  };
+  int status = 0;
+  size_t len;
+  AutoFree af(abi::__cxa_demangle(Symbol.c_str(), 0, &len, &status));
+  assert(((len && af.Str[len-1]==0) || status != 0) && "Not null terminated");
+  return status == 0 ? std::string(af.Str, len-1) : std::string();
+}
+
 } // namespace platform
 } // namespace utils
 } // namespace cling
diff --git a/interpreter/cling/lib/Utils/PlatformWin.cpp b/interpreter/cling/lib/Utils/PlatformWin.cpp
index 66fb80fc603..3702b8c9b86 100644
--- a/interpreter/cling/lib/Utils/PlatformWin.cpp
+++ b/interpreter/cling/lib/Utils/PlatformWin.cpp
@@ -39,6 +39,10 @@
 #include <shlobj.h>  // SHGetFolderPath
 #pragma comment(lib, "Advapi32.lib")
 
+extern "C" char* __unDName(char *demangled, const char *mangled, int out_len,
+                           void * (* pAlloc )(size_t), void (* pFree )(void *),
+                           unsigned short int flags);
+
 #define MAX_PATHC (MAX_PATH + 1)
 
 namespace cling {
@@ -685,6 +689,16 @@ bool Popen(const std::string& Cmd, llvm::SmallVectorImpl<char>& Buf, bool RdE) {
   return !Buf.empty();
 }
 
+std::string Demangle(const std::string& Symbol) {
+  struct AutoFree {
+    char* Str;
+    AutoFree(char* Ptr) : Str(Ptr) {}
+    ~AutoFree() { ::free(Str); };
+  };
+  AutoFree af(__unDName(0, Symbol.c_str(), 0, ::malloc, ::free, 0));
+  return af.Str ? std::string(af.Str) : std::string();
+}
+
 } // namespace platform
 } // namespace utils
 } // namespace cling
-- 
GitLab