From 70fe3101ebd8fe28ef821a0c9097ea51d4e0691b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 8 Jul 2018 21:28:13 +0200
Subject: Filtered one more component for Itanium substitutions.

---
 plugins/itanium/abi.c       | 18 +++++++++++++++++-
 plugins/itanium/component.c | 29 +++++++++++++++++++++++++++--
 plugins/itanium/component.h |  3 +++
 3 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c
index 3f6f713..fa661dc 100644
--- a/plugins/itanium/abi.c
+++ b/plugins/itanium/abi.c
@@ -1826,6 +1826,7 @@ static itanium_component *itd_type(GItaniumDemangling *context)
     GDataType *builtin;                     /* Type construit              */
     itd_state saved;                        /* Position d'analyse courante */
     itanium_component *targs;               /* Composant 'template-args'   */
+    ItaniumComponentType comp_type;         /* Type de composant final     */
 
     /**
      * La règle traitée ici est la suivante :
@@ -2102,10 +2103,25 @@ static itanium_component *itd_type(GItaniumDemangling *context)
          *       function and operator names other than extern "C" functions.
          *
          * On saute donc éventuelleement certains résultats.
+         *
+         * Par ailleurs, il existe quelques restrictions à propos des qualificatifs :
+         *
+         *    For purposes of substitution, given a CV-qualified type, the base
+         *    type is substitutible, and the type with all the C, V, and r qualifiers
+         *    plus any vendor extended types in the same order-insensitive set is
+         *    substitutible; any type with a subset of those qualifiers is not.
+         *
+         * Le code courant englobe tous les qualificatifs, donc il n'y a pas de
+         * mesure particulière à prendre ici.
          */
 
-        if (itd_get_component_type(result) != ICT_TYPE)
+        comp_type = itd_get_component_type(result);
+
+        if (comp_type != ICT_TYPE
+            && (comp_type != ICT_FUNCTION_TYPE || itd_is_external_function(result)))
+        {
             g_itanium_demangling_add_substitution(context, result);
+        }
 
     }
 
diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c
index c2bf78a..e7315e8 100644
--- a/plugins/itanium/component.c
+++ b/plugins/itanium/component.c
@@ -579,8 +579,8 @@ itanium_component *itd_make_qualified_type(itanium_component *sub, TypeQualifier
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : sub       = composant de type en place à référencer.         *
-*                qualifier = propriétés supplémentaires pour le type.         *
+*  Paramètres  : extern_c = nature de la fonction à représenter.              *
+*                args     = arguments de cette même fonction.                 *
 *                                                                             *
 *  Description : Construit un composant dans un contexte Itanium.             *
 *                                                                             *
@@ -607,6 +607,31 @@ itanium_component *itd_make_function_type(bool extern_c, itanium_component *args
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : comp = composant Itanium à consulter.                        *
+*                                                                             *
+*  Description : Indique si une fonction est externalisée en C.               *
+*                                                                             *
+*  Retour      : Nature de la fonction représentée.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool itd_is_external_function(const itanium_component *comp)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    assert(comp->type == ICT_FUNCTION_TYPE);
+
+    result = comp->function.extern_c;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : number = dimension du tableau.                               *
 *                type   = type des membres du même tableau.                   *
 *                                                                             *
diff --git a/plugins/itanium/component.h b/plugins/itanium/component.h
index 7012283..a20272a 100644
--- a/plugins/itanium/component.h
+++ b/plugins/itanium/component.h
@@ -261,6 +261,9 @@ itanium_component *itd_make_qualified_type(itanium_component *, TypeQualifier);
 /* Construit un composant dans un contexte Itanium. */
 itanium_component *itd_make_function_type(bool, itanium_component *);
 
+/* Indique si une fonction est externalisée en C. */
+bool itd_is_external_function(const itanium_component *);
+
 /* Construit un composant dans un contexte Itanium. */
 itanium_component *itd_make_array_with_dim_number(ssize_t, itanium_component *);
 
-- 
cgit v0.11.2-87-g4458