+/* Demangles and omits an <nv-offset>.
+
+ <nv-offset> ::= <offset number> # non-virtual base override */
+
+static status_t
+demangle_nv_offset (dm)
+ demangling_t dm;
+{
+ dyn_string_t number;
+ status_t status = STATUS_OK;
+
+ DEMANGLE_TRACE ("h-offset", dm);
+
+ /* Demangle the offset. */
+ number = dyn_string_new (4);
+ if (number == NULL)
+ return STATUS_ALLOCATION_FAILED;
+ demangle_number_literally (dm, number, 10, 1);
+
+ /* Don't display the offset unless in verbose mode. */
+ if (flag_verbose)
+ {
+ status = result_add (dm, " [nv:");
+ if (STATUS_NO_ERROR (status))
+ status = result_add_string (dm, number);
+ if (STATUS_NO_ERROR (status))
+ status = result_add_char (dm, ']');
+ }
+
+ /* Clean up. */
+ dyn_string_delete (number);
+ RETURN_IF_ERROR (status);
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <v-offset>.
+
+ <v-offset> ::= <offset number> _ <virtual offset number>
+ # virtual base override, with vcall offset */
+
+static status_t
+demangle_v_offset (dm)
+ demangling_t dm;
+{
+ dyn_string_t number;
+ status_t status = STATUS_OK;
+
+ DEMANGLE_TRACE ("v-offset", dm);
+
+ /* Demangle the offset. */
+ number = dyn_string_new (4);
+ if (number == NULL)
+ return STATUS_ALLOCATION_FAILED;
+ demangle_number_literally (dm, number, 10, 1);
+
+ /* Don't display the offset unless in verbose mode. */
+ if (flag_verbose)
+ {
+ status = result_add (dm, " [v:");
+ if (STATUS_NO_ERROR (status))
+ status = result_add_string (dm, number);
+ if (STATUS_NO_ERROR (status))
+ result_add_char (dm, ',');
+ }
+ dyn_string_delete (number);
+ RETURN_IF_ERROR (status);
+
+ /* Demangle the separator. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+
+ /* Demangle the vcall offset. */
+ number = dyn_string_new (4);
+ if (number == NULL)
+ return STATUS_ALLOCATION_FAILED;
+ demangle_number_literally (dm, number, 10, 1);
+
+ /* Don't display the vcall offset unless in verbose mode. */
+ if (flag_verbose)
+ {
+ status = result_add_string (dm, number);
+ if (STATUS_NO_ERROR (status))
+ status = result_add_char (dm, ']');
+ }
+ dyn_string_delete (number);
+ RETURN_IF_ERROR (status);
+
+ return STATUS_OK;
+}
+
+/* Demangles and emits a <call-offset>.
+
+ <call-offset> ::= h <nv-offset> _
+ ::= v <v-offset> _ */
+
+static status_t
+demangle_call_offset (dm)
+ demangling_t dm;
+{
+ DEMANGLE_TRACE ("call-offset", dm);
+
+ switch (peek_char (dm))
+ {
+ case 'h':
+ advance_char (dm);
+ /* Demangle the offset. */
+ RETURN_IF_ERROR (demangle_nv_offset (dm));
+ /* Demangle the separator. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ break;
+
+ case 'v':
+ advance_char (dm);
+ /* Demangle the offset. */
+ RETURN_IF_ERROR (demangle_v_offset (dm));
+ /* Demangle the separator. */
+ RETURN_IF_ERROR (demangle_char (dm, '_'));
+ break;
+
+ default:
+ return "Unrecognized <call-offset>.";
+ }
+
+ return STATUS_OK;
+}
+