├── .gitignore ├── README.md ├── XCppfilt.pro ├── xcppfilt.cmake ├── xcppfilt.pri ├── 3rdparty └── cppfilt │ ├── cppfilt.pri │ ├── src │ ├── xstrdup.c │ ├── environ.h │ ├── xexit.c │ ├── xmalloc.c │ ├── safe-ctype.h │ ├── cp-demangle.h │ ├── safe-ctype.c │ ├── cplus-dem.c │ ├── ansidecl.h │ ├── demangle.h │ ├── libiberty.h │ └── rust-demangle.c │ └── cppfilt.pro ├── LICENSE ├── CMakeLists.txt ├── xcppfilt.h └── xcppfilt.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | 3rdparty/cppfilt/libs 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XCppfilt 2 | C++ demangler GNU V3 3 | Java demangler 4 | Rust demangler 5 | -------------------------------------------------------------------------------- /XCppfilt.pro: -------------------------------------------------------------------------------- 1 | # build libs 2 | TEMPLATE = subdirs 3 | SUBDIRS += 3rdparty/cppfilt -------------------------------------------------------------------------------- /xcppfilt.cmake: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_CURRENT_LIST_DIR}) 2 | include_directories(${CMAKE_CURRENT_LIST_DIR}/3rdparty/cppfilt/src/) 3 | 4 | set(XCPPFILT_SOURCES 5 | ${XCPPFILT_SOURCES} 6 | ${CMAKE_CURRENT_LIST_DIR}/xcppfilt.cpp 7 | ${CMAKE_CURRENT_LIST_DIR}/xcppfilt.h 8 | ) 9 | -------------------------------------------------------------------------------- /xcppfilt.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | DEPENDPATH += $$PWD 3 | 4 | HEADERS += \ 5 | $$PWD/xcppfilt.h 6 | 7 | SOURCES += \ 8 | $$PWD/xcppfilt.cpp 9 | 10 | !contains(XCONFIG, cppfilt) { 11 | XCONFIG += cppfilt 12 | include($$PWD/3rdparty/cppfilt/cppfilt.pri) 13 | } 14 | 15 | DISTFILES += \ 16 | $$PWD/LICENSE \ 17 | $$PWD/README.md \ 18 | $$PWD/xcppfilt.cmake 19 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/cppfilt.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD/src 2 | DEPENDPATH += $$PWD/src 3 | 4 | win32-g++ { 5 | LIBS += $$PWD/libs/libcppfilt-win-$${QT_ARCH}.a 6 | } 7 | win32-msvc* { 8 | LIBS += $$PWD/libs/cppfilt-win-$${QT_ARCH}.lib 9 | } 10 | unix:!macx { 11 | LIBS += $$PWD/libs/libcppfilt-unix-$${QT_ARCH}.a 12 | } 13 | unix:macx { 14 | LIBS += $$PWD/libs/libcppfilt-macos-$${QT_ARCH}.a 15 | } 16 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/xstrdup.c: -------------------------------------------------------------------------------- 1 | /* xstrdup.c -- Duplicate a string in memory, using xmalloc. 2 | This trivial function is in the public domain. 3 | Ian Lance Taylor, Cygnus Support, December 1995. */ 4 | 5 | /* 6 | 7 | @deftypefn Replacement char* xstrdup (const char *@var{s}) 8 | 9 | Duplicates a character string without fail, using @code{xmalloc} to 10 | obtain memory. 11 | 12 | @end deftypefn 13 | 14 | */ 15 | 16 | #ifdef HAVE_CONFIG_H 17 | #include "config.h" 18 | #endif 19 | #include 20 | #ifdef HAVE_STRING_H 21 | #include 22 | #else 23 | # ifdef HAVE_STRINGS_H 24 | # include 25 | # endif 26 | #endif 27 | #include "ansidecl.h" 28 | #include "libiberty.h" 29 | 30 | char * 31 | xstrdup (const char *s) 32 | { 33 | register size_t len = strlen (s) + 1; 34 | register char *ret = XNEWVEC (char, len); 35 | return (char *) memcpy (ret, s, len); 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2025 hors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/cppfilt.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2019-02-01T10:50:10 4 | # 5 | #------------------------------------------------- 6 | 7 | QT -= core gui 8 | 9 | TARGET = cppfilt 10 | TEMPLATE = lib 11 | CONFIG += staticlib 12 | 13 | include(../../build.pri) 14 | 15 | win32{ 16 | TARGET = cppfilt-win-$${QT_ARCH} 17 | } 18 | unix:!macx { 19 | TARGET = cppfilt-unix-$${QT_ARCH} 20 | } 21 | unix:macx { 22 | TARGET = cppfilt-macos-$${QT_ARCH} 23 | } 24 | 25 | DEFINES += "HAVE_STDLIB_H" 26 | DEFINES += "HAVE_STRING_H" 27 | 28 | INCLUDEPATH += $$PWD/src 29 | DEPENDPATH += $$PWD/src 30 | 31 | SOURCES += \ 32 | src/cp-demangle.c \ 33 | src/cplus-dem.c \ 34 | src/d-demangle.c \ 35 | src/rust-demangle.c \ 36 | src/safe-ctype.c \ 37 | src/xexit.c \ 38 | src/xmalloc.c \ 39 | src/xstrdup.c 40 | 41 | HEADERS += \ 42 | src/ansidecl.h \ 43 | src/cp-demangle.h \ 44 | src/demangle.h \ 45 | src/environ.h \ 46 | src/libiberty.h \ 47 | src/safe-ctype.h 48 | 49 | TARGETLIB_PATH = $$PWD 50 | 51 | DESTDIR=$${TARGETLIB_PATH}/libs -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/environ.h: -------------------------------------------------------------------------------- 1 | /* Declare the environ system variable. 2 | Copyright (C) 2015-2021 Free Software Foundation, Inc. 3 | 4 | This file is part of the libiberty library. 5 | Libiberty is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Library General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | Libiberty is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Library General Public License for more details. 14 | 15 | You should have received a copy of the GNU Library General Public 16 | License along with libiberty; see the file COPYING.LIB. If not, 17 | write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 18 | Boston, MA 02110-1301, USA. */ 19 | 20 | /* On OSX, the environ variable can be used directly in the code of an 21 | executable, but cannot be used in the code of a shared library (such as 22 | GCC's liblto_plugin, which links in libiberty code). Instead, the 23 | function _NSGetEnviron can be called to get the address of environ. */ 24 | 25 | #ifndef HAVE_ENVIRON_DECL 26 | # ifdef __APPLE__ 27 | # include 28 | # define environ (*_NSGetEnviron ()) 29 | # else 30 | # ifndef environ 31 | extern char **environ; 32 | # endif 33 | # endif 34 | # define HAVE_ENVIRON_DECL 35 | #endif 36 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | 3 | project(cppfilt LANGUAGES C) 4 | 5 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 6 | set(CMAKE_CXX_STANDARD 11) 7 | set(CMAKE_C_STANDARD 11) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 10 | 11 | message(${PROJECT_SOURCE_DIR}) 12 | 13 | add_definitions( 14 | -DHAVE_STDLIB_H 15 | -DHAVE_STRING_H 16 | ) 17 | 18 | include_directories(${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/) 19 | 20 | add_library(cppfilt STATIC 21 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/cp-demangle.c 22 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/cplus-dem.c 23 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/d-demangle.c 24 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/rust-demangle.c 25 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/safe-ctype.c 26 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/xexit.c 27 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/xmalloc.c 28 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/xstrdup.c 29 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/ansidecl.h 30 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/cp-demangle.h 31 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/demangle.h 32 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/environ.h 33 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/libiberty.h 34 | ${PROJECT_SOURCE_DIR}/3rdparty/cppfilt/src/safe-ctype.h 35 | ) 36 | 37 | set_target_properties(cppfilt PROPERTIES LINKER_LANGUAGE C) 38 | set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) 39 | 40 | if(MSVC) 41 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) 42 | endif() 43 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/xexit.c: -------------------------------------------------------------------------------- 1 | /* xexit.c -- Run any exit handlers, then exit. 2 | Copyright (C) 1994-2021 Free Software Foundation, Inc. 3 | 4 | This file is part of the libiberty library. 5 | Libiberty is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Library General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | Libiberty is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Library General Public License for more details. 14 | 15 | You should have received a copy of the GNU Library General Public 16 | License along with libiberty; see the file COPYING.LIB. If not, write 17 | to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 18 | Boston, MA 02110-1301, USA. */ 19 | 20 | /* 21 | 22 | @deftypefn Replacement void xexit (int @var{code}) 23 | 24 | Terminates the program. If any functions have been registered with 25 | the @code{xatexit} replacement function, they will be called first. 26 | Termination is handled via the system's normal @code{exit} call. 27 | 28 | @end deftypefn 29 | 30 | */ 31 | 32 | #ifdef HAVE_CONFIG_H 33 | #include "config.h" 34 | #endif 35 | #include 36 | #ifdef HAVE_STDLIB_H 37 | #include 38 | #endif 39 | #include "libiberty.h" 40 | 41 | 42 | /* This variable is set by xatexit if it is called. This way, xmalloc 43 | doesn't drag xatexit into the link. */ 44 | void (*_xexit_cleanup) (void); 45 | 46 | void 47 | xexit (int code) 48 | { 49 | if (_xexit_cleanup != NULL) 50 | (*_xexit_cleanup) (); 51 | exit (code); 52 | } 53 | -------------------------------------------------------------------------------- /xcppfilt.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2021-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #ifndef XCPPFILT_H 22 | #define XCPPFILT_H 23 | 24 | #include 25 | #include 26 | 27 | #include "demangle.h" 28 | 29 | class XCppfilt : public QObject { 30 | Q_OBJECT 31 | 32 | public: 33 | explicit XCppfilt(QObject *pParent = nullptr); 34 | 35 | static QString demangleGnuV3(const QString &sString); 36 | static QString demangleJavaV3(const QString &sString); 37 | static QString demangleRust(const QString &sString); 38 | static QString demangleGNAT(const QString &sString); 39 | static QString demangleDLANG(const QString &sString); 40 | }; 41 | 42 | #endif // XCPPFILT_H 43 | -------------------------------------------------------------------------------- /xcppfilt.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2021-2025 hors 2 | * 3 | * Permission is hereby granted, free of charge, to any person obtaining a copy 4 | * of this software and associated documentation files (the "Software"), to deal 5 | * in the Software without restriction, including without limitation the rights 6 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | * copies of the Software, and to permit persons to whom the Software is 8 | * furnished to do so, subject to the following conditions: 9 | * 10 | * The above copyright notice and this permission notice shall be included in all 11 | * copies or substantial portions of the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | * SOFTWARE. 20 | */ 21 | #include "xcppfilt.h" 22 | 23 | XCppfilt::XCppfilt(QObject *pParent) : QObject(pParent) 24 | { 25 | } 26 | 27 | QString XCppfilt::demangleGnuV3(const QString &sString) 28 | { 29 | QString sResult; 30 | 31 | char *pResult = cplus_demangle_v3(sString.toUtf8().data(), (DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES)); // TODO Check params !!! 32 | 33 | sResult = pResult; 34 | 35 | free(pResult); 36 | 37 | return sResult; 38 | } 39 | 40 | QString XCppfilt::demangleJavaV3(const QString &sString) 41 | { 42 | QString sResult; 43 | 44 | char *pResult = java_demangle_v3(sString.toUtf8().data()); 45 | 46 | sResult = pResult; 47 | 48 | free(pResult); 49 | 50 | return sResult; 51 | } 52 | 53 | QString XCppfilt::demangleRust(const QString &sString) 54 | { 55 | QString sResult; 56 | 57 | char *pResult = rust_demangle(sString.toUtf8().data(), (DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES)); 58 | 59 | sResult = pResult; 60 | 61 | free(pResult); 62 | 63 | return sResult; 64 | } 65 | 66 | QString XCppfilt::demangleGNAT(const QString &sString) 67 | { 68 | QString sResult; 69 | 70 | char *pResult = ada_demangle(sString.toUtf8().data(), 0); 71 | 72 | sResult = pResult; 73 | 74 | free(pResult); 75 | 76 | return sResult; 77 | } 78 | 79 | QString XCppfilt::demangleDLANG(const QString &sString) 80 | { 81 | QString sResult; 82 | 83 | char *pResult = dlang_demangle(sString.toUtf8().data(), 0); 84 | 85 | sResult = pResult; 86 | 87 | free(pResult); 88 | 89 | return sResult; 90 | } 91 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/xmalloc.c: -------------------------------------------------------------------------------- 1 | /* memory allocation routines with error checking. 2 | Copyright (C) 1989-2021 Free Software Foundation, Inc. 3 | 4 | This file is part of the libiberty library. 5 | Libiberty is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Library General Public 7 | License as published by the Free Software Foundation; either 8 | version 2 of the License, or (at your option) any later version. 9 | 10 | Libiberty is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Library General Public License for more details. 14 | 15 | You should have received a copy of the GNU Library General Public 16 | License along with libiberty; see the file COPYING.LIB. If 17 | not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 18 | Boston, MA 02110-1301, USA. */ 19 | 20 | /* 21 | 22 | @deftypefn Replacement void* xmalloc (size_t) 23 | 24 | Allocate memory without fail. If @code{malloc} fails, this will print 25 | a message to @code{stderr} (using the name set by 26 | @code{xmalloc_set_program_name}, 27 | if any) and then call @code{xexit}. Note that it is therefore safe for 28 | a program to contain @code{#define malloc xmalloc} in its source. 29 | 30 | @end deftypefn 31 | 32 | @deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size}) 33 | Reallocate memory without fail. This routine functions like @code{realloc}, 34 | but will behave the same as @code{xmalloc} if memory cannot be found. 35 | 36 | @end deftypefn 37 | 38 | @deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize}) 39 | 40 | Allocate memory without fail, and set it to zero. This routine functions 41 | like @code{calloc}, but will behave the same as @code{xmalloc} if memory 42 | cannot be found. 43 | 44 | @end deftypefn 45 | 46 | @deftypefn Replacement void xmalloc_set_program_name (const char *@var{name}) 47 | 48 | You can use this to set the name of the program used by 49 | @code{xmalloc_failed} when printing a failure message. 50 | 51 | @end deftypefn 52 | 53 | @deftypefn Replacement void xmalloc_failed (size_t) 54 | 55 | This function is not meant to be called by client code, and is listed 56 | here for completeness only. If any of the allocation routines fail, this 57 | function will be called to print an error message and terminate execution. 58 | 59 | @end deftypefn 60 | 61 | */ 62 | 63 | #ifdef HAVE_CONFIG_H 64 | #include "config.h" 65 | #endif 66 | #include "ansidecl.h" 67 | #include "libiberty.h" 68 | #include "environ.h" 69 | 70 | #include 71 | 72 | #include 73 | 74 | #if VMS 75 | #include 76 | #include 77 | #else 78 | /* For systems with larger pointers than ints, these must be declared. */ 79 | # if HAVE_STDLIB_H && HAVE_UNISTD_H && HAVE_DECL_MALLOC \ 80 | && HAVE_DECL_REALLOC && HAVE_DECL_CALLOC && HAVE_DECL_SBRK 81 | # include 82 | # include 83 | # else 84 | # ifdef __cplusplus 85 | extern "C" { 86 | # endif /* __cplusplus */ 87 | void *malloc (size_t); 88 | void *realloc (void *, size_t); 89 | void *calloc (size_t, size_t); 90 | void *sbrk (ptrdiff_t); 91 | # ifdef __cplusplus 92 | } 93 | # endif /* __cplusplus */ 94 | # endif /* HAVE_STDLIB_H ... */ 95 | #endif /* VMS */ 96 | 97 | /* The program name if set. */ 98 | static const char *name = ""; 99 | 100 | #ifdef HAVE_SBRK 101 | /* The initial sbrk, set when the program name is set. Not used for win32 102 | ports other than cygwin32. */ 103 | static char *first_break = NULL; 104 | #endif /* HAVE_SBRK */ 105 | 106 | void 107 | xmalloc_set_program_name (const char *s) 108 | { 109 | name = s; 110 | #ifdef HAVE_SBRK 111 | /* Win32 ports other than cygwin32 don't have brk() */ 112 | if (first_break == NULL) 113 | first_break = (char *) sbrk (0); 114 | #endif /* HAVE_SBRK */ 115 | } 116 | 117 | void 118 | xmalloc_failed (size_t size) 119 | { 120 | #ifdef HAVE_SBRK 121 | size_t allocated; 122 | 123 | if (first_break != NULL) 124 | allocated = (char *) sbrk (0) - first_break; 125 | else 126 | allocated = (char *) sbrk (0) - (char *) &environ; 127 | fprintf (stderr, 128 | "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n", 129 | name, *name ? ": " : "", 130 | (unsigned long) size, (unsigned long) allocated); 131 | #else /* HAVE_SBRK */ 132 | fprintf (stderr, 133 | "\n%s%sout of memory allocating %lu bytes\n", 134 | name, *name ? ": " : "", 135 | (unsigned long) size); 136 | #endif /* HAVE_SBRK */ 137 | xexit (1); 138 | } 139 | 140 | PTR 141 | xmalloc (size_t size) 142 | { 143 | PTR newmem; 144 | 145 | if (size == 0) 146 | size = 1; 147 | newmem = malloc (size); 148 | if (!newmem) 149 | xmalloc_failed (size); 150 | 151 | return (newmem); 152 | } 153 | 154 | PTR 155 | xcalloc (size_t nelem, size_t elsize) 156 | { 157 | PTR newmem; 158 | 159 | if (nelem == 0 || elsize == 0) 160 | nelem = elsize = 1; 161 | 162 | newmem = calloc (nelem, elsize); 163 | if (!newmem) 164 | xmalloc_failed (nelem * elsize); 165 | 166 | return (newmem); 167 | } 168 | 169 | PTR 170 | xrealloc (PTR oldmem, size_t size) 171 | { 172 | PTR newmem; 173 | 174 | if (size == 0) 175 | size = 1; 176 | if (!oldmem) 177 | newmem = malloc (size); 178 | else 179 | newmem = realloc (oldmem, size); 180 | if (!newmem) 181 | xmalloc_failed (size); 182 | 183 | return (newmem); 184 | } 185 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/safe-ctype.h: -------------------------------------------------------------------------------- 1 | /* replacement macros. 2 | 3 | Copyright (C) 2000-2021 Free Software Foundation, Inc. 4 | Contributed by Zack Weinberg . 5 | 6 | This file is part of the libiberty library. 7 | Libiberty is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | Libiberty is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with libiberty; see the file COPYING.LIB. If 19 | not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 20 | Boston, MA 02110-1301, USA. */ 21 | 22 | /* This is a compatible replacement of the standard C library's 23 | with the following properties: 24 | 25 | - Implements all isxxx() macros required by C99. 26 | - Also implements some character classes useful when 27 | parsing C-like languages. 28 | - Does not change behavior depending on the current locale. 29 | - Behaves properly for all values in the range of a signed or 30 | unsigned char. 31 | 32 | To avoid conflicts, this header defines the isxxx functions in upper 33 | case, e.g. ISALPHA not isalpha. */ 34 | 35 | #ifndef SAFE_CTYPE_H 36 | #define SAFE_CTYPE_H 37 | 38 | /* Determine host character set. */ 39 | #define HOST_CHARSET_UNKNOWN 0 40 | #define HOST_CHARSET_ASCII 1 41 | #define HOST_CHARSET_EBCDIC 2 42 | 43 | #if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ 44 | && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 45 | # define HOST_CHARSET HOST_CHARSET_ASCII 46 | #else 47 | # if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \ 48 | && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A 49 | # define HOST_CHARSET HOST_CHARSET_EBCDIC 50 | # else 51 | # define HOST_CHARSET HOST_CHARSET_UNKNOWN 52 | # endif 53 | #endif 54 | 55 | /* Categories. */ 56 | 57 | enum { 58 | /* In C99 */ 59 | _sch_isblank = 0x0001, /* space \t */ 60 | _sch_iscntrl = 0x0002, /* nonprinting characters */ 61 | _sch_isdigit = 0x0004, /* 0-9 */ 62 | _sch_islower = 0x0008, /* a-z */ 63 | _sch_isprint = 0x0010, /* any printing character including ' ' */ 64 | _sch_ispunct = 0x0020, /* all punctuation */ 65 | _sch_isspace = 0x0040, /* space \t \n \r \f \v */ 66 | _sch_isupper = 0x0080, /* A-Z */ 67 | _sch_isxdigit = 0x0100, /* 0-9A-Fa-f */ 68 | 69 | /* Extra categories useful to cpplib. */ 70 | _sch_isidst = 0x0200, /* A-Za-z_ */ 71 | _sch_isvsp = 0x0400, /* \n \r */ 72 | _sch_isnvsp = 0x0800, /* space \t \f \v \0 */ 73 | 74 | /* Combinations of the above. */ 75 | _sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */ 76 | _sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */ 77 | _sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */ 78 | _sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */ 79 | _sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */ 80 | _sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C 81 | (plus ` and @) */ 82 | }; 83 | 84 | /* Character classification. */ 85 | extern const unsigned short _sch_istable[256]; 86 | 87 | #define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit)) 88 | 89 | #define ISALPHA(c) _sch_test(c, _sch_isalpha) 90 | #define ISALNUM(c) _sch_test(c, _sch_isalnum) 91 | #define ISBLANK(c) _sch_test(c, _sch_isblank) 92 | #define ISCNTRL(c) _sch_test(c, _sch_iscntrl) 93 | #define ISDIGIT(c) _sch_test(c, _sch_isdigit) 94 | #define ISGRAPH(c) _sch_test(c, _sch_isgraph) 95 | #define ISLOWER(c) _sch_test(c, _sch_islower) 96 | #define ISPRINT(c) _sch_test(c, _sch_isprint) 97 | #define ISPUNCT(c) _sch_test(c, _sch_ispunct) 98 | #define ISSPACE(c) _sch_test(c, _sch_isspace) 99 | #define ISUPPER(c) _sch_test(c, _sch_isupper) 100 | #define ISXDIGIT(c) _sch_test(c, _sch_isxdigit) 101 | 102 | #define ISIDNUM(c) _sch_test(c, _sch_isidnum) 103 | #define ISIDST(c) _sch_test(c, _sch_isidst) 104 | #define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic) 105 | #define IS_VSPACE(c) _sch_test(c, _sch_isvsp) 106 | #define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp) 107 | #define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp) 108 | 109 | /* Character transformation. */ 110 | extern const unsigned char _sch_toupper[256]; 111 | extern const unsigned char _sch_tolower[256]; 112 | #define TOUPPER(c) _sch_toupper[(c) & 0xff] 113 | #define TOLOWER(c) _sch_tolower[(c) & 0xff] 114 | 115 | /* Prevent the users of safe-ctype.h from accidently using the routines 116 | from ctype.h. Initially, the approach was to produce an error when 117 | detecting that ctype.h has been included. But this was causing 118 | trouble as ctype.h might get indirectly included as a result of 119 | including another system header (for instance gnulib's stdint.h). 120 | So we include ctype.h here and then immediately redefine its macros. */ 121 | 122 | #include 123 | #undef isalpha 124 | #define isalpha(c) do_not_use_isalpha_with_safe_ctype 125 | #undef isalnum 126 | #define isalnum(c) do_not_use_isalnum_with_safe_ctype 127 | #undef iscntrl 128 | #define iscntrl(c) do_not_use_iscntrl_with_safe_ctype 129 | #undef isdigit 130 | #define isdigit(c) do_not_use_isdigit_with_safe_ctype 131 | #undef isgraph 132 | #define isgraph(c) do_not_use_isgraph_with_safe_ctype 133 | #undef islower 134 | #define islower(c) do_not_use_islower_with_safe_ctype 135 | #undef isprint 136 | #define isprint(c) do_not_use_isprint_with_safe_ctype 137 | #undef ispunct 138 | #define ispunct(c) do_not_use_ispunct_with_safe_ctype 139 | #undef isspace 140 | #define isspace(c) do_not_use_isspace_with_safe_ctype 141 | #undef isupper 142 | #define isupper(c) do_not_use_isupper_with_safe_ctype 143 | #undef isxdigit 144 | #define isxdigit(c) do_not_use_isxdigit_with_safe_ctype 145 | #undef toupper 146 | #define toupper(c) do_not_use_toupper_with_safe_ctype 147 | #undef tolower 148 | #define tolower(c) do_not_use_tolower_with_safe_ctype 149 | 150 | #endif /* SAFE_CTYPE_H */ 151 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/cp-demangle.h: -------------------------------------------------------------------------------- 1 | /* Internal demangler interface for g++ V3 ABI. 2 | Copyright (C) 2003-2021 Free Software Foundation, Inc. 3 | Written by Ian Lance Taylor . 4 | 5 | This file is part of the libiberty library, which is part of GCC. 6 | 7 | This file is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | In addition to the permissions in the GNU General Public License, the 13 | Free Software Foundation gives you unlimited permission to link the 14 | compiled version of this file into combinations with other programs, 15 | and to distribute those combinations without any restriction coming 16 | from the use of this file. (The General Public License restrictions 17 | do apply in other respects; for example, they cover modification of 18 | the file, and distribution when not linked into a combined 19 | executable.) 20 | 21 | This program is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | You should have received a copy of the GNU General Public License 27 | along with this program; if not, write to the Free Software 28 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 29 | */ 30 | 31 | /* This file provides some definitions shared by cp-demangle.c and 32 | cp-demint.c. It should not be included by any other files. */ 33 | 34 | /* Information we keep for operators. */ 35 | 36 | struct demangle_operator_info 37 | { 38 | /* Mangled name. */ 39 | const char *code; 40 | /* Real name. */ 41 | const char *name; 42 | /* Length of real name. */ 43 | int len; 44 | /* Number of arguments. */ 45 | int args; 46 | }; 47 | 48 | /* How to print the value of a builtin type. */ 49 | 50 | enum d_builtin_type_print 51 | { 52 | /* Print as (type)val. */ 53 | D_PRINT_DEFAULT, 54 | /* Print as integer. */ 55 | D_PRINT_INT, 56 | /* Print as unsigned integer, with trailing "u". */ 57 | D_PRINT_UNSIGNED, 58 | /* Print as long, with trailing "l". */ 59 | D_PRINT_LONG, 60 | /* Print as unsigned long, with trailing "ul". */ 61 | D_PRINT_UNSIGNED_LONG, 62 | /* Print as long long, with trailing "ll". */ 63 | D_PRINT_LONG_LONG, 64 | /* Print as unsigned long long, with trailing "ull". */ 65 | D_PRINT_UNSIGNED_LONG_LONG, 66 | /* Print as bool. */ 67 | D_PRINT_BOOL, 68 | /* Print as float--put value in square brackets. */ 69 | D_PRINT_FLOAT, 70 | /* Print in usual way, but here to detect void. */ 71 | D_PRINT_VOID 72 | }; 73 | 74 | /* Information we keep for a builtin type. */ 75 | 76 | struct demangle_builtin_type_info 77 | { 78 | /* Type name. */ 79 | const char *name; 80 | /* Length of type name. */ 81 | int len; 82 | /* Type name when using Java. */ 83 | const char *java_name; 84 | /* Length of java name. */ 85 | int java_len; 86 | /* How to print a value of this type. */ 87 | enum d_builtin_type_print print; 88 | }; 89 | 90 | /* The information structure we pass around. */ 91 | 92 | struct d_info 93 | { 94 | /* The string we are demangling. */ 95 | const char *s; 96 | /* The end of the string we are demangling. */ 97 | const char *send; 98 | /* The options passed to the demangler. */ 99 | int options; 100 | /* The next character in the string to consider. */ 101 | const char *n; 102 | /* The array of components. */ 103 | struct demangle_component *comps; 104 | /* The index of the next available component. */ 105 | int next_comp; 106 | /* The number of available component structures. */ 107 | int num_comps; 108 | /* The array of substitutions. */ 109 | struct demangle_component **subs; 110 | /* The index of the next substitution. */ 111 | int next_sub; 112 | /* The number of available entries in the subs array. */ 113 | int num_subs; 114 | /* The last name we saw, for constructors and destructors. */ 115 | struct demangle_component *last_name; 116 | /* A running total of the length of large expansions from the 117 | mangled name to the demangled name, such as standard 118 | substitutions and builtin types. */ 119 | int expansion; 120 | /* Non-zero if we are parsing an expression. */ 121 | int is_expression; 122 | /* Non-zero if we are parsing the type operand of a conversion 123 | operator, but not when in an expression. */ 124 | int is_conversion; 125 | /* 1: using new unresolved-name grammar. 126 | -1: using new unresolved-name grammar and saw an unresolved-name. 127 | 0: using old unresolved-name grammar. */ 128 | int unresolved_name_state; 129 | /* If DMGL_NO_RECURSE_LIMIT is not active then this is set to 130 | the current recursion level. */ 131 | unsigned int recursion_level; 132 | }; 133 | 134 | /* To avoid running past the ending '\0', don't: 135 | - call d_peek_next_char if d_peek_char returned '\0' 136 | - call d_advance with an 'i' that is too large 137 | - call d_check_char(di, '\0') 138 | Everything else is safe. */ 139 | #define d_peek_char(di) (*((di)->n)) 140 | #ifndef CHECK_DEMANGLER 141 | # define d_peek_next_char(di) ((di)->n[1]) 142 | # define d_advance(di, i) ((di)->n += (i)) 143 | #endif 144 | #define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0) 145 | #define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++)) 146 | #define d_str(di) ((di)->n) 147 | 148 | #ifdef CHECK_DEMANGLER 149 | static inline char 150 | d_peek_next_char (const struct d_info *di) 151 | { 152 | if (!di->n[0]) 153 | abort (); 154 | return di->n[1]; 155 | } 156 | 157 | static inline void 158 | d_advance (struct d_info *di, int i) 159 | { 160 | if (i < 0) 161 | abort (); 162 | while (i--) 163 | { 164 | if (!di->n[0]) 165 | abort (); 166 | di->n++; 167 | } 168 | } 169 | #endif 170 | 171 | /* Functions and arrays in cp-demangle.c which are referenced by 172 | functions in cp-demint.c. */ 173 | #ifdef IN_GLIBCPP_V3 174 | #define CP_STATIC_IF_GLIBCPP_V3 static 175 | #else 176 | #define CP_STATIC_IF_GLIBCPP_V3 extern 177 | #endif 178 | 179 | #ifndef IN_GLIBCPP_V3 180 | extern const struct demangle_operator_info cplus_demangle_operators[]; 181 | #endif 182 | 183 | #define D_BUILTIN_TYPE_COUNT (34) 184 | 185 | CP_STATIC_IF_GLIBCPP_V3 186 | const struct demangle_builtin_type_info 187 | cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT]; 188 | 189 | CP_STATIC_IF_GLIBCPP_V3 190 | struct demangle_component * 191 | cplus_demangle_mangled_name (struct d_info *, int); 192 | 193 | CP_STATIC_IF_GLIBCPP_V3 194 | struct demangle_component * 195 | cplus_demangle_type (struct d_info *); 196 | 197 | extern void 198 | cplus_demangle_init_info (const char *, int, size_t, struct d_info *); 199 | 200 | /* cp-demangle.c needs to define this a little differently */ 201 | #undef CP_STATIC_IF_GLIBCPP_V3 202 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/safe-ctype.c: -------------------------------------------------------------------------------- 1 | /* replacement macros. 2 | 3 | Copyright (C) 2000-2021 Free Software Foundation, Inc. 4 | Contributed by Zack Weinberg . 5 | 6 | This file is part of the libiberty library. 7 | Libiberty is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | Libiberty is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Library General Public License for more details. 16 | 17 | You should have received a copy of the GNU Library General Public 18 | License along with libiberty; see the file COPYING.LIB. If 19 | not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 20 | Boston, MA 02110-1301, USA. */ 21 | 22 | /* 23 | 24 | @defvr Extension HOST_CHARSET 25 | This macro indicates the basic character set and encoding used by the 26 | host: more precisely, the encoding used for character constants in 27 | preprocessor @samp{#if} statements (the C "execution character set"). 28 | It is defined by @file{safe-ctype.h}, and will be an integer constant 29 | with one of the following values: 30 | 31 | @ftable @code 32 | @item HOST_CHARSET_UNKNOWN 33 | The host character set is unknown - that is, not one of the next two 34 | possibilities. 35 | 36 | @item HOST_CHARSET_ASCII 37 | The host character set is ASCII. 38 | 39 | @item HOST_CHARSET_EBCDIC 40 | The host character set is some variant of EBCDIC. (Only one of the 41 | nineteen EBCDIC varying characters is tested; exercise caution.) 42 | @end ftable 43 | @end defvr 44 | 45 | @deffn Extension ISALPHA (@var{c}) 46 | @deffnx Extension ISALNUM (@var{c}) 47 | @deffnx Extension ISBLANK (@var{c}) 48 | @deffnx Extension ISCNTRL (@var{c}) 49 | @deffnx Extension ISDIGIT (@var{c}) 50 | @deffnx Extension ISGRAPH (@var{c}) 51 | @deffnx Extension ISLOWER (@var{c}) 52 | @deffnx Extension ISPRINT (@var{c}) 53 | @deffnx Extension ISPUNCT (@var{c}) 54 | @deffnx Extension ISSPACE (@var{c}) 55 | @deffnx Extension ISUPPER (@var{c}) 56 | @deffnx Extension ISXDIGIT (@var{c}) 57 | 58 | These twelve macros are defined by @file{safe-ctype.h}. Each has the 59 | same meaning as the corresponding macro (with name in lowercase) 60 | defined by the standard header @file{ctype.h}. For example, 61 | @code{ISALPHA} returns true for alphabetic characters and false for 62 | others. However, there are two differences between these macros and 63 | those provided by @file{ctype.h}: 64 | 65 | @itemize @bullet 66 | @item These macros are guaranteed to have well-defined behavior for all 67 | values representable by @code{signed char} and @code{unsigned char}, and 68 | for @code{EOF}. 69 | 70 | @item These macros ignore the current locale; they are true for these 71 | fixed sets of characters: 72 | @multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada} 73 | @item @code{ALPHA} @tab @kbd{A-Za-z} 74 | @item @code{ALNUM} @tab @kbd{A-Za-z0-9} 75 | @item @code{BLANK} @tab @kbd{space tab} 76 | @item @code{CNTRL} @tab @code{!PRINT} 77 | @item @code{DIGIT} @tab @kbd{0-9} 78 | @item @code{GRAPH} @tab @code{ALNUM || PUNCT} 79 | @item @code{LOWER} @tab @kbd{a-z} 80 | @item @code{PRINT} @tab @code{GRAPH ||} @kbd{space} 81 | @item @code{PUNCT} @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?} 82 | @item @code{SPACE} @tab @kbd{space tab \n \r \f \v} 83 | @item @code{UPPER} @tab @kbd{A-Z} 84 | @item @code{XDIGIT} @tab @kbd{0-9A-Fa-f} 85 | @end multitable 86 | 87 | Note that, if the host character set is ASCII or a superset thereof, 88 | all these macros will return false for all values of @code{char} outside 89 | the range of 7-bit ASCII. In particular, both ISPRINT and ISCNTRL return 90 | false for characters with numeric values from 128 to 255. 91 | @end itemize 92 | @end deffn 93 | 94 | @deffn Extension ISIDNUM (@var{c}) 95 | @deffnx Extension ISIDST (@var{c}) 96 | @deffnx Extension IS_VSPACE (@var{c}) 97 | @deffnx Extension IS_NVSPACE (@var{c}) 98 | @deffnx Extension IS_SPACE_OR_NUL (@var{c}) 99 | @deffnx Extension IS_ISOBASIC (@var{c}) 100 | These six macros are defined by @file{safe-ctype.h} and provide 101 | additional character classes which are useful when doing lexical 102 | analysis of C or similar languages. They are true for the following 103 | sets of characters: 104 | 105 | @multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada} 106 | @item @code{IDNUM} @tab @kbd{A-Za-z0-9_} 107 | @item @code{IDST} @tab @kbd{A-Za-z_} 108 | @item @code{VSPACE} @tab @kbd{\r \n} 109 | @item @code{NVSPACE} @tab @kbd{space tab \f \v \0} 110 | @item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE} 111 | @item @code{ISOBASIC} @tab @code{VSPACE || NVSPACE || PRINT} 112 | @end multitable 113 | @end deffn 114 | 115 | */ 116 | 117 | #include "ansidecl.h" 118 | #include 119 | #include /* for EOF */ 120 | 121 | #if EOF != -1 122 | #error " requires EOF == -1" 123 | #endif 124 | 125 | /* Shorthand */ 126 | #define bl _sch_isblank 127 | #define cn _sch_iscntrl 128 | #define di _sch_isdigit 129 | #define is _sch_isidst 130 | #define lo _sch_islower 131 | #define nv _sch_isnvsp 132 | #define pn _sch_ispunct 133 | #define pr _sch_isprint 134 | #define sp _sch_isspace 135 | #define up _sch_isupper 136 | #define vs _sch_isvsp 137 | #define xd _sch_isxdigit 138 | 139 | /* Masks. */ 140 | #define L (const unsigned short) (lo|is |pr) /* lower case letter */ 141 | #define XL (const unsigned short) (lo|is|xd|pr) /* lowercase hex digit */ 142 | #define U (const unsigned short) (up|is |pr) /* upper case letter */ 143 | #define XU (const unsigned short) (up|is|xd|pr) /* uppercase hex digit */ 144 | #define D (const unsigned short) (di |xd|pr) /* decimal digit */ 145 | #define P (const unsigned short) (pn |pr) /* punctuation */ 146 | #define _ (const unsigned short) (pn|is |pr) /* underscore */ 147 | 148 | #define C (const unsigned short) ( cn) /* control character */ 149 | #define Z (const unsigned short) (nv |cn) /* NUL */ 150 | #define M (const unsigned short) (nv|sp |cn) /* cursor movement: \f \v */ 151 | #define V (const unsigned short) (vs|sp |cn) /* vertical space: \r \n */ 152 | #define T (const unsigned short) (nv|sp|bl|cn) /* tab */ 153 | #define S (const unsigned short) (nv|sp|bl|pr) /* space */ 154 | 155 | /* Are we ASCII? */ 156 | #if HOST_CHARSET == HOST_CHARSET_ASCII 157 | 158 | const unsigned short _sch_istable[256] = 159 | { 160 | Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */ 161 | C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */ 162 | C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */ 163 | C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */ 164 | S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */ 165 | P, P, P, P, P, P, P, P, /* ( ) * + , - . / */ 166 | D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */ 167 | D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */ 168 | P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */ 169 | U, U, U, U, U, U, U, U, /* H I J K L M N O */ 170 | U, U, U, U, U, U, U, U, /* P Q R S T U V W */ 171 | U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */ 172 | P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */ 173 | L, L, L, L, L, L, L, L, /* h i j k l m n o */ 174 | L, L, L, L, L, L, L, L, /* p q r s t u v w */ 175 | L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */ 176 | 177 | /* high half of unsigned char is locale-specific, so all tests are 178 | false in "C" locale */ 179 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183 | 184 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188 | }; 189 | 190 | const unsigned char _sch_tolower[256] = 191 | { 192 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 193 | 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 194 | 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 195 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 196 | 64, 197 | 198 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 199 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 200 | 201 | 91, 92, 93, 94, 95, 96, 202 | 203 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 204 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 205 | 206 | 123,124,125,126,127, 207 | 208 | 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143, 209 | 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159, 210 | 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175, 211 | 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191, 212 | 213 | 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207, 214 | 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223, 215 | 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239, 216 | 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255, 217 | }; 218 | 219 | const unsigned char _sch_toupper[256] = 220 | { 221 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 222 | 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 223 | 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 224 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 225 | 64, 226 | 227 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 228 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 229 | 230 | 91, 92, 93, 94, 95, 96, 231 | 232 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 233 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 234 | 235 | 123,124,125,126,127, 236 | 237 | 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143, 238 | 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159, 239 | 160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175, 240 | 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191, 241 | 242 | 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207, 243 | 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223, 244 | 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239, 245 | 240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255, 246 | }; 247 | 248 | #else 249 | # if HOST_CHARSET == HOST_CHARSET_EBCDIC 250 | #error "FIXME: write tables for EBCDIC" 251 | # else 252 | #error "Unrecognized host character set" 253 | # endif 254 | #endif 255 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/cplus-dem.c: -------------------------------------------------------------------------------- 1 | /* Demangler for GNU C++ 2 | Copyright (C) 1989-2021 Free Software Foundation, Inc. 3 | Written by James Clark (jjc@jclark.uucp) 4 | Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling 5 | Modified by Satish Pai (pai@apollo.hp.com) for HP demangling 6 | 7 | This file is part of the libiberty library. 8 | Libiberty is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Library General Public 10 | License as published by the Free Software Foundation; either 11 | version 2 of the License, or (at your option) any later version. 12 | 13 | In addition to the permissions in the GNU Library General Public 14 | License, the Free Software Foundation gives you unlimited permission 15 | to link the compiled version of this file into combinations with other 16 | programs, and to distribute those combinations without any restriction 17 | coming from the use of this file. (The Library Public License 18 | restrictions do apply in other respects; for example, they cover 19 | modification of the file, and distribution when not linked into a 20 | combined executable.) 21 | 22 | Libiberty is distributed in the hope that it will be useful, 23 | but WITHOUT ANY WARRANTY; without even the implied warranty of 24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25 | Library General Public License for more details. 26 | 27 | You should have received a copy of the GNU Library General Public 28 | License along with libiberty; see the file COPYING.LIB. If 29 | not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 30 | Boston, MA 02110-1301, USA. */ 31 | 32 | /* This file lives in both GCC and libiberty. When making changes, please 33 | try not to break either. */ 34 | 35 | #ifdef HAVE_CONFIG_H 36 | #include "config.h" 37 | #endif 38 | 39 | #include "safe-ctype.h" 40 | 41 | #include 42 | 43 | #ifdef HAVE_STDLIB_H 44 | #include 45 | #else 46 | void * malloc (); 47 | void * realloc (); 48 | #endif 49 | 50 | #include 51 | #undef CURRENT_DEMANGLING_STYLE 52 | #define CURRENT_DEMANGLING_STYLE options 53 | 54 | #include "libiberty.h" 55 | 56 | enum demangling_styles current_demangling_style = auto_demangling; 57 | 58 | const struct demangler_engine libiberty_demanglers[] = 59 | { 60 | { 61 | NO_DEMANGLING_STYLE_STRING, 62 | no_demangling, 63 | "Demangling disabled" 64 | } 65 | , 66 | { 67 | AUTO_DEMANGLING_STYLE_STRING, 68 | auto_demangling, 69 | "Automatic selection based on executable" 70 | } 71 | , 72 | { 73 | GNU_V3_DEMANGLING_STYLE_STRING, 74 | gnu_v3_demangling, 75 | "GNU (g++) V3 (Itanium C++ ABI) style demangling" 76 | } 77 | , 78 | { 79 | JAVA_DEMANGLING_STYLE_STRING, 80 | java_demangling, 81 | "Java style demangling" 82 | } 83 | , 84 | { 85 | GNAT_DEMANGLING_STYLE_STRING, 86 | gnat_demangling, 87 | "GNAT style demangling" 88 | } 89 | , 90 | { 91 | DLANG_DEMANGLING_STYLE_STRING, 92 | dlang_demangling, 93 | "DLANG style demangling" 94 | } 95 | , 96 | { 97 | RUST_DEMANGLING_STYLE_STRING, 98 | rust_demangling, 99 | "Rust style demangling" 100 | } 101 | , 102 | { 103 | NULL, unknown_demangling, NULL 104 | } 105 | }; 106 | 107 | /* Add a routine to set the demangling style to be sure it is valid and 108 | allow for any demangler initialization that maybe necessary. */ 109 | 110 | enum demangling_styles 111 | cplus_demangle_set_style (enum demangling_styles style) 112 | { 113 | const struct demangler_engine *demangler = libiberty_demanglers; 114 | 115 | for (; demangler->demangling_style != unknown_demangling; ++demangler) 116 | if (style == demangler->demangling_style) 117 | { 118 | current_demangling_style = style; 119 | return current_demangling_style; 120 | } 121 | 122 | return unknown_demangling; 123 | } 124 | 125 | /* Do string name to style translation */ 126 | 127 | enum demangling_styles 128 | cplus_demangle_name_to_style (const char *name) 129 | { 130 | const struct demangler_engine *demangler = libiberty_demanglers; 131 | 132 | for (; demangler->demangling_style != unknown_demangling; ++demangler) 133 | if (strcmp (name, demangler->demangling_style_name) == 0) 134 | return demangler->demangling_style; 135 | 136 | return unknown_demangling; 137 | } 138 | 139 | /* char *cplus_demangle (const char *mangled, int options) 140 | 141 | If MANGLED is a mangled function name produced by GNU C++, then 142 | a pointer to a @code{malloc}ed string giving a C++ representation 143 | of the name will be returned; otherwise NULL will be returned. 144 | It is the caller's responsibility to free the string which 145 | is returned. 146 | 147 | Note that any leading underscores, or other such characters prepended by 148 | the compilation system, are presumed to have already been stripped from 149 | MANGLED. */ 150 | 151 | char * 152 | cplus_demangle (const char *mangled, int options) 153 | { 154 | char *ret; 155 | 156 | if (current_demangling_style == no_demangling) 157 | return xstrdup (mangled); 158 | 159 | if ((options & DMGL_STYLE_MASK) == 0) 160 | options |= (int) current_demangling_style & DMGL_STYLE_MASK; 161 | 162 | /* The Rust demangling is implemented elsewhere. 163 | Legacy Rust symbols overlap with GNU_V3, so try Rust first. */ 164 | if (RUST_DEMANGLING || AUTO_DEMANGLING) 165 | { 166 | ret = rust_demangle (mangled, options); 167 | if (ret || RUST_DEMANGLING) 168 | return ret; 169 | } 170 | 171 | /* The V3 ABI demangling is implemented elsewhere. */ 172 | if (GNU_V3_DEMANGLING || AUTO_DEMANGLING) 173 | { 174 | ret = cplus_demangle_v3 (mangled, options); 175 | if (ret || GNU_V3_DEMANGLING) 176 | return ret; 177 | } 178 | 179 | if (JAVA_DEMANGLING) 180 | { 181 | ret = java_demangle_v3 (mangled); 182 | if (ret) 183 | return ret; 184 | } 185 | 186 | if (GNAT_DEMANGLING) 187 | return ada_demangle (mangled, options); 188 | 189 | if (DLANG_DEMANGLING) 190 | { 191 | ret = dlang_demangle (mangled, options); 192 | if (ret) 193 | return ret; 194 | } 195 | 196 | return (ret); 197 | } 198 | 199 | /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */ 200 | 201 | char * 202 | ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) 203 | { 204 | int len0; 205 | const char* p; 206 | char *d; 207 | char *demangled = NULL; 208 | 209 | /* Discard leading _ada_, which is used for library level subprograms. */ 210 | if (strncmp (mangled, "_ada_", 5) == 0) 211 | mangled += 5; 212 | 213 | /* All ada unit names are lower-case. */ 214 | if (!ISLOWER (mangled[0])) 215 | goto unknown; 216 | 217 | /* Most of the demangling will trivially remove chars. Operator names 218 | may add one char but because they are always preceeded by '__' which is 219 | replaced by '.', they eventually never expand the size. 220 | A few special names such as '___elabs' add a few chars (at most 7), but 221 | they occur only once. */ 222 | len0 = strlen (mangled) + 7 + 1; 223 | demangled = XNEWVEC (char, len0); 224 | 225 | d = demangled; 226 | p = mangled; 227 | while (1) 228 | { 229 | /* An entity names is expected. */ 230 | if (ISLOWER (*p)) 231 | { 232 | /* An identifier, which is always lower case. */ 233 | do 234 | *d++ = *p++; 235 | while (ISLOWER(*p) || ISDIGIT (*p) 236 | || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1])))); 237 | } 238 | else if (p[0] == 'O') 239 | { 240 | /* An operator name. */ 241 | static const char * const operators[][2] = 242 | {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"}, 243 | {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"}, 244 | {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="}, 245 | {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"}, 246 | {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"}, 247 | {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"}, 248 | {"Oexpon", "**"}, {NULL, NULL}}; 249 | int k; 250 | 251 | for (k = 0; operators[k][0] != NULL; k++) 252 | { 253 | size_t slen = strlen (operators[k][0]); 254 | if (strncmp (p, operators[k][0], slen) == 0) 255 | { 256 | p += slen; 257 | slen = strlen (operators[k][1]); 258 | *d++ = '"'; 259 | memcpy (d, operators[k][1], slen); 260 | d += slen; 261 | *d++ = '"'; 262 | break; 263 | } 264 | } 265 | /* Operator not found. */ 266 | if (operators[k][0] == NULL) 267 | goto unknown; 268 | } 269 | else 270 | { 271 | /* Not a GNAT encoding. */ 272 | goto unknown; 273 | } 274 | 275 | /* The name can be directly followed by some uppercase letters. */ 276 | if (p[0] == 'T' && p[1] == 'K') 277 | { 278 | /* Task stuff. */ 279 | if (p[2] == 'B' && p[3] == 0) 280 | { 281 | /* Subprogram for task body. */ 282 | break; 283 | } 284 | else if (p[2] == '_' && p[3] == '_') 285 | { 286 | /* Inner declarations in a task. */ 287 | p += 4; 288 | *d++ = '.'; 289 | continue; 290 | } 291 | else 292 | goto unknown; 293 | } 294 | if (p[0] == 'E' && p[1] == 0) 295 | { 296 | /* Exception name. */ 297 | goto unknown; 298 | } 299 | if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0) 300 | { 301 | /* Protected type subprogram. */ 302 | break; 303 | } 304 | if ((*p == 'N' || *p == 'S') && p[1] == 0) 305 | { 306 | /* Enumerated type name table. */ 307 | goto unknown; 308 | } 309 | if (p[0] == 'X') 310 | { 311 | /* Body nested. */ 312 | p++; 313 | while (p[0] == 'n' || p[0] == 'b') 314 | p++; 315 | } 316 | if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0)) 317 | { 318 | /* Stream operations. */ 319 | const char *name; 320 | switch (p[1]) 321 | { 322 | case 'R': 323 | name = "'Read"; 324 | break; 325 | case 'W': 326 | name = "'Write"; 327 | break; 328 | case 'I': 329 | name = "'Input"; 330 | break; 331 | case 'O': 332 | name = "'Output"; 333 | break; 334 | default: 335 | goto unknown; 336 | } 337 | p += 2; 338 | strcpy (d, name); 339 | d += strlen (name); 340 | } 341 | else if (p[0] == 'D') 342 | { 343 | /* Controlled type operation. */ 344 | const char *name; 345 | switch (p[1]) 346 | { 347 | case 'F': 348 | name = ".Finalize"; 349 | break; 350 | case 'A': 351 | name = ".Adjust"; 352 | break; 353 | default: 354 | goto unknown; 355 | } 356 | strcpy (d, name); 357 | d += strlen (name); 358 | break; 359 | } 360 | 361 | if (p[0] == '_') 362 | { 363 | /* Separator. */ 364 | if (p[1] == '_') 365 | { 366 | /* Standard separator. Handled first. */ 367 | p += 2; 368 | 369 | if (ISDIGIT (*p)) 370 | { 371 | /* Overloading number. */ 372 | do 373 | p++; 374 | while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1]))); 375 | if (*p == 'X') 376 | { 377 | p++; 378 | while (p[0] == 'n' || p[0] == 'b') 379 | p++; 380 | } 381 | } 382 | else if (p[0] == '_' && p[1] != '_') 383 | { 384 | /* Special names. */ 385 | static const char * const special[][2] = { 386 | { "_elabb", "'Elab_Body" }, 387 | { "_elabs", "'Elab_Spec" }, 388 | { "_size", "'Size" }, 389 | { "_alignment", "'Alignment" }, 390 | { "_assign", ".\":=\"" }, 391 | { NULL, NULL } 392 | }; 393 | int k; 394 | 395 | for (k = 0; special[k][0] != NULL; k++) 396 | { 397 | size_t slen = strlen (special[k][0]); 398 | if (strncmp (p, special[k][0], slen) == 0) 399 | { 400 | p += slen; 401 | slen = strlen (special[k][1]); 402 | memcpy (d, special[k][1], slen); 403 | d += slen; 404 | break; 405 | } 406 | } 407 | if (special[k][0] != NULL) 408 | break; 409 | else 410 | goto unknown; 411 | } 412 | else 413 | { 414 | *d++ = '.'; 415 | continue; 416 | } 417 | } 418 | else if (p[1] == 'B' || p[1] == 'E') 419 | { 420 | /* Entry Body or barrier Evaluation. */ 421 | p += 2; 422 | while (ISDIGIT (*p)) 423 | p++; 424 | if (p[0] == 's' && p[1] == 0) 425 | break; 426 | else 427 | goto unknown; 428 | } 429 | else 430 | goto unknown; 431 | } 432 | 433 | if (p[0] == '.' && ISDIGIT (p[1])) 434 | { 435 | /* Nested subprogram. */ 436 | p += 2; 437 | while (ISDIGIT (*p)) 438 | p++; 439 | } 440 | if (*p == 0) 441 | { 442 | /* End of mangled name. */ 443 | break; 444 | } 445 | else 446 | goto unknown; 447 | } 448 | *d = 0; 449 | return demangled; 450 | 451 | unknown: 452 | XDELETEVEC (demangled); 453 | len0 = strlen (mangled); 454 | demangled = XNEWVEC (char, len0 + 3); 455 | 456 | if (mangled[0] == '<') 457 | strcpy (demangled, mangled); 458 | else 459 | sprintf (demangled, "<%s>", mangled); 460 | 461 | return demangled; 462 | } 463 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/ansidecl.h: -------------------------------------------------------------------------------- 1 | /* ANSI and traditional C compatability macros 2 | Copyright (C) 1991-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 18 | 19 | /* ANSI and traditional C compatibility macros 20 | 21 | ANSI C is assumed if __STDC__ is #defined. 22 | 23 | Macro ANSI C definition Traditional C definition 24 | ----- ---- - ---------- ----------- - ---------- 25 | PTR `void *' `char *' 26 | const not defined `' 27 | volatile not defined `' 28 | signed not defined `' 29 | 30 | For ease of writing code which uses GCC extensions but needs to be 31 | portable to other compilers, we provide the GCC_VERSION macro that 32 | simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various 33 | wrappers around __attribute__. Also, __extension__ will be #defined 34 | to nothing if it doesn't work. See below. */ 35 | 36 | #ifndef _ANSIDECL_H 37 | #define _ANSIDECL_H 1 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | /* Every source file includes this file, 44 | so they will all get the switch for lint. */ 45 | /* LINTLIBRARY */ 46 | 47 | /* Using MACRO(x,y) in cpp #if conditionals does not work with some 48 | older preprocessors. Thus we can't define something like this: 49 | 50 | #define HAVE_GCC_VERSION(MAJOR, MINOR) \ 51 | (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) 52 | 53 | and then test "#if HAVE_GCC_VERSION(2,7)". 54 | 55 | So instead we use the macro below and test it against specific values. */ 56 | 57 | /* This macro simplifies testing whether we are using gcc, and if it 58 | is of a particular minimum version. (Both major & minor numbers are 59 | significant.) This macro will evaluate to 0 if we are not using 60 | gcc at all. */ 61 | #ifndef GCC_VERSION 62 | #define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) 63 | #endif /* GCC_VERSION */ 64 | 65 | #if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) 66 | /* All known AIX compilers implement these things (but don't always 67 | define __STDC__). The RISC/OS MIPS compiler defines these things 68 | in SVR4 mode, but does not define __STDC__. */ 69 | /* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other 70 | C++ compilers, does not define __STDC__, though it acts as if this 71 | was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ 72 | 73 | #define PTR void * 74 | 75 | #undef const 76 | #undef volatile 77 | #undef signed 78 | 79 | /* inline requires special treatment; it's in C99, and GCC >=2.7 supports 80 | it too, but it's not in C89. */ 81 | #undef inline 82 | #if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__)) 83 | /* it's a keyword */ 84 | #else 85 | # if GCC_VERSION >= 2007 86 | # define inline __inline__ /* __inline__ prevents -pedantic warnings */ 87 | # else 88 | # define inline /* nothing */ 89 | # endif 90 | #endif 91 | 92 | #else /* Not ANSI C. */ 93 | 94 | #define PTR char * 95 | 96 | /* some systems define these in header files for non-ansi mode */ 97 | #undef const 98 | #undef volatile 99 | #undef signed 100 | #undef inline 101 | #define const 102 | #define volatile 103 | #define signed 104 | #define inline 105 | 106 | #endif /* ANSI C. */ 107 | 108 | /* Define macros for some gcc attributes. This permits us to use the 109 | macros freely, and know that they will come into play for the 110 | version of gcc in which they are supported. */ 111 | 112 | #if (GCC_VERSION < 2007) 113 | # define __attribute__(x) 114 | #endif 115 | 116 | /* Attribute __malloc__ on functions was valid as of gcc 2.96. */ 117 | #ifndef ATTRIBUTE_MALLOC 118 | # if (GCC_VERSION >= 2096) 119 | # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) 120 | # else 121 | # define ATTRIBUTE_MALLOC 122 | # endif /* GNUC >= 2.96 */ 123 | #endif /* ATTRIBUTE_MALLOC */ 124 | 125 | /* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For 126 | g++ an attribute on a label must be followed by a semicolon. */ 127 | #ifndef ATTRIBUTE_UNUSED_LABEL 128 | # ifndef __cplusplus 129 | # if GCC_VERSION >= 2093 130 | # define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED 131 | # else 132 | # define ATTRIBUTE_UNUSED_LABEL 133 | # endif 134 | # else 135 | # if GCC_VERSION >= 4005 136 | # define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ; 137 | # else 138 | # define ATTRIBUTE_UNUSED_LABEL 139 | # endif 140 | # endif 141 | #endif 142 | 143 | /* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend 144 | couldn't parse attributes placed after the identifier name, and now 145 | the entire compiler is built with C++. */ 146 | #ifndef ATTRIBUTE_UNUSED 147 | #if GCC_VERSION >= 3004 148 | # define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 149 | #else 150 | #define ATTRIBUTE_UNUSED 151 | #endif 152 | #endif /* ATTRIBUTE_UNUSED */ 153 | 154 | /* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the 155 | identifier name. */ 156 | #if ! defined(__cplusplus) || (GCC_VERSION >= 3004) 157 | # define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED 158 | #else /* !__cplusplus || GNUC >= 3.4 */ 159 | # define ARG_UNUSED(NAME) NAME 160 | #endif /* !__cplusplus || GNUC >= 3.4 */ 161 | 162 | #ifndef ATTRIBUTE_NORETURN 163 | #define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) 164 | #endif /* ATTRIBUTE_NORETURN */ 165 | 166 | /* Attribute `nonnull' was valid as of gcc 3.3. */ 167 | #ifndef ATTRIBUTE_NONNULL 168 | # if (GCC_VERSION >= 3003) 169 | # define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) 170 | # else 171 | # define ATTRIBUTE_NONNULL(m) 172 | # endif /* GNUC >= 3.3 */ 173 | #endif /* ATTRIBUTE_NONNULL */ 174 | 175 | /* Attribute `returns_nonnull' was valid as of gcc 4.9. */ 176 | #ifndef ATTRIBUTE_RETURNS_NONNULL 177 | # if (GCC_VERSION >= 4009) 178 | # define ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__)) 179 | # else 180 | # define ATTRIBUTE_RETURNS_NONNULL 181 | # endif /* GNUC >= 4.9 */ 182 | #endif /* ATTRIBUTE_RETURNS_NONNULL */ 183 | 184 | /* Attribute `pure' was valid as of gcc 3.0. */ 185 | #ifndef ATTRIBUTE_PURE 186 | # if (GCC_VERSION >= 3000) 187 | # define ATTRIBUTE_PURE __attribute__ ((__pure__)) 188 | # else 189 | # define ATTRIBUTE_PURE 190 | # endif /* GNUC >= 3.0 */ 191 | #endif /* ATTRIBUTE_PURE */ 192 | 193 | /* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. 194 | This was the case for the `printf' format attribute by itself 195 | before GCC 3.3, but as of 3.3 we need to add the `nonnull' 196 | attribute to retain this behavior. */ 197 | #ifndef ATTRIBUTE_PRINTF 198 | #define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) 199 | #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) 200 | #define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) 201 | #define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) 202 | #define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) 203 | #define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) 204 | #endif /* ATTRIBUTE_PRINTF */ 205 | 206 | /* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on 207 | a function pointer. Format attributes were allowed on function 208 | pointers as of gcc 3.1. */ 209 | #ifndef ATTRIBUTE_FPTR_PRINTF 210 | # if (GCC_VERSION >= 3001) 211 | # define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n) 212 | # else 213 | # define ATTRIBUTE_FPTR_PRINTF(m, n) 214 | # endif /* GNUC >= 3.1 */ 215 | # define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2) 216 | # define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3) 217 | # define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4) 218 | # define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5) 219 | # define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6) 220 | #endif /* ATTRIBUTE_FPTR_PRINTF */ 221 | 222 | /* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A 223 | NULL format specifier was allowed as of gcc 3.3. */ 224 | #ifndef ATTRIBUTE_NULL_PRINTF 225 | # if (GCC_VERSION >= 3003) 226 | # define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) 227 | # else 228 | # define ATTRIBUTE_NULL_PRINTF(m, n) 229 | # endif /* GNUC >= 3.3 */ 230 | # define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) 231 | # define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) 232 | # define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) 233 | # define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) 234 | # define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) 235 | #endif /* ATTRIBUTE_NULL_PRINTF */ 236 | 237 | /* Attribute `sentinel' was valid as of gcc 3.5. */ 238 | #ifndef ATTRIBUTE_SENTINEL 239 | # if (GCC_VERSION >= 3005) 240 | # define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) 241 | # else 242 | # define ATTRIBUTE_SENTINEL 243 | # endif /* GNUC >= 3.5 */ 244 | #endif /* ATTRIBUTE_SENTINEL */ 245 | 246 | 247 | #ifndef ATTRIBUTE_ALIGNED_ALIGNOF 248 | # if (GCC_VERSION >= 3000) 249 | # define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m)))) 250 | # else 251 | # define ATTRIBUTE_ALIGNED_ALIGNOF(m) 252 | # endif /* GNUC >= 3.0 */ 253 | #endif /* ATTRIBUTE_ALIGNED_ALIGNOF */ 254 | 255 | /* Useful for structures whose layout must match some binary specification 256 | regardless of the alignment and padding qualities of the compiler. */ 257 | #ifndef ATTRIBUTE_PACKED 258 | # define ATTRIBUTE_PACKED __attribute__ ((packed)) 259 | #endif 260 | 261 | /* Attribute `hot' and `cold' was valid as of gcc 4.3. */ 262 | #ifndef ATTRIBUTE_COLD 263 | # if (GCC_VERSION >= 4003) 264 | # define ATTRIBUTE_COLD __attribute__ ((__cold__)) 265 | # else 266 | # define ATTRIBUTE_COLD 267 | # endif /* GNUC >= 4.3 */ 268 | #endif /* ATTRIBUTE_COLD */ 269 | #ifndef ATTRIBUTE_HOT 270 | # if (GCC_VERSION >= 4003) 271 | # define ATTRIBUTE_HOT __attribute__ ((__hot__)) 272 | # else 273 | # define ATTRIBUTE_HOT 274 | # endif /* GNUC >= 4.3 */ 275 | #endif /* ATTRIBUTE_HOT */ 276 | 277 | /* Attribute 'no_sanitize_undefined' was valid as of gcc 4.9. */ 278 | #ifndef ATTRIBUTE_NO_SANITIZE_UNDEFINED 279 | # if (GCC_VERSION >= 4009) 280 | # define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__ ((no_sanitize_undefined)) 281 | # else 282 | # define ATTRIBUTE_NO_SANITIZE_UNDEFINED 283 | # endif /* GNUC >= 4.9 */ 284 | #endif /* ATTRIBUTE_NO_SANITIZE_UNDEFINED */ 285 | 286 | /* Attribute 'nonstring' was valid as of gcc 8. */ 287 | #ifndef ATTRIBUTE_NONSTRING 288 | # if GCC_VERSION >= 8000 289 | # define ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__)) 290 | # else 291 | # define ATTRIBUTE_NONSTRING 292 | # endif 293 | #endif 294 | 295 | /* Attribute `alloc_size' was valid as of gcc 4.3. */ 296 | #ifndef ATTRIBUTE_RESULT_SIZE_1 297 | # if (GCC_VERSION >= 4003) 298 | # define ATTRIBUTE_RESULT_SIZE_1 __attribute__ ((alloc_size (1))) 299 | # else 300 | # define ATTRIBUTE_RESULT_SIZE_1 301 | #endif 302 | #endif 303 | 304 | #ifndef ATTRIBUTE_RESULT_SIZE_2 305 | # if (GCC_VERSION >= 4003) 306 | # define ATTRIBUTE_RESULT_SIZE_2 __attribute__ ((alloc_size (2))) 307 | # else 308 | # define ATTRIBUTE_RESULT_SIZE_2 309 | #endif 310 | #endif 311 | 312 | #ifndef ATTRIBUTE_RESULT_SIZE_1_2 313 | # if (GCC_VERSION >= 4003) 314 | # define ATTRIBUTE_RESULT_SIZE_1_2 __attribute__ ((alloc_size (1, 2))) 315 | # else 316 | # define ATTRIBUTE_RESULT_SIZE_1_2 317 | #endif 318 | #endif 319 | 320 | /* Attribute `warn_unused_result' was valid as of gcc 3.3. */ 321 | #ifndef ATTRIBUTE_WARN_UNUSED_RESULT 322 | # if GCC_VERSION >= 3003 323 | # define ATTRIBUTE_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) 324 | # else 325 | # define ATTRIBUTE_WARN_UNUSED_RESULT 326 | # endif 327 | #endif 328 | 329 | /* We use __extension__ in some places to suppress -pedantic warnings 330 | about GCC extensions. This feature didn't work properly before 331 | gcc 2.8. */ 332 | #if GCC_VERSION < 2008 333 | #define __extension__ 334 | #endif 335 | 336 | /* This is used to declare a const variable which should be visible 337 | outside of the current compilation unit. Use it as 338 | EXPORTED_CONST int i = 1; 339 | This is because the semantics of const are different in C and C++. 340 | "extern const" is permitted in C but it looks strange, and gcc 341 | warns about it when -Wc++-compat is not used. */ 342 | #ifdef __cplusplus 343 | #define EXPORTED_CONST extern const 344 | #else 345 | #define EXPORTED_CONST const 346 | #endif 347 | 348 | /* Be conservative and only use enum bitfields with C++ or GCC. 349 | FIXME: provide a complete autoconf test for buggy enum bitfields. */ 350 | 351 | #ifdef __cplusplus 352 | #define ENUM_BITFIELD(TYPE) enum TYPE 353 | #elif (GCC_VERSION > 2000) 354 | #define ENUM_BITFIELD(TYPE) __extension__ enum TYPE 355 | #else 356 | #define ENUM_BITFIELD(TYPE) unsigned int 357 | #endif 358 | 359 | #if __cpp_constexpr >= 200704 360 | #define CONSTEXPR constexpr 361 | #else 362 | #define CONSTEXPR 363 | #endif 364 | 365 | /* C++11 adds the ability to add "override" after an implementation of a 366 | virtual function in a subclass, to: 367 | (A) document that this is an override of a virtual function 368 | (B) allow the compiler to issue a warning if it isn't (e.g. a mismatch 369 | of the type signature). 370 | 371 | Similarly, it allows us to add a "final" to indicate that no subclass 372 | may subsequently override the vfunc. 373 | 374 | Provide OVERRIDE and FINAL as macros, allowing us to get these benefits 375 | when compiling with C++11 support, but without requiring C++11. 376 | 377 | For gcc, use "-std=c++11" to enable C++11 support; gcc 6 onwards enables 378 | this by default (actually GNU++14). */ 379 | 380 | #if defined __cplusplus 381 | # if __cplusplus >= 201103 382 | /* C++11 claims to be available: use it. Final/override were only 383 | implemented in 4.7, though. */ 384 | # if GCC_VERSION < 4007 385 | # define OVERRIDE 386 | # define FINAL 387 | # else 388 | # define OVERRIDE override 389 | # define FINAL final 390 | # endif 391 | # elif GCC_VERSION >= 4007 392 | /* G++ 4.7 supports __final in C++98. */ 393 | # define OVERRIDE 394 | # define FINAL __final 395 | # else 396 | /* No C++11 support; leave the macros empty. */ 397 | # define OVERRIDE 398 | # define FINAL 399 | # endif 400 | #else 401 | /* No C++11 support; leave the macros empty. */ 402 | # define OVERRIDE 403 | # define FINAL 404 | #endif 405 | 406 | /* A macro to disable the copy constructor and assignment operator. 407 | When building with C++11 and above, the methods are explicitly 408 | deleted, causing a compile-time error if something tries to copy. 409 | For C++03, this just declares the methods, causing a link-time 410 | error if the methods end up called (assuming you don't 411 | define them). For C++03, for best results, place the macro 412 | under the private: access specifier, like this, 413 | 414 | class name_lookup 415 | { 416 | private: 417 | DISABLE_COPY_AND_ASSIGN (name_lookup); 418 | }; 419 | 420 | so that most attempts at copy are caught at compile-time. */ 421 | 422 | #if __cplusplus >= 201103 423 | #define DISABLE_COPY_AND_ASSIGN(TYPE) \ 424 | TYPE (const TYPE&) = delete; \ 425 | void operator= (const TYPE &) = delete 426 | #else 427 | #define DISABLE_COPY_AND_ASSIGN(TYPE) \ 428 | TYPE (const TYPE&); \ 429 | void operator= (const TYPE &) 430 | #endif /* __cplusplus >= 201103 */ 431 | 432 | #ifdef __cplusplus 433 | } 434 | #endif 435 | 436 | #endif /* ansidecl.h */ 437 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/demangle.h: -------------------------------------------------------------------------------- 1 | /* Defs for interface to demanglers. 2 | Copyright (C) 1992-2021 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Library General Public License 6 | as published by the Free Software Foundation; either version 2, or 7 | (at your option) any later version. 8 | 9 | In addition to the permissions in the GNU Library General Public 10 | License, the Free Software Foundation gives you unlimited 11 | permission to link the compiled version of this file into 12 | combinations with other programs, and to distribute those 13 | combinations without any restriction coming from the use of this 14 | file. (The Library Public License restrictions do apply in other 15 | respects; for example, they cover modification of the file, and 16 | distribution when not linked into a combined executable.) 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | Library General Public License for more details. 22 | 23 | You should have received a copy of the GNU Library General Public 24 | License along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 26 | 02110-1301, USA. */ 27 | 28 | 29 | #if !defined (DEMANGLE_H) 30 | #define DEMANGLE_H 31 | 32 | #include "libiberty.h" 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif /* __cplusplus */ 37 | 38 | /* Options passed to cplus_demangle (in 2nd parameter). */ 39 | 40 | #define DMGL_NO_OPTS 0 /* For readability... */ 41 | #define DMGL_PARAMS (1 << 0) /* Include function args */ 42 | #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 43 | #define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */ 44 | #define DMGL_VERBOSE (1 << 3) /* Include implementation details. */ 45 | #define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */ 46 | #define DMGL_RET_POSTFIX (1 << 5) /* Print function return types (when 47 | present) after function signature. 48 | It applies only to the toplevel 49 | function type. */ 50 | #define DMGL_RET_DROP (1 << 6) /* Suppress printing function return 51 | types, even if present. It applies 52 | only to the toplevel function type. 53 | */ 54 | 55 | #define DMGL_AUTO (1 << 8) 56 | #define DMGL_GNU_V3 (1 << 14) 57 | #define DMGL_GNAT (1 << 15) 58 | #define DMGL_DLANG (1 << 16) 59 | #define DMGL_RUST (1 << 17) /* Rust wraps GNU_V3 style mangling. */ 60 | 61 | /* If none of these are set, use 'current_demangling_style' as the default. */ 62 | #define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST) 63 | 64 | /* Disable a limit on the depth of recursion in mangled strings. 65 | Note if this limit is disabled then stack exhaustion is possible when 66 | demangling pathologically complicated strings. Bug reports about stack 67 | exhaustion when the option is enabled will be rejected. */ 68 | #define DMGL_NO_RECURSE_LIMIT (1 << 18) 69 | 70 | /* If DMGL_NO_RECURSE_LIMIT is not enabled, then this is the value used as 71 | the maximum depth of recursion allowed. It should be enough for any 72 | real-world mangled name. */ 73 | #define DEMANGLE_RECURSION_LIMIT 2048 74 | 75 | /* Enumeration of possible demangling styles. 76 | 77 | Lucid and ARM styles are still kept logically distinct, even though 78 | they now both behave identically. The resulting style is actual the 79 | union of both. I.E. either style recognizes both "__pt__" and "__rf__" 80 | for operator "->", even though the first is lucid style and the second 81 | is ARM style. (FIXME?) */ 82 | 83 | extern enum demangling_styles 84 | { 85 | no_demangling = -1, 86 | unknown_demangling = 0, 87 | auto_demangling = DMGL_AUTO, 88 | gnu_v3_demangling = DMGL_GNU_V3, 89 | java_demangling = DMGL_JAVA, 90 | gnat_demangling = DMGL_GNAT, 91 | dlang_demangling = DMGL_DLANG, 92 | rust_demangling = DMGL_RUST 93 | } current_demangling_style; 94 | 95 | /* Define string names for the various demangling styles. */ 96 | 97 | #define NO_DEMANGLING_STYLE_STRING "none" 98 | #define AUTO_DEMANGLING_STYLE_STRING "auto" 99 | #define GNU_V3_DEMANGLING_STYLE_STRING "gnu-v3" 100 | #define JAVA_DEMANGLING_STYLE_STRING "java" 101 | #define GNAT_DEMANGLING_STYLE_STRING "gnat" 102 | #define DLANG_DEMANGLING_STYLE_STRING "dlang" 103 | #define RUST_DEMANGLING_STYLE_STRING "rust" 104 | 105 | /* Some macros to test what demangling style is active. */ 106 | 107 | #define CURRENT_DEMANGLING_STYLE current_demangling_style 108 | #define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) 109 | #define GNU_V3_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU_V3) 110 | #define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA) 111 | #define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT) 112 | #define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG) 113 | #define RUST_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_RUST) 114 | 115 | /* Provide information about the available demangle styles. This code is 116 | pulled from gdb into libiberty because it is useful to binutils also. */ 117 | 118 | extern const struct demangler_engine 119 | { 120 | const char *const demangling_style_name; 121 | const enum demangling_styles demangling_style; 122 | const char *const demangling_style_doc; 123 | } libiberty_demanglers[]; 124 | 125 | extern char * 126 | cplus_demangle (const char *mangled, int options); 127 | 128 | /* Note: This sets global state. FIXME if you care about multi-threading. */ 129 | 130 | extern enum demangling_styles 131 | cplus_demangle_set_style (enum demangling_styles style); 132 | 133 | extern enum demangling_styles 134 | cplus_demangle_name_to_style (const char *name); 135 | 136 | /* Callback typedef for allocation-less demangler interfaces. */ 137 | typedef void (*demangle_callbackref) (const char *, size_t, void *); 138 | 139 | /* V3 ABI demangling entry points, defined in cp-demangle.c. Callback 140 | variants return non-zero on success, zero on error. char* variants 141 | return a string allocated by malloc on success, NULL on error. */ 142 | extern int 143 | cplus_demangle_v3_callback (const char *mangled, int options, 144 | demangle_callbackref callback, void *opaque); 145 | 146 | extern char* 147 | cplus_demangle_v3 (const char *mangled, int options); 148 | 149 | extern int 150 | java_demangle_v3_callback (const char *mangled, 151 | demangle_callbackref callback, void *opaque); 152 | 153 | extern char* 154 | java_demangle_v3 (const char *mangled); 155 | 156 | char * 157 | ada_demangle (const char *mangled, int options); 158 | 159 | extern char * 160 | dlang_demangle (const char *mangled, int options); 161 | 162 | extern int 163 | rust_demangle_callback (const char *mangled, int options, 164 | demangle_callbackref callback, void *opaque); 165 | 166 | 167 | extern char * 168 | rust_demangle (const char *mangled, int options); 169 | 170 | enum gnu_v3_ctor_kinds { 171 | gnu_v3_complete_object_ctor = 1, 172 | gnu_v3_base_object_ctor, 173 | gnu_v3_complete_object_allocating_ctor, 174 | /* These are not part of the V3 ABI. Unified constructors are generated 175 | as a speed-for-space optimization when the -fdeclone-ctor-dtor option 176 | is used, and are always internal symbols. */ 177 | gnu_v3_unified_ctor, 178 | gnu_v3_object_ctor_group 179 | }; 180 | 181 | /* Return non-zero iff NAME is the mangled form of a constructor name 182 | in the G++ V3 ABI demangling style. Specifically, return an `enum 183 | gnu_v3_ctor_kinds' value indicating what kind of constructor 184 | it is. */ 185 | extern enum gnu_v3_ctor_kinds 186 | is_gnu_v3_mangled_ctor (const char *name); 187 | 188 | 189 | enum gnu_v3_dtor_kinds { 190 | gnu_v3_deleting_dtor = 1, 191 | gnu_v3_complete_object_dtor, 192 | gnu_v3_base_object_dtor, 193 | /* These are not part of the V3 ABI. Unified destructors are generated 194 | as a speed-for-space optimization when the -fdeclone-ctor-dtor option 195 | is used, and are always internal symbols. */ 196 | gnu_v3_unified_dtor, 197 | gnu_v3_object_dtor_group 198 | }; 199 | 200 | /* Return non-zero iff NAME is the mangled form of a destructor name 201 | in the G++ V3 ABI demangling style. Specifically, return an `enum 202 | gnu_v3_dtor_kinds' value, indicating what kind of destructor 203 | it is. */ 204 | extern enum gnu_v3_dtor_kinds 205 | is_gnu_v3_mangled_dtor (const char *name); 206 | 207 | /* The V3 demangler works in two passes. The first pass builds a tree 208 | representation of the mangled name, and the second pass turns the 209 | tree representation into a demangled string. Here we define an 210 | interface to permit a caller to build their own tree 211 | representation, which they can pass to the demangler to get a 212 | demangled string. This can be used to canonicalize user input into 213 | something which the demangler might output. It could also be used 214 | by other demanglers in the future. */ 215 | 216 | /* These are the component types which may be found in the tree. Many 217 | component types have one or two subtrees, referred to as left and 218 | right (a component type with only one subtree puts it in the left 219 | subtree). */ 220 | 221 | enum demangle_component_type 222 | { 223 | /* A name, with a length and a pointer to a string. */ 224 | DEMANGLE_COMPONENT_NAME, 225 | /* A qualified name. The left subtree is a class or namespace or 226 | some such thing, and the right subtree is a name qualified by 227 | that class. */ 228 | DEMANGLE_COMPONENT_QUAL_NAME, 229 | /* A local name. The left subtree describes a function, and the 230 | right subtree is a name which is local to that function. */ 231 | DEMANGLE_COMPONENT_LOCAL_NAME, 232 | /* A typed name. The left subtree is a name, and the right subtree 233 | describes that name as a function. */ 234 | DEMANGLE_COMPONENT_TYPED_NAME, 235 | /* A template. The left subtree is a template name, and the right 236 | subtree is a template argument list. */ 237 | DEMANGLE_COMPONENT_TEMPLATE, 238 | /* A template parameter. This holds a number, which is the template 239 | parameter index. */ 240 | DEMANGLE_COMPONENT_TEMPLATE_PARAM, 241 | /* A function parameter. This holds a number, which is the index. */ 242 | DEMANGLE_COMPONENT_FUNCTION_PARAM, 243 | /* A constructor. This holds a name and the kind of 244 | constructor. */ 245 | DEMANGLE_COMPONENT_CTOR, 246 | /* A destructor. This holds a name and the kind of destructor. */ 247 | DEMANGLE_COMPONENT_DTOR, 248 | /* A vtable. This has one subtree, the type for which this is a 249 | vtable. */ 250 | DEMANGLE_COMPONENT_VTABLE, 251 | /* A VTT structure. This has one subtree, the type for which this 252 | is a VTT. */ 253 | DEMANGLE_COMPONENT_VTT, 254 | /* A construction vtable. The left subtree is the type for which 255 | this is a vtable, and the right subtree is the derived type for 256 | which this vtable is built. */ 257 | DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, 258 | /* A typeinfo structure. This has one subtree, the type for which 259 | this is the tpeinfo structure. */ 260 | DEMANGLE_COMPONENT_TYPEINFO, 261 | /* A typeinfo name. This has one subtree, the type for which this 262 | is the typeinfo name. */ 263 | DEMANGLE_COMPONENT_TYPEINFO_NAME, 264 | /* A typeinfo function. This has one subtree, the type for which 265 | this is the tpyeinfo function. */ 266 | DEMANGLE_COMPONENT_TYPEINFO_FN, 267 | /* A thunk. This has one subtree, the name for which this is a 268 | thunk. */ 269 | DEMANGLE_COMPONENT_THUNK, 270 | /* A virtual thunk. This has one subtree, the name for which this 271 | is a virtual thunk. */ 272 | DEMANGLE_COMPONENT_VIRTUAL_THUNK, 273 | /* A covariant thunk. This has one subtree, the name for which this 274 | is a covariant thunk. */ 275 | DEMANGLE_COMPONENT_COVARIANT_THUNK, 276 | /* A Java class. This has one subtree, the type. */ 277 | DEMANGLE_COMPONENT_JAVA_CLASS, 278 | /* A guard variable. This has one subtree, the name for which this 279 | is a guard variable. */ 280 | DEMANGLE_COMPONENT_GUARD, 281 | /* The init and wrapper functions for C++11 thread_local variables. */ 282 | DEMANGLE_COMPONENT_TLS_INIT, 283 | DEMANGLE_COMPONENT_TLS_WRAPPER, 284 | /* A reference temporary. This has one subtree, the name for which 285 | this is a temporary. */ 286 | DEMANGLE_COMPONENT_REFTEMP, 287 | /* A hidden alias. This has one subtree, the encoding for which it 288 | is providing alternative linkage. */ 289 | DEMANGLE_COMPONENT_HIDDEN_ALIAS, 290 | /* A standard substitution. This holds the name of the 291 | substitution. */ 292 | DEMANGLE_COMPONENT_SUB_STD, 293 | /* The restrict qualifier. The one subtree is the type which is 294 | being qualified. */ 295 | DEMANGLE_COMPONENT_RESTRICT, 296 | /* The volatile qualifier. The one subtree is the type which is 297 | being qualified. */ 298 | DEMANGLE_COMPONENT_VOLATILE, 299 | /* The const qualifier. The one subtree is the type which is being 300 | qualified. */ 301 | DEMANGLE_COMPONENT_CONST, 302 | /* The restrict qualifier modifying a member function. The one 303 | subtree is the type which is being qualified. */ 304 | DEMANGLE_COMPONENT_RESTRICT_THIS, 305 | /* The volatile qualifier modifying a member function. The one 306 | subtree is the type which is being qualified. */ 307 | DEMANGLE_COMPONENT_VOLATILE_THIS, 308 | /* The const qualifier modifying a member function. The one subtree 309 | is the type which is being qualified. */ 310 | DEMANGLE_COMPONENT_CONST_THIS, 311 | /* C++11 A reference modifying a member function. The one subtree is the 312 | type which is being referenced. */ 313 | DEMANGLE_COMPONENT_REFERENCE_THIS, 314 | /* C++11: An rvalue reference modifying a member function. The one 315 | subtree is the type which is being referenced. */ 316 | DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS, 317 | /* A vendor qualifier. The left subtree is the type which is being 318 | qualified, and the right subtree is the name of the 319 | qualifier. */ 320 | DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL, 321 | /* A pointer. The one subtree is the type which is being pointed 322 | to. */ 323 | DEMANGLE_COMPONENT_POINTER, 324 | /* A reference. The one subtree is the type which is being 325 | referenced. */ 326 | DEMANGLE_COMPONENT_REFERENCE, 327 | /* C++0x: An rvalue reference. The one subtree is the type which is 328 | being referenced. */ 329 | DEMANGLE_COMPONENT_RVALUE_REFERENCE, 330 | /* A complex type. The one subtree is the base type. */ 331 | DEMANGLE_COMPONENT_COMPLEX, 332 | /* An imaginary type. The one subtree is the base type. */ 333 | DEMANGLE_COMPONENT_IMAGINARY, 334 | /* A builtin type. This holds the builtin type information. */ 335 | DEMANGLE_COMPONENT_BUILTIN_TYPE, 336 | /* A vendor's builtin type. This holds the name of the type. */ 337 | DEMANGLE_COMPONENT_VENDOR_TYPE, 338 | /* A function type. The left subtree is the return type. The right 339 | subtree is a list of ARGLIST nodes. Either or both may be 340 | NULL. */ 341 | DEMANGLE_COMPONENT_FUNCTION_TYPE, 342 | /* An array type. The left subtree is the dimension, which may be 343 | NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an 344 | expression. The right subtree is the element type. */ 345 | DEMANGLE_COMPONENT_ARRAY_TYPE, 346 | /* A pointer to member type. The left subtree is the class type, 347 | and the right subtree is the member type. CV-qualifiers appear 348 | on the latter. */ 349 | DEMANGLE_COMPONENT_PTRMEM_TYPE, 350 | /* A fixed-point type. */ 351 | DEMANGLE_COMPONENT_FIXED_TYPE, 352 | /* A vector type. The left subtree is the number of elements, 353 | the right subtree is the element type. */ 354 | DEMANGLE_COMPONENT_VECTOR_TYPE, 355 | /* An argument list. The left subtree is the current argument, and 356 | the right subtree is either NULL or another ARGLIST node. */ 357 | DEMANGLE_COMPONENT_ARGLIST, 358 | /* A template argument list. The left subtree is the current 359 | template argument, and the right subtree is either NULL or 360 | another TEMPLATE_ARGLIST node. */ 361 | DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, 362 | /* A template parameter object (C++20). The left subtree is the 363 | corresponding template argument. */ 364 | DEMANGLE_COMPONENT_TPARM_OBJ, 365 | /* An initializer list. The left subtree is either an explicit type or 366 | NULL, and the right subtree is a DEMANGLE_COMPONENT_ARGLIST. */ 367 | DEMANGLE_COMPONENT_INITIALIZER_LIST, 368 | /* An operator. This holds information about a standard 369 | operator. */ 370 | DEMANGLE_COMPONENT_OPERATOR, 371 | /* An extended operator. This holds the number of arguments, and 372 | the name of the extended operator. */ 373 | DEMANGLE_COMPONENT_EXTENDED_OPERATOR, 374 | /* A typecast, represented as a unary operator. The one subtree is 375 | the type to which the argument should be cast. */ 376 | DEMANGLE_COMPONENT_CAST, 377 | /* A conversion operator, represented as a unary operator. The one 378 | subtree is the type to which the argument should be converted 379 | to. */ 380 | DEMANGLE_COMPONENT_CONVERSION, 381 | /* A nullary expression. The left subtree is the operator. */ 382 | DEMANGLE_COMPONENT_NULLARY, 383 | /* A unary expression. The left subtree is the operator, and the 384 | right subtree is the single argument. */ 385 | DEMANGLE_COMPONENT_UNARY, 386 | /* A binary expression. The left subtree is the operator, and the 387 | right subtree is a BINARY_ARGS. */ 388 | DEMANGLE_COMPONENT_BINARY, 389 | /* Arguments to a binary expression. The left subtree is the first 390 | argument, and the right subtree is the second argument. */ 391 | DEMANGLE_COMPONENT_BINARY_ARGS, 392 | /* A trinary expression. The left subtree is the operator, and the 393 | right subtree is a TRINARY_ARG1. */ 394 | DEMANGLE_COMPONENT_TRINARY, 395 | /* Arguments to a trinary expression. The left subtree is the first 396 | argument, and the right subtree is a TRINARY_ARG2. */ 397 | DEMANGLE_COMPONENT_TRINARY_ARG1, 398 | /* More arguments to a trinary expression. The left subtree is the 399 | second argument, and the right subtree is the third argument. */ 400 | DEMANGLE_COMPONENT_TRINARY_ARG2, 401 | /* A literal. The left subtree is the type, and the right subtree 402 | is the value, represented as a DEMANGLE_COMPONENT_NAME. */ 403 | DEMANGLE_COMPONENT_LITERAL, 404 | /* A negative literal. Like LITERAL, but the value is negated. 405 | This is a minor hack: the NAME used for LITERAL points directly 406 | to the mangled string, but since negative numbers are mangled 407 | using 'n' instead of '-', we want a way to indicate a negative 408 | number which involves neither modifying the mangled string nor 409 | allocating a new copy of the literal in memory. */ 410 | DEMANGLE_COMPONENT_LITERAL_NEG, 411 | /* A vendor's builtin expression. The left subtree holds the 412 | expression's name, and the right subtree is a argument list. */ 413 | DEMANGLE_COMPONENT_VENDOR_EXPR, 414 | /* A libgcj compiled resource. The left subtree is the name of the 415 | resource. */ 416 | DEMANGLE_COMPONENT_JAVA_RESOURCE, 417 | /* A name formed by the concatenation of two parts. The left 418 | subtree is the first part and the right subtree the second. */ 419 | DEMANGLE_COMPONENT_COMPOUND_NAME, 420 | /* A name formed by a single character. */ 421 | DEMANGLE_COMPONENT_CHARACTER, 422 | /* A number. */ 423 | DEMANGLE_COMPONENT_NUMBER, 424 | /* A decltype type. */ 425 | DEMANGLE_COMPONENT_DECLTYPE, 426 | /* Global constructors keyed to name. */ 427 | DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS, 428 | /* Global destructors keyed to name. */ 429 | DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS, 430 | /* A lambda closure type. */ 431 | DEMANGLE_COMPONENT_LAMBDA, 432 | /* A default argument scope. */ 433 | DEMANGLE_COMPONENT_DEFAULT_ARG, 434 | /* An unnamed type. */ 435 | DEMANGLE_COMPONENT_UNNAMED_TYPE, 436 | /* A transactional clone. This has one subtree, the encoding for 437 | which it is providing alternative linkage. */ 438 | DEMANGLE_COMPONENT_TRANSACTION_CLONE, 439 | /* A non-transactional clone entry point. In the i386/x86_64 abi, 440 | the unmangled symbol of a tm_callable becomes a thunk and the 441 | non-transactional function version is mangled thus. */ 442 | DEMANGLE_COMPONENT_NONTRANSACTION_CLONE, 443 | /* A pack expansion. */ 444 | DEMANGLE_COMPONENT_PACK_EXPANSION, 445 | /* A name with an ABI tag. */ 446 | DEMANGLE_COMPONENT_TAGGED_NAME, 447 | /* A transaction-safe function type. */ 448 | DEMANGLE_COMPONENT_TRANSACTION_SAFE, 449 | /* A cloned function. */ 450 | DEMANGLE_COMPONENT_CLONE, 451 | DEMANGLE_COMPONENT_NOEXCEPT, 452 | DEMANGLE_COMPONENT_THROW_SPEC 453 | }; 454 | 455 | /* Types which are only used internally. */ 456 | 457 | struct demangle_operator_info; 458 | struct demangle_builtin_type_info; 459 | 460 | /* A node in the tree representation is an instance of a struct 461 | demangle_component. Note that the field names of the struct are 462 | not well protected against macros defined by the file including 463 | this one. We can fix this if it ever becomes a problem. */ 464 | 465 | struct demangle_component 466 | { 467 | /* The type of this component. */ 468 | enum demangle_component_type type; 469 | 470 | /* Guard against recursive component printing. 471 | Initialize to zero. Private to d_print_comp. 472 | All other fields are final after initialization. */ 473 | int d_printing; 474 | int d_counting; 475 | 476 | union 477 | { 478 | /* For DEMANGLE_COMPONENT_NAME. */ 479 | struct 480 | { 481 | /* A pointer to the name (which need not NULL terminated) and 482 | its length. */ 483 | const char *s; 484 | int len; 485 | } s_name; 486 | 487 | /* For DEMANGLE_COMPONENT_OPERATOR. */ 488 | struct 489 | { 490 | /* Operator. */ 491 | const struct demangle_operator_info *op; 492 | } s_operator; 493 | 494 | /* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */ 495 | struct 496 | { 497 | /* Number of arguments. */ 498 | int args; 499 | /* Name. */ 500 | struct demangle_component *name; 501 | } s_extended_operator; 502 | 503 | /* For DEMANGLE_COMPONENT_FIXED_TYPE. */ 504 | struct 505 | { 506 | /* The length, indicated by a C integer type name. */ 507 | struct demangle_component *length; 508 | /* _Accum or _Fract? */ 509 | short accum; 510 | /* Saturating or not? */ 511 | short sat; 512 | } s_fixed; 513 | 514 | /* For DEMANGLE_COMPONENT_CTOR. */ 515 | struct 516 | { 517 | /* Kind of constructor. */ 518 | enum gnu_v3_ctor_kinds kind; 519 | /* Name. */ 520 | struct demangle_component *name; 521 | } s_ctor; 522 | 523 | /* For DEMANGLE_COMPONENT_DTOR. */ 524 | struct 525 | { 526 | /* Kind of destructor. */ 527 | enum gnu_v3_dtor_kinds kind; 528 | /* Name. */ 529 | struct demangle_component *name; 530 | } s_dtor; 531 | 532 | /* For DEMANGLE_COMPONENT_BUILTIN_TYPE. */ 533 | struct 534 | { 535 | /* Builtin type. */ 536 | const struct demangle_builtin_type_info *type; 537 | } s_builtin; 538 | 539 | /* For DEMANGLE_COMPONENT_SUB_STD. */ 540 | struct 541 | { 542 | /* Standard substitution string. */ 543 | const char* string; 544 | /* Length of string. */ 545 | int len; 546 | } s_string; 547 | 548 | /* For DEMANGLE_COMPONENT_*_PARAM. */ 549 | struct 550 | { 551 | /* Parameter index. */ 552 | long number; 553 | } s_number; 554 | 555 | /* For DEMANGLE_COMPONENT_CHARACTER. */ 556 | struct 557 | { 558 | int character; 559 | } s_character; 560 | 561 | /* For other types. */ 562 | struct 563 | { 564 | /* Left (or only) subtree. */ 565 | struct demangle_component *left; 566 | /* Right subtree. */ 567 | struct demangle_component *right; 568 | } s_binary; 569 | 570 | struct 571 | { 572 | /* subtree, same place as d_left. */ 573 | struct demangle_component *sub; 574 | /* integer. */ 575 | int num; 576 | } s_unary_num; 577 | 578 | } u; 579 | }; 580 | 581 | /* People building mangled trees are expected to allocate instances of 582 | struct demangle_component themselves. They can then call one of 583 | the following functions to fill them in. */ 584 | 585 | /* Fill in most component types with a left subtree and a right 586 | subtree. Returns non-zero on success, zero on failure, such as an 587 | unrecognized or inappropriate component type. */ 588 | 589 | extern int 590 | cplus_demangle_fill_component (struct demangle_component *fill, 591 | enum demangle_component_type, 592 | struct demangle_component *left, 593 | struct demangle_component *right); 594 | 595 | /* Fill in a DEMANGLE_COMPONENT_NAME. Returns non-zero on success, 596 | zero for bad arguments. */ 597 | 598 | extern int 599 | cplus_demangle_fill_name (struct demangle_component *fill, 600 | const char *, int); 601 | 602 | /* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the 603 | builtin type (e.g., "int", etc.). Returns non-zero on success, 604 | zero if the type is not recognized. */ 605 | 606 | extern int 607 | cplus_demangle_fill_builtin_type (struct demangle_component *fill, 608 | const char *type_name); 609 | 610 | /* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the 611 | operator and the number of arguments which it takes (the latter is 612 | used to disambiguate operators which can be both binary and unary, 613 | such as '-'). Returns non-zero on success, zero if the operator is 614 | not recognized. */ 615 | 616 | extern int 617 | cplus_demangle_fill_operator (struct demangle_component *fill, 618 | const char *opname, int args); 619 | 620 | /* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the 621 | number of arguments and the name. Returns non-zero on success, 622 | zero for bad arguments. */ 623 | 624 | extern int 625 | cplus_demangle_fill_extended_operator (struct demangle_component *fill, 626 | int numargs, 627 | struct demangle_component *nm); 628 | 629 | /* Fill in a DEMANGLE_COMPONENT_CTOR. Returns non-zero on success, 630 | zero for bad arguments. */ 631 | 632 | extern int 633 | cplus_demangle_fill_ctor (struct demangle_component *fill, 634 | enum gnu_v3_ctor_kinds kind, 635 | struct demangle_component *name); 636 | 637 | /* Fill in a DEMANGLE_COMPONENT_DTOR. Returns non-zero on success, 638 | zero for bad arguments. */ 639 | 640 | extern int 641 | cplus_demangle_fill_dtor (struct demangle_component *fill, 642 | enum gnu_v3_dtor_kinds kind, 643 | struct demangle_component *name); 644 | 645 | /* This function translates a mangled name into a struct 646 | demangle_component tree. The first argument is the mangled name. 647 | The second argument is DMGL_* options. This returns a pointer to a 648 | tree on success, or NULL on failure. On success, the third 649 | argument is set to a block of memory allocated by malloc. This 650 | block should be passed to free when the tree is no longer 651 | needed. */ 652 | 653 | extern struct demangle_component * 654 | cplus_demangle_v3_components (const char *mangled, int options, void **mem); 655 | 656 | /* This function takes a struct demangle_component tree and returns 657 | the corresponding demangled string. The first argument is DMGL_* 658 | options. The second is the tree to demangle. The third is a guess 659 | at the length of the demangled string, used to initially allocate 660 | the return buffer. The fourth is a pointer to a size_t. On 661 | success, this function returns a buffer allocated by malloc(), and 662 | sets the size_t pointed to by the fourth argument to the size of 663 | the allocated buffer (not the length of the returned string). On 664 | failure, this function returns NULL, and sets the size_t pointed to 665 | by the fourth argument to 0 for an invalid tree, or to 1 for a 666 | memory allocation error. */ 667 | 668 | extern char * 669 | cplus_demangle_print (int options, 670 | struct demangle_component *tree, 671 | int estimated_length, 672 | size_t *p_allocated_size); 673 | 674 | /* This function takes a struct demangle_component tree and passes back 675 | a demangled string in one or more calls to a callback function. 676 | The first argument is DMGL_* options. The second is the tree to 677 | demangle. The third is a pointer to a callback function; on each call 678 | this receives an element of the demangled string, its length, and an 679 | opaque value. The fourth is the opaque value passed to the callback. 680 | The callback is called once or more to return the full demangled 681 | string. The demangled element string is always nul-terminated, though 682 | its length is also provided for convenience. In contrast to 683 | cplus_demangle_print(), this function does not allocate heap memory 684 | to grow output strings (except perhaps where alloca() is implemented 685 | by malloc()), and so is normally safe for use where the heap has been 686 | corrupted. On success, this function returns 1; on failure, 0. */ 687 | 688 | extern int 689 | cplus_demangle_print_callback (int options, 690 | struct demangle_component *tree, 691 | demangle_callbackref callback, void *opaque); 692 | 693 | #ifdef __cplusplus 694 | } 695 | #endif /* __cplusplus */ 696 | 697 | #endif /* DEMANGLE_H */ 698 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/libiberty.h: -------------------------------------------------------------------------------- 1 | /* Function declarations for libiberty. 2 | 3 | Copyright (C) 1997-2021 Free Software Foundation, Inc. 4 | 5 | Note - certain prototypes declared in this header file are for 6 | functions whoes implementation copyright does not belong to the 7 | FSF. Those prototypes are present in this file for reference 8 | purposes only and their presence in this file should not construed 9 | as an indication of ownership by the FSF of the implementation of 10 | those functions in any way or form whatsoever. 11 | 12 | This program is free software; you can redistribute it and/or modify 13 | it under the terms of the GNU General Public License as published by 14 | the Free Software Foundation; either version 2, or (at your option) 15 | any later version. 16 | 17 | This program is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | GNU General Public License for more details. 21 | 22 | You should have received a copy of the GNU General Public License 23 | along with this program; if not, write to the Free Software 24 | Foundation, Inc., 51 Franklin Street - Fifth Floor, 25 | Boston, MA 02110-1301, USA. 26 | 27 | Written by Cygnus Support, 1994. 28 | 29 | The libiberty library provides a number of functions which are 30 | missing on some operating systems. We do not declare those here, 31 | to avoid conflicts with the system header files on operating 32 | systems that do support those functions. In this file we only 33 | declare those functions which are specific to libiberty. */ 34 | 35 | #ifndef LIBIBERTY_H 36 | #define LIBIBERTY_H 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | #include "ansidecl.h" 43 | 44 | /* Get a definition for size_t. */ 45 | #include 46 | /* Get a definition for va_list. */ 47 | #include 48 | 49 | #include 50 | 51 | /* If the OS supports it, ensure that the supplied stream is setup to 52 | avoid any multi-threaded locking. Otherwise leave the FILE pointer 53 | unchanged. If the stream is NULL do nothing. */ 54 | 55 | extern void unlock_stream (FILE *); 56 | 57 | /* If the OS supports it, ensure that the standard I/O streams, stdin, 58 | stdout and stderr are setup to avoid any multi-threaded locking. 59 | Otherwise do nothing. */ 60 | 61 | extern void unlock_std_streams (void); 62 | 63 | /* Open and return a FILE pointer. If the OS supports it, ensure that 64 | the stream is setup to avoid any multi-threaded locking. Otherwise 65 | return the FILE pointer unchanged. */ 66 | 67 | extern FILE *fopen_unlocked (const char *, const char *); 68 | extern FILE *fdopen_unlocked (int, const char *); 69 | extern FILE *freopen_unlocked (const char *, const char *, FILE *); 70 | 71 | /* Build an argument vector from a string. Allocates memory using 72 | malloc. Use freeargv to free the vector. */ 73 | 74 | extern char **buildargv (const char *) ATTRIBUTE_MALLOC; 75 | 76 | /* Free a vector returned by buildargv. */ 77 | 78 | extern void freeargv (char **); 79 | 80 | /* Duplicate an argument vector. Allocates memory using malloc. Use 81 | freeargv to free the vector. */ 82 | 83 | extern char **dupargv (char * const *) ATTRIBUTE_MALLOC; 84 | 85 | /* Expand "@file" arguments in argv. */ 86 | 87 | extern void expandargv (int *, char ***); 88 | 89 | /* Write argv to an @-file, inserting necessary quoting. */ 90 | 91 | extern int writeargv (char * const *, FILE *); 92 | 93 | /* Return the number of elements in argv. */ 94 | 95 | extern int countargv (char * const *); 96 | 97 | /* Return the last component of a path name. Note that we can't use a 98 | prototype here because the parameter is declared inconsistently 99 | across different systems, sometimes as "char *" and sometimes as 100 | "const char *" */ 101 | 102 | /* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is 103 | undefined, we haven't run the autoconf check so provide the 104 | declaration without arguments. If it is 0, we checked and failed 105 | to find the declaration so provide a fully prototyped one. If it 106 | is 1, we found it so don't provide any declaration at all. */ 107 | #if !HAVE_DECL_BASENAME 108 | #if defined (__GNU_LIBRARY__ ) || defined (__linux__) \ 109 | || defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__) \ 110 | || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) \ 111 | || defined (__DragonFly__) || defined (HAVE_DECL_BASENAME) 112 | extern char *base_name (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); // Rename basename -> basename conflict Qt 113 | #else 114 | /* Do not allow basename to be used if there is no prototype seen. We 115 | either need to use the above prototype or have one from 116 | autoconf which would result in HAVE_DECL_BASENAME being set. */ 117 | #define basename basename_cannot_be_used_without_a_prototype 118 | #endif 119 | #endif 120 | 121 | /* A well-defined basename () that is always compiled in. */ 122 | 123 | extern const char *lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); 124 | 125 | /* Same, but assumes DOS semantics (drive name, backslash is also a 126 | dir separator) regardless of host. */ 127 | 128 | extern const char *dos_lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); 129 | 130 | /* Same, but assumes Unix semantics (absolute paths always start with 131 | a slash, only forward slash is accepted as dir separator) 132 | regardless of host. */ 133 | 134 | extern const char *unix_lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); 135 | 136 | /* A well-defined realpath () that is always compiled in. */ 137 | 138 | extern char *lrealpath (const char *); 139 | 140 | /* Return true when FD file descriptor exists. */ 141 | 142 | extern int is_valid_fd (int fd); 143 | 144 | /* Concatenate an arbitrary number of strings. You must pass NULL as 145 | the last argument of this function, to terminate the list of 146 | strings. Allocates memory using xmalloc. */ 147 | 148 | extern char *concat (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_SENTINEL; 149 | 150 | /* Concatenate an arbitrary number of strings. You must pass NULL as 151 | the last argument of this function, to terminate the list of 152 | strings. Allocates memory using xmalloc. The first argument is 153 | not one of the strings to be concatenated, but if not NULL is a 154 | pointer to be freed after the new string is created, similar to the 155 | way xrealloc works. */ 156 | 157 | extern char *reconcat (char *, const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_SENTINEL; 158 | 159 | /* Determine the length of concatenating an arbitrary number of 160 | strings. You must pass NULL as the last argument of this function, 161 | to terminate the list of strings. */ 162 | 163 | extern unsigned long concat_length (const char *, ...) ATTRIBUTE_SENTINEL; 164 | 165 | /* Concatenate an arbitrary number of strings into a SUPPLIED area of 166 | memory. You must pass NULL as the last argument of this function, 167 | to terminate the list of strings. The supplied memory is assumed 168 | to be large enough. */ 169 | 170 | extern char *concat_copy (char *, const char *, ...) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL; 171 | 172 | /* Concatenate an arbitrary number of strings into a GLOBAL area of 173 | memory. You must pass NULL as the last argument of this function, 174 | to terminate the list of strings. The supplied memory is assumed 175 | to be large enough. */ 176 | 177 | extern char *concat_copy2 (const char *, ...) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_SENTINEL; 178 | 179 | /* This is the global area used by concat_copy2. */ 180 | 181 | extern char *libiberty_concat_ptr; 182 | 183 | /* Concatenate an arbitrary number of strings. You must pass NULL as 184 | the last argument of this function, to terminate the list of 185 | strings. Allocates memory using alloca. The arguments are 186 | evaluated twice! */ 187 | #define ACONCAT(ACONCAT_PARAMS) \ 188 | (libiberty_concat_ptr = (char *) alloca (concat_length ACONCAT_PARAMS + 1), \ 189 | concat_copy2 ACONCAT_PARAMS) 190 | 191 | /* Check whether two file descriptors refer to the same file. */ 192 | 193 | extern int fdmatch (int fd1, int fd2); 194 | 195 | /* Return the position of the first bit set in the argument. */ 196 | /* Prototypes vary from system to system, so we only provide a 197 | prototype on systems where we know that we need it. */ 198 | #if defined (HAVE_DECL_FFS) && !HAVE_DECL_FFS 199 | extern int ffs(int); 200 | #endif 201 | 202 | /* Get the working directory. The result is cached, so don't call 203 | chdir() between calls to getpwd(). */ 204 | 205 | extern char * getpwd (void); 206 | 207 | /* Get the current time. */ 208 | /* Prototypes vary from system to system, so we only provide a 209 | prototype on systems where we know that we need it. */ 210 | #ifdef __MINGW32__ 211 | /* Forward declaration to avoid #include . */ 212 | struct timeval; 213 | extern int gettimeofday (struct timeval *, void *); 214 | #endif 215 | 216 | /* Get the amount of time the process has run, in microseconds. */ 217 | 218 | extern long get_run_time (void); 219 | 220 | /* Generate a relocated path to some installation directory. Allocates 221 | return value using malloc. */ 222 | 223 | extern char *make_relative_prefix (const char *, const char *, 224 | const char *) ATTRIBUTE_MALLOC; 225 | 226 | /* Generate a relocated path to some installation directory without 227 | attempting to follow any soft links. Allocates 228 | return value using malloc. */ 229 | 230 | extern char *make_relative_prefix_ignore_links (const char *, const char *, 231 | const char *) ATTRIBUTE_MALLOC; 232 | 233 | /* Returns a pointer to a directory path suitable for creating temporary 234 | files in. */ 235 | 236 | extern const char *choose_tmpdir (void) ATTRIBUTE_RETURNS_NONNULL; 237 | 238 | /* Choose a temporary directory to use for scratch files. */ 239 | 240 | extern char *choose_temp_base (void) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL; 241 | 242 | /* Return a temporary file name or NULL if unable to create one. */ 243 | 244 | extern char *make_temp_file (const char *) ATTRIBUTE_MALLOC; 245 | 246 | /* Return a temporary file name with given PREFIX and SUFFIX 247 | or NULL if unable to create one. */ 248 | 249 | extern char *make_temp_file_with_prefix (const char *, const char *) ATTRIBUTE_MALLOC; 250 | 251 | /* Remove a link to a file unless it is special. */ 252 | 253 | extern int unlink_if_ordinary (const char *); 254 | 255 | /* Allocate memory filled with spaces. Allocates using malloc. */ 256 | 257 | extern const char *spaces (int count); 258 | 259 | /* Return the maximum error number for which strerror will return a 260 | string. */ 261 | 262 | extern int errno_max (void); 263 | 264 | /* Return the name of an errno value (e.g., strerrno (EINVAL) returns 265 | "EINVAL"). */ 266 | 267 | extern const char *strerrno (int); 268 | 269 | /* Given the name of an errno value, return the value. */ 270 | 271 | extern int strtoerrno (const char *); 272 | 273 | /* ANSI's strerror(), but more robust. */ 274 | 275 | extern char *xstrerror (int) ATTRIBUTE_RETURNS_NONNULL; 276 | 277 | /* Return the maximum signal number for which strsignal will return a 278 | string. */ 279 | 280 | extern int signo_max (void); 281 | 282 | /* Return a signal message string for a signal number 283 | (e.g., strsignal (SIGHUP) returns something like "Hangup"). */ 284 | /* This is commented out as it can conflict with one in system headers. 285 | We still document its existence though. */ 286 | 287 | /*extern const char *strsignal (int);*/ 288 | 289 | /* Return the name of a signal number (e.g., strsigno (SIGHUP) returns 290 | "SIGHUP"). */ 291 | 292 | extern const char *strsigno (int); 293 | 294 | /* Given the name of a signal, return its number. */ 295 | 296 | extern int strtosigno (const char *); 297 | 298 | /* Register a function to be run by xexit. Returns 0 on success. */ 299 | 300 | extern int xatexit (void (*fn) (void)); 301 | 302 | /* Exit, calling all the functions registered with xatexit. */ 303 | 304 | extern void xexit (int status) ATTRIBUTE_NORETURN; 305 | 306 | /* Set the program name used by xmalloc. */ 307 | 308 | extern void xmalloc_set_program_name (const char *); 309 | 310 | /* Report an allocation failure. */ 311 | extern void xmalloc_failed (size_t) ATTRIBUTE_NORETURN; 312 | 313 | /* Allocate memory without fail. If malloc fails, this will print a 314 | message to stderr (using the name set by xmalloc_set_program_name, 315 | if any) and then call xexit. */ 316 | 317 | extern void *xmalloc (size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_RESULT_SIZE_1 ATTRIBUTE_WARN_UNUSED_RESULT; 318 | 319 | /* Reallocate memory without fail. This works like xmalloc. Note, 320 | realloc type functions are not suitable for attribute malloc since 321 | they may return the same address across multiple calls. */ 322 | 323 | extern void *xrealloc (void *, size_t) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_RESULT_SIZE_2 ATTRIBUTE_WARN_UNUSED_RESULT; 324 | 325 | /* Allocate memory without fail and set it to zero. This works like 326 | xmalloc. */ 327 | 328 | extern void *xcalloc (size_t, size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_RESULT_SIZE_1_2 ATTRIBUTE_WARN_UNUSED_RESULT; 329 | 330 | /* Copy a string into a memory buffer without fail. */ 331 | 332 | extern char *xstrdup (const char *) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_WARN_UNUSED_RESULT; 333 | 334 | /* Copy at most N characters from string into a buffer without fail. */ 335 | 336 | extern char *xstrndup (const char *, size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_WARN_UNUSED_RESULT; 337 | 338 | /* Copy an existing memory buffer to a new memory buffer without fail. */ 339 | 340 | extern void *xmemdup (const void *, size_t, size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_WARN_UNUSED_RESULT; 341 | 342 | /* Physical memory routines. Return values are in BYTES. */ 343 | extern double physmem_total (void); 344 | extern double physmem_available (void); 345 | 346 | /* Compute the 32-bit CRC of a block of memory. */ 347 | extern unsigned int xcrc32 (const unsigned char *, int, unsigned int); 348 | 349 | /* These macros provide a K&R/C89/C++-friendly way of allocating structures 350 | with nice encapsulation. The XDELETE*() macros are technically 351 | superfluous, but provided here for symmetry. Using them consistently 352 | makes it easier to update client code to use different allocators such 353 | as new/delete and new[]/delete[]. */ 354 | 355 | /* Scalar allocators. */ 356 | 357 | #define XALLOCA(T) ((T *) alloca (sizeof (T))) 358 | #define XNEW(T) ((T *) xmalloc (sizeof (T))) 359 | #define XCNEW(T) ((T *) xcalloc (1, sizeof (T))) 360 | #define XDUP(T, P) ((T *) xmemdup ((P), sizeof (T), sizeof (T))) 361 | #define XDELETE(P) free ((void*) (P)) 362 | 363 | /* Array allocators. */ 364 | 365 | #define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N))) 366 | #define XNEWVEC(T, N) ((T *) xmalloc (sizeof (T) * (N))) 367 | #define XCNEWVEC(T, N) ((T *) xcalloc ((N), sizeof (T))) 368 | #define XDUPVEC(T, P, N) ((T *) xmemdup ((P), sizeof (T) * (N), sizeof (T) * (N))) 369 | #define XRESIZEVEC(T, P, N) ((T *) xrealloc ((void *) (P), sizeof (T) * (N))) 370 | #define XDELETEVEC(P) free ((void*) (P)) 371 | 372 | /* Allocators for variable-sized structures and raw buffers. */ 373 | 374 | #define XALLOCAVAR(T, S) ((T *) alloca ((S))) 375 | #define XNEWVAR(T, S) ((T *) xmalloc ((S))) 376 | #define XCNEWVAR(T, S) ((T *) xcalloc (1, (S))) 377 | #define XDUPVAR(T, P, S1, S2) ((T *) xmemdup ((P), (S1), (S2))) 378 | #define XRESIZEVAR(T, P, S) ((T *) xrealloc ((P), (S))) 379 | 380 | /* Type-safe obstack allocator. */ 381 | 382 | #define XOBNEW(O, T) ((T *) obstack_alloc ((O), sizeof (T))) 383 | #define XOBNEWVEC(O, T, N) ((T *) obstack_alloc ((O), sizeof (T) * (N))) 384 | #define XOBNEWVAR(O, T, S) ((T *) obstack_alloc ((O), (S))) 385 | #define XOBFINISH(O, T) ((T) obstack_finish ((O))) 386 | 387 | /* hex character manipulation routines */ 388 | 389 | #define _hex_array_size 256 390 | #define _hex_bad 99 391 | extern const unsigned char _hex_value[_hex_array_size]; 392 | extern void hex_init (void); 393 | #define hex_p(c) (hex_value (c) != _hex_bad) 394 | /* If you change this, note well: Some code relies on side effects in 395 | the argument being performed exactly once. */ 396 | #define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)]) 397 | 398 | /* Flags for pex_init. These are bits to be or'ed together. */ 399 | 400 | /* Record subprocess times, if possible. */ 401 | #define PEX_RECORD_TIMES 0x1 402 | 403 | /* Use pipes for communication between processes, if possible. */ 404 | #define PEX_USE_PIPES 0x2 405 | 406 | /* Save files used for communication between processes. */ 407 | #define PEX_SAVE_TEMPS 0x4 408 | 409 | /* Max number of alloca bytes per call before we must switch to malloc. 410 | 411 | ?? Swiped from gnulib's regex_internal.h header. Is this actually 412 | the case? This number seems arbitrary, though sane. 413 | 414 | The OS usually guarantees only one guard page at the bottom of the stack, 415 | and a page size can be as small as 4096 bytes. So we cannot safely 416 | allocate anything larger than 4096 bytes. Also care for the possibility 417 | of a few compiler-allocated temporary stack slots. */ 418 | #define MAX_ALLOCA_SIZE 4032 419 | 420 | /* Prepare to execute one or more programs, with standard output of 421 | each program fed to standard input of the next. 422 | FLAGS As above. 423 | PNAME The name of the program to report in error messages. 424 | TEMPBASE A base name to use for temporary files; may be NULL to 425 | use a random name. 426 | Returns NULL on error. */ 427 | 428 | extern struct pex_obj *pex_init (int flags, const char *pname, 429 | const char *tempbase) ATTRIBUTE_RETURNS_NONNULL; 430 | 431 | /* Flags for pex_run. These are bits to be or'ed together. */ 432 | 433 | /* Last program in pipeline. Standard output of program goes to 434 | OUTNAME, or, if OUTNAME is NULL, to standard output of caller. Do 435 | not set this if you want to call pex_read_output. After this is 436 | set, pex_run may no longer be called with the same struct 437 | pex_obj. */ 438 | #define PEX_LAST 0x1 439 | 440 | /* Search for program in executable search path. */ 441 | #define PEX_SEARCH 0x2 442 | 443 | /* OUTNAME is a suffix. */ 444 | #define PEX_SUFFIX 0x4 445 | 446 | /* Send program's standard error to standard output. */ 447 | #define PEX_STDERR_TO_STDOUT 0x8 448 | 449 | /* Input file should be opened in binary mode. This flag is ignored 450 | on Unix. */ 451 | #define PEX_BINARY_INPUT 0x10 452 | 453 | /* Output file should be opened in binary mode. This flag is ignored 454 | on Unix. For proper behaviour PEX_BINARY_INPUT and 455 | PEX_BINARY_OUTPUT have to match appropriately--i.e., a call using 456 | PEX_BINARY_OUTPUT should be followed by a call using 457 | PEX_BINARY_INPUT. */ 458 | #define PEX_BINARY_OUTPUT 0x20 459 | 460 | /* Capture stderr to a pipe. The output can be read by 461 | calling pex_read_err and reading from the returned 462 | FILE object. This flag may be specified only for 463 | the last program in a pipeline. 464 | 465 | This flag is supported only on Unix and Windows. */ 466 | #define PEX_STDERR_TO_PIPE 0x40 467 | 468 | /* Capture stderr in binary mode. This flag is ignored 469 | on Unix. */ 470 | #define PEX_BINARY_ERROR 0x80 471 | 472 | /* Append stdout to existing file instead of truncating it. */ 473 | #define PEX_STDOUT_APPEND 0x100 474 | 475 | /* Thes same as PEX_STDOUT_APPEND, but for STDERR. */ 476 | #define PEX_STDERR_APPEND 0x200 477 | 478 | /* Execute one program. Returns NULL on success. On error returns an 479 | error string (typically just the name of a system call); the error 480 | string is statically allocated. 481 | 482 | OBJ Returned by pex_init. 483 | 484 | FLAGS As above. 485 | 486 | EXECUTABLE The program to execute. 487 | 488 | ARGV NULL terminated array of arguments to pass to the program. 489 | 490 | OUTNAME Sets the output file name as follows: 491 | 492 | PEX_SUFFIX set (OUTNAME may not be NULL): 493 | TEMPBASE parameter to pex_init not NULL: 494 | Output file name is the concatenation of TEMPBASE 495 | and OUTNAME. 496 | TEMPBASE is NULL: 497 | Output file name is a random file name ending in 498 | OUTNAME. 499 | PEX_SUFFIX not set: 500 | OUTNAME not NULL: 501 | Output file name is OUTNAME. 502 | OUTNAME NULL, TEMPBASE not NULL: 503 | Output file name is randomly chosen using 504 | TEMPBASE. 505 | OUTNAME NULL, TEMPBASE NULL: 506 | Output file name is randomly chosen. 507 | 508 | If PEX_LAST is not set, the output file name is the 509 | name to use for a temporary file holding stdout, if 510 | any (there will not be a file if PEX_USE_PIPES is set 511 | and the system supports pipes). If a file is used, it 512 | will be removed when no longer needed unless 513 | PEX_SAVE_TEMPS is set. 514 | 515 | If PEX_LAST is set, and OUTNAME is not NULL, standard 516 | output is written to the output file name. The file 517 | will not be removed. If PEX_LAST and PEX_SUFFIX are 518 | both set, TEMPBASE may not be NULL. 519 | 520 | ERRNAME If not NULL, this is the name of a file to which 521 | standard error is written. If NULL, standard error of 522 | the program is standard error of the caller. 523 | 524 | ERR On an error return, *ERR is set to an errno value, or 525 | to 0 if there is no relevant errno. 526 | */ 527 | 528 | extern const char *pex_run (struct pex_obj *obj, int flags, 529 | const char *executable, char * const *argv, 530 | const char *outname, const char *errname, 531 | int *err); 532 | 533 | /* As for pex_run (), but takes an extra parameter to enable the 534 | environment for the child process to be specified. 535 | 536 | ENV The environment for the child process, specified as 537 | an array of character pointers. Each element of the 538 | array should point to a string of the form VAR=VALUE, 539 | with the exception of the last element which must be 540 | a null pointer. 541 | */ 542 | 543 | extern const char *pex_run_in_environment (struct pex_obj *obj, int flags, 544 | const char *executable, 545 | char * const *argv, 546 | char * const *env, 547 | const char *outname, 548 | const char *errname, int *err); 549 | 550 | /* Return a stream for a temporary file to pass to the first program 551 | in the pipeline as input. The file name is chosen as for pex_run. 552 | pex_run closes the file automatically; don't close it yourself. */ 553 | 554 | extern FILE *pex_input_file (struct pex_obj *obj, int flags, 555 | const char *in_name); 556 | 557 | /* Return a stream for a pipe connected to the standard input of the 558 | first program in the pipeline. You must have passed 559 | `PEX_USE_PIPES' to `pex_init'. Close the returned stream 560 | yourself. */ 561 | 562 | extern FILE *pex_input_pipe (struct pex_obj *obj, int binary); 563 | 564 | /* Read the standard output of the last program to be executed. 565 | pex_run cannot be called after this. BINARY should be non-zero if 566 | the file should be opened in binary mode; this is ignored on Unix. 567 | Returns NULL on error. Don't call fclose on the returned FILE; it 568 | will be closed by pex_free. */ 569 | 570 | extern FILE *pex_read_output (struct pex_obj *, int binary); 571 | 572 | /* Read the standard error of the last program to be executed. 573 | pex_run cannot be called after this. BINARY should be non-zero if 574 | the file should be opened in binary mode; this is ignored on Unix. 575 | Returns NULL on error. Don't call fclose on the returned FILE; it 576 | will be closed by pex_free. */ 577 | 578 | extern FILE *pex_read_err (struct pex_obj *, int binary); 579 | 580 | /* Return exit status of all programs in VECTOR. COUNT indicates the 581 | size of VECTOR. The status codes in the vector are in the order of 582 | the calls to pex_run. Returns 0 on error, 1 on success. */ 583 | 584 | extern int pex_get_status (struct pex_obj *, int count, int *vector); 585 | 586 | /* Return times of all programs in VECTOR. COUNT indicates the size 587 | of VECTOR. struct pex_time is really just struct timeval, but that 588 | is not portable to all systems. Returns 0 on error, 1 on 589 | success. */ 590 | 591 | struct pex_time 592 | { 593 | unsigned long user_seconds; 594 | unsigned long user_microseconds; 595 | unsigned long system_seconds; 596 | unsigned long system_microseconds; 597 | }; 598 | 599 | extern int pex_get_times (struct pex_obj *, int count, 600 | struct pex_time *vector); 601 | 602 | /* Clean up a pex_obj. If you have not called pex_get_times or 603 | pex_get_status, this will try to kill the subprocesses. */ 604 | 605 | extern void pex_free (struct pex_obj *); 606 | 607 | /* Just execute one program. Return value is as for pex_run. 608 | FLAGS Combination of PEX_SEARCH and PEX_STDERR_TO_STDOUT. 609 | EXECUTABLE As for pex_run. 610 | ARGV As for pex_run. 611 | PNAME As for pex_init. 612 | OUTNAME As for pex_run when PEX_LAST is set. 613 | ERRNAME As for pex_run. 614 | STATUS Set to exit status on success. 615 | ERR As for pex_run. 616 | */ 617 | 618 | extern const char *pex_one (int flags, const char *executable, 619 | char * const *argv, const char *pname, 620 | const char *outname, const char *errname, 621 | int *status, int *err); 622 | 623 | /* pexecute and pwait are the old pexecute interface, still here for 624 | backward compatibility. Don't use these for new code. Instead, 625 | use pex_init/pex_run/pex_get_status/pex_free, or pex_one. */ 626 | 627 | /* Definitions used by the pexecute routine. */ 628 | 629 | #define PEXECUTE_FIRST 1 630 | #define PEXECUTE_LAST 2 631 | #define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) 632 | #define PEXECUTE_SEARCH 4 633 | #define PEXECUTE_VERBOSE 8 634 | 635 | /* Execute a program. */ 636 | 637 | extern int pexecute (const char *, char * const *, const char *, 638 | const char *, char **, char **, int); 639 | 640 | /* Wait for pexecute to finish. */ 641 | 642 | extern int pwait (int, int *, int); 643 | 644 | /* Like bsearch, but takes and passes on an argument like qsort_r. */ 645 | 646 | extern void *bsearch_r (const void *, const void *, 647 | size_t, size_t, 648 | int (*)(const void *, const void *, void *), 649 | void *); 650 | 651 | #if defined(HAVE_DECL_ASPRINTF) && !HAVE_DECL_ASPRINTF 652 | /* Like sprintf but provides a pointer to malloc'd storage, which must 653 | be freed by the caller. */ 654 | 655 | extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2; 656 | #endif 657 | 658 | /* Like asprintf but allocates memory without fail. This works like 659 | xmalloc. */ 660 | 661 | extern char *xasprintf (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_PRINTF_1; 662 | 663 | #if defined(HAVE_DECL_VASPRINTF) && !HAVE_DECL_VASPRINTF 664 | /* Like vsprintf but provides a pointer to malloc'd storage, which 665 | must be freed by the caller. */ 666 | 667 | extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0); 668 | #endif 669 | 670 | /* Like vasprintf but allocates memory without fail. This works like 671 | xmalloc. */ 672 | 673 | extern char *xvasprintf (const char *, va_list) ATTRIBUTE_MALLOC ATTRIBUTE_PRINTF(1,0); 674 | 675 | #if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF 676 | /* Like sprintf but prints at most N characters. */ 677 | extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3; 678 | #endif 679 | 680 | #if defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF 681 | /* Like vsprintf but prints at most N characters. */ 682 | extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0); 683 | #endif 684 | 685 | #if defined (HAVE_DECL_STRNLEN) && !HAVE_DECL_STRNLEN 686 | extern size_t strnlen (const char *, size_t); 687 | #endif 688 | 689 | #if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP 690 | /* Compare version strings. */ 691 | extern int strverscmp (const char *, const char *); 692 | #endif 693 | 694 | #if defined(HAVE_DECL_STRTOL) && !HAVE_DECL_STRTOL 695 | extern long int strtol (const char *nptr, 696 | char **endptr, int base); 697 | #endif 698 | 699 | #if defined(HAVE_DECL_STRTOUL) && !HAVE_DECL_STRTOUL 700 | extern unsigned long int strtoul (const char *nptr, 701 | char **endptr, int base); 702 | #endif 703 | 704 | #if defined(HAVE_LONG_LONG) && defined(HAVE_DECL_STRTOLL) && !HAVE_DECL_STRTOLL 705 | __extension__ 706 | extern long long int strtoll (const char *nptr, 707 | char **endptr, int base); 708 | #endif 709 | 710 | #if defined(HAVE_LONG_LONG) && defined(HAVE_DECL_STRTOULL) && !HAVE_DECL_STRTOULL 711 | __extension__ 712 | extern unsigned long long int strtoull (const char *nptr, 713 | char **endptr, int base); 714 | #endif 715 | 716 | #if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP 717 | /* Compare version strings. */ 718 | extern int strverscmp (const char *, const char *); 719 | #endif 720 | 721 | /* Set the title of a process */ 722 | extern void setproctitle (const char *name, ...); 723 | 724 | /* Increase stack limit if possible. */ 725 | extern void stack_limit_increase (unsigned long); 726 | 727 | #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) 728 | 729 | /* Drastically simplified alloca configurator. If we're using GCC, 730 | we use __builtin_alloca; otherwise we use the C alloca. The C 731 | alloca is always available. You can override GCC by defining 732 | USE_C_ALLOCA yourself. The canonical autoconf macro C_ALLOCA is 733 | also set/unset as it is often used to indicate whether code needs 734 | to call alloca(0). */ 735 | extern void *C_alloca (size_t) ATTRIBUTE_MALLOC; 736 | #undef alloca 737 | #if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA 738 | # define alloca(x) __builtin_alloca(x) 739 | # undef C_ALLOCA 740 | # define ASTRDUP(X) \ 741 | (__extension__ ({ const char *const libiberty_optr = (X); \ 742 | const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \ 743 | char *const libiberty_nptr = (char *) alloca (libiberty_len); \ 744 | (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); })) 745 | #else 746 | # define alloca(x) _alloca(x) 747 | # undef USE_C_ALLOCA 748 | //# define alloca(x) C_alloca(x) 749 | //# undef USE_C_ALLOCA 750 | //# define USE_C_ALLOCA 1 751 | //# undef C_ALLOCA 752 | //# define C_ALLOCA 1 753 | extern const char *libiberty_optr; 754 | extern char *libiberty_nptr; 755 | extern unsigned long libiberty_len; 756 | # define ASTRDUP(X) \ 757 | (libiberty_optr = (X), \ 758 | libiberty_len = strlen (libiberty_optr) + 1, \ 759 | libiberty_nptr = (char *) alloca (libiberty_len), \ 760 | (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len)) 761 | #endif 762 | 763 | #ifdef __cplusplus 764 | } 765 | #endif 766 | 767 | 768 | #endif /* ! defined (LIBIBERTY_H) */ 769 | -------------------------------------------------------------------------------- /3rdparty/cppfilt/src/rust-demangle.c: -------------------------------------------------------------------------------- 1 | /* Demangler for the Rust programming language 2 | Copyright (C) 2016-2021 Free Software Foundation, Inc. 3 | Written by David Tolnay (dtolnay@gmail.com). 4 | Rewritten by Eduard-Mihai Burtescu (eddyb@lyken.rs) for v0 support. 5 | 6 | This file is part of the libiberty library. 7 | Libiberty is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Library General Public 9 | License as published by the Free Software Foundation; either 10 | version 2 of the License, or (at your option) any later version. 11 | 12 | In addition to the permissions in the GNU Library General Public 13 | License, the Free Software Foundation gives you unlimited permission 14 | to link the compiled version of this file into combinations with other 15 | programs, and to distribute those combinations without any restriction 16 | coming from the use of this file. (The Library Public License 17 | restrictions do apply in other respects; for example, they cover 18 | modification of the file, and distribution when not linked into a 19 | combined executable.) 20 | 21 | Libiberty is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 | Library General Public License for more details. 25 | 26 | You should have received a copy of the GNU Library General Public 27 | License along with libiberty; see the file COPYING.LIB. 28 | If not, see . */ 29 | 30 | 31 | #ifdef HAVE_CONFIG_H 32 | #include "config.h" 33 | #endif 34 | 35 | #include "safe-ctype.h" 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #ifdef HAVE_STRING_H 44 | #include 45 | #else 46 | extern size_t strlen(const char *s); 47 | extern int strncmp(const char *s1, const char *s2, size_t n); 48 | extern void *memset(void *s, int c, size_t n); 49 | #endif 50 | 51 | #include 52 | #include "libiberty.h" 53 | 54 | struct rust_demangler 55 | { 56 | const char *sym; 57 | size_t sym_len; 58 | 59 | void *callback_opaque; 60 | demangle_callbackref callback; 61 | 62 | /* Position of the next character to read from the symbol. */ 63 | size_t next; 64 | 65 | /* Non-zero if any error occurred. */ 66 | int errored; 67 | 68 | /* Non-zero if nothing should be printed. */ 69 | int skipping_printing; 70 | 71 | /* Non-zero if printing should be verbose (e.g. include hashes). */ 72 | int verbose; 73 | 74 | /* Rust mangling version, with legacy mangling being -1. */ 75 | int version; 76 | 77 | uint64_t bound_lifetime_depth; 78 | }; 79 | 80 | /* Parsing functions. */ 81 | 82 | static char 83 | peek (const struct rust_demangler *rdm) 84 | { 85 | if (rdm->next < rdm->sym_len) 86 | return rdm->sym[rdm->next]; 87 | return 0; 88 | } 89 | 90 | static int 91 | eat (struct rust_demangler *rdm, char c) 92 | { 93 | if (peek (rdm) == c) 94 | { 95 | rdm->next++; 96 | return 1; 97 | } 98 | else 99 | return 0; 100 | } 101 | 102 | static char 103 | next (struct rust_demangler *rdm) 104 | { 105 | char c = peek (rdm); 106 | if (!c) 107 | rdm->errored = 1; 108 | else 109 | rdm->next++; 110 | return c; 111 | } 112 | 113 | static uint64_t 114 | parse_integer_62 (struct rust_demangler *rdm) 115 | { 116 | char c; 117 | uint64_t x; 118 | 119 | if (eat (rdm, '_')) 120 | return 0; 121 | 122 | x = 0; 123 | while (!eat (rdm, '_')) 124 | { 125 | c = next (rdm); 126 | x *= 62; 127 | if (ISDIGIT (c)) 128 | x += c - '0'; 129 | else if (ISLOWER (c)) 130 | x += 10 + (c - 'a'); 131 | else if (ISUPPER (c)) 132 | x += 10 + 26 + (c - 'A'); 133 | else 134 | { 135 | rdm->errored = 1; 136 | return 0; 137 | } 138 | } 139 | return x + 1; 140 | } 141 | 142 | static uint64_t 143 | parse_opt_integer_62 (struct rust_demangler *rdm, char tag) 144 | { 145 | if (!eat (rdm, tag)) 146 | return 0; 147 | return 1 + parse_integer_62 (rdm); 148 | } 149 | 150 | static uint64_t 151 | parse_disambiguator (struct rust_demangler *rdm) 152 | { 153 | return parse_opt_integer_62 (rdm, 's'); 154 | } 155 | 156 | static size_t 157 | parse_hex_nibbles (struct rust_demangler *rdm, uint64_t *value) 158 | { 159 | char c; 160 | size_t hex_len; 161 | 162 | hex_len = 0; 163 | *value = 0; 164 | 165 | while (!eat (rdm, '_')) 166 | { 167 | *value <<= 4; 168 | 169 | c = next (rdm); 170 | if (ISDIGIT (c)) 171 | *value |= c - '0'; 172 | else if (c >= 'a' && c <= 'f') 173 | *value |= 10 + (c - 'a'); 174 | else 175 | { 176 | rdm->errored = 1; 177 | return 0; 178 | } 179 | hex_len++; 180 | } 181 | 182 | return hex_len; 183 | } 184 | 185 | struct rust_mangled_ident 186 | { 187 | /* ASCII part of the identifier. */ 188 | const char *ascii; 189 | size_t ascii_len; 190 | 191 | /* Punycode insertion codes for Unicode codepoints, if any. */ 192 | const char *punycode; 193 | size_t punycode_len; 194 | }; 195 | 196 | static struct rust_mangled_ident 197 | parse_ident (struct rust_demangler *rdm) 198 | { 199 | char c; 200 | size_t start, len; 201 | int is_punycode = 0; 202 | struct rust_mangled_ident ident; 203 | 204 | ident.ascii = NULL; 205 | ident.ascii_len = 0; 206 | ident.punycode = NULL; 207 | ident.punycode_len = 0; 208 | 209 | if (rdm->version != -1) 210 | is_punycode = eat (rdm, 'u'); 211 | 212 | c = next (rdm); 213 | if (!ISDIGIT (c)) 214 | { 215 | rdm->errored = 1; 216 | return ident; 217 | } 218 | len = c - '0'; 219 | 220 | if (c != '0') 221 | while (ISDIGIT (peek (rdm))) 222 | len = len * 10 + (next (rdm) - '0'); 223 | 224 | /* Skip past the optional `_` separator (v0). */ 225 | if (rdm->version != -1) 226 | eat (rdm, '_'); 227 | 228 | start = rdm->next; 229 | rdm->next += len; 230 | /* Check for overflows. */ 231 | if ((start > rdm->next) || (rdm->next > rdm->sym_len)) 232 | { 233 | rdm->errored = 1; 234 | return ident; 235 | } 236 | 237 | ident.ascii = rdm->sym + start; 238 | ident.ascii_len = len; 239 | 240 | if (is_punycode) 241 | { 242 | ident.punycode_len = 0; 243 | while (ident.ascii_len > 0) 244 | { 245 | ident.ascii_len--; 246 | 247 | /* The last '_' is a separator between ascii & punycode. */ 248 | if (ident.ascii[ident.ascii_len] == '_') 249 | break; 250 | 251 | ident.punycode_len++; 252 | } 253 | if (!ident.punycode_len) 254 | { 255 | rdm->errored = 1; 256 | return ident; 257 | } 258 | ident.punycode = ident.ascii + (len - ident.punycode_len); 259 | } 260 | 261 | if (ident.ascii_len == 0) 262 | ident.ascii = NULL; 263 | 264 | return ident; 265 | } 266 | 267 | /* Printing functions. */ 268 | 269 | static void 270 | print_str (struct rust_demangler *rdm, const char *data, size_t len) 271 | { 272 | if (!rdm->errored && !rdm->skipping_printing) 273 | rdm->callback (data, len, rdm->callback_opaque); 274 | } 275 | 276 | #define PRINT(s) print_str (rdm, s, strlen (s)) 277 | 278 | static void 279 | print_uint64 (struct rust_demangler *rdm, uint64_t x) 280 | { 281 | char s[21]; 282 | sprintf (s, "%" PRIu64, x); 283 | PRINT (s); 284 | } 285 | 286 | static void 287 | print_uint64_hex (struct rust_demangler *rdm, uint64_t x) 288 | { 289 | char s[17]; 290 | sprintf (s, "%" PRIx64, x); 291 | PRINT (s); 292 | } 293 | 294 | /* Return a 0x0-0xf value if the char is 0-9a-f, and -1 otherwise. */ 295 | static int 296 | decode_lower_hex_nibble (char nibble) 297 | { 298 | if ('0' <= nibble && nibble <= '9') 299 | return nibble - '0'; 300 | if ('a' <= nibble && nibble <= 'f') 301 | return 0xa + (nibble - 'a'); 302 | return -1; 303 | } 304 | 305 | /* Return the unescaped character for a "$...$" escape, or 0 if invalid. */ 306 | static char 307 | decode_legacy_escape (const char *e, size_t len, size_t *out_len) 308 | { 309 | char c = 0; 310 | size_t escape_len = 0; 311 | int lo_nibble = -1, hi_nibble = -1; 312 | 313 | if (len < 3 || e[0] != '$') 314 | return 0; 315 | 316 | e++; 317 | len--; 318 | 319 | if (e[0] == 'C') 320 | { 321 | escape_len = 1; 322 | 323 | c = ','; 324 | } 325 | else if (len > 2) 326 | { 327 | escape_len = 2; 328 | 329 | if (e[0] == 'S' && e[1] == 'P') 330 | c = '@'; 331 | else if (e[0] == 'B' && e[1] == 'P') 332 | c = '*'; 333 | else if (e[0] == 'R' && e[1] == 'F') 334 | c = '&'; 335 | else if (e[0] == 'L' && e[1] == 'T') 336 | c = '<'; 337 | else if (e[0] == 'G' && e[1] == 'T') 338 | c = '>'; 339 | else if (e[0] == 'L' && e[1] == 'P') 340 | c = '('; 341 | else if (e[0] == 'R' && e[1] == 'P') 342 | c = ')'; 343 | else if (e[0] == 'u' && len > 3) 344 | { 345 | escape_len = 3; 346 | 347 | hi_nibble = decode_lower_hex_nibble (e[1]); 348 | if (hi_nibble < 0) 349 | return 0; 350 | lo_nibble = decode_lower_hex_nibble (e[2]); 351 | if (lo_nibble < 0) 352 | return 0; 353 | 354 | /* Only allow non-control ASCII characters. */ 355 | if (hi_nibble > 7) 356 | return 0; 357 | c = (hi_nibble << 4) | lo_nibble; 358 | if (c < 0x20) 359 | return 0; 360 | } 361 | } 362 | 363 | if (!c || len <= escape_len || e[escape_len] != '$') 364 | return 0; 365 | 366 | *out_len = 2 + escape_len; 367 | return c; 368 | } 369 | 370 | static void 371 | print_ident (struct rust_demangler *rdm, struct rust_mangled_ident ident) 372 | { 373 | char unescaped; 374 | uint8_t *out, *p, d; 375 | size_t len, cap, punycode_pos, j; 376 | /* Punycode parameters and state. */ 377 | uint32_t c; 378 | size_t base, t_min, t_max, skew, damp, bias, i; 379 | size_t delta, w, k, t; 380 | 381 | if (rdm->errored || rdm->skipping_printing) 382 | return; 383 | 384 | if (rdm->version == -1) 385 | { 386 | /* Ignore leading underscores preceding escape sequences. 387 | The mangler inserts an underscore to make sure the 388 | identifier begins with a XID_Start character. */ 389 | if (ident.ascii_len >= 2 && ident.ascii[0] == '_' 390 | && ident.ascii[1] == '$') 391 | { 392 | ident.ascii++; 393 | ident.ascii_len--; 394 | } 395 | 396 | while (ident.ascii_len > 0) 397 | { 398 | /* Handle legacy escape sequences ("$...$", ".." or "."). */ 399 | if (ident.ascii[0] == '$') 400 | { 401 | unescaped 402 | = decode_legacy_escape (ident.ascii, ident.ascii_len, &len); 403 | if (unescaped) 404 | print_str (rdm, &unescaped, 1); 405 | else 406 | { 407 | /* Unexpected escape sequence, print the rest verbatim. */ 408 | print_str (rdm, ident.ascii, ident.ascii_len); 409 | return; 410 | } 411 | } 412 | else if (ident.ascii[0] == '.') 413 | { 414 | if (ident.ascii_len >= 2 && ident.ascii[1] == '.') 415 | { 416 | /* ".." becomes "::" */ 417 | PRINT ("::"); 418 | len = 2; 419 | } 420 | else 421 | { 422 | PRINT ("."); 423 | len = 1; 424 | } 425 | } 426 | else 427 | { 428 | /* Print everything before the next escape sequence, at once. */ 429 | for (len = 0; len < ident.ascii_len; len++) 430 | if (ident.ascii[len] == '$' || ident.ascii[len] == '.') 431 | break; 432 | 433 | print_str (rdm, ident.ascii, len); 434 | } 435 | 436 | ident.ascii += len; 437 | ident.ascii_len -= len; 438 | } 439 | 440 | return; 441 | } 442 | 443 | if (!ident.punycode) 444 | { 445 | print_str (rdm, ident.ascii, ident.ascii_len); 446 | return; 447 | } 448 | 449 | len = 0; 450 | cap = 4; 451 | while (cap < ident.ascii_len) 452 | { 453 | cap *= 2; 454 | /* Check for overflows. */ 455 | if ((cap * 4) / 4 != cap) 456 | { 457 | rdm->errored = 1; 458 | return; 459 | } 460 | } 461 | 462 | /* Store the output codepoints as groups of 4 UTF-8 bytes. */ 463 | out = (uint8_t *)malloc (cap * 4); 464 | if (!out) 465 | { 466 | rdm->errored = 1; 467 | return; 468 | } 469 | 470 | /* Populate initial output from ASCII fragment. */ 471 | for (len = 0; len < ident.ascii_len; len++) 472 | { 473 | p = out + 4 * len; 474 | p[0] = 0; 475 | p[1] = 0; 476 | p[2] = 0; 477 | p[3] = ident.ascii[len]; 478 | } 479 | 480 | /* Punycode parameters and initial state. */ 481 | base = 36; 482 | t_min = 1; 483 | t_max = 26; 484 | skew = 38; 485 | damp = 700; 486 | bias = 72; 487 | i = 0; 488 | c = 0x80; 489 | 490 | punycode_pos = 0; 491 | while (punycode_pos < ident.punycode_len) 492 | { 493 | /* Read one delta value. */ 494 | delta = 0; 495 | w = 1; 496 | k = 0; 497 | do 498 | { 499 | k += base; 500 | t = k < bias ? 0 : (k - bias); 501 | if (t < t_min) 502 | t = t_min; 503 | if (t > t_max) 504 | t = t_max; 505 | 506 | if (punycode_pos >= ident.punycode_len) 507 | goto cleanup; 508 | d = ident.punycode[punycode_pos++]; 509 | 510 | if (ISLOWER (d)) 511 | d = d - 'a'; 512 | else if (ISDIGIT (d)) 513 | d = 26 + (d - '0'); 514 | else 515 | { 516 | rdm->errored = 1; 517 | goto cleanup; 518 | } 519 | 520 | delta += d * w; 521 | w *= base - t; 522 | } 523 | while (d >= t); 524 | 525 | /* Compute the new insert position and character. */ 526 | len++; 527 | i += delta; 528 | c += i / len; 529 | i %= len; 530 | 531 | /* Ensure enough space is available. */ 532 | if (cap < len) 533 | { 534 | cap *= 2; 535 | /* Check for overflows. */ 536 | if ((cap * 4) / 4 != cap || cap < len) 537 | { 538 | rdm->errored = 1; 539 | goto cleanup; 540 | } 541 | } 542 | p = (uint8_t *)realloc (out, cap * 4); 543 | if (!p) 544 | { 545 | rdm->errored = 1; 546 | goto cleanup; 547 | } 548 | out = p; 549 | 550 | /* Move the characters after the insert position. */ 551 | p = out + i * 4; 552 | memmove (p + 4, p, (len - i - 1) * 4); 553 | 554 | /* Insert the new character, as UTF-8 bytes. */ 555 | p[0] = c >= 0x10000 ? 0xf0 | (c >> 18) : 0; 556 | p[1] = c >= 0x800 ? (c < 0x10000 ? 0xe0 : 0x80) | ((c >> 12) & 0x3f) : 0; 557 | p[2] = (c < 0x800 ? 0xc0 : 0x80) | ((c >> 6) & 0x3f); 558 | p[3] = 0x80 | (c & 0x3f); 559 | 560 | /* If there are no more deltas, decoding is complete. */ 561 | if (punycode_pos == ident.punycode_len) 562 | break; 563 | 564 | i++; 565 | 566 | /* Perform bias adaptation. */ 567 | delta /= damp; 568 | damp = 2; 569 | 570 | delta += delta / len; 571 | k = 0; 572 | while (delta > ((base - t_min) * t_max) / 2) 573 | { 574 | delta /= base - t_min; 575 | k += base; 576 | } 577 | bias = k + ((base - t_min + 1) * delta) / (delta + skew); 578 | } 579 | 580 | /* Remove all the 0 bytes to leave behind an UTF-8 string. */ 581 | for (i = 0, j = 0; i < len * 4; i++) 582 | if (out[i] != 0) 583 | out[j++] = out[i]; 584 | 585 | print_str (rdm, (const char *)out, j); 586 | 587 | cleanup: 588 | free (out); 589 | } 590 | 591 | /* Print the lifetime according to the previously decoded index. 592 | An index of `0` always refers to `'_`, but starting with `1`, 593 | indices refer to late-bound lifetimes introduced by a binder. */ 594 | static void 595 | print_lifetime_from_index (struct rust_demangler *rdm, uint64_t lt) 596 | { 597 | char c; 598 | uint64_t depth; 599 | 600 | PRINT ("'"); 601 | if (lt == 0) 602 | { 603 | PRINT ("_"); 604 | return; 605 | } 606 | 607 | depth = rdm->bound_lifetime_depth - lt; 608 | /* Try to print lifetimes alphabetically first. */ 609 | if (depth < 26) 610 | { 611 | c = 'a' + depth; 612 | print_str (rdm, &c, 1); 613 | } 614 | else 615 | { 616 | /* Use `'_123` after running out of letters. */ 617 | PRINT ("_"); 618 | print_uint64 (rdm, depth); 619 | } 620 | } 621 | 622 | /* Demangling functions. */ 623 | 624 | static void demangle_binder (struct rust_demangler *rdm); 625 | static void demangle_path (struct rust_demangler *rdm, int in_value); 626 | static void demangle_generic_arg (struct rust_demangler *rdm); 627 | static void demangle_type (struct rust_demangler *rdm); 628 | static int demangle_path_maybe_open_generics (struct rust_demangler *rdm); 629 | static void demangle_dyn_trait (struct rust_demangler *rdm); 630 | static void demangle_const (struct rust_demangler *rdm); 631 | static void demangle_const_uint (struct rust_demangler *rdm); 632 | static void demangle_const_int (struct rust_demangler *rdm); 633 | static void demangle_const_bool (struct rust_demangler *rdm); 634 | static void demangle_const_char (struct rust_demangler *rdm); 635 | 636 | /* Optionally enter a binder ('G') for late-bound lifetimes, 637 | printing e.g. `for<'a, 'b> `, and make those lifetimes visible 638 | to the caller (via depth level, which the caller should reset). */ 639 | static void 640 | demangle_binder (struct rust_demangler *rdm) 641 | { 642 | uint64_t i, bound_lifetimes; 643 | 644 | if (rdm->errored) 645 | return; 646 | 647 | bound_lifetimes = parse_opt_integer_62 (rdm, 'G'); 648 | if (bound_lifetimes > 0) 649 | { 650 | PRINT ("for<"); 651 | for (i = 0; i < bound_lifetimes; i++) 652 | { 653 | if (i > 0) 654 | PRINT (", "); 655 | rdm->bound_lifetime_depth++; 656 | print_lifetime_from_index (rdm, 1); 657 | } 658 | PRINT ("> "); 659 | } 660 | } 661 | 662 | static void 663 | demangle_path (struct rust_demangler *rdm, int in_value) 664 | { 665 | char tag, ns; 666 | int was_skipping_printing; 667 | size_t i, backref, old_next; 668 | uint64_t dis; 669 | struct rust_mangled_ident name; 670 | 671 | if (rdm->errored) 672 | return; 673 | 674 | switch (tag = next (rdm)) 675 | { 676 | case 'C': 677 | dis = parse_disambiguator (rdm); 678 | name = parse_ident (rdm); 679 | 680 | print_ident (rdm, name); 681 | if (rdm->verbose) 682 | { 683 | PRINT ("["); 684 | print_uint64_hex (rdm, dis); 685 | PRINT ("]"); 686 | } 687 | break; 688 | case 'N': 689 | ns = next (rdm); 690 | if (!ISLOWER (ns) && !ISUPPER (ns)) 691 | { 692 | rdm->errored = 1; 693 | return; 694 | } 695 | 696 | demangle_path (rdm, in_value); 697 | 698 | dis = parse_disambiguator (rdm); 699 | name = parse_ident (rdm); 700 | 701 | if (ISUPPER (ns)) 702 | { 703 | /* Special namespaces, like closures and shims. */ 704 | PRINT ("::{"); 705 | switch (ns) 706 | { 707 | case 'C': 708 | PRINT ("closure"); 709 | break; 710 | case 'S': 711 | PRINT ("shim"); 712 | break; 713 | default: 714 | print_str (rdm, &ns, 1); 715 | } 716 | if (name.ascii || name.punycode) 717 | { 718 | PRINT (":"); 719 | print_ident (rdm, name); 720 | } 721 | PRINT ("#"); 722 | print_uint64 (rdm, dis); 723 | PRINT ("}"); 724 | } 725 | else 726 | { 727 | /* Implementation-specific/unspecified namespaces. */ 728 | 729 | if (name.ascii || name.punycode) 730 | { 731 | PRINT ("::"); 732 | print_ident (rdm, name); 733 | } 734 | } 735 | break; 736 | case 'M': 737 | case 'X': 738 | /* Ignore the `impl`'s own path.*/ 739 | parse_disambiguator (rdm); 740 | was_skipping_printing = rdm->skipping_printing; 741 | rdm->skipping_printing = 1; 742 | demangle_path (rdm, in_value); 743 | rdm->skipping_printing = was_skipping_printing; 744 | /* fallthrough */ 745 | case 'Y': 746 | PRINT ("<"); 747 | demangle_type (rdm); 748 | if (tag != 'M') 749 | { 750 | PRINT (" as "); 751 | demangle_path (rdm, 0); 752 | } 753 | PRINT (">"); 754 | break; 755 | case 'I': 756 | demangle_path (rdm, in_value); 757 | if (in_value) 758 | PRINT ("::"); 759 | PRINT ("<"); 760 | for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++) 761 | { 762 | if (i > 0) 763 | PRINT (", "); 764 | demangle_generic_arg (rdm); 765 | } 766 | PRINT (">"); 767 | break; 768 | case 'B': 769 | backref = parse_integer_62 (rdm); 770 | if (!rdm->skipping_printing) 771 | { 772 | old_next = rdm->next; 773 | rdm->next = backref; 774 | demangle_path (rdm, in_value); 775 | rdm->next = old_next; 776 | } 777 | break; 778 | default: 779 | rdm->errored = 1; 780 | return; 781 | } 782 | } 783 | 784 | static void 785 | demangle_generic_arg (struct rust_demangler *rdm) 786 | { 787 | uint64_t lt; 788 | if (eat (rdm, 'L')) 789 | { 790 | lt = parse_integer_62 (rdm); 791 | print_lifetime_from_index (rdm, lt); 792 | } 793 | else if (eat (rdm, 'K')) 794 | demangle_const (rdm); 795 | else 796 | demangle_type (rdm); 797 | } 798 | 799 | static const char * 800 | basic_type (char tag) 801 | { 802 | switch (tag) 803 | { 804 | case 'b': 805 | return "bool"; 806 | case 'c': 807 | return "char"; 808 | case 'e': 809 | return "str"; 810 | case 'u': 811 | return "()"; 812 | case 'a': 813 | return "i8"; 814 | case 's': 815 | return "i16"; 816 | case 'l': 817 | return "i32"; 818 | case 'x': 819 | return "i64"; 820 | case 'n': 821 | return "i128"; 822 | case 'i': 823 | return "isize"; 824 | case 'h': 825 | return "u8"; 826 | case 't': 827 | return "u16"; 828 | case 'm': 829 | return "u32"; 830 | case 'y': 831 | return "u64"; 832 | case 'o': 833 | return "u128"; 834 | case 'j': 835 | return "usize"; 836 | case 'f': 837 | return "f32"; 838 | case 'd': 839 | return "f64"; 840 | case 'z': 841 | return "!"; 842 | case 'p': 843 | return "_"; 844 | case 'v': 845 | return "..."; 846 | 847 | default: 848 | return NULL; 849 | } 850 | } 851 | 852 | static void 853 | demangle_type (struct rust_demangler *rdm) 854 | { 855 | char tag; 856 | size_t i, old_next, backref; 857 | uint64_t lt, old_bound_lifetime_depth; 858 | const char *basic; 859 | struct rust_mangled_ident abi; 860 | 861 | if (rdm->errored) 862 | return; 863 | 864 | tag = next (rdm); 865 | 866 | basic = basic_type (tag); 867 | if (basic) 868 | { 869 | PRINT (basic); 870 | return; 871 | } 872 | 873 | switch (tag) 874 | { 875 | case 'R': 876 | case 'Q': 877 | PRINT ("&"); 878 | if (eat (rdm, 'L')) 879 | { 880 | lt = parse_integer_62 (rdm); 881 | if (lt) 882 | { 883 | print_lifetime_from_index (rdm, lt); 884 | PRINT (" "); 885 | } 886 | } 887 | if (tag != 'R') 888 | PRINT ("mut "); 889 | demangle_type (rdm); 890 | break; 891 | case 'P': 892 | case 'O': 893 | PRINT ("*"); 894 | if (tag != 'P') 895 | PRINT ("mut "); 896 | else 897 | PRINT ("const "); 898 | demangle_type (rdm); 899 | break; 900 | case 'A': 901 | case 'S': 902 | PRINT ("["); 903 | demangle_type (rdm); 904 | if (tag == 'A') 905 | { 906 | PRINT ("; "); 907 | demangle_const (rdm); 908 | } 909 | PRINT ("]"); 910 | break; 911 | case 'T': 912 | PRINT ("("); 913 | for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++) 914 | { 915 | if (i > 0) 916 | PRINT (", "); 917 | demangle_type (rdm); 918 | } 919 | if (i == 1) 920 | PRINT (","); 921 | PRINT (")"); 922 | break; 923 | case 'F': 924 | old_bound_lifetime_depth = rdm->bound_lifetime_depth; 925 | demangle_binder (rdm); 926 | 927 | if (eat (rdm, 'U')) 928 | PRINT ("unsafe "); 929 | 930 | if (eat (rdm, 'K')) 931 | { 932 | if (eat (rdm, 'C')) 933 | { 934 | abi.ascii = "C"; 935 | abi.ascii_len = 1; 936 | } 937 | else 938 | { 939 | abi = parse_ident (rdm); 940 | if (!abi.ascii || abi.punycode) 941 | { 942 | rdm->errored = 1; 943 | goto restore; 944 | } 945 | } 946 | 947 | PRINT ("extern \""); 948 | 949 | /* If the ABI had any `-`, they were replaced with `_`, 950 | so the parts between `_` have to be re-joined with `-`. */ 951 | for (i = 0; i < abi.ascii_len; i++) 952 | { 953 | if (abi.ascii[i] == '_') 954 | { 955 | print_str (rdm, abi.ascii, i); 956 | PRINT ("-"); 957 | abi.ascii += i + 1; 958 | abi.ascii_len -= i + 1; 959 | i = 0; 960 | } 961 | } 962 | print_str (rdm, abi.ascii, abi.ascii_len); 963 | 964 | PRINT ("\" "); 965 | } 966 | 967 | PRINT ("fn("); 968 | for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++) 969 | { 970 | if (i > 0) 971 | PRINT (", "); 972 | demangle_type (rdm); 973 | } 974 | PRINT (")"); 975 | 976 | if (eat (rdm, 'u')) 977 | { 978 | /* Skip printing the return type if it's 'u', i.e. `()`. */ 979 | } 980 | else 981 | { 982 | PRINT (" -> "); 983 | demangle_type (rdm); 984 | } 985 | 986 | /* Restore `bound_lifetime_depth` to outside the binder. */ 987 | restore: 988 | rdm->bound_lifetime_depth = old_bound_lifetime_depth; 989 | break; 990 | case 'D': 991 | PRINT ("dyn "); 992 | 993 | old_bound_lifetime_depth = rdm->bound_lifetime_depth; 994 | demangle_binder (rdm); 995 | 996 | for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++) 997 | { 998 | if (i > 0) 999 | PRINT (" + "); 1000 | demangle_dyn_trait (rdm); 1001 | } 1002 | 1003 | /* Restore `bound_lifetime_depth` to outside the binder. */ 1004 | rdm->bound_lifetime_depth = old_bound_lifetime_depth; 1005 | 1006 | if (!eat (rdm, 'L')) 1007 | { 1008 | rdm->errored = 1; 1009 | return; 1010 | } 1011 | lt = parse_integer_62 (rdm); 1012 | if (lt) 1013 | { 1014 | PRINT (" + "); 1015 | print_lifetime_from_index (rdm, lt); 1016 | } 1017 | break; 1018 | case 'B': 1019 | backref = parse_integer_62 (rdm); 1020 | if (!rdm->skipping_printing) 1021 | { 1022 | old_next = rdm->next; 1023 | rdm->next = backref; 1024 | demangle_type (rdm); 1025 | rdm->next = old_next; 1026 | } 1027 | break; 1028 | default: 1029 | /* Go back to the tag, so `demangle_path` also sees it. */ 1030 | rdm->next--; 1031 | demangle_path (rdm, 0); 1032 | } 1033 | } 1034 | 1035 | /* A trait in a trait object may have some "existential projections" 1036 | (i.e. associated type bindings) after it, which should be printed 1037 | in the `<...>` of the trait, e.g. `dyn Trait`. 1038 | To this end, this method will keep the `<...>` of an 'I' path 1039 | open, by omitting the `>`, and return `Ok(true)` in that case. */ 1040 | static int 1041 | demangle_path_maybe_open_generics (struct rust_demangler *rdm) 1042 | { 1043 | int open; 1044 | size_t i, old_next, backref; 1045 | 1046 | open = 0; 1047 | 1048 | if (rdm->errored) 1049 | return open; 1050 | 1051 | if (eat (rdm, 'B')) 1052 | { 1053 | backref = parse_integer_62 (rdm); 1054 | if (!rdm->skipping_printing) 1055 | { 1056 | old_next = rdm->next; 1057 | rdm->next = backref; 1058 | open = demangle_path_maybe_open_generics (rdm); 1059 | rdm->next = old_next; 1060 | } 1061 | } 1062 | else if (eat (rdm, 'I')) 1063 | { 1064 | demangle_path (rdm, 0); 1065 | PRINT ("<"); 1066 | open = 1; 1067 | for (i = 0; !rdm->errored && !eat (rdm, 'E'); i++) 1068 | { 1069 | if (i > 0) 1070 | PRINT (", "); 1071 | demangle_generic_arg (rdm); 1072 | } 1073 | } 1074 | else 1075 | demangle_path (rdm, 0); 1076 | return open; 1077 | } 1078 | 1079 | static void 1080 | demangle_dyn_trait (struct rust_demangler *rdm) 1081 | { 1082 | int open; 1083 | struct rust_mangled_ident name; 1084 | 1085 | if (rdm->errored) 1086 | return; 1087 | 1088 | open = demangle_path_maybe_open_generics (rdm); 1089 | 1090 | while (eat (rdm, 'p')) 1091 | { 1092 | if (!open) 1093 | PRINT ("<"); 1094 | else 1095 | PRINT (", "); 1096 | open = 1; 1097 | 1098 | name = parse_ident (rdm); 1099 | print_ident (rdm, name); 1100 | PRINT (" = "); 1101 | demangle_type (rdm); 1102 | } 1103 | 1104 | if (open) 1105 | PRINT (">"); 1106 | } 1107 | 1108 | static void 1109 | demangle_const (struct rust_demangler *rdm) 1110 | { 1111 | char ty_tag; 1112 | size_t old_next, backref; 1113 | 1114 | if (rdm->errored) 1115 | return; 1116 | 1117 | if (eat (rdm, 'B')) 1118 | { 1119 | backref = parse_integer_62 (rdm); 1120 | if (!rdm->skipping_printing) 1121 | { 1122 | old_next = rdm->next; 1123 | rdm->next = backref; 1124 | demangle_const (rdm); 1125 | rdm->next = old_next; 1126 | } 1127 | return; 1128 | } 1129 | 1130 | ty_tag = next (rdm); 1131 | switch (ty_tag) 1132 | { 1133 | /* Placeholder. */ 1134 | case 'p': 1135 | PRINT ("_"); 1136 | return; 1137 | 1138 | /* Unsigned integer types. */ 1139 | case 'h': 1140 | case 't': 1141 | case 'm': 1142 | case 'y': 1143 | case 'o': 1144 | case 'j': 1145 | demangle_const_uint (rdm); 1146 | break; 1147 | 1148 | /* Signed integer types. */ 1149 | case 'a': 1150 | case 's': 1151 | case 'l': 1152 | case 'x': 1153 | case 'n': 1154 | case 'i': 1155 | demangle_const_int (rdm); 1156 | break; 1157 | 1158 | /* Boolean. */ 1159 | case 'b': 1160 | demangle_const_bool (rdm); 1161 | break; 1162 | 1163 | /* Character. */ 1164 | case 'c': 1165 | demangle_const_char (rdm); 1166 | break; 1167 | 1168 | default: 1169 | rdm->errored = 1; 1170 | return; 1171 | } 1172 | 1173 | if (rdm->errored) 1174 | return; 1175 | 1176 | if (rdm->verbose) 1177 | { 1178 | PRINT (": "); 1179 | PRINT (basic_type (ty_tag)); 1180 | } 1181 | } 1182 | 1183 | static void 1184 | demangle_const_uint (struct rust_demangler *rdm) 1185 | { 1186 | size_t hex_len; 1187 | uint64_t value; 1188 | 1189 | if (rdm->errored) 1190 | return; 1191 | 1192 | hex_len = parse_hex_nibbles (rdm, &value); 1193 | 1194 | if (hex_len > 16) 1195 | { 1196 | /* Print anything that doesn't fit in `uint64_t` verbatim. */ 1197 | PRINT ("0x"); 1198 | print_str (rdm, rdm->sym + (rdm->next - hex_len), hex_len); 1199 | } 1200 | else if (hex_len > 0) 1201 | print_uint64 (rdm, value); 1202 | else 1203 | rdm->errored = 1; 1204 | } 1205 | 1206 | static void 1207 | demangle_const_int (struct rust_demangler *rdm) 1208 | { 1209 | if (eat (rdm, 'n')) 1210 | PRINT ("-"); 1211 | demangle_const_uint (rdm); 1212 | } 1213 | 1214 | static void 1215 | demangle_const_bool (struct rust_demangler *rdm) 1216 | { 1217 | uint64_t value; 1218 | 1219 | if (parse_hex_nibbles (rdm, &value) != 1) 1220 | { 1221 | rdm->errored = 1; 1222 | return; 1223 | } 1224 | 1225 | if (value == 0) 1226 | PRINT ("false"); 1227 | else if (value == 1) 1228 | PRINT ("true"); 1229 | else 1230 | rdm->errored = 1; 1231 | } 1232 | 1233 | static void 1234 | demangle_const_char (struct rust_demangler *rdm) 1235 | { 1236 | size_t hex_len; 1237 | uint64_t value; 1238 | 1239 | hex_len = parse_hex_nibbles (rdm, &value); 1240 | 1241 | if (hex_len == 0 || hex_len > 8) 1242 | { 1243 | rdm->errored = 1; 1244 | return; 1245 | } 1246 | 1247 | /* Match Rust's character "debug" output as best as we can. */ 1248 | PRINT ("'"); 1249 | if (value == '\t') 1250 | PRINT ("\\t"); 1251 | else if (value == '\r') 1252 | PRINT ("\\r"); 1253 | else if (value == '\n') 1254 | PRINT ("\\n"); 1255 | else if (value > ' ' && value < '~') 1256 | { 1257 | /* Rust also considers many non-ASCII codepoints to be printable, but 1258 | that logic is not easily ported to C. */ 1259 | char c = value; 1260 | print_str (rdm, &c, 1); 1261 | } 1262 | else 1263 | { 1264 | PRINT ("\\u{"); 1265 | print_uint64_hex (rdm, value); 1266 | PRINT ("}"); 1267 | } 1268 | PRINT ("'"); 1269 | } 1270 | 1271 | /* A legacy hash is the prefix "h" followed by 16 lowercase hex digits. 1272 | The hex digits must contain at least 5 distinct digits. */ 1273 | static int 1274 | is_legacy_prefixed_hash (struct rust_mangled_ident ident) 1275 | { 1276 | uint16_t seen; 1277 | int nibble; 1278 | size_t i, count; 1279 | 1280 | if (ident.ascii_len != 17 || ident.ascii[0] != 'h') 1281 | return 0; 1282 | 1283 | seen = 0; 1284 | for (i = 0; i < 16; i++) 1285 | { 1286 | nibble = decode_lower_hex_nibble (ident.ascii[1 + i]); 1287 | if (nibble < 0) 1288 | return 0; 1289 | seen |= (uint16_t)1 << nibble; 1290 | } 1291 | 1292 | /* Count how many distinct digits were seen. */ 1293 | count = 0; 1294 | while (seen) 1295 | { 1296 | if (seen & 1) 1297 | count++; 1298 | seen >>= 1; 1299 | } 1300 | 1301 | return count >= 5; 1302 | } 1303 | 1304 | int 1305 | rust_demangle_callback (const char *mangled, int options, 1306 | demangle_callbackref callback, void *opaque) 1307 | { 1308 | const char *p; 1309 | struct rust_demangler rdm; 1310 | struct rust_mangled_ident ident; 1311 | 1312 | rdm.sym = mangled; 1313 | rdm.sym_len = 0; 1314 | 1315 | rdm.callback_opaque = opaque; 1316 | rdm.callback = callback; 1317 | 1318 | rdm.next = 0; 1319 | rdm.errored = 0; 1320 | rdm.skipping_printing = 0; 1321 | rdm.verbose = (options & DMGL_VERBOSE) != 0; 1322 | rdm.version = 0; 1323 | rdm.bound_lifetime_depth = 0; 1324 | 1325 | /* Rust symbols always start with _R (v0) or _ZN (legacy). */ 1326 | if (rdm.sym[0] == '_' && rdm.sym[1] == 'R') 1327 | rdm.sym += 2; 1328 | else if (rdm.sym[0] == '_' && rdm.sym[1] == 'Z' && rdm.sym[2] == 'N') 1329 | { 1330 | rdm.sym += 3; 1331 | rdm.version = -1; 1332 | } 1333 | else 1334 | return 0; 1335 | 1336 | /* Paths (v0) always start with uppercase characters. */ 1337 | if (rdm.version != -1 && !ISUPPER (rdm.sym[0])) 1338 | return 0; 1339 | 1340 | /* Rust symbols (v0) use only [_0-9a-zA-Z] characters. */ 1341 | for (p = rdm.sym; *p; p++) 1342 | { 1343 | rdm.sym_len++; 1344 | 1345 | if (*p == '_' || ISALNUM (*p)) 1346 | continue; 1347 | 1348 | /* Legacy Rust symbols can also contain [.:$] characters. */ 1349 | if (rdm.version == -1 && (*p == '$' || *p == '.' || *p == ':')) 1350 | continue; 1351 | 1352 | return 0; 1353 | } 1354 | 1355 | /* Legacy Rust symbols need to be handled separately. */ 1356 | if (rdm.version == -1) 1357 | { 1358 | /* Legacy Rust symbols always end with E. */ 1359 | if (!(rdm.sym_len > 0 && rdm.sym[rdm.sym_len - 1] == 'E')) 1360 | return 0; 1361 | rdm.sym_len--; 1362 | 1363 | /* Legacy Rust symbols also always end with a path segment 1364 | that encodes a 16 hex digit hash, i.e. '17h[a-f0-9]{16}'. 1365 | This early check, before any parse_ident calls, should 1366 | quickly filter out most C++ symbols unrelated to Rust. */ 1367 | if (!(rdm.sym_len > 19 1368 | && !memcmp (&rdm.sym[rdm.sym_len - 19], "17h", 3))) 1369 | return 0; 1370 | 1371 | do 1372 | { 1373 | ident = parse_ident (&rdm); 1374 | if (rdm.errored || !ident.ascii) 1375 | return 0; 1376 | } 1377 | while (rdm.next < rdm.sym_len); 1378 | 1379 | /* The last path segment should be the hash. */ 1380 | if (!is_legacy_prefixed_hash (ident)) 1381 | return 0; 1382 | 1383 | /* Reset the state for a second pass, to print the symbol. */ 1384 | rdm.next = 0; 1385 | if (!rdm.verbose && rdm.sym_len > 19) 1386 | { 1387 | /* Hide the last segment, containing the hash, if not verbose. */ 1388 | rdm.sym_len -= 19; 1389 | } 1390 | 1391 | do 1392 | { 1393 | if (rdm.next > 0) 1394 | print_str (&rdm, "::", 2); 1395 | 1396 | ident = parse_ident (&rdm); 1397 | print_ident (&rdm, ident); 1398 | } 1399 | while (rdm.next < rdm.sym_len); 1400 | } 1401 | else 1402 | { 1403 | demangle_path (&rdm, 1); 1404 | 1405 | /* Skip instantiating crate. */ 1406 | if (!rdm.errored && rdm.next < rdm.sym_len) 1407 | { 1408 | rdm.skipping_printing = 1; 1409 | demangle_path (&rdm, 0); 1410 | } 1411 | 1412 | /* It's an error to not reach the end. */ 1413 | rdm.errored |= rdm.next != rdm.sym_len; 1414 | } 1415 | 1416 | return !rdm.errored; 1417 | } 1418 | 1419 | /* Growable string buffers. */ 1420 | struct str_buf 1421 | { 1422 | char *ptr; 1423 | size_t len; 1424 | size_t cap; 1425 | int errored; 1426 | }; 1427 | 1428 | static void 1429 | str_buf_reserve (struct str_buf *buf, size_t extra) 1430 | { 1431 | size_t available, min_new_cap, new_cap; 1432 | char *new_ptr; 1433 | 1434 | /* Allocation failed before. */ 1435 | if (buf->errored) 1436 | return; 1437 | 1438 | available = buf->cap - buf->len; 1439 | 1440 | if (extra <= available) 1441 | return; 1442 | 1443 | min_new_cap = buf->cap + (extra - available); 1444 | 1445 | /* Check for overflows. */ 1446 | if (min_new_cap < buf->cap) 1447 | { 1448 | buf->errored = 1; 1449 | return; 1450 | } 1451 | 1452 | new_cap = buf->cap; 1453 | 1454 | if (new_cap == 0) 1455 | new_cap = 4; 1456 | 1457 | /* Double capacity until sufficiently large. */ 1458 | while (new_cap < min_new_cap) 1459 | { 1460 | new_cap *= 2; 1461 | 1462 | /* Check for overflows. */ 1463 | if (new_cap < buf->cap) 1464 | { 1465 | buf->errored = 1; 1466 | return; 1467 | } 1468 | } 1469 | 1470 | new_ptr = (char *)realloc (buf->ptr, new_cap); 1471 | if (new_ptr == NULL) 1472 | { 1473 | free (buf->ptr); 1474 | buf->ptr = NULL; 1475 | buf->len = 0; 1476 | buf->cap = 0; 1477 | buf->errored = 1; 1478 | } 1479 | else 1480 | { 1481 | buf->ptr = new_ptr; 1482 | buf->cap = new_cap; 1483 | } 1484 | } 1485 | 1486 | static void 1487 | str_buf_append (struct str_buf *buf, const char *data, size_t len) 1488 | { 1489 | str_buf_reserve (buf, len); 1490 | if (buf->errored) 1491 | return; 1492 | 1493 | memcpy (buf->ptr + buf->len, data, len); 1494 | buf->len += len; 1495 | } 1496 | 1497 | static void 1498 | str_buf_demangle_callback (const char *data, size_t len, void *opaque) 1499 | { 1500 | str_buf_append ((struct str_buf *)opaque, data, len); 1501 | } 1502 | 1503 | char * 1504 | rust_demangle (const char *mangled, int options) 1505 | { 1506 | struct str_buf out; 1507 | int success; 1508 | 1509 | out.ptr = NULL; 1510 | out.len = 0; 1511 | out.cap = 0; 1512 | out.errored = 0; 1513 | 1514 | success = rust_demangle_callback (mangled, options, 1515 | str_buf_demangle_callback, &out); 1516 | 1517 | if (!success) 1518 | { 1519 | free (out.ptr); 1520 | return NULL; 1521 | } 1522 | 1523 | str_buf_append (&out, "\0", 1); 1524 | return out.ptr; 1525 | } 1526 | --------------------------------------------------------------------------------