Line 1... |
Line 1... |
/* Demangler for g++ V3 ABI.
|
/* Demangler for g++ V3 ABI.
|
Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
|
|
Free Software Foundation, Inc.
|
Written by Ian Lance Taylor <ian@wasabisystems.com>.
|
Written by Ian Lance Taylor <ian@wasabisystems.com>.
|
|
|
This file is part of the libiberty library, which is part of GCC.
|
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
|
This file is free software; you can redistribute it and/or modify
|
Line 296... |
Line 297... |
/* The current list of modifiers (e.g., pointer, reference, etc.),
|
/* The current list of modifiers (e.g., pointer, reference, etc.),
|
if any. */
|
if any. */
|
struct d_print_mod *modifiers;
|
struct d_print_mod *modifiers;
|
/* Set to 1 if we saw a demangling error. */
|
/* Set to 1 if we saw a demangling error. */
|
int demangle_failure;
|
int demangle_failure;
|
|
/* The current index into any template argument packs we are using
|
|
for printing. */
|
|
int pack_index;
|
};
|
};
|
|
|
#ifdef CP_DEMANGLE_DEBUG
|
#ifdef CP_DEMANGLE_DEBUG
|
static void d_dump (struct demangle_component *, int);
|
static void d_dump (struct demangle_component *, int);
|
#endif
|
#endif
|
Line 615... |
Line 619... |
printf ("array type\n");
|
printf ("array type\n");
|
break;
|
break;
|
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
|
case DEMANGLE_COMPONENT_PTRMEM_TYPE:
|
printf ("pointer to member type\n");
|
printf ("pointer to member type\n");
|
break;
|
break;
|
|
case DEMANGLE_COMPONENT_FIXED_TYPE:
|
|
printf ("fixed-point type\n");
|
|
break;
|
case DEMANGLE_COMPONENT_ARGLIST:
|
case DEMANGLE_COMPONENT_ARGLIST:
|
printf ("argument list\n");
|
printf ("argument list\n");
|
break;
|
break;
|
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
|
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
|
printf ("template argument list\n");
|
printf ("template argument list\n");
|
Line 657... |
Line 664... |
printf ("compound name\n");
|
printf ("compound name\n");
|
break;
|
break;
|
case DEMANGLE_COMPONENT_CHARACTER:
|
case DEMANGLE_COMPONENT_CHARACTER:
|
printf ("character '%c'\n", dc->u.s_character.character);
|
printf ("character '%c'\n", dc->u.s_character.character);
|
return;
|
return;
|
|
case DEMANGLE_COMPONENT_DECLTYPE:
|
|
printf ("decltype\n");
|
|
break;
|
|
case DEMANGLE_COMPONENT_PACK_EXPANSION:
|
|
printf ("pack expansion\n");
|
|
break;
|
}
|
}
|
|
|
d_dump (d_left (dc), indent + 2);
|
d_dump (d_left (dc), indent + 2);
|
d_dump (d_right (dc), indent + 2);
|
d_dump (d_right (dc), indent + 2);
|
}
|
}
|
Line 704... |
Line 717... |
enum gnu_v3_ctor_kinds kind,
|
enum gnu_v3_ctor_kinds kind,
|
struct demangle_component *name)
|
struct demangle_component *name)
|
{
|
{
|
if (p == NULL
|
if (p == NULL
|
|| name == NULL
|
|| name == NULL
|
|| (kind < gnu_v3_complete_object_ctor
|
|| (int) kind < gnu_v3_complete_object_ctor
|
&& kind > gnu_v3_complete_object_allocating_ctor))
|
|| (int) kind > gnu_v3_complete_object_allocating_ctor)
|
return 0;
|
return 0;
|
p->type = DEMANGLE_COMPONENT_CTOR;
|
p->type = DEMANGLE_COMPONENT_CTOR;
|
p->u.s_ctor.kind = kind;
|
p->u.s_ctor.kind = kind;
|
p->u.s_ctor.name = name;
|
p->u.s_ctor.name = name;
|
return 1;
|
return 1;
|
Line 723... |
Line 736... |
enum gnu_v3_dtor_kinds kind,
|
enum gnu_v3_dtor_kinds kind,
|
struct demangle_component *name)
|
struct demangle_component *name)
|
{
|
{
|
if (p == NULL
|
if (p == NULL
|
|| name == NULL
|
|| name == NULL
|
|| (kind < gnu_v3_deleting_dtor
|
|| (int) kind < gnu_v3_deleting_dtor
|
&& kind > gnu_v3_base_object_dtor))
|
|| (int) kind > gnu_v3_base_object_dtor)
|
return 0;
|
return 0;
|
p->type = DEMANGLE_COMPONENT_DTOR;
|
p->type = DEMANGLE_COMPONENT_DTOR;
|
p->u.s_dtor.kind = kind;
|
p->u.s_dtor.kind = kind;
|
p->u.s_dtor.name = name;
|
p->u.s_dtor.name = name;
|
return 1;
|
return 1;
|
Line 800... |
Line 813... |
case DEMANGLE_COMPONENT_REFERENCE:
|
case DEMANGLE_COMPONENT_REFERENCE:
|
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
|
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
|
case DEMANGLE_COMPONENT_COMPLEX:
|
case DEMANGLE_COMPONENT_COMPLEX:
|
case DEMANGLE_COMPONENT_IMAGINARY:
|
case DEMANGLE_COMPONENT_IMAGINARY:
|
case DEMANGLE_COMPONENT_VENDOR_TYPE:
|
case DEMANGLE_COMPONENT_VENDOR_TYPE:
|
case DEMANGLE_COMPONENT_ARGLIST:
|
|
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
|
|
case DEMANGLE_COMPONENT_CAST:
|
case DEMANGLE_COMPONENT_CAST:
|
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
|
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
|
|
case DEMANGLE_COMPONENT_DECLTYPE:
|
|
case DEMANGLE_COMPONENT_PACK_EXPANSION:
|
|
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
|
|
case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
|
if (left == NULL)
|
if (left == NULL)
|
return NULL;
|
return NULL;
|
break;
|
break;
|
|
|
/* This needs a right parameter, but the left parameter can be
|
/* This needs a right parameter, but the left parameter can be
|
Line 824... |
Line 839... |
case DEMANGLE_COMPONENT_VOLATILE:
|
case DEMANGLE_COMPONENT_VOLATILE:
|
case DEMANGLE_COMPONENT_CONST:
|
case DEMANGLE_COMPONENT_CONST:
|
case DEMANGLE_COMPONENT_RESTRICT_THIS:
|
case DEMANGLE_COMPONENT_RESTRICT_THIS:
|
case DEMANGLE_COMPONENT_VOLATILE_THIS:
|
case DEMANGLE_COMPONENT_VOLATILE_THIS:
|
case DEMANGLE_COMPONENT_CONST_THIS:
|
case DEMANGLE_COMPONENT_CONST_THIS:
|
|
case DEMANGLE_COMPONENT_ARGLIST:
|
|
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
|
break;
|
break;
|
|
|
/* Other types should not be seen here. */
|
/* Other types should not be seen here. */
|
default:
|
default:
|
return NULL;
|
return NULL;
|
Line 947... |
Line 964... |
p->u.s_number.number = i;
|
p->u.s_number.number = i;
|
}
|
}
|
return p;
|
return p;
|
}
|
}
|
|
|
|
/* Add a new function parameter. */
|
|
|
|
static struct demangle_component *
|
|
d_make_function_param (struct d_info *di, long i)
|
|
{
|
|
struct demangle_component *p;
|
|
|
|
p = d_make_empty (di);
|
|
if (p != NULL)
|
|
{
|
|
p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
|
|
p->u.s_number.number = i;
|
|
}
|
|
return p;
|
|
}
|
|
|
/* Add a new standard substitution component. */
|
/* Add a new standard substitution component. */
|
|
|
static struct demangle_component *
|
static struct demangle_component *
|
d_make_sub (struct d_info *di, const char *name, int len)
|
d_make_sub (struct d_info *di, const char *name, int len)
|
{
|
{
|
Line 972... |
Line 1005... |
|
|
CP_STATIC_IF_GLIBCPP_V3
|
CP_STATIC_IF_GLIBCPP_V3
|
struct demangle_component *
|
struct demangle_component *
|
cplus_demangle_mangled_name (struct d_info *di, int top_level)
|
cplus_demangle_mangled_name (struct d_info *di, int top_level)
|
{
|
{
|
if (! d_check_char (di, '_'))
|
if (! d_check_char (di, '_')
|
|
/* Allow missing _ if not at toplevel to work around a
|
|
bug in G++ abi-version=2 mangling; see the comment in
|
|
write_template_arg. */
|
|
&& top_level)
|
return NULL;
|
return NULL;
|
if (! d_check_char (di, 'Z'))
|
if (! d_check_char (di, 'Z'))
|
return NULL;
|
return NULL;
|
return d_encoding (di, top_level);
|
return d_encoding (di, top_level);
|
}
|
}
|
Line 1419... |
Line 1456... |
{ "aN", NL ("&="), 2 },
|
{ "aN", NL ("&="), 2 },
|
{ "aS", NL ("="), 2 },
|
{ "aS", NL ("="), 2 },
|
{ "aa", NL ("&&"), 2 },
|
{ "aa", NL ("&&"), 2 },
|
{ "ad", NL ("&"), 1 },
|
{ "ad", NL ("&"), 1 },
|
{ "an", NL ("&"), 2 },
|
{ "an", NL ("&"), 2 },
|
{ "cl", NL ("()"), 0 },
|
{ "cl", NL ("()"), 2 },
|
{ "cm", NL (","), 2 },
|
{ "cm", NL (","), 2 },
|
{ "co", NL ("~"), 1 },
|
{ "co", NL ("~"), 1 },
|
{ "dV", NL ("/="), 2 },
|
{ "dV", NL ("/="), 2 },
|
{ "da", NL ("delete[]"), 1 },
|
{ "da", NL ("delete[]"), 1 },
|
{ "de", NL ("*"), 1 },
|
{ "de", NL ("*"), 1 },
|
{ "dl", NL ("delete"), 1 },
|
{ "dl", NL ("delete"), 1 },
|
|
{ "dt", NL ("."), 2 },
|
{ "dv", NL ("/"), 2 },
|
{ "dv", NL ("/"), 2 },
|
{ "eO", NL ("^="), 2 },
|
{ "eO", NL ("^="), 2 },
|
{ "eo", NL ("^"), 2 },
|
{ "eo", NL ("^"), 2 },
|
{ "eq", NL ("=="), 2 },
|
{ "eq", NL ("=="), 2 },
|
{ "ge", NL (">="), 2 },
|
{ "ge", NL (">="), 2 },
|
Line 1463... |
Line 1501... |
{ "rS", NL (">>="), 2 },
|
{ "rS", NL (">>="), 2 },
|
{ "rm", NL ("%"), 2 },
|
{ "rm", NL ("%"), 2 },
|
{ "rs", NL (">>"), 2 },
|
{ "rs", NL (">>"), 2 },
|
{ "st", NL ("sizeof "), 1 },
|
{ "st", NL ("sizeof "), 1 },
|
{ "sz", NL ("sizeof "), 1 },
|
{ "sz", NL ("sizeof "), 1 },
|
|
{ "at", NL ("alignof "), 1 },
|
|
{ "az", NL ("alignof "), 1 },
|
{ NULL, NULL, 0, 0 }
|
{ NULL, NULL, 0, 0 }
|
};
|
};
|
|
|
static struct demangle_component *
|
static struct demangle_component *
|
d_operator_name (struct d_info *di)
|
d_operator_name (struct d_info *di)
|
Line 1880... |
Line 1920... |
/* w */ { NL ("wchar_t"), NL ("char"), D_PRINT_DEFAULT },
|
/* w */ { NL ("wchar_t"), NL ("char"), D_PRINT_DEFAULT },
|
/* x */ { NL ("long long"), NL ("long"), D_PRINT_LONG_LONG },
|
/* x */ { NL ("long long"), NL ("long"), D_PRINT_LONG_LONG },
|
/* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
|
/* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
|
D_PRINT_UNSIGNED_LONG_LONG },
|
D_PRINT_UNSIGNED_LONG_LONG },
|
/* z */ { NL ("..."), NL ("..."), D_PRINT_DEFAULT },
|
/* z */ { NL ("..."), NL ("..."), D_PRINT_DEFAULT },
|
|
/* 26 */ { NL ("decimal32"), NL ("decimal32"), D_PRINT_DEFAULT },
|
|
/* 27 */ { NL ("decimal64"), NL ("decimal64"), D_PRINT_DEFAULT },
|
|
/* 28 */ { NL ("decimal128"), NL ("decimal128"), D_PRINT_DEFAULT },
|
|
/* 29 */ { NL ("half"), NL ("half"), D_PRINT_FLOAT },
|
|
/* 30 */ { NL ("char16_t"), NL ("char16_t"), D_PRINT_DEFAULT },
|
|
/* 31 */ { NL ("char32_t"), NL ("char32_t"), D_PRINT_DEFAULT },
|
};
|
};
|
|
|
CP_STATIC_IF_GLIBCPP_V3
|
CP_STATIC_IF_GLIBCPP_V3
|
struct demangle_component *
|
struct demangle_component *
|
cplus_demangle_type (struct d_info *di)
|
cplus_demangle_type (struct d_info *di)
|
Line 2043... |
Line 2089... |
ret = d_source_name (di);
|
ret = d_source_name (di);
|
ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
|
ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
|
cplus_demangle_type (di), ret);
|
cplus_demangle_type (di), ret);
|
break;
|
break;
|
|
|
|
case 'D':
|
|
can_subst = 0;
|
|
d_advance (di, 1);
|
|
peek = d_next_char (di);
|
|
switch (peek)
|
|
{
|
|
case 'T':
|
|
case 't':
|
|
/* decltype (expression) */
|
|
ret = d_make_comp (di, DEMANGLE_COMPONENT_DECLTYPE,
|
|
d_expression (di), NULL);
|
|
if (ret && d_next_char (di) != 'E')
|
|
ret = NULL;
|
|
break;
|
|
|
|
case 'p':
|
|
/* Pack expansion. */
|
|
ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
|
|
cplus_demangle_type (di), NULL);
|
|
break;
|
|
|
|
case 'f':
|
|
/* 32-bit decimal floating point */
|
|
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
|
|
di->expansion += ret->u.s_builtin.type->len;
|
|
break;
|
|
case 'd':
|
|
/* 64-bit DFP */
|
|
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]);
|
|
di->expansion += ret->u.s_builtin.type->len;
|
|
break;
|
|
case 'e':
|
|
/* 128-bit DFP */
|
|
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]);
|
|
di->expansion += ret->u.s_builtin.type->len;
|
|
break;
|
|
case 'h':
|
|
/* 16-bit half-precision FP */
|
|
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
|
|
di->expansion += ret->u.s_builtin.type->len;
|
|
break;
|
|
case 's':
|
|
/* char16_t */
|
|
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
|
|
di->expansion += ret->u.s_builtin.type->len;
|
|
break;
|
|
case 'i':
|
|
/* char32_t */
|
|
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
|
|
di->expansion += ret->u.s_builtin.type->len;
|
|
break;
|
|
|
|
case 'F':
|
|
/* Fixed point types. DF<int bits><length><fract bits><sat> */
|
|
ret = d_make_empty (di);
|
|
ret->type = DEMANGLE_COMPONENT_FIXED_TYPE;
|
|
if ((ret->u.s_fixed.accum = IS_DIGIT (d_peek_char (di))))
|
|
/* For demangling we don't care about the bits. */
|
|
d_number (di);
|
|
ret->u.s_fixed.length = cplus_demangle_type (di);
|
|
d_number (di);
|
|
peek = d_next_char (di);
|
|
ret->u.s_fixed.sat = (peek == 's');
|
|
break;
|
|
|
|
default:
|
|
return NULL;
|
|
}
|
|
break;
|
|
|
default:
|
default:
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
if (can_subst)
|
if (can_subst)
|
Line 2334... |
Line 2450... |
hold_last_name = di->last_name;
|
hold_last_name = di->last_name;
|
|
|
if (! d_check_char (di, 'I'))
|
if (! d_check_char (di, 'I'))
|
return NULL;
|
return NULL;
|
|
|
|
if (d_peek_char (di) == 'E')
|
|
{
|
|
/* An argument pack can be empty. */
|
|
d_advance (di, 1);
|
|
return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL);
|
|
}
|
|
|
al = NULL;
|
al = NULL;
|
pal = &al;
|
pal = &al;
|
while (1)
|
while (1)
|
{
|
{
|
struct demangle_component *a;
|
struct demangle_component *a;
|
Line 2383... |
Line 2506... |
return ret;
|
return ret;
|
|
|
case 'L':
|
case 'L':
|
return d_expr_primary (di);
|
return d_expr_primary (di);
|
|
|
|
case 'I':
|
|
/* An argument pack. */
|
|
return d_template_args (di);
|
|
|
default:
|
default:
|
return cplus_demangle_type (di);
|
return cplus_demangle_type (di);
|
}
|
}
|
}
|
}
|
|
|
|
/* Subroutine of <expression> ::= cl <expression>+ E */
|
|
|
|
static struct demangle_component *
|
|
d_exprlist (struct d_info *di)
|
|
{
|
|
struct demangle_component *list = NULL;
|
|
struct demangle_component **p = &list;
|
|
|
|
if (d_peek_char (di) == 'E')
|
|
{
|
|
d_advance (di, 1);
|
|
return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
struct demangle_component *arg = d_expression (di);
|
|
if (arg == NULL)
|
|
return NULL;
|
|
|
|
*p = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, arg, NULL);
|
|
if (*p == NULL)
|
|
return NULL;
|
|
p = &d_right (*p);
|
|
|
|
if (d_peek_char (di) == 'E')
|
|
{
|
|
d_advance (di, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
/* <expression> ::= <(unary) operator-name> <expression>
|
/* <expression> ::= <(unary) operator-name> <expression>
|
::= <(binary) operator-name> <expression> <expression>
|
::= <(binary) operator-name> <expression> <expression>
|
::= <(trinary) operator-name> <expression> <expression> <expression>
|
::= <(trinary) operator-name> <expression> <expression> <expression>
|
|
::= cl <expression>+ E
|
::= st <type>
|
::= st <type>
|
::= <template-param>
|
::= <template-param>
|
::= sr <type> <unqualified-name>
|
::= sr <type> <unqualified-name>
|
::= sr <type> <unqualified-name> <template-args>
|
::= sr <type> <unqualified-name> <template-args>
|
::= <expr-primary>
|
::= <expr-primary>
|
Line 2423... |
Line 2586... |
else
|
else
|
return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
|
return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
|
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
|
d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
|
d_template_args (di)));
|
d_template_args (di)));
|
}
|
}
|
|
else if (peek == 's' && d_peek_next_char (di) == 'p')
|
|
{
|
|
d_advance (di, 2);
|
|
return d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
|
|
d_expression (di), NULL);
|
|
}
|
|
else if (peek == 'f' && d_peek_next_char (di) == 'p')
|
|
{
|
|
/* Function parameter used in a late-specified return type. */
|
|
int index;
|
|
d_advance (di, 2);
|
|
if (d_peek_char (di) == '_')
|
|
index = 1;
|
|
else
|
|
{
|
|
index = d_number (di);
|
|
if (index < 0)
|
|
return NULL;
|
|
index += 2;
|
|
}
|
|
|
|
if (! d_check_char (di, '_'))
|
|
return NULL;
|
|
|
|
return d_make_function_param (di, index);
|
|
}
|
|
else if (IS_DIGIT (peek))
|
|
{
|
|
/* We can get an unqualified name as an expression in the case of
|
|
a dependent member access, i.e. decltype(T().i). */
|
|
struct demangle_component *name = d_unqualified_name (di);
|
|
if (name == NULL)
|
|
return NULL;
|
|
if (d_peek_char (di) == 'I')
|
|
return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
|
|
d_template_args (di));
|
|
else
|
|
return name;
|
|
}
|
else
|
else
|
{
|
{
|
struct demangle_component *op;
|
struct demangle_component *op;
|
int args;
|
int args;
|
|
|
Line 2458... |
Line 2660... |
}
|
}
|
|
|
switch (args)
|
switch (args)
|
{
|
{
|
case 1:
|
case 1:
|
|
{
|
|
struct demangle_component *operand;
|
|
if (op->type == DEMANGLE_COMPONENT_CAST
|
|
&& d_check_char (di, '_'))
|
|
operand = d_exprlist (di);
|
|
else
|
|
operand = d_expression (di);
|
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
d_expression (di));
|
operand);
|
|
}
|
case 2:
|
case 2:
|
{
|
{
|
struct demangle_component *left;
|
struct demangle_component *left;
|
|
struct demangle_component *right;
|
|
|
left = d_expression (di);
|
left = d_expression (di);
|
|
if (!strcmp (op->u.s_operator.op->code, "cl"))
|
|
right = d_exprlist (di);
|
|
else
|
|
right = d_expression (di);
|
|
|
return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
|
return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
|
d_make_comp (di,
|
d_make_comp (di,
|
DEMANGLE_COMPONENT_BINARY_ARGS,
|
DEMANGLE_COMPONENT_BINARY_ARGS,
|
left,
|
left, right));
|
d_expression (di)));
|
|
}
|
}
|
case 3:
|
case 3:
|
{
|
{
|
struct demangle_component *first;
|
struct demangle_component *first;
|
struct demangle_component *second;
|
struct demangle_component *second;
|
Line 2505... |
Line 2720... |
{
|
{
|
struct demangle_component *ret;
|
struct demangle_component *ret;
|
|
|
if (! d_check_char (di, 'L'))
|
if (! d_check_char (di, 'L'))
|
return NULL;
|
return NULL;
|
if (d_peek_char (di) == '_')
|
if (d_peek_char (di) == '_'
|
|
/* Workaround for G++ bug; see comment in write_template_arg. */
|
|
|| d_peek_char (di) == 'Z')
|
ret = cplus_demangle_mangled_name (di, 0);
|
ret = cplus_demangle_mangled_name (di, 0);
|
else
|
else
|
{
|
{
|
struct demangle_component *type;
|
struct demangle_component *type;
|
enum demangle_component_type t;
|
enum demangle_component_type t;
|
Line 2679... |
Line 2896... |
return NULL;
|
return NULL;
|
|
|
c = d_next_char (di);
|
c = d_next_char (di);
|
if (c == '_' || IS_DIGIT (c) || IS_UPPER (c))
|
if (c == '_' || IS_DIGIT (c) || IS_UPPER (c))
|
{
|
{
|
int id;
|
unsigned int id;
|
|
|
id = 0;
|
id = 0;
|
if (c != '_')
|
if (c != '_')
|
{
|
{
|
do
|
do
|
{
|
{
|
|
unsigned int new_id;
|
|
|
if (IS_DIGIT (c))
|
if (IS_DIGIT (c))
|
id = id * 36 + c - '0';
|
new_id = id * 36 + c - '0';
|
else if (IS_UPPER (c))
|
else if (IS_UPPER (c))
|
id = id * 36 + c - 'A' + 10;
|
new_id = id * 36 + c - 'A' + 10;
|
else
|
else
|
return NULL;
|
return NULL;
|
if (id < 0)
|
if (new_id < id)
|
return NULL;
|
return NULL;
|
|
id = new_id;
|
c = d_next_char (di);
|
c = d_next_char (di);
|
}
|
}
|
while (c != '_');
|
while (c != '_');
|
|
|
++id;
|
++id;
|
}
|
}
|
|
|
if (id >= di->next_sub)
|
if (id >= (unsigned int) di->next_sub)
|
return NULL;
|
return NULL;
|
|
|
++di->did_subs;
|
++di->did_subs;
|
|
|
return di->subs[id];
|
return di->subs[id];
|
Line 2962... |
Line 3182... |
|
|
*palc = dgs.allocation_failure ? 1 : dgs.alc;
|
*palc = dgs.allocation_failure ? 1 : dgs.alc;
|
return dgs.buf;
|
return dgs.buf;
|
}
|
}
|
|
|
|
/* Returns the I'th element of the template arglist ARGS, or NULL on
|
|
failure. */
|
|
|
|
static struct demangle_component *
|
|
d_index_template_argument (struct demangle_component *args, int i)
|
|
{
|
|
struct demangle_component *a;
|
|
|
|
for (a = args;
|
|
a != NULL;
|
|
a = d_right (a))
|
|
{
|
|
if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
|
|
return NULL;
|
|
if (i <= 0)
|
|
break;
|
|
--i;
|
|
}
|
|
if (i != 0 || a == NULL)
|
|
return NULL;
|
|
|
|
return d_left (a);
|
|
}
|
|
|
|
/* Returns the template argument from the current context indicated by DC,
|
|
which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL. */
|
|
|
|
static struct demangle_component *
|
|
d_lookup_template_argument (struct d_print_info *dpi,
|
|
const struct demangle_component *dc)
|
|
{
|
|
if (dpi->templates == NULL)
|
|
{
|
|
d_print_error (dpi);
|
|
return NULL;
|
|
}
|
|
|
|
return d_index_template_argument
|
|
(d_right (dpi->templates->template_decl),
|
|
dc->u.s_number.number);
|
|
}
|
|
|
|
/* Returns a template argument pack used in DC (any will do), or NULL. */
|
|
|
|
static struct demangle_component *
|
|
d_find_pack (struct d_print_info *dpi,
|
|
const struct demangle_component *dc)
|
|
{
|
|
struct demangle_component *a;
|
|
if (dc == NULL)
|
|
return NULL;
|
|
|
|
switch (dc->type)
|
|
{
|
|
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
|
|
a = d_lookup_template_argument (dpi, dc);
|
|
if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
|
|
return a;
|
|
return NULL;
|
|
|
|
case DEMANGLE_COMPONENT_PACK_EXPANSION:
|
|
return NULL;
|
|
|
|
case DEMANGLE_COMPONENT_NAME:
|
|
case DEMANGLE_COMPONENT_OPERATOR:
|
|
case DEMANGLE_COMPONENT_BUILTIN_TYPE:
|
|
case DEMANGLE_COMPONENT_SUB_STD:
|
|
case DEMANGLE_COMPONENT_CHARACTER:
|
|
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
|
|
return NULL;
|
|
|
|
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
|
|
return d_find_pack (dpi, dc->u.s_extended_operator.name);
|
|
case DEMANGLE_COMPONENT_CTOR:
|
|
return d_find_pack (dpi, dc->u.s_ctor.name);
|
|
case DEMANGLE_COMPONENT_DTOR:
|
|
return d_find_pack (dpi, dc->u.s_dtor.name);
|
|
|
|
default:
|
|
a = d_find_pack (dpi, d_left (dc));
|
|
if (a)
|
|
return a;
|
|
return d_find_pack (dpi, d_right (dc));
|
|
}
|
|
}
|
|
|
|
/* Returns the length of the template argument pack DC. */
|
|
|
|
static int
|
|
d_pack_length (const struct demangle_component *dc)
|
|
{
|
|
int count = 0;
|
|
while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST
|
|
&& d_left (dc) != NULL)
|
|
{
|
|
++count;
|
|
dc = d_right (dc);
|
|
}
|
|
return count;
|
|
}
|
|
|
|
/* DC is a component of a mangled expression. Print it, wrapped in parens
|
|
if needed. */
|
|
|
|
static void
|
|
d_print_subexpr (struct d_print_info *dpi,
|
|
const struct demangle_component *dc)
|
|
{
|
|
int simple = 0;
|
|
if (dc->type == DEMANGLE_COMPONENT_NAME
|
|
|| dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
|
|
simple = 1;
|
|
if (!simple)
|
|
d_append_char (dpi, '(');
|
|
d_print_comp (dpi, dc);
|
|
if (!simple)
|
|
d_append_char (dpi, ')');
|
|
}
|
|
|
/* Subroutine to handle components. */
|
/* Subroutine to handle components. */
|
|
|
static void
|
static void
|
d_print_comp (struct d_print_info *dpi,
|
d_print_comp (struct d_print_info *dpi,
|
const struct demangle_component *dc)
|
const struct demangle_component *dc)
|
Line 3007... |
Line 3346... |
|
|
/* Pass the name down to the type so that it can be printed in
|
/* Pass the name down to the type so that it can be printed in
|
the right place for the type. We also have to pass down
|
the right place for the type. We also have to pass down
|
any CV-qualifiers, which apply to the this parameter. */
|
any CV-qualifiers, which apply to the this parameter. */
|
hold_modifiers = dpi->modifiers;
|
hold_modifiers = dpi->modifiers;
|
|
dpi->modifiers = 0;
|
i = 0;
|
i = 0;
|
typed_name = d_left (dc);
|
typed_name = d_left (dc);
|
while (typed_name != NULL)
|
while (typed_name != NULL)
|
{
|
{
|
if (i >= sizeof adpm / sizeof adpm[0])
|
if (i >= sizeof adpm / sizeof adpm[0])
|
Line 3147... |
Line 3487... |
return;
|
return;
|
}
|
}
|
|
|
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
|
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
|
{
|
{
|
long i;
|
|
struct demangle_component *a;
|
|
struct d_print_template *hold_dpt;
|
struct d_print_template *hold_dpt;
|
|
struct demangle_component *a = d_lookup_template_argument (dpi, dc);
|
|
|
if (dpi->templates == NULL)
|
if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
|
{
|
a = d_index_template_argument (a, dpi->pack_index);
|
d_print_error (dpi);
|
|
return;
|
if (a == NULL)
|
}
|
|
i = dc->u.s_number.number;
|
|
for (a = d_right (dpi->templates->template_decl);
|
|
a != NULL;
|
|
a = d_right (a))
|
|
{
|
|
if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
|
|
{
|
|
d_print_error (dpi);
|
|
return;
|
|
}
|
|
if (i <= 0)
|
|
break;
|
|
--i;
|
|
}
|
|
if (i != 0 || a == NULL)
|
|
{
|
{
|
d_print_error (dpi);
|
d_print_error (dpi);
|
return;
|
return;
|
}
|
}
|
|
|
Line 3184... |
Line 3507... |
template. */
|
template. */
|
|
|
hold_dpt = dpi->templates;
|
hold_dpt = dpi->templates;
|
dpi->templates = hold_dpt->next;
|
dpi->templates = hold_dpt->next;
|
|
|
d_print_comp (dpi, d_left (a));
|
d_print_comp (dpi, a);
|
|
|
dpi->templates = hold_dpt;
|
dpi->templates = hold_dpt;
|
|
|
return;
|
return;
|
}
|
}
|
Line 3471... |
Line 3794... |
dpi->modifiers = dpm.next;
|
dpi->modifiers = dpm.next;
|
|
|
return;
|
return;
|
}
|
}
|
|
|
|
case DEMANGLE_COMPONENT_FIXED_TYPE:
|
|
if (dc->u.s_fixed.sat)
|
|
d_append_string (dpi, "_Sat ");
|
|
/* Don't print "int _Accum". */
|
|
if (dc->u.s_fixed.length->u.s_builtin.type
|
|
!= &cplus_demangle_builtin_types['i'-'a'])
|
|
{
|
|
d_print_comp (dpi, dc->u.s_fixed.length);
|
|
d_append_char (dpi, ' ');
|
|
}
|
|
if (dc->u.s_fixed.accum)
|
|
d_append_string (dpi, "_Accum");
|
|
else
|
|
d_append_string (dpi, "_Fract");
|
|
return;
|
|
|
case DEMANGLE_COMPONENT_ARGLIST:
|
case DEMANGLE_COMPONENT_ARGLIST:
|
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
|
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
|
|
if (d_left (dc) != NULL)
|
d_print_comp (dpi, d_left (dc));
|
d_print_comp (dpi, d_left (dc));
|
if (d_right (dc) != NULL)
|
if (d_right (dc) != NULL)
|
{
|
{
|
|
size_t len;
|
d_append_string (dpi, ", ");
|
d_append_string (dpi, ", ");
|
|
len = dpi->len;
|
d_print_comp (dpi, d_right (dc));
|
d_print_comp (dpi, d_right (dc));
|
|
/* If that didn't print anything (which can happen with empty
|
|
template argument packs), remove the comma and space. */
|
|
if (dpi->len == len)
|
|
dpi->len -= 2;
|
}
|
}
|
return;
|
return;
|
|
|
case DEMANGLE_COMPONENT_OPERATOR:
|
case DEMANGLE_COMPONENT_OPERATOR:
|
{
|
{
|
Line 3513... |
Line 3859... |
{
|
{
|
d_append_char (dpi, '(');
|
d_append_char (dpi, '(');
|
d_print_cast (dpi, d_left (dc));
|
d_print_cast (dpi, d_left (dc));
|
d_append_char (dpi, ')');
|
d_append_char (dpi, ')');
|
}
|
}
|
d_append_char (dpi, '(');
|
d_print_subexpr (dpi, d_right (dc));
|
d_print_comp (dpi, d_right (dc));
|
|
d_append_char (dpi, ')');
|
|
return;
|
return;
|
|
|
case DEMANGLE_COMPONENT_BINARY:
|
case DEMANGLE_COMPONENT_BINARY:
|
if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS)
|
if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS)
|
{
|
{
|
Line 3533... |
Line 3877... |
if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
|
if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
|
&& d_left (dc)->u.s_operator.op->len == 1
|
&& d_left (dc)->u.s_operator.op->len == 1
|
&& d_left (dc)->u.s_operator.op->name[0] == '>')
|
&& d_left (dc)->u.s_operator.op->name[0] == '>')
|
d_append_char (dpi, '(');
|
d_append_char (dpi, '(');
|
|
|
d_append_char (dpi, '(');
|
d_print_subexpr (dpi, d_left (d_right (dc)));
|
d_print_comp (dpi, d_left (d_right (dc)));
|
if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
|
d_append_string (dpi, ") ");
|
|
d_print_expr_op (dpi, d_left (dc));
|
d_print_expr_op (dpi, d_left (dc));
|
d_append_string (dpi, " (");
|
d_print_subexpr (dpi, d_right (d_right (dc)));
|
d_print_comp (dpi, d_right (d_right (dc)));
|
|
d_append_char (dpi, ')');
|
|
|
|
if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
|
if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
|
&& d_left (dc)->u.s_operator.op->len == 1
|
&& d_left (dc)->u.s_operator.op->len == 1
|
&& d_left (dc)->u.s_operator.op->name[0] == '>')
|
&& d_left (dc)->u.s_operator.op->name[0] == '>')
|
d_append_char (dpi, ')');
|
d_append_char (dpi, ')');
|
Line 3560... |
Line 3901... |
|| d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2)
|
|| d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2)
|
{
|
{
|
d_print_error (dpi);
|
d_print_error (dpi);
|
return;
|
return;
|
}
|
}
|
d_append_char (dpi, '(');
|
d_print_subexpr (dpi, d_left (d_right (dc)));
|
d_print_comp (dpi, d_left (d_right (dc)));
|
|
d_append_string (dpi, ") ");
|
|
d_print_expr_op (dpi, d_left (dc));
|
d_print_expr_op (dpi, d_left (dc));
|
d_append_string (dpi, " (");
|
d_print_subexpr (dpi, d_left (d_right (d_right (dc))));
|
d_print_comp (dpi, d_left (d_right (d_right (dc))));
|
d_append_string (dpi, " : ");
|
d_append_string (dpi, ") : (");
|
d_print_subexpr (dpi, d_right (d_right (d_right (dc))));
|
d_print_comp (dpi, d_right (d_right (d_right (dc))));
|
|
d_append_char (dpi, ')');
|
|
return;
|
return;
|
|
|
case DEMANGLE_COMPONENT_TRINARY_ARG1:
|
case DEMANGLE_COMPONENT_TRINARY_ARG1:
|
case DEMANGLE_COMPONENT_TRINARY_ARG2:
|
case DEMANGLE_COMPONENT_TRINARY_ARG2:
|
/* We should only see these are part of DEMANGLE_COMPONENT_TRINARY. */
|
/* We should only see these are part of DEMANGLE_COMPONENT_TRINARY. */
|
Line 3675... |
Line 4012... |
|
|
case DEMANGLE_COMPONENT_CHARACTER:
|
case DEMANGLE_COMPONENT_CHARACTER:
|
d_append_char (dpi, dc->u.s_character.character);
|
d_append_char (dpi, dc->u.s_character.character);
|
return;
|
return;
|
|
|
|
case DEMANGLE_COMPONENT_DECLTYPE:
|
|
d_append_string (dpi, "decltype (");
|
|
d_print_comp (dpi, d_left (dc));
|
|
d_append_char (dpi, ')');
|
|
return;
|
|
|
|
case DEMANGLE_COMPONENT_PACK_EXPANSION:
|
|
{
|
|
int len;
|
|
int i;
|
|
struct demangle_component *a = d_find_pack (dpi, d_left (dc));
|
|
if (a == NULL)
|
|
{
|
|
/* d_find_pack won't find anything if the only packs involved
|
|
in this expansion are function parameter packs; in that
|
|
case, just print the pattern and "...". */
|
|
d_print_subexpr (dpi, d_left (dc));
|
|
d_append_string (dpi, "...");
|
|
return;
|
|
}
|
|
|
|
len = d_pack_length (a);
|
|
dc = d_left (dc);
|
|
for (i = 0; i < len; ++i)
|
|
{
|
|
dpi->pack_index = i;
|
|
d_print_comp (dpi, dc);
|
|
if (i < len-1)
|
|
d_append_string (dpi, ", ");
|
|
}
|
|
}
|
|
return;
|
|
|
|
case DEMANGLE_COMPONENT_FUNCTION_PARAM:
|
|
{
|
|
char buf[25];
|
|
d_append_string (dpi, "parm#");
|
|
sprintf(buf,"%ld", dc->u.s_number.number);
|
|
d_append_string (dpi, buf);
|
|
return;
|
|
}
|
|
|
|
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
|
|
d_append_string (dpi, "global constructors keyed to ");
|
|
d_print_comp (dpi, dc->u.s_binary.left);
|
|
return;
|
|
|
|
case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
|
|
d_append_string (dpi, "global destructors keyed to ");
|
|
d_print_comp (dpi, dc->u.s_binary.left);
|
|
return;
|
|
|
default:
|
default:
|
d_print_error (dpi);
|
d_print_error (dpi);
|
return;
|
return;
|
}
|
}
|
}
|
}
|
Line 4105... |
Line 4494... |
|
|
static int
|
static int
|
d_demangle_callback (const char *mangled, int options,
|
d_demangle_callback (const char *mangled, int options,
|
demangle_callbackref callback, void *opaque)
|
demangle_callbackref callback, void *opaque)
|
{
|
{
|
int type;
|
enum
|
|
{
|
|
DCT_TYPE,
|
|
DCT_MANGLED,
|
|
DCT_GLOBAL_CTORS,
|
|
DCT_GLOBAL_DTORS
|
|
}
|
|
type;
|
struct d_info di;
|
struct d_info di;
|
struct demangle_component *dc;
|
struct demangle_component *dc;
|
int status;
|
int status;
|
|
|
if (mangled[0] == '_' && mangled[1] == 'Z')
|
if (mangled[0] == '_' && mangled[1] == 'Z')
|
type = 0;
|
type = DCT_MANGLED;
|
else if (strncmp (mangled, "_GLOBAL_", 8) == 0
|
else if (strncmp (mangled, "_GLOBAL_", 8) == 0
|
&& (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$')
|
&& (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$')
|
&& (mangled[9] == 'D' || mangled[9] == 'I')
|
&& (mangled[9] == 'D' || mangled[9] == 'I')
|
&& mangled[10] == '_')
|
&& mangled[10] == '_')
|
{
|
type = mangled[9] == 'I' ? DCT_GLOBAL_CTORS : DCT_GLOBAL_DTORS;
|
const char *intro;
|
|
|
|
intro = (mangled[9] == 'I')
|
|
? "global constructors keyed to "
|
|
: "global destructors keyed to ";
|
|
|
|
callback (intro, strlen (intro), opaque);
|
|
callback (mangled + 11, strlen (mangled + 11), opaque);
|
|
return 1;
|
|
}
|
|
else
|
else
|
{
|
{
|
if ((options & DMGL_TYPES) == 0)
|
if ((options & DMGL_TYPES) == 0)
|
return 0;
|
return 0;
|
type = 1;
|
type = DCT_TYPE;
|
}
|
}
|
|
|
cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
|
cplus_demangle_init_info (mangled, options, strlen (mangled), &di);
|
|
|
{
|
{
|
Line 4148... |
Line 4534... |
#else
|
#else
|
di.comps = alloca (di.num_comps * sizeof (*di.comps));
|
di.comps = alloca (di.num_comps * sizeof (*di.comps));
|
di.subs = alloca (di.num_subs * sizeof (*di.subs));
|
di.subs = alloca (di.num_subs * sizeof (*di.subs));
|
#endif
|
#endif
|
|
|
if (type)
|
switch (type)
|
|
{
|
|
case DCT_TYPE:
|
dc = cplus_demangle_type (&di);
|
dc = cplus_demangle_type (&di);
|
else
|
break;
|
|
case DCT_MANGLED:
|
dc = cplus_demangle_mangled_name (&di, 1);
|
dc = cplus_demangle_mangled_name (&di, 1);
|
|
break;
|
|
case DCT_GLOBAL_CTORS:
|
|
case DCT_GLOBAL_DTORS:
|
|
d_advance (&di, 11);
|
|
dc = d_make_comp (&di,
|
|
(type == DCT_GLOBAL_CTORS
|
|
? DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS
|
|
: DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS),
|
|
d_make_name (&di, d_str (&di), strlen (d_str (&di))),
|
|
NULL);
|
|
d_advance (&di, strlen (d_str (&di)));
|
|
break;
|
|
}
|
|
|
/* If DMGL_PARAMS is set, then if we didn't consume the entire
|
/* If DMGL_PARAMS is set, then if we didn't consume the entire
|
mangled string, then we didn't successfully demangle it. If
|
mangled string, then we didn't successfully demangle it. If
|
DMGL_PARAMS is not set, we didn't look at the trailing
|
DMGL_PARAMS is not set, we didn't look at the trailing
|
parameters. */
|
parameters. */
|