+Wed Apr 22 10:53:49 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cplus-dem.c (struct work stuff): Add field for B and K mangle codes.
+ (cplus_demangle_opname): Call mop_up_squangle.
+ (cplus_demangle): Initialize squangle info, then call
+ internal_cplus_demangle. (Most code moved there as well)
+ (internal_cplus_demangle): New function, performs most of what use
+ to be done in cplus_demangle, but is only called with this file.
+ (squangle_mop_up): New function to clean up B and K code data.
+ (mop_up): set pointers to NULL after freeing.
+ (demangle_signature, demangle_template, demangle_class): Add
+ switch elements to handle K and B codes.
+ (demangle_prefix, gnu_special, demangle_qualified): Add
+ code to handle K and B codes.
+ (do_type, demangle_fund_type): Handle B and K codes.
+ (remember_Ktype): New function to store K info.
+ (register_Btype, remember_Btype): New functions for B codes.
+ (forget_B_and_K_types): New function to destroy B and K info.
+
1998-04-21 Jim Wilson <wilson@cygnus.com>
* stmt.c (check_seenlabel): When search for line number note for
{
int options;
char **typevec;
+ char **ktypevec;
+ char **btypevec;
+ int numk;
+ int numb;
+ int ksize;
+ int bsize;
int ntypes;
int typevec_size;
int constructor;
string_prepend(str, " ");}
#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
string_append(str, " ");}
+#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
static char *
mop_up PARAMS ((struct work_stuff *, string *, int));
+static char *
+squangle_mop_up PARAMS ((struct work_stuff *));
+
#if 0
static int
-demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
+demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
#endif
+static char *
+internal_cplus_demangle PARAMS ((struct work_stuff *, const char *, int));
+
static int
demangle_template_template_parm PARAMS ((struct work_stuff *work,
const char **, string *));
remember_type PARAMS ((struct work_stuff *, const char *, int));
static void
+remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
+
+static int
+register_Btype PARAMS ((struct work_stuff *));
+
+static void
+remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
+
+static void
forget_types PARAMS ((struct work_stuff *));
static void
+forget_B_and_K_types PARAMS ((struct work_stuff *));
+
+static void
string_prepends PARAMS ((string *, string *));
static int
ret = 1;
}
}
+ squangle_mop_up (work);
return ret;
}
const char *mangled;
int options;
{
+ char *ret;
+ struct work_stuff work[1];
+ memset ((char *) work, 0, sizeof (work));
+ work -> options = options;
+ if ((work -> options & DMGL_STYLE_MASK) == 0)
+ work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
+
+ ret = internal_cplus_demangle (work, mangled, options);
+ squangle_mop_up (work);
+ return (ret);
+}
+
+
+/* This function performs most of what cplus_demangle use to do, but
+ to be able to demangle a name with a B, K or n code, we need to
+ have a longer term memory of what types have been seen. The original
+ now intializes and cleans up the squangle code info, while internal
+ calls go directly to this routine to avoid resetting that info. */
+
+static char *
+internal_cplus_demangle (work, mangled, options)
+ struct work_stuff *work;
+ const char *mangled;
+ int options;
+{
+
string decl;
int success = 0;
- struct work_stuff work[1];
char *demangled = NULL;
+ int s1,s2,s3,s4;
+ s1 = work->constructor;
+ s2 = work->destructor;
+ s3 = work->static_type;
+ s4 = work->const_type;
+ work->constructor = work->destructor = 0;
+ work->static_type = work->const_type = 0;
if ((mangled != NULL) && (*mangled != '\0'))
{
- memset ((char *) work, 0, sizeof (work));
- work -> options = options;
- if ((work->options & DMGL_STYLE_MASK) == 0)
- work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
-
string_init (&decl);
/* First check to see if gnu style demangling is active and if the
}
if (work->constructor == 2)
{
- string_prepend(&decl, "global constructors keyed to ");
+ string_prepend (&decl, "global constructors keyed to ");
work->constructor = 0;
}
else if (work->destructor == 2)
{
- string_prepend(&decl, "global destructors keyed to ");
+ string_prepend (&decl, "global destructors keyed to ");
work->destructor = 0;
}
demangled = mop_up (work, &decl, success);
}
+ work->constructor = s1;
+ work->destructor = s2;
+ work->static_type = s3;
+ work->const_type = s4;
return (demangled);
}
+
+/* Clear out and squangling related storage */
+static char *
+squangle_mop_up (work)
+ struct work_stuff *work;
+{
+ /* clean up the B and K type mangling types. */
+ forget_B_and_K_types (work);
+ if (work -> btypevec != NULL)
+ {
+ free ((char *) work -> btypevec);
+ }
+ if (work -> ktypevec != NULL)
+ {
+ free ((char *) work -> ktypevec);
+ }
+}
+
+/* Clear out any mangled storage */
+
static char *
mop_up (work, declp, success)
struct work_stuff *work;
if (work -> typevec != NULL)
{
free ((char *) work -> typevec);
+ work -> typevec = NULL;
}
if (work->tmpl_argvec)
{
free ((char*) work->tmpl_argvec[i]);
free ((char*) work->tmpl_argvec);
+ work->tmpl_argvec = NULL;
}
/* If demangling was successful, ensure that the demangled string is null
}
oldmangled = NULL;
break;
+
+ case 'K':
+ oldmangled = *mangled;
+ success = demangle_qualified (work, mangled, declp, 1, 0);
+ if (AUTO_DEMANGLING || GNU_DEMANGLING)
+ {
+ expect_func = 1;
+ }
+ oldmangled = NULL;
+ break;
case 'S':
/* Static member function */
(*mangled)++;
}
}
- else if (**mangled == 'Q')
+ else if (**mangled == 'Q' || **mangled == 'K')
success = demangle_qualified (work, mangled, s, 0, 1);
else
{
continue;
case 'E': /* expression */
case 'Q': /* qualified name */
+ case 'K': /* qualified name */
+ done = is_integral = 1;
+ break;
+ case 'B': /* squangled name */
done = is_integral = 1;
break;
case 'T': /* remembered type */
char *p = xmalloc (symbol_len + 1), *q;
strncpy (p, *mangled, symbol_len);
p [symbol_len] = '\0';
- q = cplus_demangle (p, work->options);
+ q = internal_cplus_demangle (work, p, work->options);
string_appendn (s, "&", 1);
if (q)
{
string *declp;
{
int success = 0;
+ int btype;
string class_name;
string_init (&class_name);
+ btype = register_Btype (work);
if (demangle_class_name (work, mangled, &class_name))
{
if ((work->constructor & 1) || (work->destructor & 1))
work -> constructor -= 1;
}
}
+ remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
+ remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
string_prepends (declp, &class_name);
success = 1;
}
else if ((scan == *mangled)
&& (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
- || (scan[2] == 'H')))
+ || (scan[2] == 'K') || (scan[2] == 'H')))
{
/* The ARM says nothing about the mangling of local variables.
But cfront mangles local variables by prepending __<nesting_level>
switch (**mangled)
{
case 'Q':
+ case 'K':
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
switch (**mangled)
{
case 'Q':
+ case 'K':
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
else if (strncmp (*mangled, "__thunk_", 8) == 0)
{
int delta = ((*mangled) += 8, consume_count (mangled));
- char *method = cplus_demangle (++*mangled, work->options);
+ char *method = internal_cplus_demangle (work, ++*mangled, work->options);
if (method)
{
char buf[50];
switch (**mangled)
{
case 'Q':
+ case 'K':
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
int isfuncname;
int append;
{
- int qualifiers;
+ int qualifiers = 0;
int namelength;
int success = 1;
const char *p;
string temp;
string_init (&temp);
- switch ((*mangled)[1])
+
+ if ((*mangled)[0] == 'K')
+ {
+ /* Squangling qualified name reuse */
+ int idx;
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1 || idx > work -> numk)
+ success = 0;
+ else
+ string_append (&temp, work -> ktypevec[idx]);
+ }
+ else
+ switch ((*mangled)[1])
{
case '_':
/* GNU mangled name with more than 9 classes. The count is preceded
while (qualifiers-- > 0)
{
+ int remember_K = 1;
if (*mangled[0] == '_')
*mangled = *mangled + 1;
if (*mangled[0] == 't')
success = do_type (work, mangled, &temp);
if (!success) break;
}
+ if (*mangled[0] == 'K')
+ {
+ int idx;
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1 || idx > work->numk)
+ success = 0;
+ else
+ string_append (&temp, work->ktypevec[idx]);
+ remember_K = 0;
+
+ if (!success) break;
+ }
else
{
namelength = consume_count (mangled);
string_appendn (&temp, *mangled, namelength);
*mangled += namelength;
}
+
+ if (remember_K)
+ {
+ remember_Ktype (work, temp.b, LEN_STRING (&temp));
+ }
+
if (qualifiers > 0)
{
string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
const char *remembered_type;
int constp;
int volatilep;
+ string btype;
+ string_init (&btype);
string_init (&decl);
string_init (result);
{
/* A qualified name, such as "Outer::Inner". */
case 'Q':
- success = demangle_qualified (work, mangled, result, 0, 1);
+ case 'K':
+ {
+ int btype = register_Btype (work);
+ success = demangle_qualified (work, mangled, result, 0, 1);
+ remember_Btype (work, result->b, LEN_STRING (result), btype);
+
+ break;
+ }
+
+ /* A back reference to a previously seen squangled type */
+ case 'B':
+ (*mangled)++;
+ if (!get_count (mangled, &n) || n >= work -> numb)
+ success = 0;
+ else
+ {
+ string_append (result, work->btypevec[n]);
+ }
break;
case 'X':
{
int done = 0;
int success = 1;
+ string btype;
+ string_init (&btype);
/* First pick off any type qualifiers. There can be more than one. */
case '7':
case '8':
case '9':
- APPEND_BLANK (result);
- if (!demangle_class_name (work, mangled, result)) {
- --result->p;
- success = 0;
+ {
+ int bindex = register_Btype (work);
+ string btype;
+ string_init (&btype);
+ if (demangle_class_name (work, mangled, &btype)) {
+ remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+ APPEND_BLANK (result);
+ string_appends (result, &btype);
+ }
+ else
+ success = 0;
+ string_delete (&btype);
+ break;
}
- break;
case 't':
- success = demangle_template(work,mangled, result, 0, 1);
- break;
+ {
+ int bindex= register_Btype (work);
+ success = demangle_template (work, mangled, &btype, 0, 1);
+ remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+ string_appends (result, &btype);
+ break;
+ }
default:
success = 0;
break;
work -> typevec[work -> ntypes++] = tem;
}
+
+/* Remember a K type class qualifier. */
+static void
+remember_Ktype (work, start, len)
+ struct work_stuff *work;
+ const char *start;
+ int len;
+{
+ char *tem;
+
+ if (work -> numk >= work -> ksize)
+ {
+ if (work -> ksize == 0)
+ {
+ work -> ksize = 5;
+ work -> ktypevec
+ = (char **) xmalloc (sizeof (char *) * work -> ksize);
+ }
+ else
+ {
+ work -> ksize *= 2;
+ work -> ktypevec
+ = (char **) xrealloc ((char *)work -> ktypevec,
+ sizeof (char *) * work -> ksize);
+ }
+ }
+ tem = xmalloc (len + 1);
+ memcpy (tem, start, len);
+ tem[len] = '\0';
+ work -> ktypevec[work -> numk++] = tem;
+}
+
+/* Register a B code, and get an index for it. B codes are registered
+ as they are seen, rather than as they are completed, so map<temp<char> >
+ registers map<temp<char> > as B0, and temp<char> as B1 */
+
+static int
+register_Btype (work)
+ struct work_stuff *work;
+{
+ int ret;
+
+ if (work -> numb >= work -> bsize)
+ {
+ if (work -> bsize == 0)
+ {
+ work -> bsize = 5;
+ work -> btypevec
+ = (char **) xmalloc (sizeof (char *) * work -> bsize);
+ }
+ else
+ {
+ work -> bsize *= 2;
+ work -> btypevec
+ = (char **) xrealloc ((char *)work -> btypevec,
+ sizeof (char *) * work -> bsize);
+ }
+ }
+ ret = work -> numb++;
+ work -> btypevec[ret] = NULL;
+ return(ret);
+}
+
+/* Store a value into a previously registered B code type. */
+
+static void
+remember_Btype (work, start, len, index)
+ struct work_stuff *work;
+ const char *start;
+ int len, index;
+{
+ char *tem;
+
+ tem = xmalloc (len + 1);
+ memcpy (tem, start, len);
+ tem[len] = '\0';
+ work -> btypevec[index] = tem;
+}
+
+/* Lose all the info related to B and K type codes. */
+static void
+forget_B_and_K_types (work)
+ struct work_stuff *work;
+{
+ int i;
+
+ while (work -> numk > 0)
+ {
+ i = --(work -> numk);
+ if (work -> ktypevec[i] != NULL)
+ {
+ free (work -> ktypevec[i]);
+ work -> ktypevec[i] = NULL;
+ }
+ }
+
+ while (work -> numb > 0)
+ {
+ i = --(work -> numb);
+ if (work -> btypevec[i] != NULL)
+ {
+ free (work -> btypevec[i]);
+ work -> btypevec[i] = NULL;
+ }
+ }
+}
/* Forget the remembered types, but not the type vector itself. */
static void
+Wed Apr 22 10:53:49 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
+
+ * cplus-dem.c (struct work stuff): Add field for B and K mangle codes.
+ (cplus_demangle_opname): Call mop_up_squangle.
+ (cplus_demangle): Initialize squangle info, then call
+ internal_cplus_demangle. (Most code moved there as well)
+ (internal_cplus_demangle): New function, performs most of what use
+ to be done in cplus_demangle, but is only called with this file.
+ (squangle_mop_up): New function to clean up B and K code data.
+ (mop_up): set pointers to NULL after freeing.
+ (demangle_signature, demangle_template, demangle_class): Add
+ switch elements to handle K and B codes.
+ (demangle_prefix, gnu_special, demangle_qualified): Add
+ code to handle K and B codes.
+ (do_type, demangle_fund_type): Handle B and K codes.
+ (remember_Ktype): New function to store K info.
+ (register_Btype, remember_Btype): New functions for B codes.
+ (forget_B_and_K_types): New function to destroy B and K info.
+
Fri Apr 10 01:45:09 1998 Jeffrey A Law (law@cygnus.com)
* cplus-dem.c: Sync with gcc.
{
int options;
char **typevec;
+ char **ktypevec;
+ char **btypevec;
+ int numk;
+ int numb;
+ int ksize;
+ int bsize;
int ntypes;
int typevec_size;
int constructor;
string_prepend(str, " ");}
#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
string_append(str, " ");}
+#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
static char *
mop_up PARAMS ((struct work_stuff *, string *, int));
+static char *
+squangle_mop_up PARAMS ((struct work_stuff *));
+
#if 0
static int
-demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *));
+demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
#endif
+static char *
+internal_cplus_demangle PARAMS ((struct work_stuff *, const char *, int));
+
static int
demangle_template_template_parm PARAMS ((struct work_stuff *work,
const char **, string *));
remember_type PARAMS ((struct work_stuff *, const char *, int));
static void
+remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
+
+static int
+register_Btype PARAMS ((struct work_stuff *));
+
+static void
+remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
+
+static void
forget_types PARAMS ((struct work_stuff *));
static void
+forget_B_and_K_types PARAMS ((struct work_stuff *));
+
+static void
string_prepends PARAMS ((string *, string *));
static int
ret = 1;
}
}
+ squangle_mop_up (work);
return ret;
}
const char *mangled;
int options;
{
+ char *ret;
+ struct work_stuff work[1];
+ memset ((char *) work, 0, sizeof (work));
+ work -> options = options;
+ if ((work -> options & DMGL_STYLE_MASK) == 0)
+ work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK;
+
+ ret = internal_cplus_demangle (work, mangled, options);
+ squangle_mop_up (work);
+ return (ret);
+}
+
+
+/* This function performs most of what cplus_demangle use to do, but
+ to be able to demangle a name with a B, K or n code, we need to
+ have a longer term memory of what types have been seen. The original
+ now intializes and cleans up the squangle code info, while internal
+ calls go directly to this routine to avoid resetting that info. */
+
+static char *
+internal_cplus_demangle (work, mangled, options)
+ struct work_stuff *work;
+ const char *mangled;
+ int options;
+{
+
string decl;
int success = 0;
- struct work_stuff work[1];
char *demangled = NULL;
+ int s1,s2,s3,s4;
+ s1 = work->constructor;
+ s2 = work->destructor;
+ s3 = work->static_type;
+ s4 = work->const_type;
+ work->constructor = work->destructor = 0;
+ work->static_type = work->const_type = 0;
if ((mangled != NULL) && (*mangled != '\0'))
{
- memset ((char *) work, 0, sizeof (work));
- work -> options = options;
- if ((work->options & DMGL_STYLE_MASK) == 0)
- work->options |= (int)current_demangling_style & DMGL_STYLE_MASK;
-
string_init (&decl);
/* First check to see if gnu style demangling is active and if the
}
if (work->constructor == 2)
{
- string_prepend(&decl, "global constructors keyed to ");
+ string_prepend (&decl, "global constructors keyed to ");
work->constructor = 0;
}
else if (work->destructor == 2)
{
- string_prepend(&decl, "global destructors keyed to ");
+ string_prepend (&decl, "global destructors keyed to ");
work->destructor = 0;
}
demangled = mop_up (work, &decl, success);
}
+ work->constructor = s1;
+ work->destructor = s2;
+ work->static_type = s3;
+ work->const_type = s4;
return (demangled);
}
+
+/* Clear out and squangling related storage */
+static char *
+squangle_mop_up (work)
+ struct work_stuff *work;
+{
+ /* clean up the B and K type mangling types. */
+ forget_B_and_K_types (work);
+ if (work -> btypevec != NULL)
+ {
+ free ((char *) work -> btypevec);
+ }
+ if (work -> ktypevec != NULL)
+ {
+ free ((char *) work -> ktypevec);
+ }
+}
+
+/* Clear out any mangled storage */
+
static char *
mop_up (work, declp, success)
struct work_stuff *work;
if (work -> typevec != NULL)
{
free ((char *) work -> typevec);
+ work -> typevec = NULL;
}
if (work->tmpl_argvec)
{
free ((char*) work->tmpl_argvec[i]);
free ((char*) work->tmpl_argvec);
+ work->tmpl_argvec = NULL;
}
/* If demangling was successful, ensure that the demangled string is null
}
oldmangled = NULL;
break;
+
+ case 'K':
+ oldmangled = *mangled;
+ success = demangle_qualified (work, mangled, declp, 1, 0);
+ if (AUTO_DEMANGLING || GNU_DEMANGLING)
+ {
+ expect_func = 1;
+ }
+ oldmangled = NULL;
+ break;
case 'S':
/* Static member function */
(*mangled)++;
}
}
- else if (**mangled == 'Q')
+ else if (**mangled == 'Q' || **mangled == 'K')
success = demangle_qualified (work, mangled, s, 0, 1);
else
{
continue;
case 'E': /* expression */
case 'Q': /* qualified name */
+ case 'K': /* qualified name */
+ done = is_integral = 1;
+ break;
+ case 'B': /* squangled name */
done = is_integral = 1;
break;
case 'T': /* remembered type */
char *p = xmalloc (symbol_len + 1), *q;
strncpy (p, *mangled, symbol_len);
p [symbol_len] = '\0';
- q = cplus_demangle (p, work->options);
+ q = internal_cplus_demangle (work, p, work->options);
string_appendn (s, "&", 1);
if (q)
{
string *declp;
{
int success = 0;
+ int btype;
string class_name;
string_init (&class_name);
+ btype = register_Btype (work);
if (demangle_class_name (work, mangled, &class_name))
{
if ((work->constructor & 1) || (work->destructor & 1))
work -> constructor -= 1;
}
}
+ remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
+ remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::");
string_prepends (declp, &class_name);
success = 1;
}
else if ((scan == *mangled)
&& (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't')
- || (scan[2] == 'H')))
+ || (scan[2] == 'K') || (scan[2] == 'H')))
{
/* The ARM says nothing about the mangling of local variables.
But cfront mangles local variables by prepending __<nesting_level>
switch (**mangled)
{
case 'Q':
+ case 'K':
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
switch (**mangled)
{
case 'Q':
+ case 'K':
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
else if (strncmp (*mangled, "__thunk_", 8) == 0)
{
int delta = ((*mangled) += 8, consume_count (mangled));
- char *method = cplus_demangle (++*mangled, work->options);
+ char *method = internal_cplus_demangle (work, ++*mangled, work->options);
if (method)
{
char buf[50];
switch (**mangled)
{
case 'Q':
+ case 'K':
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
int isfuncname;
int append;
{
- int qualifiers;
+ int qualifiers = 0;
int namelength;
int success = 1;
const char *p;
string temp;
string_init (&temp);
- switch ((*mangled)[1])
+
+ if ((*mangled)[0] == 'K')
+ {
+ /* Squangling qualified name reuse */
+ int idx;
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1 || idx > work -> numk)
+ success = 0;
+ else
+ string_append (&temp, work -> ktypevec[idx]);
+ }
+ else
+ switch ((*mangled)[1])
{
case '_':
/* GNU mangled name with more than 9 classes. The count is preceded
while (qualifiers-- > 0)
{
+ int remember_K = 1;
if (*mangled[0] == '_')
*mangled = *mangled + 1;
if (*mangled[0] == 't')
success = do_type (work, mangled, &temp);
if (!success) break;
}
+ if (*mangled[0] == 'K')
+ {
+ int idx;
+ (*mangled)++;
+ idx = consume_count_with_underscores (mangled);
+ if (idx == -1 || idx > work->numk)
+ success = 0;
+ else
+ string_append (&temp, work->ktypevec[idx]);
+ remember_K = 0;
+
+ if (!success) break;
+ }
else
{
namelength = consume_count (mangled);
string_appendn (&temp, *mangled, namelength);
*mangled += namelength;
}
+
+ if (remember_K)
+ {
+ remember_Ktype (work, temp.b, LEN_STRING (&temp));
+ }
+
if (qualifiers > 0)
{
string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::");
const char *remembered_type;
int constp;
int volatilep;
+ string btype;
+ string_init (&btype);
string_init (&decl);
string_init (result);
{
/* A qualified name, such as "Outer::Inner". */
case 'Q':
- success = demangle_qualified (work, mangled, result, 0, 1);
+ case 'K':
+ {
+ int btype = register_Btype (work);
+ success = demangle_qualified (work, mangled, result, 0, 1);
+ remember_Btype (work, result->b, LEN_STRING (result), btype);
+
+ break;
+ }
+
+ /* A back reference to a previously seen squangled type */
+ case 'B':
+ (*mangled)++;
+ if (!get_count (mangled, &n) || n >= work -> numb)
+ success = 0;
+ else
+ {
+ string_append (result, work->btypevec[n]);
+ }
break;
case 'X':
{
int done = 0;
int success = 1;
+ string btype;
+ string_init (&btype);
/* First pick off any type qualifiers. There can be more than one. */
case '7':
case '8':
case '9':
- APPEND_BLANK (result);
- if (!demangle_class_name (work, mangled, result)) {
- --result->p;
- success = 0;
+ {
+ int bindex = register_Btype (work);
+ string btype;
+ string_init (&btype);
+ if (demangle_class_name (work, mangled, &btype)) {
+ remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+ APPEND_BLANK (result);
+ string_appends (result, &btype);
+ }
+ else
+ success = 0;
+ string_delete (&btype);
+ break;
}
- break;
case 't':
- success = demangle_template(work,mangled, result, 0, 1);
- break;
+ {
+ int bindex= register_Btype (work);
+ success = demangle_template (work, mangled, &btype, 0, 1);
+ remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+ string_appends (result, &btype);
+ break;
+ }
default:
success = 0;
break;
work -> typevec[work -> ntypes++] = tem;
}
+
+/* Remember a K type class qualifier. */
+static void
+remember_Ktype (work, start, len)
+ struct work_stuff *work;
+ const char *start;
+ int len;
+{
+ char *tem;
+
+ if (work -> numk >= work -> ksize)
+ {
+ if (work -> ksize == 0)
+ {
+ work -> ksize = 5;
+ work -> ktypevec
+ = (char **) xmalloc (sizeof (char *) * work -> ksize);
+ }
+ else
+ {
+ work -> ksize *= 2;
+ work -> ktypevec
+ = (char **) xrealloc ((char *)work -> ktypevec,
+ sizeof (char *) * work -> ksize);
+ }
+ }
+ tem = xmalloc (len + 1);
+ memcpy (tem, start, len);
+ tem[len] = '\0';
+ work -> ktypevec[work -> numk++] = tem;
+}
+
+/* Register a B code, and get an index for it. B codes are registered
+ as they are seen, rather than as they are completed, so map<temp<char> >
+ registers map<temp<char> > as B0, and temp<char> as B1 */
+
+static int
+register_Btype (work)
+ struct work_stuff *work;
+{
+ int ret;
+
+ if (work -> numb >= work -> bsize)
+ {
+ if (work -> bsize == 0)
+ {
+ work -> bsize = 5;
+ work -> btypevec
+ = (char **) xmalloc (sizeof (char *) * work -> bsize);
+ }
+ else
+ {
+ work -> bsize *= 2;
+ work -> btypevec
+ = (char **) xrealloc ((char *)work -> btypevec,
+ sizeof (char *) * work -> bsize);
+ }
+ }
+ ret = work -> numb++;
+ work -> btypevec[ret] = NULL;
+ return(ret);
+}
+
+/* Store a value into a previously registered B code type. */
+
+static void
+remember_Btype (work, start, len, index)
+ struct work_stuff *work;
+ const char *start;
+ int len, index;
+{
+ char *tem;
+
+ tem = xmalloc (len + 1);
+ memcpy (tem, start, len);
+ tem[len] = '\0';
+ work -> btypevec[index] = tem;
+}
+
+/* Lose all the info related to B and K type codes. */
+static void
+forget_B_and_K_types (work)
+ struct work_stuff *work;
+{
+ int i;
+
+ while (work -> numk > 0)
+ {
+ i = --(work -> numk);
+ if (work -> ktypevec[i] != NULL)
+ {
+ free (work -> ktypevec[i]);
+ work -> ktypevec[i] = NULL;
+ }
+ }
+
+ while (work -> numb > 0)
+ {
+ i = --(work -> numb);
+ if (work -> btypevec[i] != NULL)
+ {
+ free (work -> btypevec[i]);
+ work -> btypevec[i] = NULL;
+ }
+ }
+}
/* Forget the remembered types, but not the type vector itself. */
static void