Re: [RFA] Extend demangler to recognize destructors/constructors

Jim Blandy
2001-03-15T10:48:00Z

Meant to send this to the entire list.

------- Start of forwarded message -------
To: Gabriel Dos Reis <gdr@codesourcery.com>
Subject: Re: [RFA] Extend demangler to recognize destructors/constructors
References: < 200103150901.EAA25623@zwingli.cygnus.com >
< fld7bj8kbk.fsf@sel.cmla.ens-cachan.fr >
From: Jim Blandy <jimb@zwingli.cygnus.com>
Date: 15 Mar 2001 05:17:03 -0500
Message-ID: <np4rwv49r4.fsf@zwingli.cygnus.com>

Gabriel Dos Reis <gdr@codesourcery.com> writes:
> May I suggest use of enums to make it much more readable?

Yes, that's a fine idea.

libiberty/ChangeLog:

2001-03-15 Jim Blandy <jimb@redhat.com>

* cp-demangle.c (struct demangling_def): New fields:
is_constructor and is_destructor.
(demangling_new): Initialize them.
(demangle_ctor_dtor_name): Set them, if we detect a constructor
or destructor.
(demangle_v3_with_details, is_gnu_v3_mangled_ctor,
is_gnu_v3_mangled_dtor): New functions.

include/ChangeLog:

2001-03-15 Jim Blandy <jimb@redhat.com>

* demangle.h (enum gnu_v3_constructor_kinds,
is_gnu_v3_mangled_constructor, enum gnu_v3_destructor_kinds,
is_gnu_v3_mangled_destructor): New declarations.

Index: libiberty/cp-demangle.c
===================================================================
RCS file: /cvs/src/src/libiberty/cp-demangle.c,v
retrieving revision 1.8
diff -c -c -3 -p -r1.8 cp-demangle.c
*** libiberty/cp-demangle.c 2001/02/02 18:58:39 1.8
--- libiberty/cp-demangle.c 2001/03/15 10:11:23
*************** struct demangling_def
*** 172,177 ****
--- 172,186 ----

/* Language style to use for demangled output. */
int style;
+
+ /* Set to non-zero iff this name is a constructor. The actual value
+ indicates what sort of constructor this is; see demangle.h. */
+ enum gnu_v3_ctor_kinds is_constructor;
+
+ /* Set to non-zero iff this name is a destructor. The actual value
+ indicates what sort of destructor this is; see demangle.h. */
+ enum gnu_v3_dtor_kinds is_destructor;
+
};

typedef struct demangling_def *demangling_t;
*************** demangling_new (name, style)
*** 815,820 ****
--- 824,831 ----
return NULL;
}
dm->style = style;
+ dm->is_constructor = 0;
+ dm->is_destructor = 0;

return dm;
}
*************** demangle_ctor_dtor_name (dm)
*** 2018,2032 ****
{
/* A constructor name. Consume the C. */
advance_char (dm);
! if (peek_char (dm) < '1' || peek_char (dm) > '3')
return "Unrecognized constructor.";
RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
/* Print the flavor of the constructor if in verbose mode. */
- flavor = next_char (dm) - '1';
if (flag_verbose)
{
RETURN_IF_ERROR (result_add (dm, "["));
! RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor]));
RETURN_IF_ERROR (result_add_char (dm, ']'));
}
}
--- 2029,2052 ----
{
/* A constructor name. Consume the C. */
advance_char (dm);
! flavor = next_char (dm);
! if (flavor < '1' || flavor > '3')
return "Unrecognized constructor.";
RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
+ switch (flavor)
+ {
+ case '1': dm->is_constructor = gnu_v3_complete_object_ctor;
+ break;
+ case '2': dm->is_constructor = gnu_v3_base_object_ctor;
+ break;
+ case '3': dm->is_constructor = gnu_v3_complete_object_allocating_ctor;
+ break;
+ }
/* Print the flavor of the constructor if in verbose mode. */
if (flag_verbose)
{
RETURN_IF_ERROR (result_add (dm, "["));
! RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor - '1']));
RETURN_IF_ERROR (result_add_char (dm, ']'));
}
}
*************** demangle_ctor_dtor_name (dm)
*** 2034,2049 ****
{
/* A destructor name. Consume the D. */
advance_char (dm);
! if (peek_char (dm) < '0' || peek_char (dm) > '2')
return "Unrecognized destructor.";
RETURN_IF_ERROR (result_add_char (dm, '~'));
RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
/* Print the flavor of the destructor if in verbose mode. */
- flavor = next_char (dm) - '0';
if (flag_verbose)
{
RETURN_IF_ERROR (result_add (dm, " ["));
! RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor]));
RETURN_IF_ERROR (result_add_char (dm, ']'));
}
}
--- 2054,2078 ----
{
/* A destructor name. Consume the D. */
advance_char (dm);
! flavor = next_char (dm);
! if (flavor < '0' || flavor > '2')
return "Unrecognized destructor.";
RETURN_IF_ERROR (result_add_char (dm, '~'));
RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
+ switch (flavor)
+ {
+ case '0': dm->is_destructor = gnu_v3_deleting_dtor;
+ break;
+ case '1': dm->is_destructor = gnu_v3_complete_object_dtor;
+ break;
+ case '2': dm->is_destructor = gnu_v3_base_object_dtor;
+ break;
+ }
/* Print the flavor of the destructor if in verbose mode. */
if (flag_verbose)
{
RETURN_IF_ERROR (result_add (dm, " ["));
! RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor - '0']));
RETURN_IF_ERROR (result_add_char (dm, ']'));
}
}
*************** java_demangle_v3 (mangled)
*** 3788,3793 ****
--- 3817,3901 ----
}

#endif /* IN_LIBGCC2 */
+
+
+ /* Demangle NAME in the G++ V3 ABI demangling style, and return either
+ zero, indicating that some error occurred, or a demangling_t
+ holding the results. */
+ static demangling_t
+ demangle_v3_with_details (const char *name)
+ {
+ demangling_t dm;
+ status_t status;
+
+ if (strncmp (name, "_Z", 2))
+ return 0;
+
+ dm = demangling_new (name, DMGL_GNU_V3);
+ if (dm == NULL)
+ {
+ fprintf (stderr, "Memory allocation failed.\n");
+ abort ();
+ }
+
+ status = result_push (dm);
+ if (! STATUS_NO_ERROR (status))
+ {
+ demangling_delete (dm);
+ fprintf (stderr, "%s\n", status);
+ abort ();
+ }
+
+ status = demangle_mangled_name (dm);
+ if (STATUS_NO_ERROR (status))
+ return dm;
+
+ demangling_delete (dm);
+ return 0;
+ }
+
+
+ /* Return non-zero iff NAME is the mangled form of a constructor name
+ in the G++ V3 ABI demangling style. Specifically, return:
+ - '1' if NAME is a complete object constructor,
+ - '2' if NAME is a base object constructor, or
+ - '3' if NAME is a complete object allocating constructor. */
+ enum gnu_v3_ctor_kinds
+ is_gnu_v3_mangled_ctor (const char *name)
+ {
+ demangling_t dm = demangle_v3_with_details (name);
+
+ if (dm)
+ {
+ enum gnu_v3_ctor_kinds result = dm->is_constructor;
+ demangling_delete (dm);
+ return result;
+ }
+ else
+ return 0;
+ }
+
+
+ /* Return non-zero iff NAME is the mangled form of a destructor name
+ in the G++ V3 ABI demangling style. Specifically, return:
+ - '0' if NAME is a deleting destructor,
+ - '1' if NAME is a complete object destructor, or
+ - '2' if NAME is a base object destructor. */
+ enum gnu_v3_dtor_kinds
+ is_gnu_v3_mangled_dtor (const char *name)
+ {
+ demangling_t dm = demangle_v3_with_details (name);
+
+ if (dm)
+ {
+ enum gnu_v3_dtor_kinds result = dm->is_destructor;
+ demangling_delete (dm);
+ return result;
+ }
+ else
+ return 0;
+ }
+

#ifdef STANDALONE_DEMANGLER

Index: include/demangle.h
===================================================================
RCS file: /cvs/src/src/include/demangle.h,v
retrieving revision 1.6
diff -c -c -3 -p -r1.6 demangle.h
*** include/demangle.h 2001/03/14 02:27:43 1.6
--- include/demangle.h 2001/03/15 10:11:24
*************** cplus_demangle_v3 PARAMS ((const char* m
*** 128,131 ****
--- 128,157 ----
extern char*
java_demangle_v3 PARAMS ((const char* mangled));

+
+ enum gnu_v3_ctor_kinds {
+ gnu_v3_complete_object_ctor = 1,
+ gnu_v3_base_object_ctor,
+ gnu_v3_complete_object_allocating_ctor
+ };
+
+ /* Return non-zero iff NAME is the mangled form of a constructor name
+ in the G++ V3 ABI demangling style. Specifically, return an `enum
+ gnu_v3_ctor_kinds' value indicating what kind of constructor
+ it is. */
+ extern enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name);
+
+
+ enum gnu_v3_dtor_kinds {
+ gnu_v3_deleting_dtor = 1,
+ gnu_v3_complete_object_dtor,
+ gnu_v3_base_object_dtor
+ };
+
+ /* Return non-zero iff NAME is the mangled form of a destructor name
+ in the G++ V3 ABI demangling style. Specifically, return an `enum
+ gnu_v3_dtor_kinds' value, indicating what kind of destructor
+ it is. */
+ extern enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name);
+
#endif /* DEMANGLE_H */

------- End of forwarded message -------