summaryrefslogtreecommitdiff
path: root/plugins/itanium
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-07-04 10:24:39 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-07-04 10:24:39 (GMT)
commit1ade82e135d4e815db5b33c9ebd67632b74e5e1d (patch)
treeeafda5b3e4062922ee4f0b64e8f90695bfbde9c3 /plugins/itanium
parent8dc83465a6ca2d5b94b983b39f6c06d37e4126a0 (diff)
Fixed various mistakes in Itanium C++ demangling.
Diffstat (limited to 'plugins/itanium')
-rw-r--r--plugins/itanium/abi.c59
-rw-r--r--plugins/itanium/component-int.h5
-rw-r--r--plugins/itanium/component.c63
-rw-r--r--plugins/itanium/component.h16
-rw-r--r--plugins/itanium/context.c43
-rw-r--r--plugins/itanium/context.h2
6 files changed, 98 insertions, 90 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);