summaryrefslogtreecommitdiff
path: root/gcc/cplus-dem.c
diff options
context:
space:
mode:
authorMark Mitchell <mmitchell@usa.net>1998-03-24 10:25:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-03-24 10:25:44 +0000
commit050367a36dc31833f15828aef52e33a37ef2a952 (patch)
tree28c2266d2091a5affc7ff055388b2d8a8fd6ff0c /gcc/cplus-dem.c
parent0b93b64e20444a5a105b0cb9935b7841486559aa (diff)
downloadgcc-050367a36dc31833f15828aef52e33a37ef2a952.tar.gz
cplus-dem.c (optable): Add sizeof.
* cplus-dem.c (optable): Add sizeof. (demangle_template_value_parm): New function containing code previously found in demangle_template. (demangle_integral_value): New function which handles complicated integral expressions. (demangle_template): Use them. * error.c (dump_expr): Remove unused variable `l'. * pt.c (for_each_template_parm): New function, created by converting uses_template_parms. (tree_fn_t): New typedef. (uses_template_parms): Use it. (mark_template_parm): New function. (push_template_decl): Check that the argument list of a partial specialization uses all the template parameters. * Make-lang.in (c++filt): Don't delete cxxmain.c after we're done with it; we might want it for debugging. * cp-tree.h (type_unification): Change interface. * class.c (finish_struct_1): Skip nested template types, just like ordinary nested types. (instantiate_type): Use new interface to type_unification. * lex.c (init_lex): Add __sz as opname for sizeof. * method.c (build_overload_scope_ref): New function. (build_overload_int): Handle complex expressions. Set numeric_output_need_bar if necessary. (build_overload_value): Handle non-PARM_DECL nodes; this routine is now used by build_overload_int. Remove some assignments to numeric_output_need_bar. Use build_overload_scope_ref. (build_qualified_name): Note that some template mangled names end with digits, and set numeric_output_need_bar appropriately. Use build_underscore_int. * pt.c (unify): Change interface. (type_unification_real): Likewise. (determine_specialization): Use new interfaces. (tsubst): Deal gracefully with situations in which the argument vector is not fully filled. (fn_type_unification): Use new interfaces. (type_unification): Likewise. Remove NOP_EXPR hack. (type_unification_real): Likewise. (unify): Likewise. Deal with unification of complex expresions. From-SVN: r18795
Diffstat (limited to 'gcc/cplus-dem.c')
-rw-r--r--gcc/cplus-dem.c478
1 files changed, 278 insertions, 200 deletions
diff --git a/gcc/cplus-dem.c b/gcc/cplus-dem.c
index af9244909f7..898ab4bd500 100644
--- a/gcc/cplus-dem.c
+++ b/gcc/cplus-dem.c
@@ -197,7 +197,8 @@ static const struct optable
{"min", "<?", 0}, /* old */
{"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
{"nop", "", 0}, /* old (for operator=) */
- {"rm", "->*", DMGL_ANSI} /* ansi */
+ {"rm", "->*", DMGL_ANSI}, /* ansi */
+ {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
};
@@ -330,6 +331,10 @@ forget_types PARAMS ((struct work_stuff *));
static void
string_prepends PARAMS ((string *, string *));
+static int
+demangle_template_value_parm PARAMS ((struct work_stuff*,
+ const char**, string*));
+
/* Translate count to integer, consuming tokens in the process.
Conversion terminates on the first non-digit character.
Trying to consume something that isn't a count results in
@@ -996,6 +1001,270 @@ demangle_template_template_parm (work, mangled, tname)
}
static int
+demangle_integral_value (work, mangled, s)
+ struct work_stuff *work;
+ const char** mangled;
+ string* s;
+{
+ int success;
+
+ if (**mangled == 'E')
+ {
+ int need_operator = 0;
+
+ success = 1;
+ string_appendn (s, "(", 1);
+ (*mangled)++;
+ while (success && **mangled != 'W' && **mangled != '\0')
+ {
+ if (need_operator)
+ {
+ size_t i;
+ size_t len;
+
+ success = 0;
+
+ len = strlen (*mangled);
+
+ for (i = 0;
+ i < sizeof (optable) / sizeof (optable [0]);
+ ++i)
+ {
+ size_t l = strlen (optable[i].in);
+
+ if (l <= len
+ && memcmp (optable[i].in, *mangled, l) == 0)
+ {
+ string_appendn (s, " ", 1);
+ string_append (s, optable[i].out);
+ string_appendn (s, " ", 1);
+ success = 1;
+ (*mangled) += l;
+ break;
+ }
+ }
+
+ if (!success)
+ break;
+ }
+ else
+ need_operator = 1;
+
+ success = demangle_template_value_parm (work, mangled, s);
+ }
+
+ if (**mangled != 'W')
+ success = 0;
+ else
+ {
+ string_appendn (s, ")", 1);
+ (*mangled)++;
+ }
+ }
+ else if (**mangled == 'Q')
+ success = demangle_qualified (work, mangled, s, 0, 1);
+ else
+ {
+ success = 0;
+
+ if (**mangled == 'm')
+ {
+ string_appendn (s, "-", 1);
+ (*mangled)++;
+ }
+ while (isdigit (**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ success = 1;
+ }
+ }
+
+ return success;
+}
+
+static int
+demangle_template_value_parm (work, mangled, s)
+ struct work_stuff *work;
+ const char **mangled;
+ string* s;
+{
+ const char *old_p = *mangled;
+ int is_pointer = 0;
+ int is_real = 0;
+ int is_integral = 0;
+ int is_char = 0;
+ int is_bool = 0;
+ int done = 0;
+ int success = 1;
+
+ while (*old_p && !done)
+ {
+ switch (*old_p)
+ {
+ case 'P':
+ case 'p':
+ case 'R':
+ done = is_pointer = 1;
+ break;
+ case 'C': /* const */
+ case 'S': /* explicitly signed [char] */
+ case 'U': /* unsigned */
+ case 'V': /* volatile */
+ case 'F': /* function */
+ case 'M': /* member function */
+ case 'O': /* ??? */
+ case 'J': /* complex */
+ old_p++;
+ continue;
+ case 'E': /* expression */
+ case 'Q': /* qualified name */
+ done = is_integral = 1;
+ break;
+ case 'T': /* remembered type */
+ abort ();
+ break;
+ case 'v': /* void */
+ abort ();
+ break;
+ case 'x': /* long long */
+ case 'l': /* long */
+ case 'i': /* int */
+ case 's': /* short */
+ case 'w': /* wchar_t */
+ done = is_integral = 1;
+ break;
+ case 'b': /* bool */
+ done = is_bool = 1;
+ break;
+ case 'c': /* char */
+ done = is_char = 1;
+ break;
+ case 'r': /* long double */
+ case 'd': /* double */
+ case 'f': /* float */
+ done = is_real = 1;
+ break;
+ default:
+ /* it's probably user defined type, let's assume
+ it's integral, it seems hard to figure out
+ what it really is */
+ done = is_integral = 1;
+ }
+ }
+ if (**mangled == 'Y')
+ {
+ /* The next argument is a template parameter. */
+ int idx;
+
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1
+ || (work->tmpl_argvec && idx >= work->ntmpl_args)
+ || consume_count_with_underscores (mangled) == -1)
+ return -1;
+ if (work->tmpl_argvec)
+ string_append (s, work->tmpl_argvec[idx]);
+ else
+ {
+ char buf[10];
+ sprintf(buf, "T%d", idx);
+ string_append (s, buf);
+ }
+ }
+ else if (is_integral)
+ success = demangle_integral_value (work, mangled, s);
+ else if (is_char)
+ {
+ char tmp[2];
+ int val;
+ if (**mangled == 'm')
+ {
+ string_appendn (s, "-", 1);
+ (*mangled)++;
+ }
+ string_appendn (s, "'", 1);
+ val = consume_count(mangled);
+ if (val == 0)
+ return -1;
+ tmp[0] = (char)val;
+ tmp[1] = '\0';
+ string_appendn (s, &tmp[0], 1);
+ string_appendn (s, "'", 1);
+ }
+ else if (is_bool)
+ {
+ int val = consume_count (mangled);
+ if (val == 0)
+ string_appendn (s, "false", 5);
+ else if (val == 1)
+ string_appendn (s, "true", 4);
+ else
+ success = 0;
+ }
+ else if (is_real)
+ {
+ if (**mangled == 'm')
+ {
+ string_appendn (s, "-", 1);
+ (*mangled)++;
+ }
+ while (isdigit (**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ }
+ if (**mangled == '.') /* fraction */
+ {
+ string_appendn (s, ".", 1);
+ (*mangled)++;
+ while (isdigit (**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ }
+ }
+ if (**mangled == 'e') /* exponent */
+ {
+ string_appendn (s, "e", 1);
+ (*mangled)++;
+ while (isdigit (**mangled))
+ {
+ string_appendn (s, *mangled, 1);
+ (*mangled)++;
+ }
+ }
+ }
+ else if (is_pointer)
+ {
+ int symbol_len = consume_count (mangled);
+ if (symbol_len == 0)
+ return -1;
+ if (symbol_len == 0)
+ string_appendn (s, "0", 1);
+ else
+ {
+ char *p = xmalloc (symbol_len + 1), *q;
+ strncpy (p, *mangled, symbol_len);
+ p [symbol_len] = '\0';
+ q = cplus_demangle (p, work->options);
+ string_appendn (s, "&", 1);
+ if (q)
+ {
+ string_append (s, q);
+ free (q);
+ }
+ else
+ string_append (s, p);
+ free (p);
+ }
+ *mangled += symbol_len;
+ }
+
+ return success;
+}
+
+static int
demangle_template (work, mangled, tname, trawname, is_type)
struct work_stuff *work;
const char **mangled;
@@ -1004,18 +1273,10 @@ demangle_template (work, mangled, tname, trawname, is_type)
int is_type;
{
int i;
- int is_pointer;
- int is_real;
- int is_integral;
- int is_char;
- int is_bool;
int r;
int need_comma = 0;
int success = 0;
- int done;
- const char *old_p;
const char *start;
- int symbol_len;
int is_java_array = 0;
string temp;
@@ -1148,13 +1409,7 @@ demangle_template (work, mangled, tname, trawname, is_type)
string* s;
/* otherwise, value parameter */
- old_p = *mangled;
- is_pointer = 0;
- is_real = 0;
- is_integral = 0;
- is_char = 0;
- is_bool = 0;
- done = 0;
+
/* temp is initialized in do_type */
success = do_type (work, mangled, &temp);
/*
@@ -1180,193 +1435,16 @@ demangle_template (work, mangled, tname, trawname, is_type)
else
s = tname;
- while (*old_p && !done)
- {
- switch (*old_p)
- {
- case 'P':
- case 'p':
- case 'R':
- done = is_pointer = 1;
- break;
- case 'C': /* const */
- case 'S': /* explicitly signed [char] */
- case 'U': /* unsigned */
- case 'V': /* volatile */
- case 'F': /* function */
- case 'M': /* member function */
- case 'O': /* ??? */
- case 'J': /* complex */
- old_p++;
- continue;
- case 'Q': /* qualified name */
- done = is_integral = 1;
- break;
- case 'T': /* remembered type */
- abort ();
- break;
- case 'v': /* void */
- abort ();
- break;
- case 'x': /* long long */
- case 'l': /* long */
- case 'i': /* int */
- case 's': /* short */
- case 'w': /* wchar_t */
- done = is_integral = 1;
- break;
- case 'b': /* bool */
- done = is_bool = 1;
- break;
- case 'c': /* char */
- done = is_char = 1;
- break;
- case 'r': /* long double */
- case 'd': /* double */
- case 'f': /* float */
- done = is_real = 1;
- break;
- default:
- /* it's probably user defined type, let's assume
- it's integral, it seems hard to figure out
- what it really is */
- done = is_integral = 1;
- }
- }
- if (**mangled == 'Y')
- {
- /* The next argument is a template parameter. */
- int idx;
+ success = demangle_template_value_parm (work, mangled, s);
- (*mangled)++;
- idx = consume_count_with_underscores (mangled);
- if (idx == -1
- || (work->tmpl_argvec && idx >= work->ntmpl_args)
- || consume_count_with_underscores (mangled) == -1)
- {
- success = 0;
- if (!is_type)
- string_delete (s);
- break;
- }
- if (work->tmpl_argvec)
- string_append (s, work->tmpl_argvec[idx]);
- else
- {
- char buf[10];
- sprintf(buf, "T%d", idx);
- string_append (s, buf);
- }
- }
- else if (is_integral)
- {
- if (**mangled == 'm')
- {
- string_appendn (s, "-", 1);
- (*mangled)++;
- }
- while (isdigit (**mangled))
- {
- string_appendn (s, *mangled, 1);
- (*mangled)++;
- }
- }
- else if (is_char)
- {
- char tmp[2];
- int val;
- if (**mangled == 'm')
- {
- string_appendn (s, "-", 1);
- (*mangled)++;
- }
- string_appendn (s, "'", 1);
- val = consume_count(mangled);
- if (val == 0)
- {
- success = 0;
- if (!is_type)
- string_delete (s);
- break;
- }
- tmp[0] = (char)val;
- tmp[1] = '\0';
- string_appendn (s, &tmp[0], 1);
- string_appendn (s, "'", 1);
- }
- else if (is_bool)
- {
- int val = consume_count (mangled);
- if (val == 0)
- string_appendn (s, "false", 5);
- else if (val == 1)
- string_appendn (s, "true", 4);
- else
- success = 0;
- }
- else if (is_real)
- {
- if (**mangled == 'm')
- {
- string_appendn (s, "-", 1);
- (*mangled)++;
- }
- while (isdigit (**mangled))
- {
- string_appendn (s, *mangled, 1);
- (*mangled)++;
- }
- if (**mangled == '.') /* fraction */
- {
- string_appendn (s, ".", 1);
- (*mangled)++;
- while (isdigit (**mangled))
- {
- string_appendn (s, *mangled, 1);
- (*mangled)++;
- }
- }
- if (**mangled == 'e') /* exponent */
- {
- string_appendn (s, "e", 1);
- (*mangled)++;
- while (isdigit (**mangled))
- {
- string_appendn (s, *mangled, 1);
- (*mangled)++;
- }
- }
- }
- else if (is_pointer)
+ if (!success)
{
- symbol_len = consume_count (mangled);
- if (symbol_len == 0)
- {
- success = 0;
- if (!is_type)
- string_delete (s);
- break;
- }
- if (symbol_len == 0)
- string_appendn (s, "0", 1);
- else
- {
- char *p = xmalloc (symbol_len + 1), *q;
- strncpy (p, *mangled, symbol_len);
- p [symbol_len] = '\0';
- q = cplus_demangle (p, work->options);
- string_appendn (s, "&", 1);
- if (q)
- {
- string_append (s, q);
- free (q);
- }
- else
- string_append (s, p);
- free (p);
- }
- *mangled += symbol_len;
+ if (!is_type)
+ string_delete (s);
+ success = 0;
+ break;
}
+
if (!is_type)
{
int len = s->p - s->b;