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" 140b57cec5SDimitry Andric #include <cstdlib> 15349cc55cSDimitry Andric #include <cstring> 160b57cec5SDimitry Andric 17349cc55cSDimitry Andric static bool isItaniumEncoding(const char *S) { 18349cc55cSDimitry Andric // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'. 19349cc55cSDimitry Andric return std::strncmp(S, "_Z", 2) == 0 || std::strncmp(S, "___Z", 4) == 0; 200b57cec5SDimitry Andric } 210b57cec5SDimitry Andric 22349cc55cSDimitry Andric static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; } 23349cc55cSDimitry Andric 24349cc55cSDimitry Andric static bool isDLangEncoding(const std::string &MangledName) { 25fe6060f1SDimitry Andric return MangledName.size() >= 2 && MangledName[0] == '_' && 26349cc55cSDimitry Andric MangledName[1] == 'D'; 27fe6060f1SDimitry Andric } 28fe6060f1SDimitry Andric 290b57cec5SDimitry Andric std::string llvm::demangle(const std::string &MangledName) { 30349cc55cSDimitry Andric std::string Result; 31349cc55cSDimitry Andric const char *S = MangledName.c_str(); 32349cc55cSDimitry Andric 33349cc55cSDimitry Andric if (nonMicrosoftDemangle(S, Result)) 34349cc55cSDimitry Andric return Result; 35349cc55cSDimitry Andric 36349cc55cSDimitry Andric if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result)) 37349cc55cSDimitry Andric return Result; 38349cc55cSDimitry Andric 39349cc55cSDimitry Andric if (char *Demangled = 40349cc55cSDimitry Andric microsoftDemangle(S, nullptr, nullptr, nullptr, nullptr)) { 41349cc55cSDimitry Andric Result = Demangled; 42349cc55cSDimitry Andric std::free(Demangled); 43349cc55cSDimitry Andric return Result; 44349cc55cSDimitry Andric } 45349cc55cSDimitry Andric 46349cc55cSDimitry Andric return MangledName; 47349cc55cSDimitry Andric } 48349cc55cSDimitry Andric 49349cc55cSDimitry Andric bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) { 50349cc55cSDimitry Andric char *Demangled = nullptr; 510b57cec5SDimitry Andric if (isItaniumEncoding(MangledName)) 52349cc55cSDimitry Andric Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr); 53fe6060f1SDimitry Andric else if (isRustEncoding(MangledName)) 54*81ad6265SDimitry Andric Demangled = rustDemangle(MangledName); 55349cc55cSDimitry Andric else if (isDLangEncoding(MangledName)) 56349cc55cSDimitry Andric Demangled = dlangDemangle(MangledName); 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric if (!Demangled) 59349cc55cSDimitry Andric return false; 600b57cec5SDimitry Andric 61349cc55cSDimitry Andric Result = Demangled; 62e8d8bef9SDimitry Andric std::free(Demangled); 63349cc55cSDimitry Andric return true; 640b57cec5SDimitry Andric } 65