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; | 
