Add an c++ itanium demangler to llvm.

This adds a copy of the demangler in libcxxabi.

The code also has no dependencies on anything else in LLVM. To enforce
that I added it as another library. That way a BUILD_SHARED_LIBS will
fail if anyone adds an use of StringRef for example.

The no llvm dependency combined with the fact that this has to build
on linux, OS X and Windows required a few changes to the code. In
particular:

    No constexpr.
    No alignas

On OS X at least this library has only one global symbol:
__ZN4llvm16itanium_demangleEPKcPcPmPi

My current plan is:

    Commit something like this
    Change lld to use it
    Change lldb to use it as the fallback

    Add a few #ifdefs so that exactly the same file can be used in
    libcxxabi to export abi::__cxa_demangle.

Once the fast demangler in lldb can handle any names this
implementation can be replaced with it and we will have the one true
demangler.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280732 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2016-09-06 19:16:48 +00:00
parent 99f377bc53
commit ec44cfdaf0
20 changed files with 4539 additions and 39 deletions

View File

@ -82,13 +82,6 @@ check_include_file(mach/mach.h HAVE_MACH_MACH_H)
check_include_file(mach-o/dyld.h HAVE_MACH_O_DYLD_H)
check_include_file(histedit.h HAVE_HISTEDIT_H)
# size_t must be defined before including cxxabi.h on FreeBSD 10.0.
check_cxx_source_compiles("
#include <stddef.h>
#include <cxxabi.h>
int main() { return 0; }
" HAVE_CXXABI_H)
# library checks
if( NOT PURE_WINDOWS )
check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD)

View File

@ -28,9 +28,6 @@
/* Define to 1 if you have the `closedir' function. */
#cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}
/* Define to 1 if you have the <cxxabi.h> header file. */
#cmakedefine HAVE_CXXABI_H ${HAVE_CXXABI_H}
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H

View File

@ -0,0 +1,28 @@
//===--- Demangle.h ---------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstddef>
namespace llvm {
/// This is a llvm local version of __cxa_demangle. Other than the name and
/// being in the llvm namespace it is identical.
///
/// The mangled_name is demangled into buf and returned. If the buffer is not
/// large enough, realloc is used to expand it.
///
/// The *status will be set to
/// unknown_error: -4
/// invalid_args: -3
/// invalid_mangled_name: -2
/// memory_alloc_failure: -1
/// success: 0
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
int *status);
}

View File

@ -1,5 +1,6 @@
# `Support' and `TableGen' libraries are added on the top-level CMakeLists.txt
add_subdirectory(Demangle)
add_subdirectory(IR)
add_subdirectory(IRReader)
add_subdirectory(CodeGen)

View File

@ -0,0 +1,3 @@
add_llvm_library(LLVMDemangle
ItaniumDemangle.cpp
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
;===- ./lib/Support/LLVMBuild.txt ------------------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = Demangle
parent = Libraries

View File

@ -22,6 +22,7 @@ subdirectories =
Bitcode
CodeGen
DebugInfo
Demangle
ExecutionEngine
LibDriver
LineEditor

View File

@ -19,3 +19,4 @@
type = Library
name = Support
parent = Libraries
required_libraries = Demangle

View File

@ -14,6 +14,7 @@
#include "Unix.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
@ -33,9 +34,6 @@
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_CXXABI_H
#include <cxxabi.h>
#endif
#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif
@ -443,12 +441,8 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS) {
if (dlinfo.dli_sname != nullptr) {
OS << ' ';
# if HAVE_CXXABI_H
int res;
char* d = abi::__cxa_demangle(dlinfo.dli_sname, nullptr, nullptr, &res);
# else
char* d = NULL;
# endif
char* d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
if (!d) OS << dlinfo.dli_sname;
else OS << d;
free(d);

View File

@ -32,6 +32,7 @@ set(LLVM_TEST_DEPENDS
llvm-as
llvm-bcanalyzer
llvm-c-test
llvm-cxxfilt
llvm-config
llvm-cov
llvm-cxxdump

View File

@ -0,0 +1 @@
config.suffixes = ['.test']

View File

@ -0,0 +1,4 @@
RUN: llvm-cxxfilt _Z1fi abc | FileCheck %s
CHECK: f(int)
CHECK-NEXT: abc

View File

@ -309,6 +309,7 @@ for pattern in [r"\bbugpoint\b(?!-)",
r"\bllvm-split\b",
r"\bllvm-tblgen\b",
r"\bllvm-c-test\b",
r"\bllvm-cxxfilt\b",
NOJUNK + r"\bllvm-symbolizer\b",
NOJUNK + r"\bopt\b",
r"\bFileCheck\b",

View File

@ -31,10 +31,7 @@ ObjC-EXE: 0000000100000f1b movq 0x10e(%rip), %rsi ## Objc selector ref: da
ObjC-EXE: 0000000100000f25 callq 0x100000f4a ## Objc message: +[NSDate date]
ObjC-EXE: 0000000100000f33 callq 0x100000f44 ## symbol stub for: _NSLog
CXX-EXE: 00000001000014cb callq __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
// FIXME: Demangler depends on host's <cxxabi.h>.
// std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char)
CXX-EXE: 00000001000014cb callq __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_ ## std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char)
i386-OBJ: 0000002f calll _printf

View File

@ -0,0 +1,7 @@
set(LLVM_LINK_COMPONENTS
Demangle
)
add_llvm_tool(llvm-cxxfilt
llvm-cxxfilt.cpp
)

View File

@ -0,0 +1,29 @@
//===-- llvm-c++filt.cpp --------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Demangle/Demangle.h"
#include <stdio.h>
#include <stdlib.h>
using namespace llvm;
int main(int argc, char **argv) {
for (int I = 1; I < argc; ++I) {
const char *Mangled = argv[I];
int Status;
char *Demangled = itaniumDemangle(Mangled, nullptr, nullptr, &Status);
if (Demangled)
printf("%s\n", Demangled);
else
printf("%s\n", Mangled);
free(Demangled);
}
return 0;
}

View File

@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
CodeGen
DebugInfoDWARF
DebugInfoPDB
Demangle
MC
MCDisassembler
Object

View File

@ -19,4 +19,4 @@
type = Tool
name = llvm-objdump
parent = Tools
required_libraries = DebugInfoDWARF MC MCDisassembler MCParser Object all-targets
required_libraries = DebugInfoDWARF MC MCDisassembler MCParser Object all-targets Demangle

View File

@ -20,6 +20,7 @@
#include "llvm/Config/config.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
@ -48,10 +49,6 @@
#include <cstring>
#include <system_error>
#if HAVE_CXXABI_H
#include <cxxabi.h>
#endif
#ifdef HAVE_LIBXAR
extern "C" {
#include <xar/xar.h>
@ -6235,11 +6232,9 @@ static const char *GuessLiteralPointer(uint64_t ReferenceValue,
// Out type and the ReferenceName will also be set which is added as a comment
// to the disassembled instruction.
//
#if HAVE_CXXABI_H
// If the symbol name is a C++ mangled name then the demangled name is
// returned through ReferenceName and ReferenceType is set to
// LLVMDisassembler_ReferenceType_DeMangled_Name .
#endif
//
// When this is called to get a symbol name for a branch target then the
// ReferenceType will be LLVMDisassembler_ReferenceType_In_Branch and then
@ -6274,21 +6269,18 @@ static const char *SymbolizerSymbolLookUp(void *DisInfo,
method_reference(info, ReferenceType, ReferenceName);
if (*ReferenceType != LLVMDisassembler_ReferenceType_Out_Objc_Message)
*ReferenceType = LLVMDisassembler_ReferenceType_Out_SymbolStub;
} else
#if HAVE_CXXABI_H
if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
} else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
if (info->demangled_name != nullptr)
free(info->demangled_name);
int status;
info->demangled_name =
abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
if (info->demangled_name != nullptr) {
*ReferenceName = info->demangled_name;
*ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
} else
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
} else
#endif
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
} else if (*ReferenceType == LLVMDisassembler_ReferenceType_In_PCrel_Load) {
*ReferenceName =
@ -6377,20 +6369,17 @@ static const char *SymbolizerSymbolLookUp(void *DisInfo,
GuessLiteralPointer(ReferenceValue, ReferencePC, ReferenceType, info);
if (*ReferenceName == nullptr)
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
}
#if HAVE_CXXABI_H
else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
} else if (SymbolName != nullptr && strncmp(SymbolName, "__Z", 3) == 0) {
if (info->demangled_name != nullptr)
free(info->demangled_name);
int status;
info->demangled_name =
abi::__cxa_demangle(SymbolName + 1, nullptr, nullptr, &status);
itaniumDemangle(SymbolName + 1, nullptr, nullptr, &status);
if (info->demangled_name != nullptr) {
*ReferenceName = info->demangled_name;
*ReferenceType = LLVMDisassembler_ReferenceType_DeMangled_Name;
}
}
#endif
else {
*ReferenceName = nullptr;
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;