case DEMANGLE_COMPONENT_LITERAL_NEG:
printf ("negative literal\n");
break;
+ case DEMANGLE_COMPONENT_VENDOR_EXPR:
+ printf ("vendor expression\n");
+ break;
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
printf ("java resource\n");
break;
case DEMANGLE_COMPONENT_TRINARY_ARG1:
case DEMANGLE_COMPONENT_LITERAL:
case DEMANGLE_COMPONENT_LITERAL_NEG:
+ case DEMANGLE_COMPONENT_VENDOR_EXPR:
case DEMANGLE_COMPONENT_COMPOUND_NAME:
case DEMANGLE_COMPONENT_VECTOR_TYPE:
case DEMANGLE_COMPONENT_CLONE:
/* <bare-function-type> ::= [J]<type>+ */
static struct demangle_component *
-d_bare_function_type (struct d_info *di, int has_return_tipe)
+d_bare_function_type (struct d_info *di, int has_return_type)
{
struct demangle_component *return_type;
struct demangle_component *tl;
if (peek == 'J')
{
d_advance (di, 1);
- has_return_tipe = 1;
+ has_return_type = 1;
}
- if (has_return_tipe)
+ if (has_return_type)
{
return_type = cplus_demangle_type (di);
if (return_type == NULL)
::= cl <expression>+ E
::= st <type>
::= <template-param>
+ ::= u <source-name> <template-arg>* E # vendor extended expression
::= <unresolved-name>
::= <expr-primary>
return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
type, d_exprlist (di, 'E'));
}
+ else if (peek == 'u')
+ {
+ /* A vendor extended expression. */
+ struct demangle_component *name, *args;
+ d_advance (di, 1);
+ name = d_source_name (di);
+ args = d_template_args_1 (di);
+ return d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_EXPR, name, args);
+ }
else
{
struct demangle_component *op;
case DEMANGLE_COMPONENT_TRINARY_ARG2:
case DEMANGLE_COMPONENT_LITERAL:
case DEMANGLE_COMPONENT_LITERAL_NEG:
+ case DEMANGLE_COMPONENT_VENDOR_EXPR:
case DEMANGLE_COMPONENT_JAVA_RESOURCE:
case DEMANGLE_COMPONENT_COMPOUND_NAME:
case DEMANGLE_COMPONENT_DECLTYPE:
}
case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
- {
- struct demangle_component *name = dc->u.s_extended_operator.name;
- if (name->type == DEMANGLE_COMPONENT_NAME
- && !strncmp (name->u.s_name.s, "__alignof__", name->u.s_name.len))
- d_print_comp (dpi, options, dc->u.s_extended_operator.name);
- else
- {
- d_append_string (dpi, "operator ");
- d_print_comp (dpi, options, dc->u.s_extended_operator.name);
- }
- return;
- }
+ d_append_string (dpi, "operator ");
+ d_print_comp (dpi, options, dc->u.s_extended_operator.name);
+ return;
case DEMANGLE_COMPONENT_CONVERSION:
d_append_string (dpi, "operator ");
if (code && !strcmp (code, "gs"))
/* Avoid parens after '::'. */
d_print_comp (dpi, options, operand);
- else if ((code && !strcmp (code, "st"))
- || (op->type == DEMANGLE_COMPONENT_EXTENDED_OPERATOR
- && (op->u.s_extended_operator.name->type
- == DEMANGLE_COMPONENT_NAME)
- && !strncmp (op->u.s_extended_operator.name->u.s_name.s,
- "__alignof__",
- op->u.s_extended_operator.name->u.s_name.len)))
- /* Always print parens for sizeof (type) and __alignof__. */
+ else if (code && !strcmp (code, "st"))
+ /* Always print parens for sizeof (type). */
{
d_append_char (dpi, '(');
d_print_comp (dpi, options, operand);
}
return;
+ case DEMANGLE_COMPONENT_VENDOR_EXPR:
+ d_print_comp (dpi, options, d_left (dc));
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, options, d_right (dc));
+ d_append_char (dpi, ')');
+ return;
+
case DEMANGLE_COMPONENT_NUMBER:
d_append_num (dpi, dc->u.s_number.number);
return;
static const char *dlang_type (string *, const char *, struct dlang_info *);
-static const char *dlang_value (string *, const char *, const char *, char);
+static const char *dlang_value (string *, const char *, const char *, char,
+ struct dlang_info *);
static const char *dlang_parse_qualified (string *, const char *,
struct dlang_info *, int);
/* Must point to a simple identifier. */
backref = dlang_number (backref, &len);
- if (backref == NULL)
+ if (backref == NULL || strlen(backref) < len)
return NULL;
backref = dlang_lname (decl, backref, len);
case 'g':
case 'h':
case 'k':
+ case 'n':
/* inout parameter is represented as 'Ng'.
vector parameter is represented as 'Nh'.
- return paramenter is represented as 'Nk'.
+ return parameter is represented as 'Nk'.
+ typeof(*null) parameter is represented as 'Nn'.
If we see this, then we know we're really in the
parameter list. Rewind and break. */
mangled--;
string_append (decl, ")");
return mangled;
}
+ else if (*mangled == 'n') /* typeof(*null) */
+ {
+ mangled++;
+ string_append (decl, "typeof(*null)");
+ return mangled;
+ }
else
return NULL;
case 'A': /* dynamic array (T[]) */
szmods = string_length (&mods);
/* Back referenced function type. */
- if (*mangled == 'Q')
+ if (mangled && *mangled == 'Q')
mangled = dlang_type_backref (decl, mangled, info, 1);
else
mangled = dlang_function_type (decl, mangled, info);
/* Basic types */
case 'n':
mangled++;
- string_append (decl, "none");
+ string_append (decl, "typeof(null)");
return mangled;
case 'v':
mangled++;
&& (mangled[2] == 'T' || mangled[2] == 'U'))
return dlang_parse_template (decl, mangled, info, len);
+ /* There can be multiple different declarations in the same function that have
+ the same mangled name. To make the mangled names unique, a fake parent in
+ the form `__Sddd' is added to the symbol. */
+ if (len >= 4 && mangled[0] == '_' && mangled[1] == '_' && mangled[2] == 'S')
+ {
+ const char *numptr = mangled + 3;
+ while (numptr < (mangled + len) && ISDIGIT (*numptr))
+ numptr++;
+
+ if (mangled + len == numptr)
+ {
+ /* Skip over the fake parent. */
+ mangled += len;
+ return dlang_identifier (decl, mangled, info);
+ }
+
+ /* else demangle it as a plain identifier. */
+ }
+
return dlang_lname (decl, mangled, len);
}
/* Extract the static array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
-dlang_parse_arrayliteral (string *decl, const char *mangled)
+dlang_parse_arrayliteral (string *decl, const char *mangled,
+ struct dlang_info *info)
{
unsigned long elements;
string_append (decl, "[");
while (elements--)
{
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
/* Extract the associative array value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
-dlang_parse_assocarray (string *decl, const char *mangled)
+dlang_parse_assocarray (string *decl, const char *mangled,
+ struct dlang_info *info)
{
unsigned long elements;
string_append (decl, "[");
while (elements--)
{
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
string_append (decl, ":");
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
/* Extract the struct literal value for NAME from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
-dlang_parse_structlit (string *decl, const char *mangled, const char *name)
+dlang_parse_structlit (string *decl, const char *mangled, const char *name,
+ struct dlang_info *info)
{
unsigned long args;
string_append (decl, "(");
while (args--)
{
- mangled = dlang_value (decl, mangled, NULL, '\0');
+ mangled = dlang_value (decl, mangled, NULL, '\0', info);
if (mangled == NULL)
return NULL;
/* Extract the value from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
-dlang_value (string *decl, const char *mangled, const char *name, char type)
+dlang_value (string *decl, const char *mangled, const char *name, char type,
+ struct dlang_info *info)
{
if (mangled == NULL || *mangled == '\0')
return NULL;
case 'A':
mangled++;
if (type == 'H')
- mangled = dlang_parse_assocarray (decl, mangled);
+ mangled = dlang_parse_assocarray (decl, mangled, info);
else
- mangled = dlang_parse_arrayliteral (decl, mangled);
+ mangled = dlang_parse_arrayliteral (decl, mangled, info);
break;
/* Struct values. */
case 'S':
mangled++;
- mangled = dlang_parse_structlit (decl, mangled, name);
+ mangled = dlang_parse_structlit (decl, mangled, name, info);
+ break;
+
+ /* Function literal symbol. */
+ case 'f':
+ mangled++;
+ if (strncmp (mangled, "_D", 2) != 0
+ || !dlang_symbol_name_p (mangled + 2, info))
+ return NULL;
+ mangled = dlang_parse_mangle (decl, mangled, info);
break;
default:
string_need (&name, 1);
*(name.p) = '\0';
- mangled = dlang_value (decl, mangled, name.b, type);
+ mangled = dlang_value (decl, mangled, name.b, type, info);
string_delete (&name);
break;
}