10b57cec5SDimitry Andric //===-- Demangle.cpp - Common demangling functions ------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file This file contains definitions of common demangling functions. 100b57cec5SDimitry Andric /// 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Demangle/Demangle.h" 1406c3fb27SDimitry Andric #include "llvm/Demangle/StringViewExtras.h" 150b57cec5SDimitry Andric #include <cstdlib> 1606c3fb27SDimitry Andric #include <string_view> 170b57cec5SDimitry Andric 1806c3fb27SDimitry Andric using llvm::itanium_demangle::starts_with; 190b57cec5SDimitry Andric 2006c3fb27SDimitry Andric std::string llvm::demangle(std::string_view MangledName) { 21349cc55cSDimitry Andric std::string Result; 22349cc55cSDimitry Andric 2306c3fb27SDimitry Andric if (nonMicrosoftDemangle(MangledName, Result)) 24349cc55cSDimitry Andric return Result; 25349cc55cSDimitry Andric 2606c3fb27SDimitry Andric if (starts_with(MangledName, '_') && 275f757f3fSDimitry Andric nonMicrosoftDemangle(MangledName.substr(1), Result, 285f757f3fSDimitry Andric /*CanHaveLeadingDot=*/false)) 29349cc55cSDimitry Andric return Result; 30349cc55cSDimitry Andric 3106c3fb27SDimitry Andric if (char *Demangled = microsoftDemangle(MangledName, nullptr, nullptr)) { 32349cc55cSDimitry Andric Result = Demangled; 33349cc55cSDimitry Andric std::free(Demangled); 3406c3fb27SDimitry Andric } else { 3506c3fb27SDimitry Andric Result = MangledName; 3606c3fb27SDimitry Andric } 37349cc55cSDimitry Andric return Result; 38349cc55cSDimitry Andric } 39349cc55cSDimitry Andric 4006c3fb27SDimitry Andric static bool isItaniumEncoding(std::string_view S) { 4106c3fb27SDimitry Andric // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'. 4206c3fb27SDimitry Andric return starts_with(S, "_Z") || starts_with(S, "___Z"); 43349cc55cSDimitry Andric } 44349cc55cSDimitry Andric 4506c3fb27SDimitry Andric static bool isRustEncoding(std::string_view S) { return starts_with(S, "_R"); } 4606c3fb27SDimitry Andric 4706c3fb27SDimitry Andric static bool isDLangEncoding(std::string_view S) { return starts_with(S, "_D"); } 4806c3fb27SDimitry Andric 4906c3fb27SDimitry Andric bool llvm::nonMicrosoftDemangle(std::string_view MangledName, 50*1db9f3b2SDimitry Andric std::string &Result, bool CanHaveLeadingDot, 51*1db9f3b2SDimitry Andric bool ParseParams) { 52349cc55cSDimitry Andric char *Demangled = nullptr; 535f757f3fSDimitry Andric 545f757f3fSDimitry Andric // Do not consider the dot prefix as part of the demangled symbol name. 555f757f3fSDimitry Andric if (CanHaveLeadingDot && MangledName.size() > 0 && MangledName[0] == '.') { 565f757f3fSDimitry Andric MangledName.remove_prefix(1); 575f757f3fSDimitry Andric Result = "."; 585f757f3fSDimitry Andric } 595f757f3fSDimitry Andric 600b57cec5SDimitry Andric if (isItaniumEncoding(MangledName)) 61*1db9f3b2SDimitry Andric Demangled = itaniumDemangle(MangledName, ParseParams); 62fe6060f1SDimitry Andric else if (isRustEncoding(MangledName)) 6381ad6265SDimitry Andric Demangled = rustDemangle(MangledName); 64349cc55cSDimitry Andric else if (isDLangEncoding(MangledName)) 65349cc55cSDimitry Andric Demangled = dlangDemangle(MangledName); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric if (!Demangled) 68349cc55cSDimitry Andric return false; 690b57cec5SDimitry Andric 705f757f3fSDimitry Andric Result += Demangled; 71e8d8bef9SDimitry Andric std::free(Demangled); 72349cc55cSDimitry Andric return true; 730b57cec5SDimitry Andric } 74