xref: /llvm-project/llvm/lib/Demangle/Demangle.cpp (revision 12d967c95f1633bebd1b225ddd53573951a7ca43)
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>
153e3c6f24SNick Desaulniers #include <cstring>
16ce5b5b48SJames Henderson 
173e3c6f24SNick Desaulniers static bool isItaniumEncoding(const char *S) {
183e3c6f24SNick Desaulniers   // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'.
193e3c6f24SNick Desaulniers   return std::strncmp(S, "_Z", 2) == 0 || std::strncmp(S, "___Z", 4) == 0;
203e3c6f24SNick Desaulniers }
21f5356944SJames Henderson 
223e3c6f24SNick Desaulniers static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; }
233e3c6f24SNick Desaulniers 
243e3c6f24SNick Desaulniers static bool isDLangEncoding(const std::string &MangledName) {
253e3c6f24SNick Desaulniers   return MangledName.size() >= 2 && MangledName[0] == '_' &&
263e3c6f24SNick Desaulniers          MangledName[1] == 'D';
273e3c6f24SNick Desaulniers }
283e3c6f24SNick Desaulniers 
293e3c6f24SNick Desaulniers std::string llvm::demangle(const std::string &MangledName) {
3041a6fc84STomasz Miąsko   std::string Result;
313e3c6f24SNick Desaulniers   const char *S = MangledName.c_str();
3241a6fc84STomasz Miąsko 
3361e1c3d8SNick Desaulniers   if (nonMicrosoftDemangle(MangledName, Result))
3441a6fc84STomasz Miąsko     return Result;
3541a6fc84STomasz Miąsko 
3661e1c3d8SNick Desaulniers   if (S[0] == '_' && nonMicrosoftDemangle(MangledName.substr(1), Result))
3741a6fc84STomasz Miąsko     return Result;
3841a6fc84STomasz Miąsko 
39c2709fcbSNick Desaulniers   if (char *Demangled = microsoftDemangle(S, nullptr, nullptr)) {
4041a6fc84STomasz Miąsko     Result = Demangled;
4141a6fc84STomasz Miąsko     std::free(Demangled);
4241a6fc84STomasz Miąsko     return Result;
4341a6fc84STomasz Miąsko   }
4441a6fc84STomasz Miąsko 
453e3c6f24SNick Desaulniers   return MangledName;
4641a6fc84STomasz Miąsko }
4741a6fc84STomasz Miąsko 
4861e1c3d8SNick Desaulniers bool llvm::nonMicrosoftDemangle(std::string_view MangledName,
4961e1c3d8SNick Desaulniers                                 std::string &Result) {
5041a6fc84STomasz Miąsko   char *Demangled = nullptr;
5161e1c3d8SNick Desaulniers   if (isItaniumEncoding(MangledName.data()))
523b01fa26SNick Desaulniers     Demangled = itaniumDemangle(MangledName);
5361e1c3d8SNick Desaulniers   else if (isRustEncoding(MangledName.data()))
54*12d967c9SNick Desaulniers     Demangled = rustDemangle(MangledName);
5561e1c3d8SNick Desaulniers   else if (isDLangEncoding(MangledName.data()))
5661e1c3d8SNick Desaulniers     Demangled = dlangDemangle(MangledName.data());
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