From a955b79a17f23157a02e2312b8693498c5f54b09 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 13 Mar 2020 15:46:23 +0100
Subject: Added support for extra Itanium builtin types.

---
 plugins/itanium/abi.c      | 84 ++++++++++++++++++++++++++++++++++++++++++++--
 src/analysis/types/basic.c | 12 +++++++
 src/analysis/types/basic.h |  3 ++
 tests/mangling/itanium.py  |  3 ++
 4 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c
index 0e7ce27..2a9561f 100644
--- a/plugins/itanium/abi.c
+++ b/plugins/itanium/abi.c
@@ -2200,7 +2200,9 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context)
 {
     itanium_component *result;              /* Construction à retourner    */
     input_buffer *ibuf;                     /* Tampon de texte manipulé    */
+    size_t consumed;                        /* Nombre de consommations     */
     BaseType type;                          /* Type reconnu ou BTP_INVALID */
+    GDataType *std;                         /* Espace de noms              */
     itanium_component *vendor;              /* Extension propriétaire      */
     GDataType *builtin;                     /* Type construit              */
 
@@ -2228,12 +2230,24 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context)
      *                ::= e  # long double, __float80
      *                ::= g  # __float128
      *                ::= z  # ellipsis
-     *                ::= u <source-name>    # vendor extended type
+     *                ::= Dd # IEEE 754r decimal floating point (64 bits)
+     *                ::= De # IEEE 754r decimal floating point (128 bits)
+     *                ::= Df # IEEE 754r decimal floating point (32 bits)
+     *                ::= Dh # IEEE 754r half-precision floating point (16 bits)
+     *                ::= DF <number> _ # ISO/IEC TS 18661 binary floating point type _FloatN (N bits)
+     *                ::= Di # char32_t
+     *                ::= Ds # char16_t
+     *                ::= Da # auto
+     *                ::= Dc # decltype(auto)
+     *                ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
+     *                ::= u <source-name> # vendor extended type
      *
      */
 
     ibuf = &G_DEMANGLING_CONTEXT(context)->buffer;
 
+    consumed = 1;
+
     switch (peek_input_buffer_char(ibuf))
     {
         case 'v':
@@ -2299,6 +2313,71 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context)
         case 'z':
             type = BTP_ELLIPSIS;
             break;
+
+        case 'D':
+
+            consumed = 2;
+
+            switch (peek_input_buffer_next_char(ibuf))
+            {
+                case 'd':
+                    type = BTP_754R_64;
+                    break;
+                case 'e':
+                    type = BTP_754R_128;
+                    break;
+                case 'f':
+                    type = BTP_754R_32;
+                    break;
+                case 'h':
+                    type = BTP_754R_16;
+                    break;
+
+                case 'F':
+                    advance_input_buffer(ibuf, 2);
+
+                    if (itd_number(context, (ssize_t []) { 0 }) && check_input_buffer_char(ibuf, '_'))
+                        type = BTP_754R_N;
+                    else
+                        type = BTP_INVALID;
+
+                    consumed = 0;
+                    break;
+
+                case 'i':
+                    type = BTP_CHAR32_T;
+                    break;
+                case 's':
+                    type = BTP_CHAR16_T;
+                    break;
+                case 'a':
+                    type = BTP_AUTO;
+                    break;
+                case 'c':
+                    type = BTP_DECL_AUTO;
+                    break;
+
+                case 'n':
+
+                    std = g_class_enum_type_new(CET_NAMESPACE, strdup("std"));
+
+                    builtin = g_class_enum_type_new(CET_CLASS, strdup("nullptr_t"));
+                    g_data_type_set_namespace(builtin, std, strdup("::"));
+
+                    result = itd_make_type(builtin);
+                    itd_set_type(result, ICT_STD_SUBST);
+
+                    goto done;
+                    break;
+
+                default:
+                    type = BTP_INVALID;
+                    break;
+
+            }
+
+            break;
+
         case 'u':
 
             advance_input_buffer(ibuf, 1);
@@ -2320,13 +2399,14 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context)
         default:
             type = BTP_INVALID;
             break;
+
     }
 
     if (type != BTP_INVALID)
     {
         builtin = g_basic_type_new(type);
         result = itd_make_type(builtin);
-        advance_input_buffer(ibuf, 1);
+        advance_input_buffer(ibuf, consumed);
     }
     else
         result = NULL;
diff --git a/src/analysis/types/basic.c b/src/analysis/types/basic.c
index 596c696..755a6f6 100644
--- a/src/analysis/types/basic.c
+++ b/src/analysis/types/basic.c
@@ -327,6 +327,10 @@ static char *g_basic_type_to_string(const GBasicType *type, bool include)
             desc = "__float754r_16";
             break;
 
+        case BTP_754R_N:
+            desc = "__float754r_n";
+            break;
+
         case BTP_CHAR32_T:
             desc = "char32_t";
             break;
@@ -335,6 +339,14 @@ static char *g_basic_type_to_string(const GBasicType *type, bool include)
             desc = "char16_t";
             break;
 
+        case BTP_AUTO:
+            desc = "auto";
+            break;
+
+        case BTP_DECL_AUTO:
+            desc = "decltype(auto)";
+            break;
+
         default:
             assert(false);
             desc = NULL;
diff --git a/src/analysis/types/basic.h b/src/analysis/types/basic.h
index 5707f2f..d2b3055 100644
--- a/src/analysis/types/basic.h
+++ b/src/analysis/types/basic.h
@@ -60,8 +60,11 @@ typedef enum _BaseType
     BTP_754R_128,                           /* IEEE 754r float (128 bits)  */
     BTP_754R_32,                            /* IEEE 754r float (32 bits)   */
     BTP_754R_16,                            /* IEEE 754r float (16 bits)   */
+    BTP_754R_N,                             /* IEEE 754r float (n bits)    */
     BTP_CHAR32_T,                           /* char32_t                    */
     BTP_CHAR16_T,                           /* char16_t                    */
+    BTP_AUTO,                               /* auto                        */
+    BTP_DECL_AUTO,                          /* decltype(auto)              */
 
     BTP_INVALID
 
diff --git a/tests/mangling/itanium.py b/tests/mangling/itanium.py
index 57a1129..7ff16c2 100644
--- a/tests/mangling/itanium.py
+++ b/tests/mangling/itanium.py
@@ -208,3 +208,6 @@ class TestItaniumMangling(ChrysalideTestCase):
 
         demangled = demangler.decode_routine('_ZNSt3__16vectorIfNS_9allocatorIfEEE8__appendEj')
         self.check_demangling(demangled, '??? std::__1::vector<float, allocator<float>>::__append(unsigned int)')
+
+        demangled = demangler.decode_routine('_ZN7android7String8C1EPKDsj')
+        self.check_demangling(demangled, 'android::String8 *android::String8::String8(const char16_t *, unsigned int)')
-- 
cgit v0.11.2-87-g4458