diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-07-04 10:24:39 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-07-04 10:24:39 (GMT) |
commit | 1ade82e135d4e815db5b33c9ebd67632b74e5e1d (patch) | |
tree | eafda5b3e4062922ee4f0b64e8f90695bfbde9c3 /plugins | |
parent | 8dc83465a6ca2d5b94b983b39f6c06d37e4126a0 (diff) |
Fixed various mistakes in Itanium C++ demangling.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/itanium/abi.c | 59 | ||||
-rw-r--r-- | plugins/itanium/component-int.h | 5 | ||||
-rw-r--r-- | plugins/itanium/component.c | 63 | ||||
-rw-r--r-- | plugins/itanium/component.h | 16 | ||||
-rw-r--r-- | plugins/itanium/context.c | 43 | ||||
-rw-r--r-- | plugins/itanium/context.h | 2 | ||||
-rw-r--r-- | plugins/pychrysalide/analysis/types/array.c | 19 |
7 files changed, 113 insertions, 94 deletions
diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c index 5f76342..3f6f713 100644 --- a/plugins/itanium/abi.c +++ b/plugins/itanium/abi.c @@ -1954,6 +1954,7 @@ static itanium_component *itd_type(GItaniumDemangling *context) { builtin = g_class_enum_type_new(CET_UNKNOWN, itd_translate_component(vendor, NULL)); result = itd_make_type(builtin); + itd_set_type(result, ICT_VENDOR_TYPE); itd_unref_comp(vendor); sub = itd_type(context); @@ -2483,10 +2484,10 @@ static itanium_component *itd_array_type(GItaniumDemangling *context) { itanium_component *result; /* Construction à retourner */ input_buffer *ibuf; /* Tampon de texte manipulé */ - char peek; /* Prochain caractère dispo. */ - itanium_component *dim_expr; /* Dimension via expression */ ssize_t dim_number; /* Dimension par un nombre */ itanium_component *type; /* Type du tableau */ + itd_state saved; /* Position d'analyse courante */ + itanium_component *dim_expr; /* Dimension via expression */ /** * La règle traitée ici est la suivante : @@ -2501,58 +2502,46 @@ static itanium_component *itd_array_type(GItaniumDemangling *context) if (!check_input_buffer_char(ibuf, 'A')) return NULL; - peek = peek_input_buffer_char(ibuf); - - if (peek == '[') + if (itd_number(context, &dim_number)) { - advance_input_buffer(ibuf, 1); - - dim_expr = itd_expression(context); - - if (dim_expr == NULL) - return NULL; - - if (!check_input_buffer_char(ibuf, ']')) - return NULL; - if (!check_input_buffer_char(ibuf, '_')) return NULL; type = itd_type(context); if (type == NULL) - { - itd_unref_comp(dim_expr); return NULL; - } - result = itd_make_array_with_dim_expr(dim_expr, type); - - if (result == NULL) - { - itd_unref_comp(dim_expr); - itd_unref_comp(type); - } + result = itd_make_array_with_dim_number(dim_number, type); } else { - if (!itd_number(context, &dim_number)) - return NULL; + g_itanium_demangling_push_state(context, &saved); + + dim_expr = itd_expression(context); + + if (dim_expr == NULL) + g_itanium_demangling_pop_state(context, &saved); if (!check_input_buffer_char(ibuf, '_')) + { + if (dim_expr != NULL) + itd_unref_comp(dim_expr); return NULL; + } type = itd_type(context); if (type == NULL) + { + if (dim_expr != NULL) + itd_unref_comp(dim_expr); return NULL; + } - result = itd_make_array_with_dim_number(dim_number, type); - - if (result == NULL) - itd_unref_comp(type); + result = itd_make_array_with_dim_expr(dim_expr, type); } @@ -2660,6 +2649,9 @@ static itanium_component *itd_template_param(GItaniumDemangling *context) result = g_itanium_demangling_get_template_arg(context, id); + if (result != NULL) + result = itd_make_unary(ICT_TEMPLATE_PARAM, result); + } } @@ -2761,6 +2753,8 @@ static itanium_component *itd_template_args(GItaniumDemangling *context) result = itd_make_unary(ICT_TEMPLATE_ARGS, result); + g_itanium_demangling_add_template_args(context, result); + return result; } @@ -2817,9 +2811,6 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context) else result = itd_type(context); - if (result != NULL) - g_itanium_demangling_add_template_arg(context, result); - return result; } diff --git a/plugins/itanium/component-int.h b/plugins/itanium/component-int.h index fb8c423..20b2c8d 100644 --- a/plugins/itanium/component-int.h +++ b/plugins/itanium/component-int.h @@ -36,8 +36,6 @@ struct _itanium_component unsigned int refcount; /* Compteur de références */ - fnv64_t hash; /* Empreinte en cache */ - union { /* ICT_NAME */ @@ -66,8 +64,9 @@ struct _itanium_component /* ICT_VIRTUAL_OFFSET */ ssize_t offset; /* Décalage de fonction */ - /* ICT_STD_SUBST */ /* ICT_TYPE */ + /* ICT_VENDOR_TYPE */ + /* ICT_STD_SUBST */ GDataType *dtype; /* Type instancié */ /* ICT_QUALIFIED_TYPE */ diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c index 6e580f6..d890a1b 100644 --- a/plugins/itanium/component.c +++ b/plugins/itanium/component.c @@ -48,9 +48,6 @@ typedef void (* visit_comp_fc) (itanium_component *); -#define reset_comp_hash(c) c->hash = 0 - - /* Crée un composant de contexte Itanium complètement vierge. */ static itanium_component *itd_alloc(void); @@ -191,6 +188,7 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor) break; case ICT_TYPE: + case ICT_VENDOR_TYPE: break; case ICT_QUALIFIED_TYPE: @@ -227,7 +225,7 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor) break; case ICT_ARRAY: - if (!comp->array.numbered_dim) + if (!comp->array.numbered_dim && comp->array.dim_expr != NULL) visit_comp(comp->array.dim_expr, visitor); visit_comp(comp->array.atype, visitor); break; @@ -237,6 +235,10 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor) visit_comp(comp->pmember.member, visitor); break; + case ICT_TEMPLATE_PARAM: + visit_comp(comp->unary, visitor); + break; + case ICT_TEMPLATE_ARGS: visit_comp(comp->unary, visitor); break; @@ -320,7 +322,7 @@ void itd_unref_comp(itanium_component *comp) { if (--comp->refcount == 0) { - if (comp->type == ICT_TYPE || comp->type == ICT_STD_SUBST) + if (comp->type == ICT_TYPE || comp->type == ICT_VENDOR_TYPE || comp->type == ICT_STD_SUBST) g_object_unref(G_OBJECT(comp->dtype)); itd_free(comp); @@ -336,34 +338,6 @@ void itd_unref_comp(itanium_component *comp) /****************************************************************************** * * -* Paramètres : comp = composant à manipuler. * -* * -* Description : Détermine ou fournit l'empreinte d'un composant. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -fnv64_t itd_hash_comp(itanium_component *comp) -{ - char *desc; /* Description du composant */ - - if (comp->hash == 0) - { - desc = itd_translate_component(comp, NULL); - comp->hash = fnv_64a_hash(desc); - free(desc); - } - - return comp->hash; - -} - - -/****************************************************************************** -* * * Paramètres : type = type à définir pour le composant. * * * * Description : Construit un composant dans un contexte Itanium. * @@ -797,7 +771,7 @@ itanium_component *itd_append_right_to_binary(ItaniumComponentType type, itanium if (parent != NULL) { for (iter = parent; iter->binary.right != NULL; iter = iter->binary.right) - reset_comp_hash(iter); + ; iter->binary.right = result; } @@ -854,8 +828,6 @@ void itd_set_type(itanium_component *comp, ItaniumComponentType type) { comp->type = type; - reset_comp_hash(comp); - } @@ -1025,6 +997,7 @@ char *itd_translate_component(const itanium_component *comp, char *base) break; case ICT_TYPE: + case ICT_VENDOR_TYPE: name = g_data_type_to_string(comp->dtype, true); result = stradd(base, name); free(name); @@ -1112,7 +1085,7 @@ char *itd_translate_component(const itanium_component *comp, char *base) free(tmp); } - else + else if (comp->array.dim_expr != NULL) result = itd_translate_component(comp->array.dim_expr, result); result = stradd(result, "]"); @@ -1125,6 +1098,10 @@ char *itd_translate_component(const itanium_component *comp, char *base) result = itd_translate_component(comp->pmember.member, result); break; + case ICT_TEMPLATE_PARAM: + result = itd_translate_component(comp->unary, base); + break; + case ICT_TEMPLATE_ARGS: result = stradd(base, "<"); result = itd_translate_component(comp->unary, result); @@ -1543,6 +1520,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp) break; case ICT_TYPE: + case ICT_VENDOR_TYPE: result = g_data_type_dup(comp->dtype); break; @@ -1631,9 +1609,12 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp) if (comp->array.numbered_dim) g_array_type_set_dimension_number(G_ARRAY_TYPE(result), comp->array.dim_number); - else + else if (comp->array.dim_expr != NULL) g_array_type_set_dimension_expression(G_ARRAY_TYPE(result), - itd_translate_component(comp, NULL)); + itd_translate_component(comp->array.dim_expr, NULL)); + + else + g_array_type_set_empty_dimension(G_ARRAY_TYPE(result)); } @@ -1660,6 +1641,10 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp) break; + case ICT_TEMPLATE_PARAM: + result = itd_translate_component_to_type(comp->unary); + break; + case ICT_TEMPLATE_ARGS: assert(comp->unary->type == ICT_TYPES_LIST); diff --git a/plugins/itanium/component.h b/plugins/itanium/component.h index f921ff9..7012283 100644 --- a/plugins/itanium/component.h +++ b/plugins/itanium/component.h @@ -34,7 +34,6 @@ #include <analysis/routine.h> #include <analysis/type.h> -#include <common/fnv1a.h> @@ -113,6 +112,12 @@ typedef enum _ItaniumComponentType ICT_TYPE, /** + * Simple distinction de ICT_TYPE, pour la distinction lors des candidatures + * aux substitutions. + */ + ICT_VENDOR_TYPE, + + /** * Type qualifié ; les infos utilies sont explicitement * conservées dans le champ qualified. */ @@ -154,6 +159,12 @@ typedef enum _ItaniumComponentType ICT_POINTER_TO_MEMBER, /** + * Argument de template. Utile pour les candidatures aux substitutions. + * 'unary' renvoie vers le composant utile. + */ + ICT_TEMPLATE_PARAM, + + /** * Liste d'arguments pour templates, à encadrer par des chevrons. * 'unary' pointe vers la liste des éléments. */ @@ -223,9 +234,6 @@ void itd_ref_comp(itanium_component *); /* Décrémente le nombre d'utilisation du composant. */ void itd_unref_comp(itanium_component *); -/* Détermine ou fournit l'empreinte d'un composant. */ -fnv64_t itd_hash_comp(itanium_component *); - /* Construit un composant dans un contexte Itanium. */ itanium_component *itd_make_with_type(ItaniumComponentType); diff --git a/plugins/itanium/context.c b/plugins/itanium/context.c index 1d2c365..c89f823 100644 --- a/plugins/itanium/context.c +++ b/plugins/itanium/context.c @@ -411,10 +411,12 @@ void g_itanium_demangling_pop_state(GItaniumDemangling *context, const itd_state * * ******************************************************************************/ -void g_itanium_demangling_add_template_arg(GItaniumDemangling *context, itanium_component *comp) +void g_itanium_demangling_add_template_args(GItaniumDemangling *context, itanium_component *comp) { assert(comp != NULL); + assert(itd_get_component_type(comp) == ICT_TEMPLATE_ARGS); + context->template_args[context->targs_count++] = comp; itd_ref_comp(comp); @@ -437,14 +439,37 @@ void g_itanium_demangling_add_template_arg(GItaniumDemangling *context, itanium_ itanium_component *g_itanium_demangling_get_template_arg(GItaniumDemangling *context, size_t index) { itanium_component *result; /* Composant à retourner */ + itanium_component *targs; /* Racine des arguments */ + itanium_component *iter; /* Boucle de parcours #1 */ + + if (context->targs_count == 0) + result = NULL; - if (index < context->targs_count) + else { - result = context->template_args[index]; - itd_ref_comp(result); + targs = context->template_args[context->targs_count - 1]; + + for (iter = targs->unary; iter != NULL; iter = iter->binary.right) + { + assert(itd_get_component_type(iter) == ICT_TYPES_LIST); + + if (index == 0) + break; + + index--; + + } + + if (iter != NULL) + { + result = iter->binary.left; + itd_ref_comp(result); + } + + else + result = NULL; + } - else - result = NULL; return result; @@ -466,15 +491,15 @@ itanium_component *g_itanium_demangling_get_template_arg(GItaniumDemangling *con void g_itanium_demangling_add_substitution(GItaniumDemangling *context, itanium_component *comp) { - fnv64_t hash; /* Empreinte du candidat */ size_t i; /* Boucle de parcours */ assert(comp != NULL); - hash = itd_hash_comp(comp); + if (itd_get_component_type(comp) == ICT_STD_SUBST) + return; for (i = 0; i < context->subst_count; i++) - if (cmp_fnv_64a(itd_hash_comp(context->substitutions[i]), hash) == 0) + if (comp == context->substitutions[i]) break; if (i == context->subst_count) diff --git a/plugins/itanium/context.h b/plugins/itanium/context.h index 6ec65ae..d836afb 100644 --- a/plugins/itanium/context.h +++ b/plugins/itanium/context.h @@ -67,7 +67,7 @@ void g_itanium_demangling_push_state(const GItaniumDemangling *, itd_state *); void g_itanium_demangling_pop_state(GItaniumDemangling *, const itd_state *); /* Indexe un composant représentant un argument de modèle. */ -void g_itanium_demangling_add_template_arg(GItaniumDemangling *, itanium_component *); +void g_itanium_demangling_add_template_args(GItaniumDemangling *, itanium_component *); /* Fournit un composant représentant un argument de modèle. */ itanium_component *g_itanium_demangling_get_template_arg(GItaniumDemangling *, size_t); diff --git a/plugins/pychrysalide/analysis/types/array.c b/plugins/pychrysalide/analysis/types/array.c index d021e16..6f70b02 100644 --- a/plugins/pychrysalide/analysis/types/array.c +++ b/plugins/pychrysalide/analysis/types/array.c @@ -281,7 +281,14 @@ static PyObject *py_array_type_get_dimension_expression(PyObject *self, void *cl dim = g_array_type_get_dimension_expression(type); - result = PyUnicode_FromString(dim); + if (dim != NULL) + result = PyUnicode_FromString(dim); + + else + { + result = Py_None; + Py_INCREF(result); + } return result; @@ -306,15 +313,19 @@ static int py_array_type_set_dimension_expression(PyObject *self, PyObject *valu { GArrayType *type; /* Version GLib du type */ - if (!PyUnicode_Check(value)) + if (!PyUnicode_Check(value) && value != Py_None) { - PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string.")); + PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string or None.")); return -1; } type = G_ARRAY_TYPE(pygobject_get(self)); - g_array_type_set_dimension_expression(type, strdup(PyUnicode_DATA(value))); + if (value == Py_None) + g_array_type_set_empty_dimension(type); + + else + g_array_type_set_dimension_expression(type, strdup(PyUnicode_DATA(value))); return 0; |