summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog7
-rw-r--r--include/demangle.h14
-rw-r--r--libiberty/ChangeLog16
-rw-r--r--libiberty/Makefile.in6
-rw-r--r--libiberty/cp-demangle.c299
-rw-r--r--libiberty/regex.c7
-rw-r--r--libiberty/testsuite/demangle-expected26
7 files changed, 305 insertions, 70 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index 7e8f3450551..8e3f70d5ecd 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,10 @@
+2009-09-29 Jason Merrill <jason@redhat.com>
+
+ * demangle.h (enum demangle_component_type): Add
+ DEMANGLE_COMPONENT_LAMBDA, DEMANGLE_COMPONENT_DEFAULT_ARG,
+ DEMANGLE_COMPONENT_UNNAMED_TYPE.
+ (struct demangle_component): Add s_unary_num.
+
2009-09-29 DJ Delorie <dj@redhat.com>
* dis-asm.h: Add prototype for print_insn_rx.
diff --git a/include/demangle.h b/include/demangle.h
index 4b3565bfbb8..76fab0a4582 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -381,6 +381,12 @@ enum demangle_component_type
DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS,
/* Global destructors keyed to name. */
DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS,
+ /* A lambda closure type. */
+ DEMANGLE_COMPONENT_LAMBDA,
+ /* A default argument scope. */
+ DEMANGLE_COMPONENT_DEFAULT_ARG,
+ /* An unnamed type. */
+ DEMANGLE_COMPONENT_UNNAMED_TYPE,
/* A pack expansion. */
DEMANGLE_COMPONENT_PACK_EXPANSION
};
@@ -494,6 +500,14 @@ struct demangle_component
struct demangle_component *right;
} s_binary;
+ struct
+ {
+ /* subtree, same place as d_left. */
+ struct demangle_component *sub;
+ /* integer. */
+ int num;
+ } s_unary_num;
+
} u;
};
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index dd1c1a301fc..1b3a44c4a2e 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,19 @@
+2009-09-30 Martin Thuresson <martint@google.com>
+
+ * regex.c (byte_re_match_2_internal): Split declaration and
+ assignment to avoid -Wc++-compat warning due to goto.
+
+2009-09-29 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in: Enable demangle target.
+ * cp-demangle.c (d_lambda, d_unnamed_type, d_make_default_arg): New.
+ (d_name, d_prefix, d_unqualified_name, d_local_name): Handle lambdas.
+ (d_parmlist): Factor out from d_bare_function_type.
+ (d_compact_number): Factor out from d_template_param and d_expression.
+ (d_append_num): Factor out from d_print_comp.
+ (d_print_comp, d_print_mod_list): Handle lambdas.
+ * testsuite/demangle-expected: Add lambda tests.
+
2009-09-23 Matthew Gingell <gingell@adacore.com>
* cplus-dem.c (ada_demangle): Ensure demangled is freed.
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 5d2adffc7b7..ba24c6db7a7 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -371,10 +371,12 @@ TAGS: $(CFILES)
etags `for i in $(CFILES); do echo $(srcdir)/$$i ; done`
# The standalone demangler (c++filt) has been moved to binutils.
-demangle:
+# But make this target work anyway for demangler hacking.
+demangle: $(ALL) $(srcdir)/cp-demangle.c
@echo "The standalone demangler, now named c++filt, is now"
@echo "a part of binutils."
- @false
+ $(CC) @DEFS@ $(CFLAGS) $(CPPFLAGS) -I. -I$(INCDIR) $(HDEFINES) \
+ $(srcdir)/cp-demangle.c -DSTANDALONE_DEMANGLER $(TARGETLIB) -o $@
ls:
@echo Makefile $(CFILES)
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 2c7296f7eef..43cf34a36cf 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -408,6 +408,10 @@ static struct demangle_component *d_local_name (struct d_info *);
static int d_discriminator (struct d_info *);
+static struct demangle_component *d_lambda (struct d_info *);
+
+static struct demangle_component *d_unnamed_type (struct d_info *);
+
static int
d_add_substitution (struct d_info *, struct demangle_component *);
@@ -922,6 +926,20 @@ d_make_extended_operator (struct d_info *di, int args,
return p;
}
+static struct demangle_component *
+d_make_default_arg (struct d_info *di, int num,
+ struct demangle_component *sub)
+{
+ struct demangle_component *p = d_make_empty (di);
+ if (p)
+ {
+ p->type = DEMANGLE_COMPONENT_DEFAULT_ARG;
+ p->u.s_unary_num.num = num;
+ p->u.s_unary_num.sub = sub;
+ }
+ return p;
+}
+
/* Add a new constructor component. */
static struct demangle_component *
@@ -1153,8 +1171,9 @@ d_name (struct d_info *di)
return d_local_name (di);
case 'L':
+ case 'U':
return d_unqualified_name (di);
-
+
case 'S':
{
int subst;
@@ -1276,6 +1295,7 @@ d_prefix (struct d_info *di)
|| IS_LOWER (peek)
|| peek == 'C'
|| peek == 'D'
+ || peek == 'U'
|| peek == 'L')
dc = d_unqualified_name (di);
else if (peek == 'S')
@@ -1291,6 +1311,16 @@ d_prefix (struct d_info *di)
dc = d_template_param (di);
else if (peek == 'E')
return ret;
+ else if (peek == 'M')
+ {
+ /* Initializer scope for a lambda. We don't need to represent
+ this; the normal code will just treat the variable as a type
+ scope, which gives appropriate output. */
+ if (ret == NULL)
+ return NULL;
+ d_advance (di, 1);
+ continue;
+ }
else
return NULL;
@@ -1347,6 +1377,18 @@ d_unqualified_name (struct d_info *di)
return NULL;
return ret;
}
+ else if (peek == 'U')
+ {
+ switch (d_peek_next_char (di))
+ {
+ case 'l':
+ return d_lambda (di);
+ case 't':
+ return d_unnamed_type (di);
+ default:
+ return NULL;
+ }
+ }
else
return NULL;
}
@@ -2242,50 +2284,30 @@ d_function_type (struct d_info *di)
return ret;
}
-/* <bare-function-type> ::= [J]<type>+ */
+/* <type>+ */
static struct demangle_component *
-d_bare_function_type (struct d_info *di, int has_return_type)
+d_parmlist (struct d_info *di)
{
- struct demangle_component *return_type;
struct demangle_component *tl;
struct demangle_component **ptl;
- char peek;
- /* Detect special qualifier indicating that the first argument
- is the return type. */
- peek = d_peek_char (di);
- if (peek == 'J')
- {
- d_advance (di, 1);
- has_return_type = 1;
- }
-
- return_type = NULL;
tl = NULL;
ptl = &tl;
while (1)
{
struct demangle_component *type;
- peek = d_peek_char (di);
+ char peek = d_peek_char (di);
if (peek == '\0' || peek == 'E')
break;
type = cplus_demangle_type (di);
if (type == NULL)
return NULL;
- if (has_return_type)
- {
- return_type = type;
- has_return_type = 0;
- }
- else
- {
- *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
- if (*ptl == NULL)
- return NULL;
- ptl = &d_right (*ptl);
- }
+ *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
+ if (*ptl == NULL)
+ return NULL;
+ ptl = &d_right (*ptl);
}
/* There should be at least one parameter type besides the optional
@@ -2300,10 +2322,45 @@ d_bare_function_type (struct d_info *di, int has_return_type)
&& d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID)
{
di->expansion -= d_left (tl)->u.s_builtin.type->len;
- tl = NULL;
+ d_left (tl) = NULL;
}
- return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, return_type, tl);
+ return tl;
+}
+
+/* <bare-function-type> ::= [J]<type>+ */
+
+static struct demangle_component *
+d_bare_function_type (struct d_info *di, int has_return_type)
+{
+ struct demangle_component *return_type;
+ struct demangle_component *tl;
+ char peek;
+
+ /* Detect special qualifier indicating that the first argument
+ is the return type. */
+ peek = d_peek_char (di);
+ if (peek == 'J')
+ {
+ d_advance (di, 1);
+ has_return_type = 1;
+ }
+
+ if (has_return_type)
+ {
+ return_type = cplus_demangle_type (di);
+ if (return_type == NULL)
+ return NULL;
+ }
+ else
+ return_type = NULL;
+
+ tl = d_parmlist (di);
+ if (tl == NULL)
+ return NULL;
+
+ return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE,
+ return_type, tl);
}
/* <class-enum-type> ::= <name> */
@@ -2405,6 +2462,24 @@ d_pointer_to_member_type (struct d_info *di)
return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
}
+/* <non-negative number> _ */
+
+static long
+d_compact_number (struct d_info *di)
+{
+ long num;
+ if (d_peek_char (di) == '_')
+ num = 0;
+ else if (d_peek_char (di) == 'n')
+ return -1;
+ else
+ num = d_number (di) + 1;
+
+ if (! d_check_char (di, '_'))
+ return -1;
+ return num;
+}
+
/* <template-param> ::= T_
::= T <(parameter-2 non-negative) number> _
*/
@@ -2417,17 +2492,8 @@ d_template_param (struct d_info *di)
if (! d_check_char (di, 'T'))
return NULL;
- if (d_peek_char (di) == '_')
- param = 0;
- else
- {
- param = d_number (di);
- if (param < 0)
- return NULL;
- param += 1;
- }
-
- if (! d_check_char (di, '_'))
+ param = d_compact_number (di);
+ if (param < 0)
return NULL;
++di->did_subs;
@@ -2599,17 +2665,8 @@ d_expression (struct d_info *di)
/* 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, '_'))
+ index = d_compact_number (di);
+ if (index < 0)
return NULL;
return d_make_function_param (di, index);
@@ -2802,10 +2859,31 @@ d_local_name (struct d_info *di)
else
{
struct demangle_component *name;
+ int num = -1;
+
+ if (d_peek_char (di) == 'd')
+ {
+ /* Default argument scope: d <number> _. */
+ d_advance (di, 1);
+ num = d_compact_number (di);
+ if (num < 0)
+ return NULL;
+ }
name = d_name (di);
- if (! d_discriminator (di))
- return NULL;
+ if (name)
+ switch (name->type)
+ {
+ /* Lambdas and unnamed types have internal discriminators. */
+ case DEMANGLE_COMPONENT_LAMBDA:
+ case DEMANGLE_COMPONENT_UNNAMED_TYPE:
+ break;
+ default:
+ if (! d_discriminator (di))
+ return NULL;
+ }
+ if (num >= 0)
+ name = d_make_default_arg (di, num, name);
return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name);
}
}
@@ -2829,6 +2907,75 @@ d_discriminator (struct d_info *di)
return 1;
}
+/* <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ */
+
+static struct demangle_component *
+d_lambda (struct d_info *di)
+{
+ struct demangle_component *tl;
+ struct demangle_component *ret;
+ int num;
+
+ if (! d_check_char (di, 'U'))
+ return NULL;
+ if (! d_check_char (di, 'l'))
+ return NULL;
+
+ tl = d_parmlist (di);
+ if (tl == NULL)
+ return NULL;
+
+ if (! d_check_char (di, 'E'))
+ return NULL;
+
+ num = d_compact_number (di);
+ if (num < 0)
+ return NULL;
+
+ ret = d_make_empty (di);
+ if (ret)
+ {
+ ret->type = DEMANGLE_COMPONENT_LAMBDA;
+ ret->u.s_unary_num.sub = tl;
+ ret->u.s_unary_num.num = num;
+ }
+
+ if (! d_add_substitution (di, ret))
+ return NULL;
+
+ return ret;
+}
+
+/* <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ */
+
+static struct demangle_component *
+d_unnamed_type (struct d_info *di)
+{
+ struct demangle_component *ret;
+ long num;
+
+ if (! d_check_char (di, 'U'))
+ return NULL;
+ if (! d_check_char (di, 't'))
+ return NULL;
+
+ num = d_compact_number (di);
+ if (num < 0)
+ return NULL;
+
+ ret = d_make_empty (di);
+ if (ret)
+ {
+ ret->type = DEMANGLE_COMPONENT_UNNAMED_TYPE;
+ ret->u.s_number.number = num;
+ }
+
+ if (! d_add_substitution (di, ret))
+ return NULL;
+
+ return ret;
+}
+
/* Add a new substitution. */
static int
@@ -3122,6 +3269,14 @@ d_append_string (struct d_print_info *dpi, const char *s)
d_append_buffer (dpi, s, strlen (s));
}
+static inline void
+d_append_num (struct d_print_info *dpi, long l)
+{
+ char buf[25];
+ sprintf (buf,"%ld", l);
+ d_append_string (dpi, buf);
+}
+
static inline char
d_last_char (struct d_print_info *dpi)
{
@@ -3398,6 +3553,8 @@ d_print_comp (struct d_print_info *dpi,
struct demangle_component *local_name;
local_name = d_right (typed_name);
+ if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
+ local_name = local_name->u.s_unary_num.sub;
while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| local_name->type == DEMANGLE_COMPONENT_CONST_THIS)
@@ -4048,13 +4205,10 @@ d_print_comp (struct d_print_info *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;
- }
+ d_append_string (dpi, "{parm#");
+ d_append_num (dpi, dc->u.s_number.number + 1);
+ d_append_char (dpi, '}');
+ return;
case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
d_append_string (dpi, "global constructors keyed to ");
@@ -4066,6 +4220,20 @@ d_print_comp (struct d_print_info *dpi,
d_print_comp (dpi, dc->u.s_binary.left);
return;
+ case DEMANGLE_COMPONENT_LAMBDA:
+ d_append_string (dpi, "{lambda(");
+ d_print_comp (dpi, dc->u.s_unary_num.sub);
+ d_append_string (dpi, ")#");
+ d_append_num (dpi, dc->u.s_unary_num.num + 1);
+ d_append_char (dpi, '}');
+ return;
+
+ case DEMANGLE_COMPONENT_UNNAMED_TYPE:
+ d_append_string (dpi, "{unnamed type#");
+ d_append_num (dpi, dc->u.s_number.number + 1);
+ d_append_char (dpi, '}');
+ return;
+
default:
d_print_error (dpi);
return;
@@ -4184,6 +4352,15 @@ d_print_mod_list (struct d_print_info *dpi,
d_append_char (dpi, '.');
dc = d_right (mods->mod);
+
+ if (dc->type == DEMANGLE_COMPONENT_DEFAULT_ARG)
+ {
+ d_append_string (dpi, "{default arg#");
+ d_append_num (dpi, dc->u.s_unary_num.num + 1);
+ d_append_string (dpi, "}::");
+ dc = dc->u.s_unary_num.sub;
+ }
+
while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| dc->type == DEMANGLE_COMPONENT_CONST_THIS)
diff --git a/libiberty/regex.c b/libiberty/regex.c
index fa1df197ce9..ad496846904 100644
--- a/libiberty/regex.c
+++ b/libiberty/regex.c
@@ -5910,11 +5910,14 @@ byte_re_match_2_internal (struct re_pattern_buffer *bufp,
{
/* 1 if this match ends in the same string (string1 or string2)
as the best previous match. */
- boolean same_str_p = (FIRST_STRING_P (match_end)
- == MATCHING_IN_FIRST_STRING);
+ boolean same_str_p;
+
/* 1 if this match is the best seen so far. */
boolean best_match_p;
+ same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+
/* AIX compiler got confused when this was combined
with the previous declaration. */
if (same_str_p)
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 0c451184fc4..6798154d2f3 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -3885,11 +3885,11 @@ java resource java/util/iso4217.properties
# decltype/param placeholder test
--format=gnu-v3
_Z3addIidEDTplfp_fp0_ET_T0_
-decltype (parm#1+parm#2) add<int, double>(int, double)
+decltype ({parm#1}+{parm#2}) add<int, double>(int, double)
# decltype/fn call test
--format=gnu-v3
_Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
-decltype (g(parm#1, parm#2)) add3<int, double>(int, double)
+decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double)
# new (2008) built in types test
--format=gnu-v3
_Z1fDfDdDeDhDsDi
@@ -3901,12 +3901,28 @@ void f<int*, float*, double*>(int*, float*, double*)
# '.' test
--format=gnu-v3
_Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_
-decltype ((parm#1.(g<double>))()) h<A<int>, double>(A<int>, double)
+decltype (({parm#1}.(g<double>))()) h<A<int>, double>(A<int>, double)
# test for typed function in decltype
--format=gnu-v3
_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_
-decltype (parm#1+((x())())) A<int>::j<int>(int)
+decltype ({parm#1}+((x())())) A<int>::j<int>(int)
# test for expansion of function parameter pack
--format=gnu-v3
_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_
-decltype (f((parm#1+(1))...)) g<int, double>(int, double)
+decltype (f(({parm#1}+(1))...)) g<int, double>(int, double)
+# lambda tests
+--format=gnu-v3
+_ZZ1giENKUlvE_clEv
+g(int)::{lambda()#1}::operator()() const
+--format=gnu-v3
+_Z4algoIZ1giEUlvE0_EiT_
+int algo<g(int)::{lambda()#2}>(g(int)::{lambda()#2})
+--format=gnu-v3
+_ZZN1S1fEiiEd0_NKUlvE0_clEv
+S::f(int, int)::{default arg#2}::{lambda()#2}::operator()() const
+--format=gnu-v3
+_ZNK1SIiE1xMUlvE1_clEv
+S<int>::x::{lambda()#3}::operator()() const
+--format=gnu-v3
+_Z1fN1SUt_E
+f(S::{unnamed type#1})