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