📄 cp-demangle.c
字号:
/* Demangler for g++ V3 ABI. Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Written by Ian Lance Taylor <ian@wasabisystems.com>. This file is part of the libiberty library, which is part of GCC. This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. In addition to the permissions in the GNU General Public License, the Free Software Foundation gives you unlimited permission to link the compiled version of this file into combinations with other programs, and to distribute those combinations without any restriction coming from the use of this file. (The General Public License restrictions do apply in other respects; for example, they cover modification of the file, and distribution when not linked into a combined executable.) This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. *//* This code implements a demangler for the g++ V3 ABI. The ABI is described on this web page: http://www.codesourcery.com/cxx-abi/abi.html#mangling This code was written while looking at the demangler written by Alex Samuel <samuel@codesourcery.com>. This code first pulls the mangled name apart into a list of components, and then walks the list generating the demangled name. This file will normally define the following functions, q.v.: char *cplus_demangle_v3(const char *mangled, int options) char *java_demangle_v3(const char *mangled) int cplus_demangle_v3_callback(const char *mangled, int options, demangle_callbackref callback) int java_demangle_v3_callback(const char *mangled, demangle_callbackref callback) enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name) enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name) Also, the interface to the component list is public, and defined in demangle.h. The interface consists of these types, which are defined in demangle.h: enum demangle_component_type struct demangle_component demangle_callbackref and these functions defined in this file: cplus_demangle_fill_name cplus_demangle_fill_extended_operator cplus_demangle_fill_ctor cplus_demangle_fill_dtor cplus_demangle_print cplus_demangle_print_callback and other functions defined in the file cp-demint.c. This file also defines some other functions and variables which are only to be used by the file cp-demint.c. Preprocessor macros you can define while compiling this file: IN_LIBGCC2 If defined, this file defines the following functions, q.v.: char *__cxa_demangle (const char *mangled, char *buf, size_t *len, int *status) int __gcclibcxx_demangle_callback (const char *, void (*) (const char *, size_t, void *), void *) instead of cplus_demangle_v3[_callback]() and java_demangle_v3[_callback](). IN_GLIBCPP_V3 If defined, this file defines only __cxa_demangle() and __gcclibcxx_demangle_callback(), and no other publically visible functions or variables. STANDALONE_DEMANGLER If defined, this file defines a main() function which demangles any arguments, or, if none, demangles stdin. CP_DEMANGLE_DEBUG If defined, turns on debugging mode, which prints information on stdout about the mangled string. This is not generally useful.*/#if defined (_AIX) && !defined (__GNUC__) #pragma alloca#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_ALLOCA_H# include <alloca.h>#else# ifndef alloca# ifdef __GNUC__# define alloca __builtin_alloca# elseextern char *alloca ();# endif /* __GNUC__ */# endif /* alloca */#endif /* HAVE_ALLOCA_H */#include "demangle.h"#include "cp-demangle.h"/* If IN_GLIBCPP_V3 is defined, some functions are made static. We also rename them via #define to avoid compiler errors when the static definition conflicts with the extern declaration in a header file. */#ifdef IN_GLIBCPP_V3#define CP_STATIC_IF_GLIBCPP_V3 static#define cplus_demangle_fill_name d_fill_namestatic int d_fill_name (struct demangle_component *, const char *, int);#define cplus_demangle_fill_extended_operator d_fill_extended_operatorstatic intd_fill_extended_operator (struct demangle_component *, int, struct demangle_component *);#define cplus_demangle_fill_ctor d_fill_ctorstatic intd_fill_ctor (struct demangle_component *, enum gnu_v3_ctor_kinds, struct demangle_component *);#define cplus_demangle_fill_dtor d_fill_dtorstatic intd_fill_dtor (struct demangle_component *, enum gnu_v3_dtor_kinds, struct demangle_component *);#define cplus_demangle_mangled_name d_mangled_namestatic struct demangle_component *d_mangled_name (struct d_info *, int);#define cplus_demangle_type d_typestatic struct demangle_component *d_type (struct d_info *);#define cplus_demangle_print d_printstatic char *d_print (int, const struct demangle_component *, int, size_t *);#define cplus_demangle_print_callback d_print_callbackstatic int d_print_callback (int, const struct demangle_component *, demangle_callbackref, void *);#define cplus_demangle_init_info d_init_infostatic void d_init_info (const char *, int, size_t, struct d_info *);#else /* ! defined(IN_GLIBCPP_V3) */#define CP_STATIC_IF_GLIBCPP_V3#endif /* ! defined(IN_GLIBCPP_V3) *//* See if the compiler supports dynamic arrays. */#ifdef __GNUC__#define CP_DYNAMIC_ARRAYS#else#ifdef __STDC__#ifdef __STDC_VERSION__#if __STDC_VERSION__ >= 199901L#define CP_DYNAMIC_ARRAYS#endif /* __STDC__VERSION >= 199901L */#endif /* defined (__STDC_VERSION__) */#endif /* defined (__STDC__) */#endif /* ! defined (__GNUC__) *//* We avoid pulling in the ctype tables, to prevent pulling in additional unresolved symbols when this code is used in a library. FIXME: Is this really a valid reason? This comes from the original V3 demangler code. As of this writing this file has the following undefined references when compiled with -DIN_GLIBCPP_V3: realloc, free, memcpy, strcpy, strcat, strlen. */#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')#define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')/* The prefix prepended by GCC to an identifier represnting the anonymous namespace. */#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"#define ANONYMOUS_NAMESPACE_PREFIX_LEN \ (sizeof (ANONYMOUS_NAMESPACE_PREFIX) - 1)/* Information we keep for the standard substitutions. */struct d_standard_sub_info{ /* The code for this substitution. */ char code; /* The simple string it expands to. */ const char *simple_expansion; /* The length of the simple expansion. */ int simple_len; /* The results of a full, verbose, expansion. This is used when qualifying a constructor/destructor, or when in verbose mode. */ const char *full_expansion; /* The length of the full expansion. */ int full_len; /* What to set the last_name field of d_info to; NULL if we should not set it. This is only relevant when qualifying a constructor/destructor. */ const char *set_last_name; /* The length of set_last_name. */ int set_last_name_len;};/* Accessors for subtrees of struct demangle_component. */#define d_left(dc) ((dc)->u.s_binary.left)#define d_right(dc) ((dc)->u.s_binary.right)/* A list of templates. This is used while printing. */struct d_print_template{ /* Next template on the list. */ struct d_print_template *next; /* This template. */ const struct demangle_component *template_decl;};/* A list of type modifiers. This is used while printing. */struct d_print_mod{ /* Next modifier on the list. These are in the reverse of the order in which they appeared in the mangled string. */ struct d_print_mod *next; /* The modifier. */ const struct demangle_component *mod; /* Whether this modifier was printed. */ int printed; /* The list of templates which applies to this modifier. */ struct d_print_template *templates;};/* We use these structures to hold information during printing. */struct d_growable_string{ /* Buffer holding the result. */ char *buf; /* Current length of data in buffer. */ size_t len; /* Allocated size of buffer. */ size_t alc; /* Set to 1 if we had a memory allocation failure. */ int allocation_failure;};enum { D_PRINT_BUFFER_LENGTH = 256 };struct d_print_info{ /* The options passed to the demangler. */ int options; /* Fixed-length allocated buffer for demangled data, flushed to the callback with a NUL termination once full. */ char buf[D_PRINT_BUFFER_LENGTH]; /* Current length of data in buffer. */ size_t len; /* The last character printed, saved individually so that it survives any buffer flush. */ char last_char; /* Callback function to handle demangled buffer flush. */ demangle_callbackref callback; /* Opaque callback argument. */ void *opaque; /* The current list of templates, if any. */ struct d_print_template *templates; /* The current list of modifiers (e.g., pointer, reference, etc.), if any. */ struct d_print_mod *modifiers; /* Set to 1 if we saw a demangling error. */ int demangle_failure;};#ifdef CP_DEMANGLE_DEBUGstatic void d_dump (struct demangle_component *, int);#endifstatic struct demangle_component *d_make_empty (struct d_info *);static struct demangle_component *d_make_comp (struct d_info *, enum demangle_component_type, struct demangle_component *, struct demangle_component *);static struct demangle_component *d_make_name (struct d_info *, const char *, int);static struct demangle_component *d_make_builtin_type (struct d_info *, const struct demangle_builtin_type_info *);static struct demangle_component *d_make_operator (struct d_info *, const struct demangle_operator_info *);static struct demangle_component *d_make_extended_operator (struct d_info *, int, struct demangle_component *);static struct demangle_component *d_make_ctor (struct d_info *, enum gnu_v3_ctor_kinds, struct demangle_component *);static struct demangle_component *d_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds, struct demangle_component *);static struct demangle_component *d_make_template_param (struct d_info *, long);static struct demangle_component *d_make_sub (struct d_info *, const char *, int);static inthas_return_type (struct demangle_component *);static intis_ctor_dtor_or_conversion (struct demangle_component *);static struct demangle_component *d_encoding (struct d_info *, int);static struct demangle_component *d_name (struct d_info *);static struct demangle_component *d_nested_name (struct d_info *);static struct demangle_component *d_prefix (struct d_info *);static struct demangle_component *d_unqualified_name (struct d_info *);static struct demangle_component *d_source_name (struct d_info *);static long d_number (struct d_info *);static struct demangle_component *d_identifier (struct d_info *, int);static struct demangle_component *d_operator_name (struct d_info *);static struct demangle_component *d_special_name (struct d_info *);static int d_call_offset (struct d_info *, int);static struct demangle_component *d_ctor_dtor_name (struct d_info *);static struct demangle_component **d_cv_qualifiers (struct d_info *, struct demangle_component **, int);static struct demangle_component *d_function_type (struct d_info *);static struct demangle_component *d_bare_function_type (struct d_info *, int);static struct demangle_component *d_class_enum_type (struct d_info *);static struct demangle_component *d_array_type (struct d_info *);static struct demangle_component *d_pointer_to_member_type (struct d_info *);static struct demangle_component *d_template_param (struct d_info *);static struct demangle_component *d_template_args (struct d_info *);static struct demangle_component *d_template_arg (struct d_info *);static struct demangle_component *d_expression (struct d_info *);static struct demangle_component *d_expr_primary (struct d_info *);static struct demangle_component *d_local_name (struct d_info *);static int d_discriminator (struct d_info *);static intd_add_substitution (struct d_info *, struct demangle_component *);static struct demangle_component *d_substitution (struct d_info *, int);static void d_growable_string_init (struct d_growable_string *, size_t);static inline voidd_growable_string_resize (struct d_growable_string *, size_t);static inline voidd_growable_string_append_buffer (struct d_growable_string *, const char *, size_t);static voidd_growable_string_callback_adapter (const char *, size_t, void *);static voidd_print_init (struct d_print_info *, int, demangle_callbackref, void *);static inline void d_print_error (struct d_print_info *);static inline int d_print_saw_error (struct d_print_info *);static inline void d_print_flush (struct d_print_info *);static inline void d_append_char (struct d_print_info *, char);static inline void d_append_buffer (struct d_print_info *, const char *, size_t);static inline void d_append_string (struct d_print_info *, const char *);static inline char d_last_char (struct d_print_info *);static voidd_print_comp (struct d_print_info *, const struct demangle_component *);static voidd_print_java_identifier (struct d_print_info *, const char *, int);static voidd_print_mod_list (struct d_print_info *, struct d_print_mod *, int);static voidd_print_mod (struct d_print_info *, const struct demangle_component *);static voidd_print_function_type (struct d_print_info *, const struct demangle_component *, struct d_print_mod *);static voidd_print_array_type (struct d_print_info *, const struct demangle_component *, struct d_print_mod *);static voidd_print_expr_op (struct d_print_info *, const struct demangle_component *);static voidd_print_cast (struct d_print_info *, const struct demangle_component *);static int d_demangle_callback (const char *, int, demangle_callbackref, void *);static char *d_demangle (const char *, int, size_t *);#ifdef CP_DEMANGLE_DEBUGstatic voidd_dump (struct demangle_component *dc, int indent){ int i; if (dc == NULL) { if (indent == 0) printf ("failed demangling\n"); return; } for (i = 0; i < indent; ++i) putchar (' '); switch (dc->type)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -