diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2020-03-15 19:28:02 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2020-03-15 19:28:02 (GMT) |
commit | 46cf7042cf511215001bb28c072821998a83d011 (patch) | |
tree | 2aa12b84c2f01d124cafe788ad5b314e9e94ae59 | |
parent | 0df5bc8635819dcb268cf8ca1f82b9713417a6cb (diff) |
Added support for packed template arguments in Itanium demangling.
-rw-r--r-- | plugins/itanium/abi.c | 57 | ||||
-rw-r--r-- | plugins/itanium/component.c | 52 | ||||
-rw-r--r-- | plugins/itanium/component.h | 9 | ||||
-rw-r--r-- | tests/mangling/itanium.py | 3 |
4 files changed, 118 insertions, 3 deletions
diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c index 300bf59..0304938 100644 --- a/plugins/itanium/abi.c +++ b/plugins/itanium/abi.c @@ -1818,6 +1818,7 @@ static itanium_component *itd_type(GItaniumDemangling *context) * ::= C <type> # complex pair (C 2000) * ::= G <type> # imaginary (C 2000) * ::= U <source-name> <type> # vendor extended type qualifier + * ::= Dp <type> # pack expansion (C++0x) * */ @@ -1946,6 +1947,17 @@ static itanium_component *itd_type(GItaniumDemangling *context) handled = true; break; + case 'D': + if (peek_input_buffer_next_char(ibuf) == 'p') + { + advance_input_buffer(ibuf, 2); + + result = itd_type(context); + handled = true; + + } + break; + case 'T': /** @@ -2832,7 +2844,7 @@ static itanium_component *itd_template_args(GItaniumDemangling *context) arg = itd_template_arg(context); if (arg == NULL) return NULL; - result = itd_append_right_to_binary(ICT_TYPES_LIST, NULL, arg); + result = itd_merge_list_right_to_binary(ICT_TYPES_LIST, NULL, arg); while (1) { @@ -2845,7 +2857,7 @@ static itanium_component *itd_template_args(GItaniumDemangling *context) break; } - result = itd_append_right_to_binary(ICT_TYPES_LIST, result, arg); + result = itd_merge_list_right_to_binary(ICT_TYPES_LIST, result, arg); } @@ -2881,6 +2893,7 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context) itanium_component *result; /* Construction à retourner */ input_buffer *ibuf; /* Tampon de texte manipulé */ char peek; /* Prochain caractère lu */ + itanium_component *packed; /* Argument compressé */ /** * La règle traitée ici est la suivante : @@ -2888,6 +2901,7 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context) * <template-arg> ::= <type> # type or template * ::= X <expression> E # expression * ::= <expr-primary> # simple expressions + * ::= J <template-arg>* E # argument pack * */ @@ -2912,9 +2926,48 @@ static itanium_component *itd_template_arg(GItaniumDemangling *context) else if (peek == 'L') result = itd_expr_primary(context); + else if (peek == 'J') + { + advance_input_buffer(ibuf, 1); + + result = NULL; + + while (peek_input_buffer_char(ibuf) != 'E') + { + packed = itd_template_arg(context); + + if (packed == NULL) + { + if (result != NULL) + { + itd_unref_comp(result); + result = NULL; + } + + goto packed_failed; + + } + + result = itd_merge_list_right_to_binary(ICT_TYPES_LIST, result, packed); + + } + + if (result == NULL) + result = itd_make_with_type(ICT_PACKED_EMPTY); + + if (!check_input_buffer_char(ibuf, 'E')) + { + itd_unref_comp(result); + result = NULL; + } + + } + else result = itd_type(context); + packed_failed: + return result; } diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c index f5aad1d..f035e36 100644 --- a/plugins/itanium/component.c +++ b/plugins/itanium/component.c @@ -254,6 +254,9 @@ static void visit_comp(itanium_component *comp, visit_comp_fc visitor) break; + case ICT_PACKED_EMPTY: + break; + case ICT_EXPR_LIST: visit_comp(comp->binary.left, visitor); @@ -810,6 +813,46 @@ itanium_component *itd_append_right_to_binary(ItaniumComponentType type, itanium /****************************************************************************** * * * Paramètres : type = type du composant à mettre en place. * +* left = second composant à associer. * +* * +* Description : Construit un composant dans un contexte Itanium. * +* * +* Retour : Composant extrait ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +itanium_component *itd_merge_list_right_to_binary(ItaniumComponentType type, itanium_component *parent, itanium_component *left) +{ + itanium_component *result; /* Composant à renvoyer */ + itanium_component *iter; /* Boucle de parcours */ + + if (left->type != ICT_TYPES_LIST) + result = itd_append_right_to_binary(type, parent, left); + + else + { + if (parent == NULL) + result = left; + + else + { + for (iter = parent; iter->binary.right != NULL; iter = iter->binary.right) + ; + iter->binary.right = left; + } + + } + + return (parent != NULL ? parent : result); + +} + + +/****************************************************************************** +* * +* Paramètres : type = type du composant à mettre en place. * * c0 = premier composant à associer. * * c1 = second composant à associer. * * c2 = troisième composant à associer. * @@ -1146,6 +1189,9 @@ char *itd_translate_component(const itanium_component *comp, char *base) break; + case ICT_PACKED_EMPTY: + break; + case ICT_EXPR_LIST: /** @@ -1751,12 +1797,15 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin case ICT_TEMPLATE_ARGS: - assert(comp->unary->type == ICT_TYPES_LIST); + assert(comp->unary->type == ICT_TYPES_LIST || comp->unary->type == ICT_PACKED_EMPTY); result = g_template_type_new(); for (iter = comp->unary; iter != NULL && result != NULL; iter = iter->binary.right) { + if (iter->type == ICT_PACKED_EMPTY) + continue; + assert(iter->type == ICT_TYPES_LIST); param = itd_translate_component_to_type(iter->binary.left, rtype); @@ -1774,6 +1823,7 @@ GDataType *itd_translate_component_to_type(const itanium_component *comp, Routin break; case ICT_TYPES_LIST: + case ICT_PACKED_EMPTY: /** * Les listes doient être rassemblées par l'appelant ! diff --git a/plugins/itanium/component.h b/plugins/itanium/component.h index 36852d9..c4b5eb3 100644 --- a/plugins/itanium/component.h +++ b/plugins/itanium/component.h @@ -178,6 +178,12 @@ typedef enum _ItaniumComponentType ICT_TYPES_LIST, /** + * Paramètres compressés de patron non définis. + * (cf. règle <template-arg> ::= J <template-arg>* E ) + */ + ICT_PACKED_EMPTY, + + /** * Liste d'expressions, sous forme binaire comme pour ICT_TYPES_LIST : * -> left = élément de la liste de types. * -> right = reste de la liste de types. @@ -283,6 +289,9 @@ itanium_component *itd_make_binary(ItaniumComponentType, itanium_component *, it itanium_component *itd_append_right_to_binary(ItaniumComponentType, itanium_component *, itanium_component *); /* Construit un composant dans un contexte Itanium. */ +itanium_component *itd_merge_list_right_to_binary(ItaniumComponentType, itanium_component *, itanium_component *); + +/* Construit un composant dans un contexte Itanium. */ itanium_component *itd_make_ternary(ItaniumComponentType, itanium_component *, itanium_component *, itanium_component *); /* Modifie légèrement le type d'un composant donné. */ diff --git a/tests/mangling/itanium.py b/tests/mangling/itanium.py index a1cc517..1b24c3d 100644 --- a/tests/mangling/itanium.py +++ b/tests/mangling/itanium.py @@ -214,3 +214,6 @@ class TestItaniumMangling(ChrysalideTestCase): demangled = demangler.decode_routine('_ZNSt3__111__tree_nextIPNS_16__tree_node_baseIPvEEEET_S5_') self.check_demangling(demangled, 'std::__1::__tree_node_base<void *> *std::__1::__tree_next<std::__1::__tree_node_base<void *> *>(std::__1::__tree_node_base<void *> *)') + + demangled = demangler.decode_routine('_ZNSt3__110shared_ptrIN7android14CameraMetadataEE11make_sharedIJRKS2_EEES3_DpOT_') + self.check_demangling(demangled, 'std::__1::shared_ptr<android::CameraMetadata> std::__1::shared_ptr<android::CameraMetadata>::make_shared<const android::CameraMetadata &>(const android::CameraMetadata &&&)') |