summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-03-15 19:28:02 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-03-15 19:28:02 (GMT)
commit46cf7042cf511215001bb28c072821998a83d011 (patch)
tree2aa12b84c2f01d124cafe788ad5b314e9e94ae59
parent0df5bc8635819dcb268cf8ca1f82b9713417a6cb (diff)
Added support for packed template arguments in Itanium demangling.
-rw-r--r--plugins/itanium/abi.c57
-rw-r--r--plugins/itanium/component.c52
-rw-r--r--plugins/itanium/component.h9
-rw-r--r--tests/mangling/itanium.py3
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 &&&)')