Date: Sun, 8 Nov 2020 00:00:49 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r367467 - stable/11/contrib/libcxxrt Message-ID: <202011080000.0A800ns4054909@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Sun Nov 8 00:00:49 2020 New Revision: 367467 URL: https://svnweb.freebsd.org/changeset/base/367467 Log: MFC r367323: Update libcxxrt's private copy of elftoolchain demangler This updates the private copy of libelftc_dem_gnu3.c in libcxxrt with the most recent version from upstream r3877. Similar to r367322, this fixes a number of possible assertions, and allows it to correctly demangle several names that it could not handle before. PR: 250702 MFC r367337: Make vector-related functions in libcxxrt's demangler static Follow-up to r367323 by re-adding static to a number of the functions copied from elftc's libelftc_vstr.c. This was requested by upstream. PR: 250702 Modified: stable/11/contrib/libcxxrt/libelftc_dem_gnu3.c Directory Properties: stable/11/ (props changed) Modified: stable/11/contrib/libcxxrt/libelftc_dem_gnu3.c ============================================================================== --- stable/11/contrib/libcxxrt/libelftc_dem_gnu3.c Sat Nov 7 23:57:57 2020 (r367466) +++ stable/11/contrib/libcxxrt/libelftc_dem_gnu3.c Sun Nov 8 00:00:49 2020 (r367467) @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2007, 2008 Hyogeol Lee <hyogeollee@gmail.com> + * Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com> + * Copyright (c) 2015-2017 Kai Wang <kaiwang27@gmail.com> * 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,35 +79,57 @@ 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 #define FLOAT_SPRINTF_TRY_LIMIT 5 #define FLOAT_QUADRUPLE_BYTES 16 #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, st 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); @@ -342,6 +370,47 @@ vector_str_push_vector_head(struct vector_str *dst, st } /** + * @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. * * If r_len is not NULL, string length will be returned. @@ -387,6 +456,7 @@ static int cpp_demangle_push_fp(struct cpp_demangle_da 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 c 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,14 +534,16 @@ 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) + if (org == NULL || (org_len = strlen(org)) < 2) return (NULL); - org_len = strlen(org); if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { if ((rtn = malloc(org_len + 19)) == NULL) return (NULL); @@ -476,52 +552,100 @@ __cxa_demangle_gnu3(const char *org) 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)) - return (NULL); - if (!cpp_demangle_read_type(&ddata, 0)) - goto clean; - rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); - goto clean; - } + if (org[0] != '_' || org[1] != 'Z') + return (NULL); - 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 && !vector_str_push(&ddata.output, " volatile", 9)) + if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile")) goto clean; - if (ddata.mem_cst && !vector_str_push(&ddata.output, " const", 6)) + if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const")) goto clean; - if (ddata.mem_rst && !vector_str_push(&ddata.output, " restrict", 9)) + if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict")) goto clean; + if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &")) + goto clean; + 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 +662,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 +674,42 @@ cpp_demangle_data_init(struct cpp_demangle_data *d, co 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,13 +754,27 @@ cpp_demangle_push_str(struct cpp_demangle_data *ddata, 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 cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, size_t len) { @@ -677,9 +813,11 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +829,22 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +853,13 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 (!vector_str_push(&subst_v, "&", 1)) + if (!VEC_PUSH_STR(&subst_v, "&")) goto clean; if (!cpp_demangle_push_subst_v(ddata, &subst_v)) @@ -722,11 +867,29 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d } 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 (!VEC_PUSH_STR(&subst_v, "&&")) + goto clean; + if (!cpp_demangle_push_subst_v(ddata, + &subst_v)) + goto clean; + } + 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 +898,13 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +913,9 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +927,13 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +948,22 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +971,22 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +994,22 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +1017,9 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +1030,12 @@ cpp_demangle_push_type_qualifier(struct cpp_demangle_d 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 +1109,10 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddat 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 +1125,13 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddat 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 +1155,11 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddat 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 +1167,7 @@ cpp_demangle_read_array(struct cpp_demangle_data *ddat free(exp); return (0); } - if (!cpp_demangle_push_str(ddata, "]", 1)) { + if (!DEM_PUSH_STR(ddata, "]")) { free(exp); return (0); } @@ -1001,10 +1203,10 @@ cpp_demangle_read_expr_primary(struct cpp_demangle_dat 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 +1243,7 @@ cpp_demangle_read_expr_primary(struct cpp_demangle_dat 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 +1272,11 @@ cpp_demangle_read_expression(struct cpp_demangle_data 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 +1553,7 @@ cpp_demangle_read_expression_flat(struct cpp_demangle_ 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 +1630,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 +1646,43 @@ cpp_demangle_read_function(struct cpp_demangle_data *d *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 +1694,69 @@ cpp_demangle_read_function(struct cpp_demangle_data *d 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); + /* 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; - } else { - if (!cpp_demangle_push_type_qualifier(ddata, v, - (const char *) NULL)) + } + + if (paren) { + if (!DEM_PUSH_STR(ddata, ")")) return (0); - vector_type_qualifier_dest(v); - if (!vector_type_qualifier_init(v)) - return (0); + paren = false; } - if (!cpp_demangle_push_str(ddata, ")(", 2)) - return (0); - + 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)) + ddata->is_functype = false; + if (td.paren) { + if (!DEM_PUSH_STR(ddata, ")")) return (0); - vector_type_qualifier_dest(v); - if (!vector_type_qualifier_init(v)) - 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 +1778,7 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *d /* 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 +1786,7 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *d 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 +1796,11 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *d 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 +1815,12 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *d 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); break; } @@ -1568,15 +1829,15 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *d case SIMPLE_HASH('G', 'V'): /* sentry object for 1 time init */ - if (!cpp_demangle_push_str(ddata, "guard variable for ", 20)) + if (!DEM_PUSH_STR(ddata, "guard variable for ")) return (0); ddata->cur += 2; break; case SIMPLE_HASH('T', 'c'): /* virtual function covariant override thunk */ - if (!cpp_demangle_push_str(ddata, - "virtual function covariant override ", 36)) + if (!DEM_PUSH_STR(ddata, + "virtual function covariant override ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') @@ -1589,8 +1850,7 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *d case SIMPLE_HASH('T', 'C'): /* construction vtable */ - if (!cpp_demangle_push_str(ddata, "construction vtable for ", - 24)) + if (!DEM_PUSH_STR(ddata, "construction vtable for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') @@ -1602,11 +1862,11 @@ cpp_demangle_read_encoding(struct cpp_demangle_data *d goto clean3; if (*ddata->cur++ != '_') *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202011080000.0A800ns4054909>