From 0df5bc8635819dcb268cf8ca1f82b9713417a6cb Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 15 Mar 2020 12:05:38 +0100
Subject: Fixed the substitution order when demangling Itanium prefixes.

---
 plugins/itanium/abi.c | 89 +++++++++++++++++++--------------------------------
 1 file changed, 33 insertions(+), 56 deletions(-)

diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c
index 34a2a01..300bf59 100644
--- a/plugins/itanium/abi.c
+++ b/plugins/itanium/abi.c
@@ -738,10 +738,9 @@ static itanium_component *itd_prefix(GItaniumDemangling *context)
     input_buffer *ibuf;                     /* Tampon de texte manipulé    */
     char peek;                              /* Prochain caractère lu       */
     itanium_component *targs;               /* Composant 'template-args'   */
-    bool backup;                            /* Solution de repli existante */
-    bool merge_targs;                       /* Fusion nécessaire ?         */
     itd_state saved;                        /* Position d'analyse courante */
     itanium_component *further;             /* Tentative de progression    */
+    itanium_component *backup;              /* Solution de repli existante */
 
     /**
      * La règle traitée ici est la suivante :
@@ -812,6 +811,9 @@ static itanium_component *itd_prefix(GItaniumDemangling *context)
     {
         g_itanium_demangling_push_state(context, &saved);
 
+        /* Ajout de la substitution tirée de <template-prefix> */
+        g_itanium_demangling_add_substitution(context, result);
+
         targs = itd_template_args(context);
 
         if (targs != NULL)
@@ -823,14 +825,8 @@ static itanium_component *itd_prefix(GItaniumDemangling *context)
             }
 
             else
-            {
-                /* Ajout de la substitution tirée de <template-prefix> */
-                g_itanium_demangling_add_substitution(context, result);
-
                 result = itd_make_binary(ICT_TEMPLATE_NAME_ARGS, result, targs);
 
-            }
-
         }
 
         else
@@ -851,13 +847,7 @@ static itanium_component *itd_prefix(GItaniumDemangling *context)
 
     while (count_input_buffer_remaining(ibuf) > 0)
     {
-        backup = is_itd_unqualified_name(context);
-
-        if (backup)
-            g_itanium_demangling_push_state(context, &saved);
-
-        merge_targs = false;
-        targs = NULL;
+        g_itanium_demangling_push_state(context, &saved);
 
         /**
          * Comme <data-member-prefix> commence par une régle <source-name> et
@@ -870,66 +860,53 @@ static itanium_component *itd_prefix(GItaniumDemangling *context)
 
         if (further == NULL)
         {
+            g_itanium_demangling_pop_state(context, &saved);
             further = itd_unqualified_name(context);
-
-            if (further != NULL && is_itd_template_args(context))
-            {
-                merge_targs = true;
-                targs = itd_template_args(context);
-
-                /* Si l'ensemble ne se termine pas par la règle finale attendue, on rétro-pédale */
-                if (targs != NULL && !is_itd_unqualified_name(context))
-                {
-                    itd_unref_comp(targs);
-
-                    merge_targs = false;
-                    targs = NULL;
-
-                    g_itanium_demangling_pop_state(context, &saved);
-
-                    break;
-
-                }
-
-            }
-
         }
 
         if (further == NULL)
             break;
 
-        if (!is_itd_unqualified_name(context))
-        {
-            if (backup)
-                g_itanium_demangling_pop_state(context, &saved);
-
-            itd_unref_comp(further);
-
-            break;
-
-        }
+        backup = result;
+        itd_ref_comp(backup);
 
         result = itd_make_binary(ICT_PREFIX_BINARY, result, further);
 
-        if (merge_targs)
-        {
-            if (targs != NULL)
-            {
-                g_itanium_demangling_add_substitution(context, result);
+        /* Ajout de la substitution tirée de <[template-]prefix> */
+        g_itanium_demangling_add_substitution(context, result);
 
-                result = itd_make_binary(ICT_TEMPLATE_NAME_ARGS, result, targs);
+        if (is_itd_template_args(context))
+        {
+            targs = itd_template_args(context);
 
-            }
-            else
+            if (targs == NULL)
             {
+                itd_unref_comp(backup);
                 itd_unref_comp(result);
                 result = NULL;
                 goto done;
             }
 
+            result = itd_make_binary(ICT_TEMPLATE_NAME_ARGS, result, targs);
+
+            g_itanium_demangling_add_substitution(context, result);
+
         }
 
-        g_itanium_demangling_add_substitution(context, result);
+        /* Si l'ensemble ne se termine pas par la règle finale attendue, on rétropédale */
+        if (!is_itd_unqualified_name(context))
+        {
+            itd_unref_comp(result);
+
+            result = backup;
+
+            g_itanium_demangling_pop_state(context, &saved);
+
+            break;
+
+        }
+
+        itd_unref_comp(backup);
 
     }
 
-- 
cgit v0.11.2-87-g4458