📄 cp-demangle.c
字号:
{ "sz", NL ("sizeof "), 1 }, { NULL, NULL, 0, 0 }};static struct demangle_component *d_operator_name (struct d_info *di){ char c1; char c2; c1 = d_next_char (di); c2 = d_next_char (di); if (c1 == 'v' && IS_DIGIT (c2)) return d_make_extended_operator (di, c2 - '0', d_source_name (di)); else if (c1 == 'c' && c2 == 'v') return d_make_comp (di, DEMANGLE_COMPONENT_CAST, cplus_demangle_type (di), NULL); else { /* LOW is the inclusive lower bound. */ int low = 0; /* HIGH is the exclusive upper bound. We subtract one to ignore the sentinel at the end of the array. */ int high = ((sizeof (cplus_demangle_operators) / sizeof (cplus_demangle_operators[0])) - 1); while (1) { int i; const struct demangle_operator_info *p; i = low + (high - low) / 2; p = cplus_demangle_operators + i; if (c1 == p->code[0] && c2 == p->code[1]) return d_make_operator (di, p); if (c1 < p->code[0] || (c1 == p->code[0] && c2 < p->code[1])) high = i; else low = i + 1; if (low == high) return NULL; } }}static struct demangle_component *d_make_character (struct d_info *di, int c){ struct demangle_component *p; p = d_make_empty (di); if (p != NULL) { p->type = DEMANGLE_COMPONENT_CHARACTER; p->u.s_character.character = c; } return p;}static struct demangle_component *d_java_resource (struct d_info *di){ struct demangle_component *p = NULL; struct demangle_component *next = NULL; long len, i; char c; const char *str; len = d_number (di); if (len <= 1) return NULL; /* Eat the leading '_'. */ if (d_next_char (di) != '_') return NULL; len--; str = d_str (di); i = 0; while (len > 0) { c = str[i]; if (!c) return NULL; /* Each chunk is either a '$' escape... */ if (c == '$') { i++; switch (str[i++]) { case 'S': c = '/'; break; case '_': c = '.'; break; case '$': c = '$'; break; default: return NULL; } next = d_make_character (di, c); d_advance (di, i); str = d_str (di); len -= i; i = 0; if (next == NULL) return NULL; } /* ... or a sequence of characters. */ else { while (i < len && str[i] && str[i] != '$') i++; next = d_make_name (di, str, i); d_advance (di, i); str = d_str (di); len -= i; i = 0; if (next == NULL) return NULL; } if (p == NULL) p = next; else { p = d_make_comp (di, DEMANGLE_COMPONENT_COMPOUND_NAME, p, next); if (p == NULL) return NULL; } } p = d_make_comp (di, DEMANGLE_COMPONENT_JAVA_RESOURCE, p, NULL); return p;}/* <special-name> ::= TV <type> ::= TT <type> ::= TI <type> ::= TS <type> ::= GV <(object) name> ::= T <call-offset> <(base) encoding> ::= Tc <call-offset> <call-offset> <(base) encoding> Also g++ extensions: ::= TC <type> <(offset) number> _ <(base) type> ::= TF <type> ::= TJ <type> ::= GR <name> ::= GA <encoding> ::= Gr <resource name>*/static struct demangle_component *d_special_name (struct d_info *di){ di->expansion += 20; if (d_check_char (di, 'T')) { switch (d_next_char (di)) { case 'V': di->expansion -= 5; return d_make_comp (di, DEMANGLE_COMPONENT_VTABLE, cplus_demangle_type (di), NULL); case 'T': di->expansion -= 10; return d_make_comp (di, DEMANGLE_COMPONENT_VTT, cplus_demangle_type (di), NULL); case 'I': return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO, cplus_demangle_type (di), NULL); case 'S': return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_NAME, cplus_demangle_type (di), NULL); case 'h': if (! d_call_offset (di, 'h')) return NULL; return d_make_comp (di, DEMANGLE_COMPONENT_THUNK, d_encoding (di, 0), NULL); case 'v': if (! d_call_offset (di, 'v')) return NULL; return d_make_comp (di, DEMANGLE_COMPONENT_VIRTUAL_THUNK, d_encoding (di, 0), NULL); case 'c': if (! d_call_offset (di, '\0')) return NULL; if (! d_call_offset (di, '\0')) return NULL; return d_make_comp (di, DEMANGLE_COMPONENT_COVARIANT_THUNK, d_encoding (di, 0), NULL); case 'C': { struct demangle_component *derived_type; long offset; struct demangle_component *base_type; derived_type = cplus_demangle_type (di); offset = d_number (di); if (offset < 0) return NULL; if (! d_check_char (di, '_')) return NULL; base_type = cplus_demangle_type (di); /* We don't display the offset. FIXME: We should display it in verbose mode. */ di->expansion += 5; return d_make_comp (di, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, base_type, derived_type); } case 'F': return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_FN, cplus_demangle_type (di), NULL); case 'J': return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS, cplus_demangle_type (di), NULL); default: return NULL; } } else if (d_check_char (di, 'G')) { switch (d_next_char (di)) { case 'V': return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL); case 'R': return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, d_name (di), NULL); case 'A': return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS, d_encoding (di, 0), NULL); case 'r': return d_java_resource (di); default: return NULL; } } else return NULL;}/* <call-offset> ::= h <nv-offset> _ ::= v <v-offset> _ <nv-offset> ::= <(offset) number> <v-offset> ::= <(offset) number> _ <(virtual offset) number> The C parameter, if not '\0', is a character we just read which is the start of the <call-offset>. We don't display the offset information anywhere. FIXME: We should display it in verbose mode. */static intd_call_offset (struct d_info *di, int c){ if (c == '\0') c = d_next_char (di); if (c == 'h') d_number (di); else if (c == 'v') { d_number (di); if (! d_check_char (di, '_')) return 0; d_number (di); } else return 0; if (! d_check_char (di, '_')) return 0; return 1;}/* <ctor-dtor-name> ::= C1 ::= C2 ::= C3 ::= D0 ::= D1 ::= D2*/static struct demangle_component *d_ctor_dtor_name (struct d_info *di){ if (di->last_name != NULL) { if (di->last_name->type == DEMANGLE_COMPONENT_NAME) di->expansion += di->last_name->u.s_name.len; else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD) di->expansion += di->last_name->u.s_string.len; } switch (d_peek_char (di)) { case 'C': { enum gnu_v3_ctor_kinds kind; switch (d_peek_next_char (di)) { case '1': kind = gnu_v3_complete_object_ctor; break; case '2': kind = gnu_v3_base_object_ctor; break; case '3': kind = gnu_v3_complete_object_allocating_ctor; break; default: return NULL; } d_advance (di, 2); return d_make_ctor (di, kind, di->last_name); } case 'D': { enum gnu_v3_dtor_kinds kind; switch (d_peek_next_char (di)) { case '0': kind = gnu_v3_deleting_dtor; break; case '1': kind = gnu_v3_complete_object_dtor; break; case '2': kind = gnu_v3_base_object_dtor; break; default: return NULL; } d_advance (di, 2); return d_make_dtor (di, kind, di->last_name); } default: return NULL; }}/* <type> ::= <builtin-type> ::= <function-type> ::= <class-enum-type> ::= <array-type> ::= <pointer-to-member-type> ::= <template-param> ::= <template-template-param> <template-args> ::= <substitution> ::= <CV-qualifiers> <type> ::= P <type> ::= R <type> ::= O <type> (C++0x) ::= C <type> ::= G <type> ::= U <source-name> <type> <builtin-type> ::= various one letter codes ::= u <source-name>*/CP_STATIC_IF_GLIBCPP_V3const struct demangle_builtin_type_infocplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] ={ /* a */ { NL ("signed char"), NL ("signed char"), D_PRINT_DEFAULT }, /* b */ { NL ("bool"), NL ("boolean"), D_PRINT_BOOL }, /* c */ { NL ("char"), NL ("byte"), D_PRINT_DEFAULT }, /* d */ { NL ("double"), NL ("double"), D_PRINT_FLOAT }, /* e */ { NL ("long double"), NL ("long double"), D_PRINT_FLOAT }, /* f */ { NL ("float"), NL ("float"), D_PRINT_FLOAT }, /* g */ { NL ("__float128"), NL ("__float128"), D_PRINT_FLOAT }, /* h */ { NL ("unsigned char"), NL ("unsigned char"), D_PRINT_DEFAULT }, /* i */ { NL ("int"), NL ("int"), D_PRINT_INT }, /* j */ { NL ("unsigned int"), NL ("unsigned"), D_PRINT_UNSIGNED }, /* k */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, /* l */ { NL ("long"), NL ("long"), D_PRINT_LONG }, /* m */ { NL ("unsigned long"), NL ("unsigned long"), D_PRINT_UNSIGNED_LONG }, /* n */ { NL ("__int128"), NL ("__int128"), D_PRINT_DEFAULT }, /* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"), D_PRINT_DEFAULT }, /* p */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, /* q */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, /* r */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, /* s */ { NL ("short"), NL ("short"), D_PRINT_DEFAULT }, /* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT }, /* u */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT }, /* v */ { NL ("void"), NL ("void"), D_PRINT_VOID }, /* w */ { NL ("wchar_t"), NL ("char"), D_PRINT_DEFAULT }, /* x */ { NL ("long long"), NL ("long"), D_PRINT_LONG_LONG }, /* y */ { NL ("unsigned long long"), NL ("unsigned long long"), D_PRINT_UNSIGNED_LONG_LONG }, /* z */ { NL ("..."), NL ("..."), D_PRINT_DEFAULT },};CP_STATIC_IF_GLIBCPP_V3struct demangle_component *cplus_demangle_type (struct d_info *di){ char peek; struct demangle_component *ret; int can_subst; /* The ABI specifies that when CV-qualifiers are used, the base type is substitutable, and the fully qualified type is substitutable, but the base type with a strict subset of the CV-qualifiers is not substitutable. The natural recursive implementation of the CV-qualifiers would cause subsets to be substitutable, so instead we pull them all off now. FIXME: The ABI says that order-insensitive vendor qualifiers should be handled in the same way, but we have no way to tell which vendor qualifiers are order-insensitive and which are order-sensitive. So we just assume that they are all order-sensitive. g++ 3.4 supports only one vendor qualifier, __vector, and it treats it as order-sensitive when mangling names. */ peek = d_peek_char (di); if (peek == 'r' || peek == 'V' || peek == 'K') { struct demangle_component **pret; pret = d_cv_qualifiers (di, &ret, 0); if (pret == NULL) return NULL; *pret = cplus_demangle_type (di); if (! *pret || ! d_add_substitution (di, ret)) return NULL; return ret; } can_subst = 1; switch (peek) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'l': case 'm': case 'n': case 'o': case 's': case 't': case 'v': case 'w': case 'x': case 'y': case 'z': ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[peek - 'a']); di->expansion += ret->u.s_builtin.type->len; can_subst = 0; d_advance (di, 1); break; case 'u': d_advance (di, 1); ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE, d_source_name (di), NULL); break; case 'F': ret = d_function_type (di); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'N': case 'Z': ret = d_class_enum_type (di); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -