[PATCH v2 13/50] helper-to-tcg: PrepareForOptPass, demangle function names

Anton Johansson via qemu development <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
Since input LLVM IR might come from languages which mangle function
names, e.g. C++, take extra care to demangle all function names and save
them on the side for future lookup.

Signed-off-by: Anton Johansson <[email protected]>
---
 .../PrepareForOptPass/PrepareForOptPass.cpp   | 43 ++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/subprojects/helper-to-tcg/src/PrepareForOptPass/PrepareForOptPass.cpp b/subprojects/helper-to-tcg/src/PrepareForOptPass/PrepareForOptPass.cpp
index 4a7e82b7bd..c15c0af6ea 100644
--- a/subprojects/helper-to-tcg/src/PrepareForOptPass/PrepareForOptPass.cpp
+++ b/subprojects/helper-to-tcg/src/PrepareForOptPass/PrepareForOptPass.cpp
@@ -15,15 +15,56 @@
 //  along with this program; if not, see <http://www.gnu.org/licenses/>.
 //
 
-#include "PrepareForOptPass.h"
+#include "PrepareForOptPass.hpp"
 
+#include <llvm/ADT/StringRef.h>
+#include <llvm/ADT/StringSet.h>
+#include <llvm/Demangle/Demangle.h>
 #include <llvm/Support/Debug.h>
 
 #define DEBUG_TYPE "prepare-for-opt"
 
 using namespace llvm;
 
+static void demangleFunctionNames(Module &M) {
+    StringSet DemangledNames;
+    for (Function &F : M) {
+        const std::string DemangledName = llvm::demangle(F.getName().str());
+        if (DemangledName == F.getName()) {
+            // Name not mangled
+            continue;
+        }
+        // The resulting demangled name might look something like
+        //
+        //   namespace::subnamespace::function(...)
+        //
+        // Extract the function name and use this to replace mangled name.  If
+        // we previously encountered the same name, give up and leave the
+        // mangled name.
+        std::string FunctionName;
+        size_t Index = 0;
+        // Remove namespaces
+        Index = DemangledName.find_last_of(':');
+        if (Index != std::string::npos) {
+            FunctionName = DemangledName.substr(Index + 1);
+        }
+        // Remove arguments
+        Index = FunctionName.find_first_of('(');
+        if (Index != std::string::npos) {
+            FunctionName = FunctionName.substr(0, Index);
+        }
+
+        if (DemangledNames.contains(FunctionName)) {
+            continue;
+        }
+        DemangledNames.insert(FunctionName);
+
+        F.setName(FunctionName);
+    }
+}
+
 PreservedAnalyses PrepareForOptPass::run(Module &M,
                                          ModuleAnalysisManager &MAM) {
+    demangleFunctionNames(M);
     return PreservedAnalyses::none();
 }
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.