xref: /llvm-project/llvm/lib/Demangle/Demangle.cpp (revision 22a1aa5a43cbdaf9dde014ba1f120e0f7ca1788b)
1ce5b5b48SJames Henderson //===-- Demangle.cpp - Common demangling functions ------------------------===//
2ce5b5b48SJames Henderson //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ce5b5b48SJames Henderson //
7ce5b5b48SJames Henderson //===----------------------------------------------------------------------===//
8ce5b5b48SJames Henderson ///
9ce5b5b48SJames Henderson /// \file This file contains definitions of common demangling functions.
10ce5b5b48SJames Henderson ///
11ce5b5b48SJames Henderson //===----------------------------------------------------------------------===//
12ce5b5b48SJames Henderson 
13ce5b5b48SJames Henderson #include "llvm/Demangle/Demangle.h"
148456cddeSKonstantin Zhuravlyov #include <cstdlib>
1541a6fc84STomasz Miąsko #include <cstring>
16ce5b5b48SJames Henderson 
1741a6fc84STomasz Miąsko static bool isItaniumEncoding(const char *S) {
1841a6fc84STomasz Miąsko   // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'.
1941a6fc84STomasz Miąsko   return std::strncmp(S, "_Z", 2) == 0 || std::strncmp(S, "___Z", 4) == 0;
20f5356944SJames Henderson }
21f5356944SJames Henderson 
2241a6fc84STomasz Miąsko static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; }
239b108560STomasz Miąsko 
24*22a1aa5aSLuís Ferreira static bool isDLangEncoding(const std::string &MangledName) {
25*22a1aa5aSLuís Ferreira   return MangledName.size() >= 2 && MangledName[0] == '_' &&
26*22a1aa5aSLuís Ferreira          MangledName[1] == 'D';
27*22a1aa5aSLuís Ferreira }
28*22a1aa5aSLuís Ferreira 
29ce5b5b48SJames Henderson std::string llvm::demangle(const std::string &MangledName) {
3041a6fc84STomasz Miąsko   std::string Result;
3141a6fc84STomasz Miąsko   const char *S = MangledName.c_str();
3241a6fc84STomasz Miąsko 
3341a6fc84STomasz Miąsko   if (nonMicrosoftDemangle(S, Result))
3441a6fc84STomasz Miąsko     return Result;
3541a6fc84STomasz Miąsko 
3641a6fc84STomasz Miąsko   if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result))
3741a6fc84STomasz Miąsko     return Result;
3841a6fc84STomasz Miąsko 
3941a6fc84STomasz Miąsko   if (char *Demangled =
4041a6fc84STomasz Miąsko           microsoftDemangle(S, nullptr, nullptr, nullptr, nullptr)) {
4141a6fc84STomasz Miąsko     Result = Demangled;
4241a6fc84STomasz Miąsko     std::free(Demangled);
4341a6fc84STomasz Miąsko     return Result;
4441a6fc84STomasz Miąsko   }
4541a6fc84STomasz Miąsko 
4641a6fc84STomasz Miąsko   return MangledName;
4741a6fc84STomasz Miąsko }
4841a6fc84STomasz Miąsko 
4941a6fc84STomasz Miąsko bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) {
5041a6fc84STomasz Miąsko   char *Demangled = nullptr;
51f5356944SJames Henderson   if (isItaniumEncoding(MangledName))
5241a6fc84STomasz Miąsko     Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr);
539b108560STomasz Miąsko   else if (isRustEncoding(MangledName))
5441a6fc84STomasz Miąsko     Demangled = rustDemangle(MangledName, nullptr, nullptr, nullptr);
55*22a1aa5aSLuís Ferreira   else if (isDLangEncoding(MangledName))
56*22a1aa5aSLuís Ferreira     Demangled = dlangDemangle(MangledName);
57ce5b5b48SJames Henderson 
58ce5b5b48SJames Henderson   if (!Demangled)
5941a6fc84STomasz Miąsko     return false;
60ce5b5b48SJames Henderson 
6141a6fc84STomasz Miąsko   Result = Demangled;
6278f543e5SLouis Dionne   std::free(Demangled);
6341a6fc84STomasz Miąsko   return true;
64ce5b5b48SJames Henderson }
65