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" 14936dcc89SNick Desaulniers #include "llvm/Demangle/StringViewExtras.h" 158456cddeSKonstantin Zhuravlyov #include <cstdlib> 168abbc17fSNick Desaulniers #include <string_view> 17ce5b5b48SJames Henderson 18936dcc89SNick Desaulniers using llvm::itanium_demangle::starts_with; 193e3c6f24SNick Desaulniers 208abbc17fSNick Desaulniers std::string llvm::demangle(std::string_view MangledName) { 2141a6fc84STomasz Miąsko std::string Result; 2241a6fc84STomasz Miąsko 2361e1c3d8SNick Desaulniers if (nonMicrosoftDemangle(MangledName, Result)) 2441a6fc84STomasz Miąsko return Result; 2541a6fc84STomasz Miąsko 268abbc17fSNick Desaulniers if (starts_with(MangledName, '_') && 271ff958c3Szhijian nonMicrosoftDemangle(MangledName.substr(1), Result, 281ff958c3Szhijian /*CanHaveLeadingDot=*/false)) 2941a6fc84STomasz Miąsko return Result; 3041a6fc84STomasz Miąsko 318abbc17fSNick Desaulniers if (char *Demangled = microsoftDemangle(MangledName, nullptr, nullptr)) { 3241a6fc84STomasz Miąsko Result = Demangled; 3341a6fc84STomasz Miąsko std::free(Demangled); 348abbc17fSNick Desaulniers } else { 358abbc17fSNick Desaulniers Result = MangledName; 3641a6fc84STomasz Miąsko } 378abbc17fSNick Desaulniers return Result; 3841a6fc84STomasz Miąsko } 3941a6fc84STomasz Miąsko 40936dcc89SNick Desaulniers static bool isItaniumEncoding(std::string_view S) { 41*0b554dd9SMichael Buch // Itanium demangler supports prefixes with 1-4 underscores. 42*0b554dd9SMichael Buch const size_t Pos = S.find_first_not_of('_'); 43*0b554dd9SMichael Buch return Pos > 0 && Pos <= 4 && S[Pos] == 'Z'; 44936dcc89SNick Desaulniers } 45936dcc89SNick Desaulniers 46936dcc89SNick Desaulniers static bool isRustEncoding(std::string_view S) { return starts_with(S, "_R"); } 47936dcc89SNick Desaulniers 48936dcc89SNick Desaulniers static bool isDLangEncoding(std::string_view S) { return starts_with(S, "_D"); } 49936dcc89SNick Desaulniers 5061e1c3d8SNick Desaulniers bool llvm::nonMicrosoftDemangle(std::string_view MangledName, 51569ec185SDmitry Vasilyev std::string &Result, bool CanHaveLeadingDot, 52569ec185SDmitry Vasilyev bool ParseParams) { 5341a6fc84STomasz Miąsko char *Demangled = nullptr; 541ff958c3Szhijian 551ff958c3Szhijian // Do not consider the dot prefix as part of the demangled symbol name. 561ff958c3Szhijian if (CanHaveLeadingDot && MangledName.size() > 0 && MangledName[0] == '.') { 571ff958c3Szhijian MangledName.remove_prefix(1); 581ff958c3Szhijian Result = "."; 591ff958c3Szhijian } 601ff958c3Szhijian 61936dcc89SNick Desaulniers if (isItaniumEncoding(MangledName)) 62569ec185SDmitry Vasilyev Demangled = itaniumDemangle(MangledName, ParseParams); 63936dcc89SNick Desaulniers else if (isRustEncoding(MangledName)) 6412d967c9SNick Desaulniers Demangled = rustDemangle(MangledName); 65936dcc89SNick Desaulniers else if (isDLangEncoding(MangledName)) 66f5371eb3SNick Desaulniers Demangled = dlangDemangle(MangledName); 67ce5b5b48SJames Henderson 68ce5b5b48SJames Henderson if (!Demangled) 6941a6fc84STomasz Miąsko return false; 70ce5b5b48SJames Henderson 711ff958c3Szhijian Result += Demangled; 7278f543e5SLouis Dionne std::free(Demangled); 7341a6fc84STomasz Miąsko return true; 74ce5b5b48SJames Henderson } 75