summaryrefslogtreecommitdiff
path: root/libiberty/cplus-dem.c
diff options
context:
space:
mode:
Diffstat (limited to 'libiberty/cplus-dem.c')
-rw-r--r--libiberty/cplus-dem.c190
1 files changed, 135 insertions, 55 deletions
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 35e49384ad2..4a4a12965e5 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -126,8 +126,7 @@ struct work_stuff
int constructor;
int destructor;
int static_type; /* A static member function */
- int const_type; /* A const member function */
- int volatile_type; /* A volatile member function */
+ int type_quals; /* The type qualifiers. */
int dllimported; /* Symbol imported from a PE DLL */
char **tmpl_argvec; /* Template function arguments. */
int ntmpl_args; /* The number of template function arguments. */
@@ -392,6 +391,24 @@ static int
demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
string*, type_kind_t));
+/* There is a TYPE_QUAL value for each type qualifier. They can be
+ combined by bitwise-or to form the complete set of qualifiers for a
+ type. */
+
+#define TYPE_UNQUALIFIED 0x0
+#define TYPE_QUAL_CONST 0x1
+#define TYPE_QUAL_VOLATILE 0x2
+#define TYPE_QUAL_RESTRICT 0x4
+
+static int
+code_for_qualifier PARAMS ((char));
+
+static const char*
+qualifier_string PARAMS ((int));
+
+static const char*
+demangle_qualifier PARAMS ((char));
+
/* 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
@@ -448,6 +465,84 @@ consume_count_with_underscores (mangled)
return idx;
}
+/* C is the code for a type-qualifier. Return the TYPE_QUAL
+ corresponding to this qualifier. */
+
+static int
+code_for_qualifier (c)
+ char c;
+{
+ switch (c)
+ {
+ case 'C':
+ return TYPE_QUAL_CONST;
+
+ case 'V':
+ return TYPE_QUAL_VOLATILE;
+
+ case 'u':
+ return TYPE_QUAL_RESTRICT;
+
+ default:
+ break;
+ }
+
+ /* C was an invalid qualifier. */
+ abort ();
+}
+
+/* Return the string corresponding to the qualifiers given by
+ TYPE_QUALS. */
+
+static const char*
+qualifier_string (type_quals)
+ int type_quals;
+{
+ switch (type_quals)
+ {
+ case TYPE_UNQUALIFIED:
+ return "";
+
+ case TYPE_QUAL_CONST:
+ return "const";
+
+ case TYPE_QUAL_VOLATILE:
+ return "volatile";
+
+ case TYPE_QUAL_RESTRICT:
+ return "__restrict";
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
+ return "const volatile";
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
+ return "const __restrict";
+
+ case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ return "volatile __restrict";
+
+ case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
+ return "const volatile __restrict";
+
+ default:
+ break;
+ }
+
+ /* TYPE_QUALS was an invalid qualifier set. */
+ abort ();
+}
+
+/* C is the code for a type-qualifier. Return the string
+ corresponding to this qualifier. This function should only be
+ called with a valid qualifier code. */
+
+static const char*
+demangle_qualifier (c)
+ char c;
+{
+ return qualifier_string (code_for_qualifier (c));
+}
+
int
cplus_demangle_opname (opname, result, options)
const char *opname;
@@ -664,15 +759,12 @@ internal_cplus_demangle (work, mangled)
int success = 0;
char *demangled = NULL;
int s1,s2,s3,s4;
- int saved_volatile_type;
s1 = work->constructor;
s2 = work->destructor;
s3 = work->static_type;
- s4 = work->const_type;
- saved_volatile_type = work->volatile_type;
+ s4 = work->type_quals;
work->constructor = work->destructor = 0;
- work->static_type = work->const_type = 0;
- work->volatile_type = 0;
+ work->type_quals = TYPE_UNQUALIFIED;
work->dllimported = 0;
if ((mangled != NULL) && (*mangled != '\0'))
@@ -718,8 +810,7 @@ internal_cplus_demangle (work, mangled)
work->constructor = s1;
work->destructor = s2;
work->static_type = s3;
- work->const_type = s4;
- work->volatile_type = saved_volatile_type;
+ work->type_quals = s4;
return (demangled);
}
@@ -871,10 +962,8 @@ demangle_signature (work, mangled, declp)
case 'C':
case 'V':
- if (**mangled == 'C')
- work -> const_type = 1;
- else
- work->volatile_type = 1;
+ case 'u':
+ work->type_quals |= code_for_qualifier (**mangled);
/* a qualified member function */
if (oldmangled == NULL)
@@ -1056,12 +1145,16 @@ demangle_signature (work, mangled, declp)
success = demangle_args (work, mangled, declp);
}
}
- if (success && work -> static_type && PRINT_ARG_TYPES)
- string_append (declp, " static");
- if (success && work -> const_type && PRINT_ARG_TYPES)
- string_append (declp, " const");
- else if (success && work->volatile_type && PRINT_ARG_TYPES)
- string_append (declp, " volatile");
+ if (success && PRINT_ARG_TYPES)
+ {
+ if (work->static_type)
+ string_append (declp, " static");
+ if (work->type_quals != TYPE_UNQUALIFIED)
+ {
+ APPEND_BLANK (declp);
+ string_append (declp, qualifier_string (work->type_quals));
+ }
+ }
return (success);
}
@@ -1345,6 +1438,8 @@ demangle_template_value_parm (work, mangled, s, tk)
p [symbol_len] = '\0';
q = internal_cplus_demangle (work, p);
string_appendn (s, "&", 1);
+ /* FIXME: Pointer-to-member constants should get a
+ qualifying class name here. */
if (q)
{
string_append (s, q);
@@ -2481,8 +2576,7 @@ do_type (work, mangled, result)
int success;
string decl;
const char *remembered_type;
- int constp;
- int volatilep;
+ int type_quals;
string btype;
type_kind_t tk = tk_none;
@@ -2574,8 +2668,7 @@ do_type (work, mangled, result)
case 'M':
case 'O':
{
- constp = 0;
- volatilep = 0;
+ type_quals = TYPE_UNQUALIFIED;
member = **mangled == 'M';
(*mangled)++;
@@ -2615,16 +2708,19 @@ do_type (work, mangled, result)
string_prepend (&decl, "(");
if (member)
{
- if (**mangled == 'C')
- {
- (*mangled)++;
- constp = 1;
- }
- if (**mangled == 'V')
+ switch (**mangled)
{
+ case 'C':
+ case 'V':
+ case 'u':
+ type_quals |= code_for_qualifier (**mangled);
(*mangled)++;
- volatilep = 1;
+ break;
+
+ default:
+ break;
}
+
if (*(*mangled)++ != 'F')
{
success = 0;
@@ -2642,15 +2738,10 @@ do_type (work, mangled, result)
{
break;
}
- if (constp)
+ if (type_quals != TYPE_UNQUALIFIED)
{
APPEND_BLANK (&decl);
- string_append (&decl, "const");
- }
- if (volatilep)
- {
- APPEND_BLANK (&decl);
- string_append (&decl, "volatile");
+ string_append (&decl, qualifier_string (type_quals));
}
break;
}
@@ -2660,18 +2751,13 @@ do_type (work, mangled, result)
case 'C':
case 'V':
- /*
- if ((*mangled)[1] == 'P')
- {
- */
+ case 'u':
if (PRINT_ANSI_QUALIFIERS)
{
if (!STRING_EMPTY (&decl))
- {
- string_prepend (&decl, " ");
- }
- string_prepend (&decl,
- (**mangled) == 'C' ? "const" : "volatile");
+ string_prepend (&decl, " ");
+
+ string_prepend (&decl, demangle_qualifier (**mangled));
}
(*mangled)++;
break;
@@ -2794,11 +2880,13 @@ demangle_fund_type (work, mangled, result)
switch (**mangled)
{
case 'C':
+ case 'V':
+ case 'u':
(*mangled)++;
if (PRINT_ANSI_QUALIFIERS)
{
APPEND_BLANK (result);
- string_append (result, "const");
+ string_append (result, demangle_qualifier (**mangled));
}
break;
case 'U':
@@ -2811,14 +2899,6 @@ demangle_fund_type (work, mangled, result)
APPEND_BLANK (result);
string_append (result, "signed");
break;
- case 'V':
- (*mangled)++;
- if (PRINT_ANSI_QUALIFIERS)
- {
- APPEND_BLANK (result);
- string_append (result, "volatile");
- }
- break;
case 'J':
(*mangled)++;
APPEND_BLANK (result);