The branch vendor/libcxxrt has been updated by dim:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3f8a54b20893fe39cf81775e18be6c4353bd2a48

commit 3f8a54b20893fe39cf81775e18be6c4353bd2a48
Author:     Dimitry Andric <[email protected]>
AuthorDate: 2021-02-18 21:07:28 +0000
Commit:     Dimitry Andric <[email protected]>
CommitDate: 2021-02-18 21:07:28 +0000

    Import libcxxrt master 8049924686b8414d8e652cbd2a52c763b48e8456
    
    Interesting fixes:
    b3c73ba libelftc_dem_gnu3: Sync with elftoolchain r3877
    7b2335c Mostly fix __cxa_demangle after #3
---
 libelftc_dem_gnu3.c | 1189 +++++++++++++++++++++++++++++++++++----------------
 unwind-arm.h        |    6 +-
 unwind-itanium.h    |   10 +-
 3 files changed, 824 insertions(+), 381 deletions(-)

diff --git a/libelftc_dem_gnu3.c b/libelftc_dem_gnu3.c
index 14a9b7420095..6e88f7b4bb4c 100644
--- a/libelftc_dem_gnu3.c
+++ b/libelftc_dem_gnu3.c
@@ -1,5 +1,6 @@
 /*-
- * Copyright (c) 2007, 2008 Hyogeol Lee <[email protected]>
+ * Copyright (c) 2007 Hyogeol Lee <[email protected]>
+ * Copyright (c) 2015-2017 Kai Wang <[email protected]>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,12 +55,17 @@ struct vector_str {
 };
 
 #define BUFFER_GROWFACTOR      1.618
-#define VECTOR_DEF_CAPACITY    8
+#define BUFFER_GROW(x)         (((x)+0.5)*BUFFER_GROWFACTOR)
+
+#define        ELFTC_FAILURE           0
 #define        ELFTC_ISDIGIT(C)        (isdigit((C) & 0xFF))
+#define        ELFTC_SUCCESS           1
+
+#define VECTOR_DEF_CAPACITY    8
 
 enum type_qualifier {
        TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT,
-       TYPE_CST, TYPE_VEC
+       TYPE_CST, TYPE_VEC, TYPE_RREF
 };
 
 struct vector_type_qualifier {
@@ -73,27 +79,47 @@ enum read_cmd {
        READ_TYPE, READ_FUNC, READ_PTRMEM
 };
 
+struct read_cmd_item {
+       enum read_cmd cmd;
+       void *data;
+};
+
 struct vector_read_cmd {
        size_t size, capacity;
-       enum read_cmd *r_container;
+       struct read_cmd_item *r_container;
+};
+
+enum push_qualifier {
+       PUSH_ALL_QUALIFIER,
+       PUSH_CV_QUALIFIER,
+       PUSH_NON_CV_QUALIFIER,
 };
 
 struct cpp_demangle_data {
        struct vector_str        output;        /* output string vector */
-       struct vector_str        output_tmp;
        struct vector_str        subst;         /* substitution string vector */
        struct vector_str        tmpl;
        struct vector_str        class_type;
+       struct vector_str       *cur_output;    /* ptr to current output vec */
        struct vector_read_cmd   cmd;
-       bool                     paren;         /* parenthesis opened */
-       bool                     pfirst;        /* first element of parameter */
        bool                     mem_rst;       /* restrict member function */
        bool                     mem_vat;       /* volatile member function */
        bool                     mem_cst;       /* const member function */
+       bool                     mem_ref;       /* lvalue-ref member func */
+       bool                     mem_rref;      /* rvalue-ref member func */
+       bool                     is_tmpl;       /* template args */
+       bool                     is_functype;   /* function type */
+       bool                     ref_qualifier; /* ref qualifier */
+       enum type_qualifier      ref_qualifier_type; /* ref qualifier type */
+       enum push_qualifier      push_qualifier; /* which qualifiers to push */
        int                      func_type;
        const char              *cur;           /* current mangled name ptr */
        const char              *last_sname;    /* last source name */
-       int                      push_head;
+};
+
+struct type_delimit {
+       bool paren;
+       bool firstp;
 };
 
 #define        CPP_DEMANGLE_TRY_LIMIT  128
@@ -102,6 +128,8 @@ struct cpp_demangle_data {
 #define        FLOAT_EXTENED_BYTES     10
 
 #define SIMPLE_HASH(x,y)       (64 * x + y)
+#define DEM_PUSH_STR(d,s)      cpp_demangle_push_str((d), (s), strlen((s)))
+#define VEC_PUSH_STR(d,s)      vector_str_push((d), (s), strlen((s)))
 
 static size_t  get_strlen_sum(const struct vector_str *v);
 static bool    vector_str_grow(struct vector_str *v);
@@ -213,7 +241,7 @@ vector_str_grow(struct vector_str *v)
 
        assert(v->capacity > 0);
 
-       tmp_cap = v->capacity * BUFFER_GROWFACTOR;
+       tmp_cap = BUFFER_GROW(v->capacity);
 
        assert(tmp_cap > v->capacity);
 
@@ -314,7 +342,7 @@ vector_str_push_vector_head(struct vector_str *dst, struct 
vector_str *org)
        if (dst == NULL || org == NULL)
                return (false);
 
-       tmp_cap = (dst->size + org->size) * BUFFER_GROWFACTOR;
+       tmp_cap = BUFFER_GROW(dst->size + org->size);
 
        if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
                return (false);
@@ -341,6 +369,47 @@ vector_str_push_vector_head(struct vector_str *dst, struct 
vector_str *org)
        return (true);
 }
 
+/**
+ * @brief Push org vector to the tail of det vector.
+ * @return false at failed, true at success.
+ */
+static bool
+vector_str_push_vector(struct vector_str *dst, struct vector_str *org)
+{
+       size_t i, j, tmp_cap;
+       char **tmp_ctn;
+
+       if (dst == NULL || org == NULL)
+               return (false);
+
+       tmp_cap = BUFFER_GROW(dst->size + org->size);
+
+       if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
+               return (false);
+
+       for (i = 0; i < dst->size; ++i)
+               tmp_ctn[i] = dst->container[i];
+
+       for (i = 0; i < org->size; ++i)
+               if ((tmp_ctn[i + dst->size] = strdup(org->container[i])) ==
+                   NULL) {
+                       for (j = 0; j < i + dst->size; ++j)
+                               free(tmp_ctn[j]);
+
+                       free(tmp_ctn);
+
+                       return (false);
+               }
+
+       free(dst->container);
+
+       dst->container = tmp_ctn;
+       dst->capacity = tmp_cap;
+       dst->size += org->size;
+
+       return (true);
+}
+
 /**
  * @brief Get new allocated flat string from vector between begin and end.
  *
@@ -387,6 +456,7 @@ static int  cpp_demangle_push_fp(struct cpp_demangle_data *,
                    char *(*)(const char *, size_t));
 static int     cpp_demangle_push_str(struct cpp_demangle_data *, const char *,
                    size_t);
+static int     cpp_demangle_pop_str(struct cpp_demangle_data *);
 static int     cpp_demangle_push_subst(struct cpp_demangle_data *,
                    const char *, size_t);
 static int     cpp_demangle_push_subst_v(struct cpp_demangle_data *,
@@ -419,16 +489,18 @@ static int        
cpp_demangle_read_number_as_string(struct cpp_demangle_data *,
 static int     cpp_demangle_read_nv_offset(struct cpp_demangle_data *);
 static int     cpp_demangle_read_offset(struct cpp_demangle_data *);
 static int     cpp_demangle_read_offset_number(struct cpp_demangle_data *);
-static int     cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *);
+static int     cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *,
+                   struct vector_type_qualifier *);
 static int     cpp_demangle_read_sname(struct cpp_demangle_data *);
 static int     cpp_demangle_read_subst(struct cpp_demangle_data *);
 static int     cpp_demangle_read_subst_std(struct cpp_demangle_data *);
 static int     cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *,
-                   const char *, size_t);
+                   const char *);
 static int     cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *);
 static int     cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);
 static int     cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);
-static int     cpp_demangle_read_type(struct cpp_demangle_data *, int);
+static int     cpp_demangle_read_type(struct cpp_demangle_data *,
+                   struct type_delimit *);
 static int     cpp_demangle_read_type_flat(struct cpp_demangle_data *,
                    char **);
 static int     cpp_demangle_read_uqname(struct cpp_demangle_data *);
@@ -440,10 +512,12 @@ static char       *decode_fp_to_float80(const char *, 
size_t);
 static char    *decode_fp_to_long_double(const char *, size_t);
 static int     hex_to_dec(char);
 static void    vector_read_cmd_dest(struct vector_read_cmd *);
-static int     vector_read_cmd_find(struct vector_read_cmd *, enum read_cmd);
+static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *,
+                   enum read_cmd);
 static int     vector_read_cmd_init(struct vector_read_cmd *);
 static int     vector_read_cmd_pop(struct vector_read_cmd *);
-static int     vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd);
+static int     vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd,
+                   void *);
 static void    vector_type_qualifier_dest(struct vector_type_qualifier *);
 static int     vector_type_qualifier_init(struct vector_type_qualifier *);
 static int     vector_type_qualifier_push(struct vector_type_qualifier *,
@@ -460,22 +534,17 @@ char *
 __cxa_demangle_gnu3(const char *org)
 {
        struct cpp_demangle_data ddata;
+       struct vector_str ret_type;
+       struct type_delimit td;
        ssize_t org_len;
        unsigned int limit;
-       char *rtn = NULL;
+       char *rtn;
+       bool has_ret, more_type;
 
        if (org == NULL)
                return (NULL);
 
        org_len = strlen(org);
-       if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
-               if ((rtn = malloc(org_len + 19)) == NULL)
-                       return (NULL);
-               snprintf(rtn, org_len + 19,
-                   "global constructors keyed to %s", org + 11);
-               return (rtn);
-       }
-
        // Try demangling as a type for short encodings
        if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) {
                if (!cpp_demangle_data_init(&ddata, org))
@@ -485,43 +554,106 @@ __cxa_demangle_gnu3(const char *org)
                rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
                goto clean;
        }
+       if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
+               if ((rtn = malloc(org_len + 19)) == NULL)
+                       return (NULL);
+               snprintf(rtn, org_len + 19,
+                   "global constructors keyed to %s", org + 11);
+               return (rtn);
+       }
 
 
        if (!cpp_demangle_data_init(&ddata, org + 2))
                return (NULL);
 
        rtn = NULL;
+       has_ret = more_type = false;
 
        if (!cpp_demangle_read_encoding(&ddata))
                goto clean;
 
+       /*
+        * Pop function name from substitution candidate list.
+        */
+       if (*ddata.cur != 0 && ddata.subst.size >= 1) {
+               if (!vector_str_pop(&ddata.subst))
+                       goto clean;
+       }
+
+       td.paren = false;
+       td.firstp = true;
        limit = 0;
+
+       /*
+        * The first type is a return type if we just demangled template
+        * args. (the template args is right next to the function name,
+        * which means it's a template function)
+        */
+       if (ddata.is_tmpl) {
+               ddata.is_tmpl = false;
+               if (!vector_str_init(&ret_type))
+                       goto clean;
+               ddata.cur_output = &ret_type;
+               has_ret = true;
+       }
+
        while (*ddata.cur != '\0') {
                /*
                 * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4
                 */
                if (*ddata.cur == '@' && *(ddata.cur + 1) == '@')
                        break;
-               if (!cpp_demangle_read_type(&ddata, 1))
-                       goto clean;
+
+               if (has_ret) {
+                       /* Read return type */
+                       if (!cpp_demangle_read_type(&ddata, NULL))
+                               goto clean;
+               } else {
+                       /* Read function arg type */
+                       if (!cpp_demangle_read_type(&ddata, &td))
+                               goto clean;
+               }
+
+               if (has_ret) {
+                       /* Push return type to the beginning */
+                       if (!VEC_PUSH_STR(&ret_type, " "))
+                               goto clean;
+                       if (!vector_str_push_vector_head(&ddata.output,
+                           &ret_type))
+                               goto clean;
+                       ddata.cur_output = &ddata.output;
+                       vector_str_dest(&ret_type);
+                       has_ret = false;
+                       more_type = true;
+               } else if (more_type)
+                       more_type = false;
                if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
                        goto clean;
        }
+       if (more_type)
+               goto clean;
 
        if (ddata.output.size == 0)
                goto clean;
-       if (ddata.paren && !vector_str_push(&ddata.output, ")", 1))
+       if (td.paren && !VEC_PUSH_STR(&ddata.output, ")"))
+               goto clean;
+       if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile"))
+               goto clean;
+       if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const"))
                goto clean;
-       if (ddata.mem_vat && !vector_str_push(&ddata.output, " volatile", 9))
+       if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict"))
                goto clean;
-       if (ddata.mem_cst && !vector_str_push(&ddata.output, " const", 6))
+       if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &"))
                goto clean;
-       if (ddata.mem_rst && !vector_str_push(&ddata.output, " restrict", 9))
+       if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&"))
                goto clean;
 
        rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
 
 clean:
+       if (has_ret)
+               vector_str_dest(&ret_type);
+
        cpp_demangle_data_dest(&ddata);
 
        return (rtn);
@@ -538,7 +670,6 @@ cpp_demangle_data_dest(struct cpp_demangle_data *d)
        vector_str_dest(&d->class_type);
        vector_str_dest(&d->tmpl);
        vector_str_dest(&d->subst);
-       vector_str_dest(&d->output_tmp);
        vector_str_dest(&d->output);
 }
 
@@ -551,43 +682,42 @@ cpp_demangle_data_init(struct cpp_demangle_data *d, const 
char *cur)
 
        if (!vector_str_init(&d->output))
                return (0);
-       if (!vector_str_init(&d->output_tmp))
-               goto clean1;
        if (!vector_str_init(&d->subst))
-               goto clean2;
+               goto clean1;
        if (!vector_str_init(&d->tmpl))
-               goto clean3;
+               goto clean2;
        if (!vector_str_init(&d->class_type))
-               goto clean4;
+               goto clean3;
        if (!vector_read_cmd_init(&d->cmd))
-               goto clean5;
+               goto clean4;
 
        assert(d->output.container != NULL);
-       assert(d->output_tmp.container != NULL);
        assert(d->subst.container != NULL);
        assert(d->tmpl.container != NULL);
        assert(d->class_type.container != NULL);
 
-       d->paren = false;
-       d->pfirst = false;
        d->mem_rst = false;
        d->mem_vat = false;
        d->mem_cst = false;
+       d->mem_ref = false;
+       d->mem_rref = false;
+       d->is_tmpl = false;
+       d->is_functype = false;
+       d->ref_qualifier = false;
+       d->push_qualifier = PUSH_ALL_QUALIFIER;
        d->func_type = 0;
        d->cur = cur;
+       d->cur_output = &d->output;
        d->last_sname = NULL;
-       d->push_head = 0;
 
        return (1);
 
-clean5:
-       vector_str_dest(&d->class_type);
 clean4:
-       vector_str_dest(&d->tmpl);
+       vector_str_dest(&d->class_type);
 clean3:
-       vector_str_dest(&d->subst);
+       vector_str_dest(&d->tmpl);
 clean2:
-       vector_str_dest(&d->output_tmp);
+       vector_str_dest(&d->subst);
 clean1:
        vector_str_dest(&d->output);
 
@@ -632,10 +762,24 @@ cpp_demangle_push_str(struct cpp_demangle_data *ddata, 
const char *str,
        if (ddata == NULL || str == NULL || len == 0)
                return (0);
 
-       if (ddata->push_head > 0)
-               return (vector_str_push(&ddata->output_tmp, str, len));
+       /*
+        * is_tmpl is used to check if the type (function arg) is right next
+        * to template args, and should always be cleared whenever new string
+        * pushed.
+        */
+       ddata->is_tmpl = false;
 
-       return (vector_str_push(&ddata->output, str, len));
+       return (vector_str_push(ddata->cur_output, str, len));
+}
+
+static int
+cpp_demangle_pop_str(struct cpp_demangle_data *ddata)
+{
+
+       if (ddata == NULL)
+               return (0);
+
+       return (vector_str_pop(ddata->cur_output));
 }
 
 static int
@@ -677,9 +821,11 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
     struct vector_type_qualifier *v, const char *type_str)
 {
        struct vector_str subst_v;
+       enum type_qualifier t;
        size_t idx, e_idx, e_len;
-       int rtn;
        char *buf;
+       int rtn;
+       bool cv;
 
        if (ddata == NULL || v == NULL)
                return (0);
@@ -691,18 +837,22 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
        if (type_str != NULL) {
                if (!vector_str_init(&subst_v))
                        return (0);
-               if (!vector_str_push(&subst_v, type_str, strlen(type_str)))
+               if (!VEC_PUSH_STR(&subst_v, type_str))
                        goto clean;
        }
 
+       cv = true;
        e_idx = 0;
        while (idx > 0) {
                switch (v->q_container[idx - 1]) {
                case TYPE_PTR:
-                       if (!cpp_demangle_push_str(ddata, "*", 1))
+                       cv = false;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, "*"))
                                goto clean;
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, "*", 1))
+                               if (!VEC_PUSH_STR(&subst_v, "*"))
                                        goto clean;
                                if (!cpp_demangle_push_subst_v(ddata,
                                    &subst_v))
@@ -711,10 +861,28 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        break;
 
                case TYPE_REF:
-                       if (!cpp_demangle_push_str(ddata, "&", 1))
+                       cv = false;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, "&"))
+                               goto clean;
+                       if (type_str != NULL) {
+                               if (!VEC_PUSH_STR(&subst_v, "&"))
+                                       goto clean;
+                               if (!cpp_demangle_push_subst_v(ddata,
+                                   &subst_v))
+                                       goto clean;
+                       }
+                       break;
+
+               case TYPE_RREF:
+                       cv = false;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, "&&"))
                                goto clean;
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, "&", 1))
+                               if (!VEC_PUSH_STR(&subst_v, "&&"))
                                        goto clean;
                                if (!cpp_demangle_push_subst_v(ddata,
                                    &subst_v))
@@ -723,10 +891,13 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        break;
 
                case TYPE_CMX:
-                       if (!cpp_demangle_push_str(ddata, " complex", 8))
+                       cv = false;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, " complex"))
                                goto clean;
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, " complex", 8))
+                               if (!VEC_PUSH_STR(&subst_v, " complex"))
                                        goto clean;
                                if (!cpp_demangle_push_subst_v(ddata,
                                    &subst_v))
@@ -735,11 +906,13 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        break;
 
                case TYPE_IMG:
-                       if (!cpp_demangle_push_str(ddata, " imaginary", 10))
+                       cv = false;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, " imaginary"))
                                goto clean;
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, " imaginary",
-                                   10))
+                               if (!VEC_PUSH_STR(&subst_v, " imaginary"))
                                        goto clean;
                                if (!cpp_demangle_push_subst_v(ddata,
                                    &subst_v))
@@ -748,6 +921,9 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        break;
 
                case TYPE_EXT:
+                       cv = false;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
+                               break;
                        if (v->ext_name.size == 0 ||
                            e_idx > v->ext_name.size - 1)
                                goto clean;
@@ -759,14 +935,13 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        snprintf(buf, e_len + 2, " %s",
                            v->ext_name.container[e_idx]);
 
-                       if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) {
+                       if (!DEM_PUSH_STR(ddata, buf)) {
                                free(buf);
                                goto clean;
                        }
 
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, buf,
-                                   e_len + 1)) {
+                               if (!VEC_PUSH_STR(&subst_v, buf)) {
                                        free(buf);
                                        goto clean;
                                }
@@ -781,11 +956,22 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        break;
 
                case TYPE_RST:
-                       if (!cpp_demangle_push_str(ddata, " restrict", 9))
+                       if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
+                           cv)
+                               break;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, " restrict"))
                                goto clean;
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, " restrict", 9))
+                               if (!VEC_PUSH_STR(&subst_v, " restrict"))
                                        goto clean;
+                               if (idx - 1 > 0) {
+                                       t = v->q_container[idx - 2];
+                                       if (t == TYPE_RST || t == TYPE_VAT ||
+                                           t == TYPE_CST)
+                                               break;
+                               }
                                if (!cpp_demangle_push_subst_v(ddata,
                                    &subst_v))
                                        goto clean;
@@ -793,11 +979,22 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        break;
 
                case TYPE_VAT:
-                       if (!cpp_demangle_push_str(ddata, " volatile", 9))
+                       if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
+                           cv)
+                               break;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, " volatile"))
                                goto clean;
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, " volatile", 9))
+                               if (!VEC_PUSH_STR(&subst_v, " volatile"))
                                        goto clean;
+                               if (idx - 1 > 0) {
+                                       t = v->q_container[idx - 2];
+                                       if (t == TYPE_RST || t == TYPE_VAT ||
+                                           t == TYPE_CST)
+                                               break;
+                               }
                                if (!cpp_demangle_push_subst_v(ddata,
                                    &subst_v))
                                        goto clean;
@@ -805,11 +1002,22 @@ cpp_demangle_push_type_qualifier(struct 
cpp_demangle_data *ddata,
                        break;
 
                case TYPE_CST:
-                       if (!cpp_demangle_push_str(ddata, " const", 6))
+                       if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
+                           cv)
+                               break;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
+                               break;
+                       if (!DEM_PUSH_STR(ddata, " const"))
                                goto clean;
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, " const", 6))
+                               if (!VEC_PUSH_STR(&subst_v, " const"))
                                        goto clean;
+                               if (idx - 1 > 0) {
+                                       t = v->q_container[idx - 2];
+                                       if (t == TYPE_RST || t == TYPE_VAT ||
+                                           t == TYPE_CST)
+                                               break;
+                               }
                                if (!cpp_demangle_push_subst_v(ddata,
                                    &subst_v))
                                        goto clean;
@@ -817,6 +1025,9 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_data 
*ddata,
                        break;
 
                case TYPE_VEC:
+                       cv = false;
+                       if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
+                               break;
                        if (v->ext_name.size == 0 ||
                            e_idx > v->ext_name.size - 1)
                                goto clean;
@@ -827,13 +1038,12 @@ cpp_demangle_push_type_qualifier(struct 
cpp_demangle_data *ddata,
                                goto clean;
                        snprintf(buf, e_len + 12, " __vector(%s)",
                            v->ext_name.container[e_idx]);
-                       if (!cpp_demangle_push_str(ddata, buf, e_len + 11)) {
+                       if (!DEM_PUSH_STR(ddata, buf)) {
                                free(buf);
                                goto clean;
                        }
                        if (type_str != NULL) {
-                               if (!vector_str_push(&subst_v, buf,
-                                   e_len + 11)) {
+                               if (!VEC_PUSH_STR(&subst_v, buf)) {
                                        free(buf);
                                        goto clean;
                                }
@@ -907,10 +1117,10 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddata)
                if (*(++ddata->cur) == '\0')
                        return (0);
 
-               if (!cpp_demangle_read_type(ddata, 0))
+               if (!cpp_demangle_read_type(ddata, NULL))
                        return (0);
 
-               if (!cpp_demangle_push_str(ddata, "[]", 2))
+               if (!DEM_PUSH_STR(ddata, "[]"))
                        return (0);
        } else {
                if (ELFTC_ISDIGIT(*ddata->cur) != 0) {
@@ -923,13 +1133,13 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddata)
                        assert(num_len > 0);
                        if (*(++ddata->cur) == '\0')
                                return (0);
-                       if (!cpp_demangle_read_type(ddata, 0))
+                       if (!cpp_demangle_read_type(ddata, NULL))
                                return (0);
-                       if (!cpp_demangle_push_str(ddata, "[", 1))
+                       if (!DEM_PUSH_STR(ddata, "["))
                                return (0);
                        if (!cpp_demangle_push_str(ddata, num, num_len))
                                return (0);
-                       if (!cpp_demangle_push_str(ddata, "]", 1))
+                       if (!DEM_PUSH_STR(ddata, "]"))
                                return (0);
                } else {
                        p_idx = ddata->output.size;
@@ -953,11 +1163,11 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddata)
                                free(exp);
                                return (0);
                        }
-                       if (!cpp_demangle_read_type(ddata, 0)) {
+                       if (!cpp_demangle_read_type(ddata, NULL)) {
                                free(exp);
                                return (0);
                        }
-                       if (!cpp_demangle_push_str(ddata, "[", 1)) {
+                       if (!DEM_PUSH_STR(ddata, "[")) {
                                free(exp);
                                return (0);
                        }
@@ -965,7 +1175,7 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddata)
                                free(exp);
                                return (0);
                        }
-                       if (!cpp_demangle_push_str(ddata, "]", 1)) {
+                       if (!DEM_PUSH_STR(ddata, "]")) {
                                free(exp);
                                return (0);
                        }
@@ -1001,10 +1211,10 @@ cpp_demangle_read_expr_primary(struct cpp_demangle_data 
*ddata)
                switch (*(++ddata->cur)) {
                case '0':
                        ddata->cur += 2;
-                       return (cpp_demangle_push_str(ddata, "false", 5));
+                       return (DEM_PUSH_STR(ddata, "false"));
                case '1':
                        ddata->cur += 2;
-                       return (cpp_demangle_push_str(ddata, "true", 4));
+                       return (DEM_PUSH_STR(ddata, "true"));
                default:
                        return (0);
                }
@@ -1041,7 +1251,7 @@ cpp_demangle_read_expr_primary(struct cpp_demangle_data 
*ddata)
        case 'x':
        case 'y':
                if (*(++ddata->cur) == 'n') {
-                       if (!cpp_demangle_push_str(ddata, "-", 1))
+                       if (!DEM_PUSH_STR(ddata, "-"))
                                return (0);
                        ++ddata->cur;
                }
@@ -1070,11 +1280,11 @@ cpp_demangle_read_expression(struct cpp_demangle_data 
*ddata)
        switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
        case SIMPLE_HASH('s', 't'):
                ddata->cur += 2;
-               return (cpp_demangle_read_type(ddata, 0));
+               return (cpp_demangle_read_type(ddata, NULL));
 
        case SIMPLE_HASH('s', 'r'):
                ddata->cur += 2;
-               if (!cpp_demangle_read_type(ddata, 0))
+               if (!cpp_demangle_read_type(ddata, NULL))
                        return (0);
                if (!cpp_demangle_read_uqname(ddata))
                        return (0);
@@ -1351,8 +1561,7 @@ cpp_demangle_read_expression_flat(struct 
cpp_demangle_data *ddata, char **str)
        size_t i, p_idx, idx, exp_len;
        char *exp;
 
-       output = ddata->push_head > 0 ? &ddata->output_tmp :
-           &ddata->output;
+       output = &ddata->output;
 
        p_idx = output->size;
 
@@ -1429,8 +1638,12 @@ static int
 cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c,
     struct vector_type_qualifier *v)
 {
+       struct type_delimit td;
+       struct read_cmd_item *rc;
        size_t class_type_size, class_type_len, limit;
        const char *class_type;
+       int i;
+       bool paren, non_cv_qualifier;
 
        if (ddata == NULL || *ddata->cur != 'F' || v == NULL)
                return (0);
@@ -1441,12 +1654,43 @@ cpp_demangle_read_function(struct cpp_demangle_data 
*ddata, int *ext_c,
                        *ext_c = 1;
                ++ddata->cur;
        }
-       if (!cpp_demangle_read_type(ddata, 0))
+
+       /* Return type */
+       if (!cpp_demangle_read_type(ddata, NULL))
                return (0);
+
        if (*ddata->cur != 'E') {
-               if (!cpp_demangle_push_str(ddata, "(", 1))
+               if (!DEM_PUSH_STR(ddata, " "))
                        return (0);
-               if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM)) {
+
+               non_cv_qualifier = false;
+               if (v->size > 0) {
+                       for (i = 0; (size_t) i < v->size; i++) {
+                               if (v->q_container[i] != TYPE_RST &&
+                                   v->q_container[i] != TYPE_VAT &&
+                                   v->q_container[i] != TYPE_CST) {
+                                       non_cv_qualifier = true;
+                                       break;
+                               }
+                       }
+               }
+
+               paren = false;
+               rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM);
+               if (non_cv_qualifier || rc != NULL) {
+                       if (!DEM_PUSH_STR(ddata, "("))
+                               return (0);
+                       paren = true;
+               }
+
+               /* Push non-cv qualifiers. */
+               ddata->push_qualifier = PUSH_NON_CV_QUALIFIER;
+               if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
+                       return (0);
+
+               if (rc) {
+                       if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " "))
+                               return (0);
                        if ((class_type_size = ddata->class_type.size) == 0)
                                return (0);
                        class_type =
@@ -1458,42 +1702,69 @@ cpp_demangle_read_function(struct cpp_demangle_data 
*ddata, int *ext_c,
                        if (!cpp_demangle_push_str(ddata, class_type,
                            class_type_len))
                                return (0);
-                       if (!cpp_demangle_push_str(ddata, "::*", 3))
+                       if (!DEM_PUSH_STR(ddata, "::*"))
                                return (0);
-                       ++ddata->func_type;
-               } else {
-                       if (!cpp_demangle_push_type_qualifier(ddata, v,
-                           (const char *) NULL))
-                               return (0);
-                       vector_type_qualifier_dest(v);
-                       if (!vector_type_qualifier_init(v))
+                       /* Push pointer-to-member qualifiers. */
+                       ddata->push_qualifier = PUSH_ALL_QUALIFIER;
+                       if (!cpp_demangle_push_type_qualifier(ddata, rc->data,
+                           NULL))
                                return (0);
+                       ++ddata->func_type;
                }
 
-               if (!cpp_demangle_push_str(ddata, ")(", 2))
-                       return (0);
+               if (paren) {
+                       if (!DEM_PUSH_STR(ddata, ")"))
+                               return (0);
+                       paren = false;
+               }
 
+               td.paren = false;
+               td.firstp = true;
                limit = 0;
+               ddata->is_functype = true;
                for (;;) {
-                       if (!cpp_demangle_read_type(ddata, 0))
+                       if (!cpp_demangle_read_type(ddata, &td))
                                return (0);
                        if (*ddata->cur == 'E')
                                break;
                        if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
                                return (0);
                }
-
-               if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM) == 1) {
-                       if (!cpp_demangle_push_type_qualifier(ddata, v,
-                           (const char *) NULL))
-                               return (0);
-                       vector_type_qualifier_dest(v);
-                       if (!vector_type_qualifier_init(v))
+               ddata->is_functype = false;
+               if (td.paren) {
+                       if (!DEM_PUSH_STR(ddata, ")"))
                                return (0);
+                       td.paren = false;
                }
 
-               if (!cpp_demangle_push_str(ddata, ")", 1))
+               /* Push CV qualifiers. */
+               ddata->push_qualifier = PUSH_CV_QUALIFIER;
+               if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
                        return (0);
+
+               ddata->push_qualifier = PUSH_ALL_QUALIFIER;
+
+               /* Release type qualifier vector. */
+               vector_type_qualifier_dest(v);
+               if (!vector_type_qualifier_init(v))
+                       return (0);
+
+               /* Push ref-qualifiers. */
+               if (ddata->ref_qualifier) {
+                       switch (ddata->ref_qualifier_type) {
+                       case TYPE_REF:
+                               if (!DEM_PUSH_STR(ddata, " &"))
+                                       return (0);
+                               break;
+                       case TYPE_RREF:
+                               if (!DEM_PUSH_STR(ddata, " &&"))
+                                       return (0);
+                               break;
+                       default:
+                               return (0);
+                       }
+                       ddata->ref_qualifier = false;
+               }
        }
 
        ++ddata->cur;
@@ -1515,7 +1786,7 @@ cpp_demangle_read_encoding(struct cpp_demangle_data 
*ddata)
        /* special name */
        switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
        case SIMPLE_HASH('G', 'A'):
-               if (!cpp_demangle_push_str(ddata, "hidden alias for ", 17))
+               if (!DEM_PUSH_STR(ddata, "hidden alias for "))
                        return (0);
                ddata->cur += 2;
                if (*ddata->cur == '\0')
@@ -1523,7 +1794,7 @@ cpp_demangle_read_encoding(struct cpp_demangle_data 
*ddata)
                return (cpp_demangle_read_encoding(ddata));
 
        case SIMPLE_HASH('G', 'R'):
-               if (!cpp_demangle_push_str(ddata, "reference temporary #", 21))
+               if (!DEM_PUSH_STR(ddata, "reference temporary #"))
                        return (0);
                ddata->cur += 2;
                if (*ddata->cur == '\0')
@@ -1533,11 +1804,11 @@ cpp_demangle_read_encoding(struct cpp_demangle_data 
*ddata)
                rtn = 0;
                if (!cpp_demangle_read_number_as_string(ddata, &num_str))
                        goto clean1;
-               if (!cpp_demangle_push_str(ddata, num_str, strlen(num_str)))
+               if (!DEM_PUSH_STR(ddata, num_str))
                        goto clean2;
-               if (!cpp_demangle_push_str(ddata, " for ", 5))
+               if (!DEM_PUSH_STR(ddata, " for "))
                        goto clean2;
-               if (!cpp_demangle_push_str(ddata, name, strlen(name)))
+               if (!DEM_PUSH_STR(ddata, name))
                        goto clean2;
                rtn = 1;
        clean2:
@@ -1552,14 +1823,12 @@ cpp_demangle_read_encoding(struct cpp_demangle_data 
*ddata)
                        return (0);
                switch (*ddata->cur) {
                case 'n':
-                       if (!cpp_demangle_push_str(ddata,
-                           "non-transaction clone for ", 26))
+                       if (!DEM_PUSH_STR(ddata, "non-transaction clone for "))
                                return (0);
                        break;
                case 't':
                default:
-                       if (!cpp_demangle_push_str(ddata,
-                           "transaction clone for ", 22))
+                       if (!DEM_PUSH_STR(ddata, "transaction clone for "))
                                return (0);
*** 1846 LINES SKIPPED ***
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to