14cc2045aSjoerg /*-
2*d678c5d4Sjoerg * Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com>
3*d678c5d4Sjoerg * Copyright (c) 2015-2017 Kai Wang <kaiwang27@gmail.com>
44cc2045aSjoerg * All rights reserved.
54cc2045aSjoerg *
64cc2045aSjoerg * Redistribution and use in source and binary forms, with or without
74cc2045aSjoerg * modification, are permitted provided that the following conditions
84cc2045aSjoerg * are met:
94cc2045aSjoerg * 1. Redistributions of source code must retain the above copyright
104cc2045aSjoerg * notice, this list of conditions and the following disclaimer
114cc2045aSjoerg * in this position and unchanged.
124cc2045aSjoerg * 2. Redistributions in binary form must reproduce the above copyright
134cc2045aSjoerg * notice, this list of conditions and the following disclaimer in the
144cc2045aSjoerg * documentation and/or other materials provided with the distribution.
154cc2045aSjoerg *
164cc2045aSjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
174cc2045aSjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
184cc2045aSjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
194cc2045aSjoerg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
204cc2045aSjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
214cc2045aSjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
224cc2045aSjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
234cc2045aSjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
244cc2045aSjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
254cc2045aSjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
264cc2045aSjoerg */
274cc2045aSjoerg #include <sys/types.h>
284cc2045aSjoerg #include <assert.h>
294cc2045aSjoerg #include <ctype.h>
304cc2045aSjoerg #include <errno.h>
314cc2045aSjoerg #include <limits.h>
324cc2045aSjoerg #include <stdbool.h>
334cc2045aSjoerg #include <stdio.h>
344cc2045aSjoerg #include <stdlib.h>
354cc2045aSjoerg #include <string.h>
364cc2045aSjoerg
374cc2045aSjoerg /**
384cc2045aSjoerg * @file cpp_demangle.c
394cc2045aSjoerg * @brief Decode IA-64 C++ ABI style implementation.
404cc2045aSjoerg *
414cc2045aSjoerg * IA-64 standard ABI(Itanium C++ ABI) references.
424cc2045aSjoerg *
434cc2045aSjoerg * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n
444cc2045aSjoerg * http://www.codesourcery.com/cxx-abi/abi-mangling.html
454cc2045aSjoerg */
464cc2045aSjoerg
474cc2045aSjoerg /** @brief Dynamic vector data for string. */
484cc2045aSjoerg struct vector_str {
494cc2045aSjoerg /** Current size */
504cc2045aSjoerg size_t size;
514cc2045aSjoerg /** Total capacity */
524cc2045aSjoerg size_t capacity;
534cc2045aSjoerg /** String array */
544cc2045aSjoerg char **container;
554cc2045aSjoerg };
564cc2045aSjoerg
574cc2045aSjoerg #define BUFFER_GROWFACTOR 1.618
58*d678c5d4Sjoerg #define BUFFER_GROW(x) (((x)+0.5)*BUFFER_GROWFACTOR)
59*d678c5d4Sjoerg
60*d678c5d4Sjoerg #define ELFTC_FAILURE 0
614cc2045aSjoerg #define ELFTC_ISDIGIT(C) (isdigit((C) & 0xFF))
62*d678c5d4Sjoerg #define ELFTC_SUCCESS 1
63*d678c5d4Sjoerg
64*d678c5d4Sjoerg #define VECTOR_DEF_CAPACITY 8
654cc2045aSjoerg
664cc2045aSjoerg enum type_qualifier {
674cc2045aSjoerg TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT,
68*d678c5d4Sjoerg TYPE_CST, TYPE_VEC, TYPE_RREF
694cc2045aSjoerg };
704cc2045aSjoerg
714cc2045aSjoerg struct vector_type_qualifier {
724cc2045aSjoerg size_t size, capacity;
734cc2045aSjoerg enum type_qualifier *q_container;
744cc2045aSjoerg struct vector_str ext_name;
754cc2045aSjoerg };
764cc2045aSjoerg
774cc2045aSjoerg enum read_cmd {
784cc2045aSjoerg READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL,
794cc2045aSjoerg READ_TYPE, READ_FUNC, READ_PTRMEM
804cc2045aSjoerg };
814cc2045aSjoerg
82*d678c5d4Sjoerg struct read_cmd_item {
83*d678c5d4Sjoerg enum read_cmd cmd;
84*d678c5d4Sjoerg void *data;
85*d678c5d4Sjoerg };
86*d678c5d4Sjoerg
874cc2045aSjoerg struct vector_read_cmd {
884cc2045aSjoerg size_t size, capacity;
89*d678c5d4Sjoerg struct read_cmd_item *r_container;
90*d678c5d4Sjoerg };
91*d678c5d4Sjoerg
92*d678c5d4Sjoerg enum push_qualifier {
93*d678c5d4Sjoerg PUSH_ALL_QUALIFIER,
94*d678c5d4Sjoerg PUSH_CV_QUALIFIER,
95*d678c5d4Sjoerg PUSH_NON_CV_QUALIFIER,
964cc2045aSjoerg };
974cc2045aSjoerg
984cc2045aSjoerg struct cpp_demangle_data {
994cc2045aSjoerg struct vector_str output; /* output string vector */
1004cc2045aSjoerg struct vector_str subst; /* substitution string vector */
1014cc2045aSjoerg struct vector_str tmpl;
1024cc2045aSjoerg struct vector_str class_type;
103*d678c5d4Sjoerg struct vector_str *cur_output; /* ptr to current output vec */
1044cc2045aSjoerg struct vector_read_cmd cmd;
1054cc2045aSjoerg bool mem_rst; /* restrict member function */
1064cc2045aSjoerg bool mem_vat; /* volatile member function */
1074cc2045aSjoerg bool mem_cst; /* const member function */
108*d678c5d4Sjoerg bool mem_ref; /* lvalue-ref member func */
109*d678c5d4Sjoerg bool mem_rref; /* rvalue-ref member func */
110*d678c5d4Sjoerg bool is_tmpl; /* template args */
111*d678c5d4Sjoerg bool is_functype; /* function type */
112*d678c5d4Sjoerg bool ref_qualifier; /* ref qualifier */
113*d678c5d4Sjoerg enum type_qualifier ref_qualifier_type; /* ref qualifier type */
114*d678c5d4Sjoerg enum push_qualifier push_qualifier; /* which qualifiers to push */
1154cc2045aSjoerg int func_type;
1164cc2045aSjoerg const char *cur; /* current mangled name ptr */
1174cc2045aSjoerg const char *last_sname; /* last source name */
118*d678c5d4Sjoerg };
119*d678c5d4Sjoerg
120*d678c5d4Sjoerg struct type_delimit {
121*d678c5d4Sjoerg bool paren;
122*d678c5d4Sjoerg bool firstp;
1234cc2045aSjoerg };
1244cc2045aSjoerg
1254cc2045aSjoerg #define CPP_DEMANGLE_TRY_LIMIT 128
1264cc2045aSjoerg #define FLOAT_SPRINTF_TRY_LIMIT 5
1274cc2045aSjoerg #define FLOAT_QUADRUPLE_BYTES 16
1284cc2045aSjoerg #define FLOAT_EXTENED_BYTES 10
1294cc2045aSjoerg
1304cc2045aSjoerg #define SIMPLE_HASH(x,y) (64 * x + y)
131*d678c5d4Sjoerg #define DEM_PUSH_STR(d,s) cpp_demangle_push_str((d), (s), strlen((s)))
132*d678c5d4Sjoerg #define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s)))
1334cc2045aSjoerg
1344cc2045aSjoerg static size_t get_strlen_sum(const struct vector_str *v);
1354cc2045aSjoerg static bool vector_str_grow(struct vector_str *v);
1364cc2045aSjoerg
1374cc2045aSjoerg static size_t
get_strlen_sum(const struct vector_str * v)1384cc2045aSjoerg get_strlen_sum(const struct vector_str *v)
1394cc2045aSjoerg {
1404cc2045aSjoerg size_t i, len = 0;
1414cc2045aSjoerg
1424cc2045aSjoerg if (v == NULL)
1434cc2045aSjoerg return (0);
1444cc2045aSjoerg
1454cc2045aSjoerg assert(v->size > 0);
1464cc2045aSjoerg
1474cc2045aSjoerg for (i = 0; i < v->size; ++i)
1484cc2045aSjoerg len += strlen(v->container[i]);
1494cc2045aSjoerg
1504cc2045aSjoerg return (len);
1514cc2045aSjoerg }
1524cc2045aSjoerg
1534cc2045aSjoerg /**
1544cc2045aSjoerg * @brief Deallocate resource in vector_str.
1554cc2045aSjoerg */
1564cc2045aSjoerg static void
vector_str_dest(struct vector_str * v)1574cc2045aSjoerg vector_str_dest(struct vector_str *v)
1584cc2045aSjoerg {
1594cc2045aSjoerg size_t i;
1604cc2045aSjoerg
1614cc2045aSjoerg if (v == NULL)
1624cc2045aSjoerg return;
1634cc2045aSjoerg
1644cc2045aSjoerg for (i = 0; i < v->size; ++i)
1654cc2045aSjoerg free(v->container[i]);
1664cc2045aSjoerg
1674cc2045aSjoerg free(v->container);
1684cc2045aSjoerg }
1694cc2045aSjoerg
1704cc2045aSjoerg /**
1714cc2045aSjoerg * @brief Find string in vector_str.
1724cc2045aSjoerg * @param v Destination vector.
1734cc2045aSjoerg * @param o String to find.
1744cc2045aSjoerg * @param l Length of the string.
1754cc2045aSjoerg * @return -1 at failed, 0 at not found, 1 at found.
1764cc2045aSjoerg */
1774cc2045aSjoerg static int
vector_str_find(const struct vector_str * v,const char * o,size_t l)1784cc2045aSjoerg vector_str_find(const struct vector_str *v, const char *o, size_t l)
1794cc2045aSjoerg {
1804cc2045aSjoerg size_t i;
1814cc2045aSjoerg
1824cc2045aSjoerg if (v == NULL || o == NULL)
1834cc2045aSjoerg return (-1);
1844cc2045aSjoerg
1854cc2045aSjoerg for (i = 0; i < v->size; ++i)
1864cc2045aSjoerg if (strncmp(v->container[i], o, l) == 0)
1874cc2045aSjoerg return (1);
1884cc2045aSjoerg
1894cc2045aSjoerg return (0);
1904cc2045aSjoerg }
1914cc2045aSjoerg
1924cc2045aSjoerg /**
1934cc2045aSjoerg * @brief Get new allocated flat string from vector.
1944cc2045aSjoerg *
1954cc2045aSjoerg * If l is not NULL, return length of the string.
1964cc2045aSjoerg * @param v Destination vector.
1974cc2045aSjoerg * @param l Length of the string.
1984cc2045aSjoerg * @return NULL at failed or NUL terminated new allocated string.
1994cc2045aSjoerg */
2004cc2045aSjoerg static char *
vector_str_get_flat(const struct vector_str * v,size_t * l)2014cc2045aSjoerg vector_str_get_flat(const struct vector_str *v, size_t *l)
2024cc2045aSjoerg {
2034cc2045aSjoerg ssize_t elem_pos, elem_size, rtn_size;
2044cc2045aSjoerg size_t i;
2054cc2045aSjoerg char *rtn;
2064cc2045aSjoerg
2074cc2045aSjoerg if (v == NULL || v->size == 0)
2084cc2045aSjoerg return (NULL);
2094cc2045aSjoerg
2104cc2045aSjoerg if ((rtn_size = get_strlen_sum(v)) == 0)
2114cc2045aSjoerg return (NULL);
2124cc2045aSjoerg
2134cc2045aSjoerg if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL)
2144cc2045aSjoerg return (NULL);
2154cc2045aSjoerg
2164cc2045aSjoerg elem_pos = 0;
2174cc2045aSjoerg for (i = 0; i < v->size; ++i) {
2184cc2045aSjoerg elem_size = strlen(v->container[i]);
2194cc2045aSjoerg
2204cc2045aSjoerg memcpy(rtn + elem_pos, v->container[i], elem_size);
2214cc2045aSjoerg
2224cc2045aSjoerg elem_pos += elem_size;
2234cc2045aSjoerg }
2244cc2045aSjoerg
2254cc2045aSjoerg rtn[rtn_size] = '\0';
2264cc2045aSjoerg
2274cc2045aSjoerg if (l != NULL)
2284cc2045aSjoerg *l = rtn_size;
2294cc2045aSjoerg
2304cc2045aSjoerg return (rtn);
2314cc2045aSjoerg }
2324cc2045aSjoerg
2334cc2045aSjoerg static bool
vector_str_grow(struct vector_str * v)2344cc2045aSjoerg vector_str_grow(struct vector_str *v)
2354cc2045aSjoerg {
2364cc2045aSjoerg size_t i, tmp_cap;
2374cc2045aSjoerg char **tmp_ctn;
2384cc2045aSjoerg
2394cc2045aSjoerg if (v == NULL)
2404cc2045aSjoerg return (false);
2414cc2045aSjoerg
2424cc2045aSjoerg assert(v->capacity > 0);
2434cc2045aSjoerg
244*d678c5d4Sjoerg tmp_cap = BUFFER_GROW(v->capacity);
2454cc2045aSjoerg
2464cc2045aSjoerg assert(tmp_cap > v->capacity);
2474cc2045aSjoerg
2484cc2045aSjoerg if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
2494cc2045aSjoerg return (false);
2504cc2045aSjoerg
2514cc2045aSjoerg for (i = 0; i < v->size; ++i)
2524cc2045aSjoerg tmp_ctn[i] = v->container[i];
2534cc2045aSjoerg
2544cc2045aSjoerg free(v->container);
2554cc2045aSjoerg
2564cc2045aSjoerg v->container = tmp_ctn;
2574cc2045aSjoerg v->capacity = tmp_cap;
2584cc2045aSjoerg
2594cc2045aSjoerg return (true);
2604cc2045aSjoerg }
2614cc2045aSjoerg
2624cc2045aSjoerg /**
2634cc2045aSjoerg * @brief Initialize vector_str.
2644cc2045aSjoerg * @return false at failed, true at success.
2654cc2045aSjoerg */
2664cc2045aSjoerg static bool
vector_str_init(struct vector_str * v)2674cc2045aSjoerg vector_str_init(struct vector_str *v)
2684cc2045aSjoerg {
2694cc2045aSjoerg
2704cc2045aSjoerg if (v == NULL)
2714cc2045aSjoerg return (false);
2724cc2045aSjoerg
2734cc2045aSjoerg v->size = 0;
2744cc2045aSjoerg v->capacity = VECTOR_DEF_CAPACITY;
2754cc2045aSjoerg
2764cc2045aSjoerg assert(v->capacity > 0);
2774cc2045aSjoerg
2784cc2045aSjoerg if ((v->container = malloc(sizeof(char *) * v->capacity)) == NULL)
2794cc2045aSjoerg return (false);
2804cc2045aSjoerg
2814cc2045aSjoerg assert(v->container != NULL);
2824cc2045aSjoerg
2834cc2045aSjoerg return (true);
2844cc2045aSjoerg }
2854cc2045aSjoerg
2864cc2045aSjoerg /**
2874cc2045aSjoerg * @brief Remove last element in vector_str.
2884cc2045aSjoerg * @return false at failed, true at success.
2894cc2045aSjoerg */
2904cc2045aSjoerg static bool
vector_str_pop(struct vector_str * v)2914cc2045aSjoerg vector_str_pop(struct vector_str *v)
2924cc2045aSjoerg {
2934cc2045aSjoerg
2944cc2045aSjoerg if (v == NULL)
2954cc2045aSjoerg return (false);
2964cc2045aSjoerg
2974cc2045aSjoerg if (v->size == 0)
2984cc2045aSjoerg return (true);
2994cc2045aSjoerg
3004cc2045aSjoerg --v->size;
3014cc2045aSjoerg
3024cc2045aSjoerg free(v->container[v->size]);
3034cc2045aSjoerg v->container[v->size] = NULL;
3044cc2045aSjoerg
3054cc2045aSjoerg return (true);
3064cc2045aSjoerg }
3074cc2045aSjoerg
3084cc2045aSjoerg /**
3094cc2045aSjoerg * @brief Push back string to vector.
3104cc2045aSjoerg * @return false at failed, true at success.
3114cc2045aSjoerg */
3124cc2045aSjoerg static bool
vector_str_push(struct vector_str * v,const char * str,size_t len)3134cc2045aSjoerg vector_str_push(struct vector_str *v, const char *str, size_t len)
3144cc2045aSjoerg {
3154cc2045aSjoerg
3164cc2045aSjoerg if (v == NULL || str == NULL)
3174cc2045aSjoerg return (false);
3184cc2045aSjoerg
3194cc2045aSjoerg if (v->size == v->capacity && vector_str_grow(v) == false)
3204cc2045aSjoerg return (false);
3214cc2045aSjoerg
3224cc2045aSjoerg if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL)
3234cc2045aSjoerg return (false);
3244cc2045aSjoerg
3254cc2045aSjoerg snprintf(v->container[v->size], len + 1, "%s", str);
3264cc2045aSjoerg
3274cc2045aSjoerg ++v->size;
3284cc2045aSjoerg
3294cc2045aSjoerg return (true);
3304cc2045aSjoerg }
3314cc2045aSjoerg
3324cc2045aSjoerg /**
3334cc2045aSjoerg * @brief Push front org vector to det vector.
3344cc2045aSjoerg * @return false at failed, true at success.
3354cc2045aSjoerg */
3364cc2045aSjoerg static bool
vector_str_push_vector_head(struct vector_str * dst,struct vector_str * org)3374cc2045aSjoerg vector_str_push_vector_head(struct vector_str *dst, struct vector_str *org)
3384cc2045aSjoerg {
3394cc2045aSjoerg size_t i, j, tmp_cap;
3404cc2045aSjoerg char **tmp_ctn;
3414cc2045aSjoerg
3424cc2045aSjoerg if (dst == NULL || org == NULL)
3434cc2045aSjoerg return (false);
3444cc2045aSjoerg
345*d678c5d4Sjoerg tmp_cap = BUFFER_GROW(dst->size + org->size);
3464cc2045aSjoerg
3474cc2045aSjoerg if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
3484cc2045aSjoerg return (false);
3494cc2045aSjoerg
3504cc2045aSjoerg for (i = 0; i < org->size; ++i)
3514cc2045aSjoerg if ((tmp_ctn[i] = strdup(org->container[i])) == NULL) {
3524cc2045aSjoerg for (j = 0; j < i; ++j)
3534cc2045aSjoerg free(tmp_ctn[j]);
3544cc2045aSjoerg
3554cc2045aSjoerg free(tmp_ctn);
3564cc2045aSjoerg
3574cc2045aSjoerg return (false);
3584cc2045aSjoerg }
3594cc2045aSjoerg
3604cc2045aSjoerg for (i = 0; i < dst->size; ++i)
3614cc2045aSjoerg tmp_ctn[i + org->size] = dst->container[i];
3624cc2045aSjoerg
3634cc2045aSjoerg free(dst->container);
3644cc2045aSjoerg
3654cc2045aSjoerg dst->container = tmp_ctn;
3664cc2045aSjoerg dst->capacity = tmp_cap;
3674cc2045aSjoerg dst->size += org->size;
3684cc2045aSjoerg
3694cc2045aSjoerg return (true);
3704cc2045aSjoerg }
3714cc2045aSjoerg
3724cc2045aSjoerg /**
373*d678c5d4Sjoerg * @brief Push org vector to the tail of det vector.
374*d678c5d4Sjoerg * @return false at failed, true at success.
375*d678c5d4Sjoerg */
376*d678c5d4Sjoerg static bool
vector_str_push_vector(struct vector_str * dst,struct vector_str * org)377*d678c5d4Sjoerg vector_str_push_vector(struct vector_str *dst, struct vector_str *org)
378*d678c5d4Sjoerg {
379*d678c5d4Sjoerg size_t i, j, tmp_cap;
380*d678c5d4Sjoerg char **tmp_ctn;
381*d678c5d4Sjoerg
382*d678c5d4Sjoerg if (dst == NULL || org == NULL)
383*d678c5d4Sjoerg return (false);
384*d678c5d4Sjoerg
385*d678c5d4Sjoerg tmp_cap = BUFFER_GROW(dst->size + org->size);
386*d678c5d4Sjoerg
387*d678c5d4Sjoerg if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
388*d678c5d4Sjoerg return (false);
389*d678c5d4Sjoerg
390*d678c5d4Sjoerg for (i = 0; i < dst->size; ++i)
391*d678c5d4Sjoerg tmp_ctn[i] = dst->container[i];
392*d678c5d4Sjoerg
393*d678c5d4Sjoerg for (i = 0; i < org->size; ++i)
394*d678c5d4Sjoerg if ((tmp_ctn[i + dst->size] = strdup(org->container[i])) ==
395*d678c5d4Sjoerg NULL) {
396*d678c5d4Sjoerg for (j = 0; j < i + dst->size; ++j)
397*d678c5d4Sjoerg free(tmp_ctn[j]);
398*d678c5d4Sjoerg
399*d678c5d4Sjoerg free(tmp_ctn);
400*d678c5d4Sjoerg
401*d678c5d4Sjoerg return (false);
402*d678c5d4Sjoerg }
403*d678c5d4Sjoerg
404*d678c5d4Sjoerg free(dst->container);
405*d678c5d4Sjoerg
406*d678c5d4Sjoerg dst->container = tmp_ctn;
407*d678c5d4Sjoerg dst->capacity = tmp_cap;
408*d678c5d4Sjoerg dst->size += org->size;
409*d678c5d4Sjoerg
410*d678c5d4Sjoerg return (true);
411*d678c5d4Sjoerg }
412*d678c5d4Sjoerg
413*d678c5d4Sjoerg /**
4144cc2045aSjoerg * @brief Get new allocated flat string from vector between begin and end.
4154cc2045aSjoerg *
4164cc2045aSjoerg * If r_len is not NULL, string length will be returned.
4174cc2045aSjoerg * @return NULL at failed or NUL terminated new allocated string.
4184cc2045aSjoerg */
4194cc2045aSjoerg static char *
vector_str_substr(const struct vector_str * v,size_t begin,size_t end,size_t * r_len)4204cc2045aSjoerg vector_str_substr(const struct vector_str *v, size_t begin, size_t end,
4214cc2045aSjoerg size_t *r_len)
4224cc2045aSjoerg {
4234cc2045aSjoerg size_t cur, i, len;
4244cc2045aSjoerg char *rtn;
4254cc2045aSjoerg
4264cc2045aSjoerg if (v == NULL || begin > end)
4274cc2045aSjoerg return (NULL);
4284cc2045aSjoerg
4294cc2045aSjoerg len = 0;
4304cc2045aSjoerg for (i = begin; i < end + 1; ++i)
4314cc2045aSjoerg len += strlen(v->container[i]);
4324cc2045aSjoerg
4334cc2045aSjoerg if ((rtn = malloc(sizeof(char) * (len + 1))) == NULL)
4344cc2045aSjoerg return (NULL);
4354cc2045aSjoerg
4364cc2045aSjoerg if (r_len != NULL)
4374cc2045aSjoerg *r_len = len;
4384cc2045aSjoerg
4394cc2045aSjoerg cur = 0;
4404cc2045aSjoerg for (i = begin; i < end + 1; ++i) {
4414cc2045aSjoerg len = strlen(v->container[i]);
4424cc2045aSjoerg memcpy(rtn + cur, v->container[i], len);
4434cc2045aSjoerg cur += len;
4444cc2045aSjoerg }
4454cc2045aSjoerg rtn[cur] = '\0';
4464cc2045aSjoerg
4474cc2045aSjoerg return (rtn);
4484cc2045aSjoerg }
4494cc2045aSjoerg
4504cc2045aSjoerg static void cpp_demangle_data_dest(struct cpp_demangle_data *);
4514cc2045aSjoerg static int cpp_demangle_data_init(struct cpp_demangle_data *,
4524cc2045aSjoerg const char *);
4534cc2045aSjoerg static int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t);
4544cc2045aSjoerg static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t);
4554cc2045aSjoerg static int cpp_demangle_push_fp(struct cpp_demangle_data *,
4564cc2045aSjoerg char *(*)(const char *, size_t));
4574cc2045aSjoerg static int cpp_demangle_push_str(struct cpp_demangle_data *, const char *,
4584cc2045aSjoerg size_t);
459*d678c5d4Sjoerg static int cpp_demangle_pop_str(struct cpp_demangle_data *);
4604cc2045aSjoerg static int cpp_demangle_push_subst(struct cpp_demangle_data *,
4614cc2045aSjoerg const char *, size_t);
4624cc2045aSjoerg static int cpp_demangle_push_subst_v(struct cpp_demangle_data *,
4634cc2045aSjoerg struct vector_str *);
4644cc2045aSjoerg static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *,
4654cc2045aSjoerg struct vector_type_qualifier *, const char *);
4664cc2045aSjoerg static int cpp_demangle_read_array(struct cpp_demangle_data *);
4674cc2045aSjoerg static int cpp_demangle_read_encoding(struct cpp_demangle_data *);
4684cc2045aSjoerg static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *);
4694cc2045aSjoerg static int cpp_demangle_read_expression(struct cpp_demangle_data *);
47086b377d0Spooka static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *,
47186b377d0Spooka char **);
4724cc2045aSjoerg static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *,
4734cc2045aSjoerg const char *, size_t);
4744cc2045aSjoerg static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *,
4754cc2045aSjoerg const char *, size_t);
4764cc2045aSjoerg static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *,
4774cc2045aSjoerg const char *, size_t, const char *, size_t);
4784cc2045aSjoerg static int cpp_demangle_read_function(struct cpp_demangle_data *, int *,
4794cc2045aSjoerg struct vector_type_qualifier *);
4805192b81bSjoerg static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata);
4814cc2045aSjoerg static int cpp_demangle_read_local_name(struct cpp_demangle_data *);
4824cc2045aSjoerg static int cpp_demangle_read_name(struct cpp_demangle_data *);
48386b377d0Spooka static int cpp_demangle_read_name_flat(struct cpp_demangle_data *,
48486b377d0Spooka char**);
4854cc2045aSjoerg static int cpp_demangle_read_nested_name(struct cpp_demangle_data *);
4864cc2045aSjoerg static int cpp_demangle_read_number(struct cpp_demangle_data *, long *);
48786b377d0Spooka static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *,
48886b377d0Spooka char **);
4894cc2045aSjoerg static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *);
4904cc2045aSjoerg static int cpp_demangle_read_offset(struct cpp_demangle_data *);
4914cc2045aSjoerg static int cpp_demangle_read_offset_number(struct cpp_demangle_data *);
492*d678c5d4Sjoerg static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *,
493*d678c5d4Sjoerg struct vector_type_qualifier *);
4944cc2045aSjoerg static int cpp_demangle_read_sname(struct cpp_demangle_data *);
4954cc2045aSjoerg static int cpp_demangle_read_subst(struct cpp_demangle_data *);
4964cc2045aSjoerg static int cpp_demangle_read_subst_std(struct cpp_demangle_data *);
4974cc2045aSjoerg static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *,
498*d678c5d4Sjoerg const char *);
4994cc2045aSjoerg static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *);
5004cc2045aSjoerg static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);
5014cc2045aSjoerg static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);
502*d678c5d4Sjoerg static int cpp_demangle_read_type(struct cpp_demangle_data *,
503*d678c5d4Sjoerg struct type_delimit *);
50486b377d0Spooka static int cpp_demangle_read_type_flat(struct cpp_demangle_data *,
50586b377d0Spooka char **);
5064cc2045aSjoerg static int cpp_demangle_read_uqname(struct cpp_demangle_data *);
5074cc2045aSjoerg static int cpp_demangle_read_v_offset(struct cpp_demangle_data *);
5084cc2045aSjoerg static char *decode_fp_to_double(const char *, size_t);
5094cc2045aSjoerg static char *decode_fp_to_float(const char *, size_t);
5104cc2045aSjoerg static char *decode_fp_to_float128(const char *, size_t);
5114cc2045aSjoerg static char *decode_fp_to_float80(const char *, size_t);
5124cc2045aSjoerg static char *decode_fp_to_long_double(const char *, size_t);
5134cc2045aSjoerg static int hex_to_dec(char);
5144cc2045aSjoerg static void vector_read_cmd_dest(struct vector_read_cmd *);
515*d678c5d4Sjoerg static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *,
516*d678c5d4Sjoerg enum read_cmd);
5174cc2045aSjoerg static int vector_read_cmd_init(struct vector_read_cmd *);
5184cc2045aSjoerg static int vector_read_cmd_pop(struct vector_read_cmd *);
519*d678c5d4Sjoerg static int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd,
520*d678c5d4Sjoerg void *);
5214cc2045aSjoerg static void vector_type_qualifier_dest(struct vector_type_qualifier *);
5224cc2045aSjoerg static int vector_type_qualifier_init(struct vector_type_qualifier *);
5234cc2045aSjoerg static int vector_type_qualifier_push(struct vector_type_qualifier *,
5244cc2045aSjoerg enum type_qualifier);
5254cc2045aSjoerg
5264cc2045aSjoerg /**
5274cc2045aSjoerg * @brief Decode the input string by IA-64 C++ ABI style.
5284cc2045aSjoerg *
5294cc2045aSjoerg * GNU GCC v3 use IA-64 standard ABI.
5304cc2045aSjoerg * @return New allocated demangled string or NULL if failed.
5314cc2045aSjoerg * @todo 1. Testing and more test case. 2. Code cleaning.
5324cc2045aSjoerg */
5334cc2045aSjoerg char *
__cxa_demangle_gnu3(const char * org)5344cc2045aSjoerg __cxa_demangle_gnu3(const char *org)
5354cc2045aSjoerg {
5364cc2045aSjoerg struct cpp_demangle_data ddata;
537*d678c5d4Sjoerg struct vector_str ret_type;
538*d678c5d4Sjoerg struct type_delimit td;
5394cc2045aSjoerg ssize_t org_len;
5404cc2045aSjoerg unsigned int limit;
541*d678c5d4Sjoerg char *rtn;
542*d678c5d4Sjoerg bool has_ret, more_type;
5434cc2045aSjoerg
5444cc2045aSjoerg if (org == NULL)
5454cc2045aSjoerg return (NULL);
5464cc2045aSjoerg
5475192b81bSjoerg org_len = strlen(org);
5485192b81bSjoerg // Try demangling as a type for short encodings
5495192b81bSjoerg if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) {
5505192b81bSjoerg if (!cpp_demangle_data_init(&ddata, org))
5515192b81bSjoerg return (NULL);
5525192b81bSjoerg if (!cpp_demangle_read_type(&ddata, 0))
5535192b81bSjoerg goto clean;
5545192b81bSjoerg rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
5555192b81bSjoerg goto clean;
5565192b81bSjoerg }
557*d678c5d4Sjoerg if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
558*d678c5d4Sjoerg if ((rtn = malloc(org_len + 19)) == NULL)
559*d678c5d4Sjoerg return (NULL);
560*d678c5d4Sjoerg snprintf(rtn, org_len + 19,
561*d678c5d4Sjoerg "global constructors keyed to %s", org + 11);
562*d678c5d4Sjoerg return (rtn);
563*d678c5d4Sjoerg }
5645192b81bSjoerg
5654cc2045aSjoerg
5664cc2045aSjoerg if (!cpp_demangle_data_init(&ddata, org + 2))
5674cc2045aSjoerg return (NULL);
5684cc2045aSjoerg
5694cc2045aSjoerg rtn = NULL;
570*d678c5d4Sjoerg has_ret = more_type = false;
5714cc2045aSjoerg
5724cc2045aSjoerg if (!cpp_demangle_read_encoding(&ddata))
5734cc2045aSjoerg goto clean;
5744cc2045aSjoerg
575*d678c5d4Sjoerg /*
576*d678c5d4Sjoerg * Pop function name from substitution candidate list.
577*d678c5d4Sjoerg */
578*d678c5d4Sjoerg if (*ddata.cur != 0 && ddata.subst.size >= 1) {
579*d678c5d4Sjoerg if (!vector_str_pop(&ddata.subst))
580*d678c5d4Sjoerg goto clean;
581*d678c5d4Sjoerg }
582*d678c5d4Sjoerg
583*d678c5d4Sjoerg td.paren = false;
584*d678c5d4Sjoerg td.firstp = true;
5854cc2045aSjoerg limit = 0;
586*d678c5d4Sjoerg
587*d678c5d4Sjoerg /*
588*d678c5d4Sjoerg * The first type is a return type if we just demangled template
589*d678c5d4Sjoerg * args. (the template args is right next to the function name,
590*d678c5d4Sjoerg * which means it's a template function)
591*d678c5d4Sjoerg */
592*d678c5d4Sjoerg if (ddata.is_tmpl) {
593*d678c5d4Sjoerg ddata.is_tmpl = false;
594*d678c5d4Sjoerg if (!vector_str_init(&ret_type))
595*d678c5d4Sjoerg goto clean;
596*d678c5d4Sjoerg ddata.cur_output = &ret_type;
597*d678c5d4Sjoerg has_ret = true;
598*d678c5d4Sjoerg }
599*d678c5d4Sjoerg
6004cc2045aSjoerg while (*ddata.cur != '\0') {
6014cc2045aSjoerg /*
6024cc2045aSjoerg * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4
6034cc2045aSjoerg */
6044cc2045aSjoerg if (*ddata.cur == '@' && *(ddata.cur + 1) == '@')
6054cc2045aSjoerg break;
606*d678c5d4Sjoerg
607*d678c5d4Sjoerg if (has_ret) {
608*d678c5d4Sjoerg /* Read return type */
609*d678c5d4Sjoerg if (!cpp_demangle_read_type(&ddata, NULL))
6104cc2045aSjoerg goto clean;
611*d678c5d4Sjoerg } else {
612*d678c5d4Sjoerg /* Read function arg type */
613*d678c5d4Sjoerg if (!cpp_demangle_read_type(&ddata, &td))
6144cc2045aSjoerg goto clean;
6154cc2045aSjoerg }
6164cc2045aSjoerg
617*d678c5d4Sjoerg if (has_ret) {
618*d678c5d4Sjoerg /* Push return type to the beginning */
619*d678c5d4Sjoerg if (!VEC_PUSH_STR(&ret_type, " "))
620*d678c5d4Sjoerg goto clean;
621*d678c5d4Sjoerg if (!vector_str_push_vector_head(&ddata.output,
622*d678c5d4Sjoerg &ret_type))
623*d678c5d4Sjoerg goto clean;
624*d678c5d4Sjoerg ddata.cur_output = &ddata.output;
625*d678c5d4Sjoerg vector_str_dest(&ret_type);
626*d678c5d4Sjoerg has_ret = false;
627*d678c5d4Sjoerg more_type = true;
628*d678c5d4Sjoerg } else if (more_type)
629*d678c5d4Sjoerg more_type = false;
630*d678c5d4Sjoerg if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
631*d678c5d4Sjoerg goto clean;
632*d678c5d4Sjoerg }
633*d678c5d4Sjoerg if (more_type)
634*d678c5d4Sjoerg goto clean;
635*d678c5d4Sjoerg
6364cc2045aSjoerg if (ddata.output.size == 0)
6374cc2045aSjoerg goto clean;
638*d678c5d4Sjoerg if (td.paren && !VEC_PUSH_STR(&ddata.output, ")"))
6394cc2045aSjoerg goto clean;
640*d678c5d4Sjoerg if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile"))
6414cc2045aSjoerg goto clean;
642*d678c5d4Sjoerg if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const"))
6434cc2045aSjoerg goto clean;
644*d678c5d4Sjoerg if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict"))
645*d678c5d4Sjoerg goto clean;
646*d678c5d4Sjoerg if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &"))
647*d678c5d4Sjoerg goto clean;
648*d678c5d4Sjoerg if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&"))
6494cc2045aSjoerg goto clean;
6504cc2045aSjoerg
6514cc2045aSjoerg rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
6524cc2045aSjoerg
6534cc2045aSjoerg clean:
654*d678c5d4Sjoerg if (has_ret)
655*d678c5d4Sjoerg vector_str_dest(&ret_type);
656*d678c5d4Sjoerg
6574cc2045aSjoerg cpp_demangle_data_dest(&ddata);
6584cc2045aSjoerg
6594cc2045aSjoerg return (rtn);
6604cc2045aSjoerg }
6614cc2045aSjoerg
6624cc2045aSjoerg static void
cpp_demangle_data_dest(struct cpp_demangle_data * d)6634cc2045aSjoerg cpp_demangle_data_dest(struct cpp_demangle_data *d)
6644cc2045aSjoerg {
6654cc2045aSjoerg
6664cc2045aSjoerg if (d == NULL)
6674cc2045aSjoerg return;
6684cc2045aSjoerg
6694cc2045aSjoerg vector_read_cmd_dest(&d->cmd);
6704cc2045aSjoerg vector_str_dest(&d->class_type);
6714cc2045aSjoerg vector_str_dest(&d->tmpl);
6724cc2045aSjoerg vector_str_dest(&d->subst);
6734cc2045aSjoerg vector_str_dest(&d->output);
6744cc2045aSjoerg }
6754cc2045aSjoerg
6764cc2045aSjoerg static int
cpp_demangle_data_init(struct cpp_demangle_data * d,const char * cur)6774cc2045aSjoerg cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur)
6784cc2045aSjoerg {
6794cc2045aSjoerg
6804cc2045aSjoerg if (d == NULL || cur == NULL)
6814cc2045aSjoerg return (0);
6824cc2045aSjoerg
6834cc2045aSjoerg if (!vector_str_init(&d->output))
6844cc2045aSjoerg return (0);
6854cc2045aSjoerg if (!vector_str_init(&d->subst))
686*d678c5d4Sjoerg goto clean1;
6874cc2045aSjoerg if (!vector_str_init(&d->tmpl))
688*d678c5d4Sjoerg goto clean2;
6894cc2045aSjoerg if (!vector_str_init(&d->class_type))
690*d678c5d4Sjoerg goto clean3;
6914cc2045aSjoerg if (!vector_read_cmd_init(&d->cmd))
692*d678c5d4Sjoerg goto clean4;
6934cc2045aSjoerg
6944cc2045aSjoerg assert(d->output.container != NULL);
6954cc2045aSjoerg assert(d->subst.container != NULL);
6964cc2045aSjoerg assert(d->tmpl.container != NULL);
6974cc2045aSjoerg assert(d->class_type.container != NULL);
6984cc2045aSjoerg
6994cc2045aSjoerg d->mem_rst = false;
7004cc2045aSjoerg d->mem_vat = false;
7014cc2045aSjoerg d->mem_cst = false;
702*d678c5d4Sjoerg d->mem_ref = false;
703*d678c5d4Sjoerg d->mem_rref = false;
704*d678c5d4Sjoerg d->is_tmpl = false;
705*d678c5d4Sjoerg d->is_functype = false;
706*d678c5d4Sjoerg d->ref_qualifier = false;
707*d678c5d4Sjoerg d->push_qualifier = PUSH_ALL_QUALIFIER;
7084cc2045aSjoerg d->func_type = 0;
7094cc2045aSjoerg d->cur = cur;
710*d678c5d4Sjoerg d->cur_output = &d->output;
7114cc2045aSjoerg d->last_sname = NULL;
7124cc2045aSjoerg
7134cc2045aSjoerg return (1);
7144cc2045aSjoerg
7154cc2045aSjoerg clean4:
716*d678c5d4Sjoerg vector_str_dest(&d->class_type);
7174cc2045aSjoerg clean3:
718*d678c5d4Sjoerg vector_str_dest(&d->tmpl);
7194cc2045aSjoerg clean2:
720*d678c5d4Sjoerg vector_str_dest(&d->subst);
7214cc2045aSjoerg clean1:
7224cc2045aSjoerg vector_str_dest(&d->output);
7234cc2045aSjoerg
7244cc2045aSjoerg return (0);
7254cc2045aSjoerg }
7264cc2045aSjoerg
7274cc2045aSjoerg static int
cpp_demangle_push_fp(struct cpp_demangle_data * ddata,char * (* decoder)(const char *,size_t))7284cc2045aSjoerg cpp_demangle_push_fp(struct cpp_demangle_data *ddata,
7294cc2045aSjoerg char *(*decoder)(const char *, size_t))
7304cc2045aSjoerg {
7314cc2045aSjoerg size_t len;
7324cc2045aSjoerg int rtn;
7334cc2045aSjoerg const char *fp;
7344cc2045aSjoerg char *f;
7354cc2045aSjoerg
7364cc2045aSjoerg if (ddata == NULL || decoder == NULL)
7374cc2045aSjoerg return (0);
7384cc2045aSjoerg
7394cc2045aSjoerg fp = ddata->cur;
7404cc2045aSjoerg while (*ddata->cur != 'E')
7414cc2045aSjoerg ++ddata->cur;
7424cc2045aSjoerg
7434cc2045aSjoerg if ((f = decoder(fp, ddata->cur - fp)) == NULL)
7444cc2045aSjoerg return (0);
7454cc2045aSjoerg
7464cc2045aSjoerg rtn = 0;
7475192b81bSjoerg if ((len = strlen(f)) > 0)
7485192b81bSjoerg rtn = cpp_demangle_push_str(ddata, f, len);
7494cc2045aSjoerg
7504cc2045aSjoerg free(f);
7514cc2045aSjoerg
75286b377d0Spooka ++ddata->cur;
75386b377d0Spooka
7545192b81bSjoerg return (rtn);
7554cc2045aSjoerg }
7564cc2045aSjoerg
7574cc2045aSjoerg static int
cpp_demangle_push_str(struct cpp_demangle_data * ddata,const char * str,size_t len)7584cc2045aSjoerg cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str,
7594cc2045aSjoerg size_t len)
7604cc2045aSjoerg {
7614cc2045aSjoerg
7624cc2045aSjoerg if (ddata == NULL || str == NULL || len == 0)
7634cc2045aSjoerg return (0);
7644cc2045aSjoerg
765*d678c5d4Sjoerg /*
766*d678c5d4Sjoerg * is_tmpl is used to check if the type (function arg) is right next
767*d678c5d4Sjoerg * to template args, and should always be cleared whenever new string
768*d678c5d4Sjoerg * pushed.
769*d678c5d4Sjoerg */
770*d678c5d4Sjoerg ddata->is_tmpl = false;
7714cc2045aSjoerg
772*d678c5d4Sjoerg return (vector_str_push(ddata->cur_output, str, len));
773*d678c5d4Sjoerg }
774*d678c5d4Sjoerg
775*d678c5d4Sjoerg static int
cpp_demangle_pop_str(struct cpp_demangle_data * ddata)776*d678c5d4Sjoerg cpp_demangle_pop_str(struct cpp_demangle_data *ddata)
777*d678c5d4Sjoerg {
778*d678c5d4Sjoerg
779*d678c5d4Sjoerg if (ddata == NULL)
780*d678c5d4Sjoerg return (0);
781*d678c5d4Sjoerg
782*d678c5d4Sjoerg return (vector_str_pop(ddata->cur_output));
7834cc2045aSjoerg }
7844cc2045aSjoerg
7854cc2045aSjoerg static int
cpp_demangle_push_subst(struct cpp_demangle_data * ddata,const char * str,size_t len)7864cc2045aSjoerg cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str,
7874cc2045aSjoerg size_t len)
7884cc2045aSjoerg {
7894cc2045aSjoerg
7904cc2045aSjoerg if (ddata == NULL || str == NULL || len == 0)
7914cc2045aSjoerg return (0);
7924cc2045aSjoerg
7934cc2045aSjoerg if (!vector_str_find(&ddata->subst, str, len))
7944cc2045aSjoerg return (vector_str_push(&ddata->subst, str, len));
7954cc2045aSjoerg
7964cc2045aSjoerg return (1);
7974cc2045aSjoerg }
7984cc2045aSjoerg
7994cc2045aSjoerg static int
cpp_demangle_push_subst_v(struct cpp_demangle_data * ddata,struct vector_str * v)8004cc2045aSjoerg cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v)
8014cc2045aSjoerg {
8024cc2045aSjoerg size_t str_len;
8034cc2045aSjoerg int rtn;
8044cc2045aSjoerg char *str;
8054cc2045aSjoerg
8064cc2045aSjoerg if (ddata == NULL || v == NULL)
8074cc2045aSjoerg return (0);
8084cc2045aSjoerg
8094cc2045aSjoerg if ((str = vector_str_get_flat(v, &str_len)) == NULL)
8104cc2045aSjoerg return (0);
8114cc2045aSjoerg
8124cc2045aSjoerg rtn = cpp_demangle_push_subst(ddata, str, str_len);
8135192b81bSjoerg
8144cc2045aSjoerg free(str);
8154cc2045aSjoerg
8164cc2045aSjoerg return (rtn);
8174cc2045aSjoerg }
8184cc2045aSjoerg
8194cc2045aSjoerg static int
cpp_demangle_push_type_qualifier(struct cpp_demangle_data * ddata,struct vector_type_qualifier * v,const char * type_str)8204cc2045aSjoerg cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata,
8214cc2045aSjoerg struct vector_type_qualifier *v, const char *type_str)
8224cc2045aSjoerg {
8234cc2045aSjoerg struct vector_str subst_v;
824*d678c5d4Sjoerg enum type_qualifier t;
8254cc2045aSjoerg size_t idx, e_idx, e_len;
8264cc2045aSjoerg char *buf;
827*d678c5d4Sjoerg int rtn;
828*d678c5d4Sjoerg bool cv;
8294cc2045aSjoerg
8304cc2045aSjoerg if (ddata == NULL || v == NULL)
8314cc2045aSjoerg return (0);
8324cc2045aSjoerg
8334cc2045aSjoerg if ((idx = v->size) == 0)
8344cc2045aSjoerg return (1);
8354cc2045aSjoerg
8364cc2045aSjoerg rtn = 0;
8374cc2045aSjoerg if (type_str != NULL) {
8384cc2045aSjoerg if (!vector_str_init(&subst_v))
8394cc2045aSjoerg return (0);
840*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, type_str))
8414cc2045aSjoerg goto clean;
8424cc2045aSjoerg }
8434cc2045aSjoerg
844*d678c5d4Sjoerg cv = true;
8454cc2045aSjoerg e_idx = 0;
8464cc2045aSjoerg while (idx > 0) {
8474cc2045aSjoerg switch (v->q_container[idx - 1]) {
8484cc2045aSjoerg case TYPE_PTR:
849*d678c5d4Sjoerg cv = false;
850*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
851*d678c5d4Sjoerg break;
852*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "*"))
8534cc2045aSjoerg goto clean;
8544cc2045aSjoerg if (type_str != NULL) {
855*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, "*"))
8564cc2045aSjoerg goto clean;
85786b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
85886b377d0Spooka &subst_v))
8594cc2045aSjoerg goto clean;
8604cc2045aSjoerg }
8614cc2045aSjoerg break;
8624cc2045aSjoerg
8634cc2045aSjoerg case TYPE_REF:
864*d678c5d4Sjoerg cv = false;
865*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
866*d678c5d4Sjoerg break;
867*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "&"))
8684cc2045aSjoerg goto clean;
8694cc2045aSjoerg if (type_str != NULL) {
870*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, "&"))
871*d678c5d4Sjoerg goto clean;
872*d678c5d4Sjoerg if (!cpp_demangle_push_subst_v(ddata,
873*d678c5d4Sjoerg &subst_v))
874*d678c5d4Sjoerg goto clean;
875*d678c5d4Sjoerg }
876*d678c5d4Sjoerg break;
877*d678c5d4Sjoerg
878*d678c5d4Sjoerg case TYPE_RREF:
879*d678c5d4Sjoerg cv = false;
880*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
881*d678c5d4Sjoerg break;
882*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "&&"))
883*d678c5d4Sjoerg goto clean;
884*d678c5d4Sjoerg if (type_str != NULL) {
885*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, "&&"))
8864cc2045aSjoerg goto clean;
88786b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
88886b377d0Spooka &subst_v))
8894cc2045aSjoerg goto clean;
8904cc2045aSjoerg }
8914cc2045aSjoerg break;
8924cc2045aSjoerg
8934cc2045aSjoerg case TYPE_CMX:
894*d678c5d4Sjoerg cv = false;
895*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
896*d678c5d4Sjoerg break;
897*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " complex"))
8984cc2045aSjoerg goto clean;
8994cc2045aSjoerg if (type_str != NULL) {
900*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, " complex"))
9014cc2045aSjoerg goto clean;
90286b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
90386b377d0Spooka &subst_v))
9044cc2045aSjoerg goto clean;
9054cc2045aSjoerg }
9064cc2045aSjoerg break;
9074cc2045aSjoerg
9084cc2045aSjoerg case TYPE_IMG:
909*d678c5d4Sjoerg cv = false;
910*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
911*d678c5d4Sjoerg break;
912*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " imaginary"))
9134cc2045aSjoerg goto clean;
9144cc2045aSjoerg if (type_str != NULL) {
915*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, " imaginary"))
9164cc2045aSjoerg goto clean;
91786b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
91886b377d0Spooka &subst_v))
9194cc2045aSjoerg goto clean;
9204cc2045aSjoerg }
9214cc2045aSjoerg break;
9224cc2045aSjoerg
9234cc2045aSjoerg case TYPE_EXT:
924*d678c5d4Sjoerg cv = false;
925*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
926*d678c5d4Sjoerg break;
92786b377d0Spooka if (v->ext_name.size == 0 ||
92886b377d0Spooka e_idx > v->ext_name.size - 1)
9294cc2045aSjoerg goto clean;
93086b377d0Spooka if ((e_len = strlen(v->ext_name.container[e_idx])) ==
93186b377d0Spooka 0)
9324cc2045aSjoerg goto clean;
93386b377d0Spooka if ((buf = malloc(e_len + 2)) == NULL)
9344cc2045aSjoerg goto clean;
93586b377d0Spooka snprintf(buf, e_len + 2, " %s",
93686b377d0Spooka v->ext_name.container[e_idx]);
9374cc2045aSjoerg
938*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, buf)) {
9394cc2045aSjoerg free(buf);
9404cc2045aSjoerg goto clean;
9414cc2045aSjoerg }
9424cc2045aSjoerg
9434cc2045aSjoerg if (type_str != NULL) {
944*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, buf)) {
9454cc2045aSjoerg free(buf);
9464cc2045aSjoerg goto clean;
9474cc2045aSjoerg }
94886b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
94986b377d0Spooka &subst_v)) {
9504cc2045aSjoerg free(buf);
9514cc2045aSjoerg goto clean;
9524cc2045aSjoerg }
9534cc2045aSjoerg }
9544cc2045aSjoerg free(buf);
9554cc2045aSjoerg ++e_idx;
9564cc2045aSjoerg break;
9574cc2045aSjoerg
9584cc2045aSjoerg case TYPE_RST:
959*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
960*d678c5d4Sjoerg cv)
961*d678c5d4Sjoerg break;
962*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
963*d678c5d4Sjoerg break;
964*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " restrict"))
9654cc2045aSjoerg goto clean;
9664cc2045aSjoerg if (type_str != NULL) {
967*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, " restrict"))
9684cc2045aSjoerg goto clean;
969*d678c5d4Sjoerg if (idx - 1 > 0) {
970*d678c5d4Sjoerg t = v->q_container[idx - 2];
971*d678c5d4Sjoerg if (t == TYPE_RST || t == TYPE_VAT ||
972*d678c5d4Sjoerg t == TYPE_CST)
973*d678c5d4Sjoerg break;
974*d678c5d4Sjoerg }
97586b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
97686b377d0Spooka &subst_v))
9774cc2045aSjoerg goto clean;
9784cc2045aSjoerg }
9794cc2045aSjoerg break;
9804cc2045aSjoerg
9814cc2045aSjoerg case TYPE_VAT:
982*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
983*d678c5d4Sjoerg cv)
984*d678c5d4Sjoerg break;
985*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
986*d678c5d4Sjoerg break;
987*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " volatile"))
9884cc2045aSjoerg goto clean;
9894cc2045aSjoerg if (type_str != NULL) {
990*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, " volatile"))
9914cc2045aSjoerg goto clean;
992*d678c5d4Sjoerg if (idx - 1 > 0) {
993*d678c5d4Sjoerg t = v->q_container[idx - 2];
994*d678c5d4Sjoerg if (t == TYPE_RST || t == TYPE_VAT ||
995*d678c5d4Sjoerg t == TYPE_CST)
996*d678c5d4Sjoerg break;
997*d678c5d4Sjoerg }
99886b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
99986b377d0Spooka &subst_v))
10004cc2045aSjoerg goto clean;
10014cc2045aSjoerg }
10024cc2045aSjoerg break;
10034cc2045aSjoerg
10044cc2045aSjoerg case TYPE_CST:
1005*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
1006*d678c5d4Sjoerg cv)
1007*d678c5d4Sjoerg break;
1008*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
1009*d678c5d4Sjoerg break;
1010*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " const"))
10114cc2045aSjoerg goto clean;
10124cc2045aSjoerg if (type_str != NULL) {
1013*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, " const"))
10144cc2045aSjoerg goto clean;
1015*d678c5d4Sjoerg if (idx - 1 > 0) {
1016*d678c5d4Sjoerg t = v->q_container[idx - 2];
1017*d678c5d4Sjoerg if (t == TYPE_RST || t == TYPE_VAT ||
1018*d678c5d4Sjoerg t == TYPE_CST)
1019*d678c5d4Sjoerg break;
1020*d678c5d4Sjoerg }
102186b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
102286b377d0Spooka &subst_v))
10234cc2045aSjoerg goto clean;
10244cc2045aSjoerg }
10254cc2045aSjoerg break;
10264cc2045aSjoerg
102786b377d0Spooka case TYPE_VEC:
1028*d678c5d4Sjoerg cv = false;
1029*d678c5d4Sjoerg if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
1030*d678c5d4Sjoerg break;
103186b377d0Spooka if (v->ext_name.size == 0 ||
103286b377d0Spooka e_idx > v->ext_name.size - 1)
103386b377d0Spooka goto clean;
103486b377d0Spooka if ((e_len = strlen(v->ext_name.container[e_idx])) ==
103586b377d0Spooka 0)
103686b377d0Spooka goto clean;
103786b377d0Spooka if ((buf = malloc(e_len + 12)) == NULL)
103886b377d0Spooka goto clean;
103986b377d0Spooka snprintf(buf, e_len + 12, " __vector(%s)",
104086b377d0Spooka v->ext_name.container[e_idx]);
1041*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, buf)) {
104286b377d0Spooka free(buf);
104386b377d0Spooka goto clean;
104486b377d0Spooka }
104586b377d0Spooka if (type_str != NULL) {
1046*d678c5d4Sjoerg if (!VEC_PUSH_STR(&subst_v, buf)) {
104786b377d0Spooka free(buf);
104886b377d0Spooka goto clean;
104986b377d0Spooka }
105086b377d0Spooka if (!cpp_demangle_push_subst_v(ddata,
105186b377d0Spooka &subst_v)) {
105286b377d0Spooka free(buf);
105386b377d0Spooka goto clean;
105486b377d0Spooka }
105586b377d0Spooka }
105686b377d0Spooka free(buf);
105786b377d0Spooka ++e_idx;
105886b377d0Spooka break;
1059*d678c5d4Sjoerg }
10604cc2045aSjoerg --idx;
10614cc2045aSjoerg }
10624cc2045aSjoerg
10634cc2045aSjoerg rtn = 1;
10644cc2045aSjoerg clean:
10654cc2045aSjoerg if (type_str != NULL)
10664cc2045aSjoerg vector_str_dest(&subst_v);
10674cc2045aSjoerg
10684cc2045aSjoerg return (rtn);
10694cc2045aSjoerg }
10704cc2045aSjoerg
10714cc2045aSjoerg static int
cpp_demangle_get_subst(struct cpp_demangle_data * ddata,size_t idx)10724cc2045aSjoerg cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx)
10734cc2045aSjoerg {
10744cc2045aSjoerg size_t len;
10754cc2045aSjoerg
10764cc2045aSjoerg if (ddata == NULL || ddata->subst.size <= idx)
10774cc2045aSjoerg return (0);
10784cc2045aSjoerg if ((len = strlen(ddata->subst.container[idx])) == 0)
10794cc2045aSjoerg return (0);
10804cc2045aSjoerg if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len))
10814cc2045aSjoerg return (0);
10824cc2045aSjoerg
10834cc2045aSjoerg /* skip '_' */
10844cc2045aSjoerg ++ddata->cur;
10854cc2045aSjoerg
10864cc2045aSjoerg return (1);
10874cc2045aSjoerg }
10884cc2045aSjoerg
10894cc2045aSjoerg static int
cpp_demangle_get_tmpl_param(struct cpp_demangle_data * ddata,size_t idx)10904cc2045aSjoerg cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx)
10914cc2045aSjoerg {
10924cc2045aSjoerg size_t len;
10934cc2045aSjoerg
10944cc2045aSjoerg if (ddata == NULL || ddata->tmpl.size <= idx)
10954cc2045aSjoerg return (0);
10964cc2045aSjoerg if ((len = strlen(ddata->tmpl.container[idx])) == 0)
10974cc2045aSjoerg return (0);
10984cc2045aSjoerg if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len))
10994cc2045aSjoerg return (0);
11004cc2045aSjoerg
11014cc2045aSjoerg ++ddata->cur;
11024cc2045aSjoerg
11034cc2045aSjoerg return (1);
11044cc2045aSjoerg }
11054cc2045aSjoerg
11064cc2045aSjoerg static int
cpp_demangle_read_array(struct cpp_demangle_data * ddata)11074cc2045aSjoerg cpp_demangle_read_array(struct cpp_demangle_data *ddata)
11084cc2045aSjoerg {
11094cc2045aSjoerg size_t i, num_len, exp_len, p_idx, idx;
11104cc2045aSjoerg const char *num;
11114cc2045aSjoerg char *exp;
11124cc2045aSjoerg
11134cc2045aSjoerg if (ddata == NULL || *(++ddata->cur) == '\0')
11144cc2045aSjoerg return (0);
11154cc2045aSjoerg
11164cc2045aSjoerg if (*ddata->cur == '_') {
11174cc2045aSjoerg if (*(++ddata->cur) == '\0')
11184cc2045aSjoerg return (0);
11194cc2045aSjoerg
1120*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
11214cc2045aSjoerg return (0);
11224cc2045aSjoerg
1123*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " []"))
11244cc2045aSjoerg return (0);
11254cc2045aSjoerg } else {
11264cc2045aSjoerg if (ELFTC_ISDIGIT(*ddata->cur) != 0) {
11274cc2045aSjoerg num = ddata->cur;
11284cc2045aSjoerg while (ELFTC_ISDIGIT(*ddata->cur) != 0)
11294cc2045aSjoerg ++ddata->cur;
11304cc2045aSjoerg if (*ddata->cur != '_')
11314cc2045aSjoerg return (0);
11324cc2045aSjoerg num_len = ddata->cur - num;
11334cc2045aSjoerg assert(num_len > 0);
11344cc2045aSjoerg if (*(++ddata->cur) == '\0')
11354cc2045aSjoerg return (0);
1136*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
11374cc2045aSjoerg return (0);
1138*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " ["))
11394cc2045aSjoerg return (0);
11404cc2045aSjoerg if (!cpp_demangle_push_str(ddata, num, num_len))
11414cc2045aSjoerg return (0);
1142*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "]"))
11434cc2045aSjoerg return (0);
11444cc2045aSjoerg } else {
11454cc2045aSjoerg p_idx = ddata->output.size;
11464cc2045aSjoerg if (!cpp_demangle_read_expression(ddata))
11474cc2045aSjoerg return (0);
11484cc2045aSjoerg if ((exp = vector_str_substr(&ddata->output, p_idx,
11494cc2045aSjoerg ddata->output.size - 1, &exp_len)) == NULL)
11504cc2045aSjoerg return (0);
11514cc2045aSjoerg idx = ddata->output.size;
11524cc2045aSjoerg for (i = p_idx; i < idx; ++i)
11534cc2045aSjoerg if (!vector_str_pop(&ddata->output)) {
11544cc2045aSjoerg free(exp);
11554cc2045aSjoerg return (0);
11564cc2045aSjoerg }
11574cc2045aSjoerg if (*ddata->cur != '_') {
11584cc2045aSjoerg free(exp);
11594cc2045aSjoerg return (0);
11604cc2045aSjoerg }
11614cc2045aSjoerg ++ddata->cur;
11624cc2045aSjoerg if (*ddata->cur == '\0') {
11634cc2045aSjoerg free(exp);
11644cc2045aSjoerg return (0);
11654cc2045aSjoerg }
1166*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL)) {
11674cc2045aSjoerg free(exp);
11684cc2045aSjoerg return (0);
11694cc2045aSjoerg }
1170*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " [")) {
11714cc2045aSjoerg free(exp);
11724cc2045aSjoerg return (0);
11734cc2045aSjoerg }
11744cc2045aSjoerg if (!cpp_demangle_push_str(ddata, exp, exp_len)) {
11754cc2045aSjoerg free(exp);
11764cc2045aSjoerg return (0);
11774cc2045aSjoerg }
1178*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "]")) {
11794cc2045aSjoerg free(exp);
11804cc2045aSjoerg return (0);
11814cc2045aSjoerg }
11824cc2045aSjoerg free(exp);
11834cc2045aSjoerg }
11844cc2045aSjoerg }
11854cc2045aSjoerg
11864cc2045aSjoerg return (1);
11874cc2045aSjoerg }
11884cc2045aSjoerg
11894cc2045aSjoerg static int
cpp_demangle_read_expr_primary(struct cpp_demangle_data * ddata)11904cc2045aSjoerg cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata)
11914cc2045aSjoerg {
11924cc2045aSjoerg const char *num;
11934cc2045aSjoerg
11944cc2045aSjoerg if (ddata == NULL || *(++ddata->cur) == '\0')
11954cc2045aSjoerg return (0);
11964cc2045aSjoerg
11974cc2045aSjoerg if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') {
11984cc2045aSjoerg ddata->cur += 2;
11994cc2045aSjoerg if (*ddata->cur == '\0')
12004cc2045aSjoerg return (0);
12014cc2045aSjoerg if (!cpp_demangle_read_encoding(ddata))
12024cc2045aSjoerg return (0);
12034cc2045aSjoerg ++ddata->cur;
12044cc2045aSjoerg return (1);
12054cc2045aSjoerg }
12064cc2045aSjoerg
12074cc2045aSjoerg switch (*ddata->cur) {
12084cc2045aSjoerg case 'b':
120986b377d0Spooka if (*(ddata->cur + 2) != 'E')
121086b377d0Spooka return (0);
12114cc2045aSjoerg switch (*(++ddata->cur)) {
12124cc2045aSjoerg case '0':
121386b377d0Spooka ddata->cur += 2;
1214*d678c5d4Sjoerg return (DEM_PUSH_STR(ddata, "false"));
12154cc2045aSjoerg case '1':
121686b377d0Spooka ddata->cur += 2;
1217*d678c5d4Sjoerg return (DEM_PUSH_STR(ddata, "true"));
12184cc2045aSjoerg default:
12194cc2045aSjoerg return (0);
1220*d678c5d4Sjoerg }
12214cc2045aSjoerg
12224cc2045aSjoerg case 'd':
12234cc2045aSjoerg ++ddata->cur;
12244cc2045aSjoerg return (cpp_demangle_push_fp(ddata, decode_fp_to_double));
12254cc2045aSjoerg
12264cc2045aSjoerg case 'e':
12274cc2045aSjoerg ++ddata->cur;
12284cc2045aSjoerg if (sizeof(long double) == 10)
12294cc2045aSjoerg return (cpp_demangle_push_fp(ddata,
12304cc2045aSjoerg decode_fp_to_double));
12314cc2045aSjoerg return (cpp_demangle_push_fp(ddata, decode_fp_to_float80));
12324cc2045aSjoerg
12334cc2045aSjoerg case 'f':
12344cc2045aSjoerg ++ddata->cur;
12354cc2045aSjoerg return (cpp_demangle_push_fp(ddata, decode_fp_to_float));
12364cc2045aSjoerg
12374cc2045aSjoerg case 'g':
12384cc2045aSjoerg ++ddata->cur;
12394cc2045aSjoerg if (sizeof(long double) == 16)
12404cc2045aSjoerg return (cpp_demangle_push_fp(ddata,
12414cc2045aSjoerg decode_fp_to_double));
12424cc2045aSjoerg return (cpp_demangle_push_fp(ddata, decode_fp_to_float128));
12434cc2045aSjoerg
12444cc2045aSjoerg case 'i':
12454cc2045aSjoerg case 'j':
12464cc2045aSjoerg case 'l':
12474cc2045aSjoerg case 'm':
12484cc2045aSjoerg case 'n':
12494cc2045aSjoerg case 's':
12504cc2045aSjoerg case 't':
12514cc2045aSjoerg case 'x':
12524cc2045aSjoerg case 'y':
12534cc2045aSjoerg if (*(++ddata->cur) == 'n') {
1254*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "-"))
12554cc2045aSjoerg return (0);
12564cc2045aSjoerg ++ddata->cur;
12574cc2045aSjoerg }
12584cc2045aSjoerg num = ddata->cur;
12594cc2045aSjoerg while (*ddata->cur != 'E') {
12604cc2045aSjoerg if (!ELFTC_ISDIGIT(*ddata->cur))
12614cc2045aSjoerg return (0);
12624cc2045aSjoerg ++ddata->cur;
12634cc2045aSjoerg }
12644cc2045aSjoerg ++ddata->cur;
126586b377d0Spooka return (cpp_demangle_push_str(ddata, num,
126686b377d0Spooka ddata->cur - num - 1));
12674cc2045aSjoerg
12684cc2045aSjoerg default:
12694cc2045aSjoerg return (0);
1270*d678c5d4Sjoerg }
12714cc2045aSjoerg }
12724cc2045aSjoerg
12734cc2045aSjoerg static int
cpp_demangle_read_expression(struct cpp_demangle_data * ddata)12744cc2045aSjoerg cpp_demangle_read_expression(struct cpp_demangle_data *ddata)
12754cc2045aSjoerg {
12764cc2045aSjoerg
12774cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
12784cc2045aSjoerg return (0);
12794cc2045aSjoerg
12804cc2045aSjoerg switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
12814cc2045aSjoerg case SIMPLE_HASH('s', 't'):
12824cc2045aSjoerg ddata->cur += 2;
1283*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
12844cc2045aSjoerg
12854cc2045aSjoerg case SIMPLE_HASH('s', 'r'):
12864cc2045aSjoerg ddata->cur += 2;
1287*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
12884cc2045aSjoerg return (0);
12894cc2045aSjoerg if (!cpp_demangle_read_uqname(ddata))
12904cc2045aSjoerg return (0);
12914cc2045aSjoerg if (*ddata->cur == 'I')
12924cc2045aSjoerg return (cpp_demangle_read_tmpl_args(ddata));
12934cc2045aSjoerg return (1);
12944cc2045aSjoerg
12954cc2045aSjoerg case SIMPLE_HASH('a', 'a'):
12964cc2045aSjoerg /* operator && */
12974cc2045aSjoerg ddata->cur += 2;
12984cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "&&", 2));
12994cc2045aSjoerg
13004cc2045aSjoerg case SIMPLE_HASH('a', 'd'):
13014cc2045aSjoerg /* operator & (unary) */
13024cc2045aSjoerg ddata->cur += 2;
13034cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "&", 1));
13044cc2045aSjoerg
13054cc2045aSjoerg case SIMPLE_HASH('a', 'n'):
13064cc2045aSjoerg /* operator & */
13074cc2045aSjoerg ddata->cur += 2;
13084cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "&", 1));
13094cc2045aSjoerg
13104cc2045aSjoerg case SIMPLE_HASH('a', 'N'):
13114cc2045aSjoerg /* operator &= */
13124cc2045aSjoerg ddata->cur += 2;
13134cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "&=", 2));
13144cc2045aSjoerg
13154cc2045aSjoerg case SIMPLE_HASH('a', 'S'):
13164cc2045aSjoerg /* operator = */
13174cc2045aSjoerg ddata->cur += 2;
13184cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "=", 1));
13194cc2045aSjoerg
13204cc2045aSjoerg case SIMPLE_HASH('c', 'l'):
13214cc2045aSjoerg /* operator () */
13224cc2045aSjoerg ddata->cur += 2;
13234cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "()", 2));
13244cc2045aSjoerg
13254cc2045aSjoerg case SIMPLE_HASH('c', 'm'):
13264cc2045aSjoerg /* operator , */
13274cc2045aSjoerg ddata->cur += 2;
13284cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, ",", 1));
13294cc2045aSjoerg
13304cc2045aSjoerg case SIMPLE_HASH('c', 'o'):
13314cc2045aSjoerg /* operator ~ */
13324cc2045aSjoerg ddata->cur += 2;
13334cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "~", 1));
13344cc2045aSjoerg
13354cc2045aSjoerg case SIMPLE_HASH('c', 'v'):
13364cc2045aSjoerg /* operator (cast) */
13374cc2045aSjoerg ddata->cur += 2;
13384cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6));
13394cc2045aSjoerg
13404cc2045aSjoerg case SIMPLE_HASH('d', 'a'):
13414cc2045aSjoerg /* operator delete [] */
13424cc2045aSjoerg ddata->cur += 2;
13434cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "delete []", 9));
13444cc2045aSjoerg
13454cc2045aSjoerg case SIMPLE_HASH('d', 'e'):
13464cc2045aSjoerg /* operator * (unary) */
13474cc2045aSjoerg ddata->cur += 2;
13484cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "*", 1));
13494cc2045aSjoerg
13504cc2045aSjoerg case SIMPLE_HASH('d', 'l'):
13514cc2045aSjoerg /* operator delete */
13524cc2045aSjoerg ddata->cur += 2;
13534cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "delete", 6));
13544cc2045aSjoerg
13554cc2045aSjoerg case SIMPLE_HASH('d', 'v'):
13564cc2045aSjoerg /* operator / */
13574cc2045aSjoerg ddata->cur += 2;
13584cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "/", 1));
13594cc2045aSjoerg
13604cc2045aSjoerg case SIMPLE_HASH('d', 'V'):
13614cc2045aSjoerg /* operator /= */
13624cc2045aSjoerg ddata->cur += 2;
13634cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "/=", 2));
13644cc2045aSjoerg
13654cc2045aSjoerg case SIMPLE_HASH('e', 'o'):
13664cc2045aSjoerg /* operator ^ */
13674cc2045aSjoerg ddata->cur += 2;
13684cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "^", 1));
13694cc2045aSjoerg
13704cc2045aSjoerg case SIMPLE_HASH('e', 'O'):
13714cc2045aSjoerg /* operator ^= */
13724cc2045aSjoerg ddata->cur += 2;
13734cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "^=", 2));
13744cc2045aSjoerg
13754cc2045aSjoerg case SIMPLE_HASH('e', 'q'):
13764cc2045aSjoerg /* operator == */
13774cc2045aSjoerg ddata->cur += 2;
13784cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "==", 2));
13794cc2045aSjoerg
13804cc2045aSjoerg case SIMPLE_HASH('g', 'e'):
13814cc2045aSjoerg /* operator >= */
13824cc2045aSjoerg ddata->cur += 2;
13834cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, ">=", 2));
13844cc2045aSjoerg
13854cc2045aSjoerg case SIMPLE_HASH('g', 't'):
13864cc2045aSjoerg /* operator > */
13874cc2045aSjoerg ddata->cur += 2;
13884cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, ">", 1));
13894cc2045aSjoerg
13904cc2045aSjoerg case SIMPLE_HASH('i', 'x'):
13914cc2045aSjoerg /* operator [] */
13924cc2045aSjoerg ddata->cur += 2;
13934cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "[]", 2));
13944cc2045aSjoerg
13954cc2045aSjoerg case SIMPLE_HASH('l', 'e'):
13964cc2045aSjoerg /* operator <= */
13974cc2045aSjoerg ddata->cur += 2;
13984cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "<=", 2));
13994cc2045aSjoerg
14004cc2045aSjoerg case SIMPLE_HASH('l', 's'):
14014cc2045aSjoerg /* operator << */
14024cc2045aSjoerg ddata->cur += 2;
14034cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "<<", 2));
14044cc2045aSjoerg
14054cc2045aSjoerg case SIMPLE_HASH('l', 'S'):
14064cc2045aSjoerg /* operator <<= */
14074cc2045aSjoerg ddata->cur += 2;
14084cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "<<=", 3));
14094cc2045aSjoerg
14104cc2045aSjoerg case SIMPLE_HASH('l', 't'):
14114cc2045aSjoerg /* operator < */
14124cc2045aSjoerg ddata->cur += 2;
14134cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "<", 1));
14144cc2045aSjoerg
14154cc2045aSjoerg case SIMPLE_HASH('m', 'i'):
14164cc2045aSjoerg /* operator - */
14174cc2045aSjoerg ddata->cur += 2;
14184cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "-", 1));
14194cc2045aSjoerg
14204cc2045aSjoerg case SIMPLE_HASH('m', 'I'):
14214cc2045aSjoerg /* operator -= */
14224cc2045aSjoerg ddata->cur += 2;
14234cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "-=", 2));
14244cc2045aSjoerg
14254cc2045aSjoerg case SIMPLE_HASH('m', 'l'):
14264cc2045aSjoerg /* operator * */
14274cc2045aSjoerg ddata->cur += 2;
14284cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "*", 1));
14294cc2045aSjoerg
14304cc2045aSjoerg case SIMPLE_HASH('m', 'L'):
14314cc2045aSjoerg /* operator *= */
14324cc2045aSjoerg ddata->cur += 2;
14334cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "*=", 2));
14344cc2045aSjoerg
14354cc2045aSjoerg case SIMPLE_HASH('m', 'm'):
14364cc2045aSjoerg /* operator -- */
14374cc2045aSjoerg ddata->cur += 2;
14384cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "--", 2));
14394cc2045aSjoerg
14404cc2045aSjoerg case SIMPLE_HASH('n', 'a'):
14414cc2045aSjoerg /* operator new[] */
14424cc2045aSjoerg ddata->cur += 2;
14434cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "new []", 6));
14444cc2045aSjoerg
14454cc2045aSjoerg case SIMPLE_HASH('n', 'e'):
14464cc2045aSjoerg /* operator != */
14474cc2045aSjoerg ddata->cur += 2;
14484cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "!=", 2));
14494cc2045aSjoerg
14504cc2045aSjoerg case SIMPLE_HASH('n', 'g'):
14514cc2045aSjoerg /* operator - (unary) */
14524cc2045aSjoerg ddata->cur += 2;
14534cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "-", 1));
14544cc2045aSjoerg
14554cc2045aSjoerg case SIMPLE_HASH('n', 't'):
14564cc2045aSjoerg /* operator ! */
14574cc2045aSjoerg ddata->cur += 2;
14584cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "!", 1));
14594cc2045aSjoerg
14604cc2045aSjoerg case SIMPLE_HASH('n', 'w'):
14614cc2045aSjoerg /* operator new */
14624cc2045aSjoerg ddata->cur += 2;
14634cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "new", 3));
14644cc2045aSjoerg
14654cc2045aSjoerg case SIMPLE_HASH('o', 'o'):
14664cc2045aSjoerg /* operator || */
14674cc2045aSjoerg ddata->cur += 2;
14684cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "||", 2));
14694cc2045aSjoerg
14704cc2045aSjoerg case SIMPLE_HASH('o', 'r'):
14714cc2045aSjoerg /* operator | */
14724cc2045aSjoerg ddata->cur += 2;
14734cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "|", 1));
14744cc2045aSjoerg
14754cc2045aSjoerg case SIMPLE_HASH('o', 'R'):
14764cc2045aSjoerg /* operator |= */
14774cc2045aSjoerg ddata->cur += 2;
14784cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "|=", 2));
14794cc2045aSjoerg
14804cc2045aSjoerg case SIMPLE_HASH('p', 'l'):
14814cc2045aSjoerg /* operator + */
14824cc2045aSjoerg ddata->cur += 2;
14834cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "+", 1));
14844cc2045aSjoerg
14854cc2045aSjoerg case SIMPLE_HASH('p', 'L'):
14864cc2045aSjoerg /* operator += */
14874cc2045aSjoerg ddata->cur += 2;
14884cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "+=", 2));
14894cc2045aSjoerg
14904cc2045aSjoerg case SIMPLE_HASH('p', 'm'):
14914cc2045aSjoerg /* operator ->* */
14924cc2045aSjoerg ddata->cur += 2;
14934cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "->*", 3));
14944cc2045aSjoerg
14954cc2045aSjoerg case SIMPLE_HASH('p', 'p'):
14964cc2045aSjoerg /* operator ++ */
14974cc2045aSjoerg ddata->cur += 2;
14984cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "++", 2));
14994cc2045aSjoerg
15004cc2045aSjoerg case SIMPLE_HASH('p', 's'):
15014cc2045aSjoerg /* operator + (unary) */
15024cc2045aSjoerg ddata->cur += 2;
15034cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "+", 1));
15044cc2045aSjoerg
15054cc2045aSjoerg case SIMPLE_HASH('p', 't'):
15064cc2045aSjoerg /* operator -> */
15074cc2045aSjoerg ddata->cur += 2;
15084cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "->", 2));
15094cc2045aSjoerg
15104cc2045aSjoerg case SIMPLE_HASH('q', 'u'):
15114cc2045aSjoerg /* operator ? */
15124cc2045aSjoerg ddata->cur += 2;
15134cc2045aSjoerg return (cpp_demangle_read_expression_trinary(ddata, "?", 1,
15144cc2045aSjoerg ":", 1));
15154cc2045aSjoerg
15164cc2045aSjoerg case SIMPLE_HASH('r', 'm'):
15174cc2045aSjoerg /* operator % */
15184cc2045aSjoerg ddata->cur += 2;
15194cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "%", 1));
15204cc2045aSjoerg
15214cc2045aSjoerg case SIMPLE_HASH('r', 'M'):
15224cc2045aSjoerg /* operator %= */
15234cc2045aSjoerg ddata->cur += 2;
15244cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, "%=", 2));
15254cc2045aSjoerg
15264cc2045aSjoerg case SIMPLE_HASH('r', 's'):
15274cc2045aSjoerg /* operator >> */
15284cc2045aSjoerg ddata->cur += 2;
15294cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, ">>", 2));
15304cc2045aSjoerg
15314cc2045aSjoerg case SIMPLE_HASH('r', 'S'):
15324cc2045aSjoerg /* operator >>= */
15334cc2045aSjoerg ddata->cur += 2;
15344cc2045aSjoerg return (cpp_demangle_read_expression_binary(ddata, ">>=", 3));
15354cc2045aSjoerg
15364cc2045aSjoerg case SIMPLE_HASH('r', 'z'):
15374cc2045aSjoerg /* operator sizeof */
15384cc2045aSjoerg ddata->cur += 2;
15394cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));
15404cc2045aSjoerg
15414cc2045aSjoerg case SIMPLE_HASH('s', 'v'):
15424cc2045aSjoerg /* operator sizeof */
15434cc2045aSjoerg ddata->cur += 2;
15444cc2045aSjoerg return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));
1545*d678c5d4Sjoerg }
15464cc2045aSjoerg
15474cc2045aSjoerg switch (*ddata->cur) {
15484cc2045aSjoerg case 'L':
15494cc2045aSjoerg return (cpp_demangle_read_expr_primary(ddata));
15504cc2045aSjoerg case 'T':
15514cc2045aSjoerg return (cpp_demangle_read_tmpl_param(ddata));
1552*d678c5d4Sjoerg }
15534cc2045aSjoerg
15544cc2045aSjoerg return (0);
15554cc2045aSjoerg }
15564cc2045aSjoerg
15574cc2045aSjoerg static int
cpp_demangle_read_expression_flat(struct cpp_demangle_data * ddata,char ** str)155886b377d0Spooka cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str)
155986b377d0Spooka {
156086b377d0Spooka struct vector_str *output;
156186b377d0Spooka size_t i, p_idx, idx, exp_len;
156286b377d0Spooka char *exp;
156386b377d0Spooka
1564*d678c5d4Sjoerg output = &ddata->output;
156586b377d0Spooka
156686b377d0Spooka p_idx = output->size;
156786b377d0Spooka
156886b377d0Spooka if (!cpp_demangle_read_expression(ddata))
156986b377d0Spooka return (0);
157086b377d0Spooka
157186b377d0Spooka if ((exp = vector_str_substr(output, p_idx, output->size - 1,
157286b377d0Spooka &exp_len)) == NULL)
157386b377d0Spooka return (0);
157486b377d0Spooka
157586b377d0Spooka idx = output->size;
157686b377d0Spooka for (i = p_idx; i < idx; ++i) {
157786b377d0Spooka if (!vector_str_pop(output)) {
157886b377d0Spooka free(exp);
157986b377d0Spooka return (0);
158086b377d0Spooka }
158186b377d0Spooka }
158286b377d0Spooka
158386b377d0Spooka *str = exp;
158486b377d0Spooka
158586b377d0Spooka return (1);
158686b377d0Spooka }
158786b377d0Spooka
158886b377d0Spooka static int
cpp_demangle_read_expression_binary(struct cpp_demangle_data * ddata,const char * name,size_t len)15894cc2045aSjoerg cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata,
15904cc2045aSjoerg const char *name, size_t len)
15914cc2045aSjoerg {
15924cc2045aSjoerg
15934cc2045aSjoerg if (ddata == NULL || name == NULL || len == 0)
15944cc2045aSjoerg return (0);
15954cc2045aSjoerg if (!cpp_demangle_read_expression(ddata))
15964cc2045aSjoerg return (0);
15974cc2045aSjoerg if (!cpp_demangle_push_str(ddata, name, len))
15984cc2045aSjoerg return (0);
15994cc2045aSjoerg
16004cc2045aSjoerg return (cpp_demangle_read_expression(ddata));
16014cc2045aSjoerg }
16024cc2045aSjoerg
16034cc2045aSjoerg static int
cpp_demangle_read_expression_unary(struct cpp_demangle_data * ddata,const char * name,size_t len)16044cc2045aSjoerg cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata,
16054cc2045aSjoerg const char *name, size_t len)
16064cc2045aSjoerg {
16074cc2045aSjoerg
16084cc2045aSjoerg if (ddata == NULL || name == NULL || len == 0)
16094cc2045aSjoerg return (0);
16104cc2045aSjoerg if (!cpp_demangle_read_expression(ddata))
16114cc2045aSjoerg return (0);
16124cc2045aSjoerg
16134cc2045aSjoerg return (cpp_demangle_push_str(ddata, name, len));
16144cc2045aSjoerg }
16154cc2045aSjoerg
16164cc2045aSjoerg static int
cpp_demangle_read_expression_trinary(struct cpp_demangle_data * ddata,const char * name1,size_t len1,const char * name2,size_t len2)16174cc2045aSjoerg cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata,
16184cc2045aSjoerg const char *name1, size_t len1, const char *name2, size_t len2)
16194cc2045aSjoerg {
16204cc2045aSjoerg
16214cc2045aSjoerg if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL ||
16224cc2045aSjoerg len2 == 0)
16234cc2045aSjoerg return (0);
16244cc2045aSjoerg
16254cc2045aSjoerg if (!cpp_demangle_read_expression(ddata))
16264cc2045aSjoerg return (0);
16274cc2045aSjoerg if (!cpp_demangle_push_str(ddata, name1, len1))
16284cc2045aSjoerg return (0);
16294cc2045aSjoerg if (!cpp_demangle_read_expression(ddata))
16304cc2045aSjoerg return (0);
16314cc2045aSjoerg if (!cpp_demangle_push_str(ddata, name2, len2))
16324cc2045aSjoerg return (0);
16334cc2045aSjoerg
16344cc2045aSjoerg return (cpp_demangle_read_expression(ddata));
16354cc2045aSjoerg }
16364cc2045aSjoerg
16374cc2045aSjoerg static int
cpp_demangle_read_function(struct cpp_demangle_data * ddata,int * ext_c,struct vector_type_qualifier * v)16384cc2045aSjoerg cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c,
16394cc2045aSjoerg struct vector_type_qualifier *v)
16404cc2045aSjoerg {
1641*d678c5d4Sjoerg struct type_delimit td;
1642*d678c5d4Sjoerg struct read_cmd_item *rc;
16434cc2045aSjoerg size_t class_type_size, class_type_len, limit;
16444cc2045aSjoerg const char *class_type;
1645*d678c5d4Sjoerg int i;
1646*d678c5d4Sjoerg bool paren, non_cv_qualifier;
16474cc2045aSjoerg
16484cc2045aSjoerg if (ddata == NULL || *ddata->cur != 'F' || v == NULL)
16494cc2045aSjoerg return (0);
16504cc2045aSjoerg
16514cc2045aSjoerg ++ddata->cur;
16524cc2045aSjoerg if (*ddata->cur == 'Y') {
16534cc2045aSjoerg if (ext_c != NULL)
16544cc2045aSjoerg *ext_c = 1;
16554cc2045aSjoerg ++ddata->cur;
16564cc2045aSjoerg }
1657*d678c5d4Sjoerg
1658*d678c5d4Sjoerg /* Return type */
1659*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
16604cc2045aSjoerg return (0);
1661*d678c5d4Sjoerg
16624cc2045aSjoerg if (*ddata->cur != 'E') {
1663*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " "))
16644cc2045aSjoerg return (0);
1665*d678c5d4Sjoerg
1666*d678c5d4Sjoerg non_cv_qualifier = false;
1667*d678c5d4Sjoerg if (v->size > 0) {
1668*d678c5d4Sjoerg for (i = 0; (size_t) i < v->size; i++) {
1669*d678c5d4Sjoerg if (v->q_container[i] != TYPE_RST &&
1670*d678c5d4Sjoerg v->q_container[i] != TYPE_VAT &&
1671*d678c5d4Sjoerg v->q_container[i] != TYPE_CST) {
1672*d678c5d4Sjoerg non_cv_qualifier = true;
1673*d678c5d4Sjoerg break;
1674*d678c5d4Sjoerg }
1675*d678c5d4Sjoerg }
1676*d678c5d4Sjoerg }
1677*d678c5d4Sjoerg
1678*d678c5d4Sjoerg paren = false;
1679*d678c5d4Sjoerg rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM);
1680*d678c5d4Sjoerg if (non_cv_qualifier || rc != NULL) {
1681*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "("))
1682*d678c5d4Sjoerg return (0);
1683*d678c5d4Sjoerg paren = true;
1684*d678c5d4Sjoerg }
1685*d678c5d4Sjoerg
1686*d678c5d4Sjoerg /* Push non-cv qualifiers. */
1687*d678c5d4Sjoerg ddata->push_qualifier = PUSH_NON_CV_QUALIFIER;
1688*d678c5d4Sjoerg if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
1689*d678c5d4Sjoerg return (0);
1690*d678c5d4Sjoerg
1691*d678c5d4Sjoerg if (rc) {
1692*d678c5d4Sjoerg if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " "))
1693*d678c5d4Sjoerg return (0);
16944cc2045aSjoerg if ((class_type_size = ddata->class_type.size) == 0)
16954cc2045aSjoerg return (0);
16964cc2045aSjoerg class_type =
16974cc2045aSjoerg ddata->class_type.container[class_type_size - 1];
16984cc2045aSjoerg if (class_type == NULL)
16994cc2045aSjoerg return (0);
17004cc2045aSjoerg if ((class_type_len = strlen(class_type)) == 0)
17014cc2045aSjoerg return (0);
17024cc2045aSjoerg if (!cpp_demangle_push_str(ddata, class_type,
17034cc2045aSjoerg class_type_len))
17044cc2045aSjoerg return (0);
1705*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "::*"))
1706*d678c5d4Sjoerg return (0);
1707*d678c5d4Sjoerg /* Push pointer-to-member qualifiers. */
1708*d678c5d4Sjoerg ddata->push_qualifier = PUSH_ALL_QUALIFIER;
1709*d678c5d4Sjoerg if (!cpp_demangle_push_type_qualifier(ddata, rc->data,
1710*d678c5d4Sjoerg NULL))
17114cc2045aSjoerg return (0);
17124cc2045aSjoerg ++ddata->func_type;
17134cc2045aSjoerg }
17144cc2045aSjoerg
1715*d678c5d4Sjoerg if (paren) {
1716*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, ")"))
17174cc2045aSjoerg return (0);
1718*d678c5d4Sjoerg paren = false;
1719*d678c5d4Sjoerg }
17204cc2045aSjoerg
1721*d678c5d4Sjoerg td.paren = false;
1722*d678c5d4Sjoerg td.firstp = true;
17234cc2045aSjoerg limit = 0;
1724*d678c5d4Sjoerg ddata->is_functype = true;
17254cc2045aSjoerg for (;;) {
1726*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, &td))
17274cc2045aSjoerg return (0);
17284cc2045aSjoerg if (*ddata->cur == 'E')
17294cc2045aSjoerg break;
17304cc2045aSjoerg if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
17314cc2045aSjoerg return (0);
17324cc2045aSjoerg }
1733*d678c5d4Sjoerg ddata->is_functype = false;
1734*d678c5d4Sjoerg if (td.paren) {
1735*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, ")"))
17364cc2045aSjoerg return (0);
1737*d678c5d4Sjoerg td.paren = false;
1738*d678c5d4Sjoerg }
1739*d678c5d4Sjoerg
1740*d678c5d4Sjoerg /* Push CV qualifiers. */
1741*d678c5d4Sjoerg ddata->push_qualifier = PUSH_CV_QUALIFIER;
1742*d678c5d4Sjoerg if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
1743*d678c5d4Sjoerg return (0);
1744*d678c5d4Sjoerg
1745*d678c5d4Sjoerg ddata->push_qualifier = PUSH_ALL_QUALIFIER;
1746*d678c5d4Sjoerg
1747*d678c5d4Sjoerg /* Release type qualifier vector. */
17484cc2045aSjoerg vector_type_qualifier_dest(v);
17494cc2045aSjoerg if (!vector_type_qualifier_init(v))
17504cc2045aSjoerg return (0);
17514cc2045aSjoerg
1752*d678c5d4Sjoerg /* Push ref-qualifiers. */
1753*d678c5d4Sjoerg if (ddata->ref_qualifier) {
1754*d678c5d4Sjoerg switch (ddata->ref_qualifier_type) {
1755*d678c5d4Sjoerg case TYPE_REF:
1756*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " &"))
17574cc2045aSjoerg return (0);
1758*d678c5d4Sjoerg break;
1759*d678c5d4Sjoerg case TYPE_RREF:
1760*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " &&"))
1761*d678c5d4Sjoerg return (0);
1762*d678c5d4Sjoerg break;
1763*d678c5d4Sjoerg default:
1764*d678c5d4Sjoerg return (0);
1765*d678c5d4Sjoerg }
1766*d678c5d4Sjoerg ddata->ref_qualifier = false;
1767*d678c5d4Sjoerg }
17684cc2045aSjoerg }
17694cc2045aSjoerg
17704cc2045aSjoerg ++ddata->cur;
17714cc2045aSjoerg
17724cc2045aSjoerg return (1);
17734cc2045aSjoerg }
17744cc2045aSjoerg
17754cc2045aSjoerg /* read encoding, encoding are function name, data name, special-name */
17764cc2045aSjoerg static int
cpp_demangle_read_encoding(struct cpp_demangle_data * ddata)17774cc2045aSjoerg cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)
17784cc2045aSjoerg {
177986b377d0Spooka char *name, *type, *num_str;
178086b377d0Spooka long offset;
178186b377d0Spooka int rtn;
17824cc2045aSjoerg
17834cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
17844cc2045aSjoerg return (0);
17854cc2045aSjoerg
17864cc2045aSjoerg /* special name */
17874cc2045aSjoerg switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
178886b377d0Spooka case SIMPLE_HASH('G', 'A'):
1789*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "hidden alias for "))
179086b377d0Spooka return (0);
179186b377d0Spooka ddata->cur += 2;
179286b377d0Spooka if (*ddata->cur == '\0')
179386b377d0Spooka return (0);
179486b377d0Spooka return (cpp_demangle_read_encoding(ddata));
179586b377d0Spooka
179686b377d0Spooka case SIMPLE_HASH('G', 'R'):
1797*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "reference temporary #"))
179886b377d0Spooka return (0);
179986b377d0Spooka ddata->cur += 2;
180086b377d0Spooka if (*ddata->cur == '\0')
180186b377d0Spooka return (0);
180286b377d0Spooka if (!cpp_demangle_read_name_flat(ddata, &name))
180386b377d0Spooka return (0);
180486b377d0Spooka rtn = 0;
180586b377d0Spooka if (!cpp_demangle_read_number_as_string(ddata, &num_str))
180686b377d0Spooka goto clean1;
1807*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, num_str))
180886b377d0Spooka goto clean2;
1809*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " for "))
181086b377d0Spooka goto clean2;
1811*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, name))
181286b377d0Spooka goto clean2;
181386b377d0Spooka rtn = 1;
181486b377d0Spooka clean2:
181586b377d0Spooka free(num_str);
181686b377d0Spooka clean1:
181786b377d0Spooka free(name);
181886b377d0Spooka return (rtn);
181986b377d0Spooka
182086b377d0Spooka case SIMPLE_HASH('G', 'T'):
182186b377d0Spooka ddata->cur += 2;
182286b377d0Spooka if (*ddata->cur == '\0')
182386b377d0Spooka return (0);
182486b377d0Spooka switch (*ddata->cur) {
182586b377d0Spooka case 'n':
1826*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "non-transaction clone for "))
182786b377d0Spooka return (0);
1828*d678c5d4Sjoerg break;
182986b377d0Spooka case 't':
183086b377d0Spooka default:
1831*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "transaction clone for "))
183286b377d0Spooka return (0);
1833*d678c5d4Sjoerg break;
183486b377d0Spooka }
183586b377d0Spooka ++ddata->cur;
183686b377d0Spooka return (cpp_demangle_read_encoding(ddata));
183786b377d0Spooka
18384cc2045aSjoerg case SIMPLE_HASH('G', 'V'):
18394cc2045aSjoerg /* sentry object for 1 time init */
1840*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "guard variable for "))
18414cc2045aSjoerg return (0);
18424cc2045aSjoerg ddata->cur += 2;
18434cc2045aSjoerg break;
18444cc2045aSjoerg
18454cc2045aSjoerg case SIMPLE_HASH('T', 'c'):
18464cc2045aSjoerg /* virtual function covariant override thunk */
1847*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata,
1848*d678c5d4Sjoerg "virtual function covariant override "))
18494cc2045aSjoerg return (0);
18504cc2045aSjoerg ddata->cur += 2;
18514cc2045aSjoerg if (*ddata->cur == '\0')
18524cc2045aSjoerg return (0);
18534cc2045aSjoerg if (!cpp_demangle_read_offset(ddata))
18544cc2045aSjoerg return (0);
18554cc2045aSjoerg if (!cpp_demangle_read_offset(ddata))
18564cc2045aSjoerg return (0);
18574cc2045aSjoerg return (cpp_demangle_read_encoding(ddata));
18584cc2045aSjoerg
185986b377d0Spooka case SIMPLE_HASH('T', 'C'):
186086b377d0Spooka /* construction vtable */
1861*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "construction vtable for "))
186286b377d0Spooka return (0);
186386b377d0Spooka ddata->cur += 2;
186486b377d0Spooka if (*ddata->cur == '\0')
186586b377d0Spooka return (0);
186686b377d0Spooka if (!cpp_demangle_read_type_flat(ddata, &type))
186786b377d0Spooka return (0);
186886b377d0Spooka rtn = 0;
186986b377d0Spooka if (!cpp_demangle_read_number(ddata, &offset))
187086b377d0Spooka goto clean3;
187186b377d0Spooka if (*ddata->cur++ != '_')
187286b377d0Spooka goto clean3;
1873*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
187486b377d0Spooka goto clean3;
1875*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "-in-"))
187686b377d0Spooka goto clean3;
1877*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, type))
187886b377d0Spooka goto clean3;
187986b377d0Spooka rtn = 1;
188086b377d0Spooka clean3:
188186b377d0Spooka free(type);
188286b377d0Spooka return (rtn);
188386b377d0Spooka
18844cc2045aSjoerg case SIMPLE_HASH('T', 'D'):
18854cc2045aSjoerg /* typeinfo common proxy */
18864cc2045aSjoerg break;
18874cc2045aSjoerg
188886b377d0Spooka case SIMPLE_HASH('T', 'F'):
188986b377d0Spooka /* typeinfo fn */
1890*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "typeinfo fn for "))
189186b377d0Spooka return (0);
189286b377d0Spooka ddata->cur += 2;
189386b377d0Spooka if (*ddata->cur == '\0')
189486b377d0Spooka return (0);
1895*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
189686b377d0Spooka
18974cc2045aSjoerg case SIMPLE_HASH('T', 'h'):
18984cc2045aSjoerg /* virtual function non-virtual override thunk */
1899*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata,
1900*d678c5d4Sjoerg "virtual function non-virtual override "))
19014cc2045aSjoerg return (0);
19024cc2045aSjoerg ddata->cur += 2;
19034cc2045aSjoerg if (*ddata->cur == '\0')
19044cc2045aSjoerg return (0);
19054cc2045aSjoerg if (!cpp_demangle_read_nv_offset(ddata))
19064cc2045aSjoerg return (0);
19074cc2045aSjoerg return (cpp_demangle_read_encoding(ddata));
19084cc2045aSjoerg
190986b377d0Spooka case SIMPLE_HASH('T', 'H'):
191086b377d0Spooka /* TLS init function */
1911*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "TLS init function for "))
19124cc2045aSjoerg return (0);
19134cc2045aSjoerg ddata->cur += 2;
19144cc2045aSjoerg if (*ddata->cur == '\0')
19154cc2045aSjoerg return (0);
191686b377d0Spooka break;
191786b377d0Spooka
191886b377d0Spooka case SIMPLE_HASH('T', 'I'):
191986b377d0Spooka /* typeinfo structure */
1920*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "typeinfo for "))
192186b377d0Spooka return (0);
192286b377d0Spooka ddata->cur += 2;
192386b377d0Spooka if (*ddata->cur == '\0')
192486b377d0Spooka return (0);
1925*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
192686b377d0Spooka
192786b377d0Spooka case SIMPLE_HASH('T', 'J'):
192886b377d0Spooka /* java class */
1929*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "java Class for "))
193086b377d0Spooka return (0);
193186b377d0Spooka ddata->cur += 2;
193286b377d0Spooka if (*ddata->cur == '\0')
193386b377d0Spooka return (0);
1934*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
193586b377d0Spooka
193686b377d0Spooka case SIMPLE_HASH('T', 'S'):
193786b377d0Spooka /* RTTI name (NTBS) */
1938*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "typeinfo name for "))
193986b377d0Spooka return (0);
194086b377d0Spooka ddata->cur += 2;
194186b377d0Spooka if (*ddata->cur == '\0')
194286b377d0Spooka return (0);
1943*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
19444cc2045aSjoerg
19454cc2045aSjoerg case SIMPLE_HASH('T', 'T'):
19464cc2045aSjoerg /* VTT table */
1947*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "VTT for "))
19484cc2045aSjoerg return (0);
19494cc2045aSjoerg ddata->cur += 2;
195086b377d0Spooka if (*ddata->cur == '\0')
195186b377d0Spooka return (0);
1952*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
19534cc2045aSjoerg
19544cc2045aSjoerg case SIMPLE_HASH('T', 'v'):
19554cc2045aSjoerg /* virtual function virtual override thunk */
1956*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "virtual function virtual override "))
19574cc2045aSjoerg return (0);
19584cc2045aSjoerg ddata->cur += 2;
19594cc2045aSjoerg if (*ddata->cur == '\0')
19604cc2045aSjoerg return (0);
19614cc2045aSjoerg if (!cpp_demangle_read_v_offset(ddata))
19624cc2045aSjoerg return (0);
19634cc2045aSjoerg return (cpp_demangle_read_encoding(ddata));
19644cc2045aSjoerg
19654cc2045aSjoerg case SIMPLE_HASH('T', 'V'):
19664cc2045aSjoerg /* virtual table */
1967*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "vtable for "))
19684cc2045aSjoerg return (0);
19694cc2045aSjoerg ddata->cur += 2;
19704cc2045aSjoerg if (*ddata->cur == '\0')
19714cc2045aSjoerg return (0);
1972*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
197386b377d0Spooka
197486b377d0Spooka case SIMPLE_HASH('T', 'W'):
197586b377d0Spooka /* TLS wrapper function */
1976*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "TLS wrapper function for "))
197786b377d0Spooka return (0);
197886b377d0Spooka ddata->cur += 2;
197986b377d0Spooka if (*ddata->cur == '\0')
198086b377d0Spooka return (0);
198186b377d0Spooka break;
1982*d678c5d4Sjoerg }
19834cc2045aSjoerg
19844cc2045aSjoerg return (cpp_demangle_read_name(ddata));
19854cc2045aSjoerg }
19864cc2045aSjoerg
19874cc2045aSjoerg static int
cpp_demangle_read_local_name(struct cpp_demangle_data * ddata)19884cc2045aSjoerg cpp_demangle_read_local_name(struct cpp_demangle_data *ddata)
19894cc2045aSjoerg {
1990*d678c5d4Sjoerg struct vector_str local_name;
1991*d678c5d4Sjoerg struct type_delimit td;
19924cc2045aSjoerg size_t limit;
1993*d678c5d4Sjoerg bool more_type;
19944cc2045aSjoerg
19954cc2045aSjoerg if (ddata == NULL)
19964cc2045aSjoerg return (0);
19974cc2045aSjoerg if (*(++ddata->cur) == '\0')
19984cc2045aSjoerg return (0);
19994cc2045aSjoerg
2000*d678c5d4Sjoerg if (!vector_str_init(&local_name))
20014cc2045aSjoerg return (0);
2002*d678c5d4Sjoerg ddata->cur_output = &local_name;
2003*d678c5d4Sjoerg
2004*d678c5d4Sjoerg if (!cpp_demangle_read_encoding(ddata)) {
2005*d678c5d4Sjoerg vector_str_dest(&local_name);
2006*d678c5d4Sjoerg return (0);
2007*d678c5d4Sjoerg }
2008*d678c5d4Sjoerg
2009*d678c5d4Sjoerg ddata->cur_output = &ddata->output;
2010*d678c5d4Sjoerg
2011*d678c5d4Sjoerg td.paren = false;
2012*d678c5d4Sjoerg td.firstp = true;
2013*d678c5d4Sjoerg more_type = false;
2014*d678c5d4Sjoerg limit = 0;
2015*d678c5d4Sjoerg
2016*d678c5d4Sjoerg /*
2017*d678c5d4Sjoerg * The first type is a return type if we just demangled template
2018*d678c5d4Sjoerg * args. (the template args is right next to the function name,
2019*d678c5d4Sjoerg * which means it's a template function)
2020*d678c5d4Sjoerg */
2021*d678c5d4Sjoerg if (ddata->is_tmpl) {
2022*d678c5d4Sjoerg ddata->is_tmpl = false;
2023*d678c5d4Sjoerg
2024*d678c5d4Sjoerg /* Read return type */
2025*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL)) {
2026*d678c5d4Sjoerg vector_str_dest(&local_name);
2027*d678c5d4Sjoerg return (0);
2028*d678c5d4Sjoerg }
2029*d678c5d4Sjoerg
2030*d678c5d4Sjoerg more_type = true;
2031*d678c5d4Sjoerg }
2032*d678c5d4Sjoerg
2033*d678c5d4Sjoerg /* Now we can push the name after possible return type is handled. */
2034*d678c5d4Sjoerg if (!vector_str_push_vector(&ddata->output, &local_name)) {
2035*d678c5d4Sjoerg vector_str_dest(&local_name);
2036*d678c5d4Sjoerg return (0);
2037*d678c5d4Sjoerg }
2038*d678c5d4Sjoerg vector_str_dest(&local_name);
2039*d678c5d4Sjoerg
2040*d678c5d4Sjoerg while (*ddata->cur != '\0') {
2041*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, &td))
2042*d678c5d4Sjoerg return (0);
2043*d678c5d4Sjoerg if (more_type)
2044*d678c5d4Sjoerg more_type = false;
20454cc2045aSjoerg if (*ddata->cur == 'E')
20464cc2045aSjoerg break;
20474cc2045aSjoerg if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
20484cc2045aSjoerg return (0);
20494cc2045aSjoerg }
2050*d678c5d4Sjoerg if (more_type)
2051*d678c5d4Sjoerg return (0);
2052*d678c5d4Sjoerg
20534cc2045aSjoerg if (*(++ddata->cur) == '\0')
20544cc2045aSjoerg return (0);
2055*d678c5d4Sjoerg if (td.paren == true) {
2056*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, ")"))
20574cc2045aSjoerg return (0);
2058*d678c5d4Sjoerg td.paren = false;
20594cc2045aSjoerg }
20604cc2045aSjoerg if (*ddata->cur == 's')
20614cc2045aSjoerg ++ddata->cur;
20624cc2045aSjoerg else {
2063*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "::"))
20644cc2045aSjoerg return (0);
20654cc2045aSjoerg if (!cpp_demangle_read_name(ddata))
20664cc2045aSjoerg return (0);
20674cc2045aSjoerg }
20684cc2045aSjoerg if (*ddata->cur == '_') {
20694cc2045aSjoerg ++ddata->cur;
20704cc2045aSjoerg while (ELFTC_ISDIGIT(*ddata->cur) != 0)
20714cc2045aSjoerg ++ddata->cur;
20724cc2045aSjoerg }
20734cc2045aSjoerg
20744cc2045aSjoerg return (1);
20754cc2045aSjoerg }
20764cc2045aSjoerg
20774cc2045aSjoerg static int
cpp_demangle_read_name(struct cpp_demangle_data * ddata)20784cc2045aSjoerg cpp_demangle_read_name(struct cpp_demangle_data *ddata)
20794cc2045aSjoerg {
20804cc2045aSjoerg struct vector_str *output, v;
20814cc2045aSjoerg size_t p_idx, subst_str_len;
20824cc2045aSjoerg int rtn;
20834cc2045aSjoerg char *subst_str;
20844cc2045aSjoerg
20854cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
20864cc2045aSjoerg return (0);
20874cc2045aSjoerg
2088*d678c5d4Sjoerg output = ddata->cur_output;
20894cc2045aSjoerg
20904cc2045aSjoerg subst_str = NULL;
20914cc2045aSjoerg
20924cc2045aSjoerg switch (*ddata->cur) {
20934cc2045aSjoerg case 'S':
20944cc2045aSjoerg return (cpp_demangle_read_subst(ddata));
20954cc2045aSjoerg case 'N':
20964cc2045aSjoerg return (cpp_demangle_read_nested_name(ddata));
20974cc2045aSjoerg case 'Z':
20984cc2045aSjoerg return (cpp_demangle_read_local_name(ddata));
2099*d678c5d4Sjoerg }
21004cc2045aSjoerg
21014cc2045aSjoerg if (!vector_str_init(&v))
21024cc2045aSjoerg return (0);
21034cc2045aSjoerg
21044cc2045aSjoerg p_idx = output->size;
21054cc2045aSjoerg rtn = 0;
21064cc2045aSjoerg if (!cpp_demangle_read_uqname(ddata))
21074cc2045aSjoerg goto clean;
21084cc2045aSjoerg if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,
21094cc2045aSjoerg &subst_str_len)) == NULL)
21104cc2045aSjoerg goto clean;
21114cc2045aSjoerg if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) {
21124cc2045aSjoerg rtn = 1;
21134cc2045aSjoerg goto clean;
21144cc2045aSjoerg }
21154cc2045aSjoerg if (!vector_str_push(&v, subst_str, subst_str_len))
21164cc2045aSjoerg goto clean;
21174cc2045aSjoerg if (!cpp_demangle_push_subst_v(ddata, &v))
21184cc2045aSjoerg goto clean;
21194cc2045aSjoerg
21204cc2045aSjoerg if (*ddata->cur == 'I') {
21214cc2045aSjoerg p_idx = output->size;
21224cc2045aSjoerg if (!cpp_demangle_read_tmpl_args(ddata))
21234cc2045aSjoerg goto clean;
21244cc2045aSjoerg free(subst_str);
21254cc2045aSjoerg if ((subst_str = vector_str_substr(output, p_idx,
21264cc2045aSjoerg output->size - 1, &subst_str_len)) == NULL)
21274cc2045aSjoerg goto clean;
21284cc2045aSjoerg if (!vector_str_push(&v, subst_str, subst_str_len))
21294cc2045aSjoerg goto clean;
21304cc2045aSjoerg if (!cpp_demangle_push_subst_v(ddata, &v))
21314cc2045aSjoerg goto clean;
21324cc2045aSjoerg }
21334cc2045aSjoerg
21344cc2045aSjoerg rtn = 1;
21354cc2045aSjoerg
21364cc2045aSjoerg clean:
21374cc2045aSjoerg free(subst_str);
21384cc2045aSjoerg vector_str_dest(&v);
21394cc2045aSjoerg
21404cc2045aSjoerg return (rtn);
21414cc2045aSjoerg }
21424cc2045aSjoerg
21434cc2045aSjoerg static int
cpp_demangle_read_name_flat(struct cpp_demangle_data * ddata,char ** str)214486b377d0Spooka cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str)
214586b377d0Spooka {
214686b377d0Spooka struct vector_str *output;
214786b377d0Spooka size_t i, p_idx, idx, name_len;
214886b377d0Spooka char *name;
214986b377d0Spooka
2150*d678c5d4Sjoerg output = ddata->cur_output;
215186b377d0Spooka
215286b377d0Spooka p_idx = output->size;
215386b377d0Spooka
215486b377d0Spooka if (!cpp_demangle_read_name(ddata))
215586b377d0Spooka return (0);
215686b377d0Spooka
215786b377d0Spooka if ((name = vector_str_substr(output, p_idx, output->size - 1,
215886b377d0Spooka &name_len)) == NULL)
215986b377d0Spooka return (0);
216086b377d0Spooka
216186b377d0Spooka idx = output->size;
216286b377d0Spooka for (i = p_idx; i < idx; ++i) {
216386b377d0Spooka if (!vector_str_pop(output)) {
216486b377d0Spooka free(name);
216586b377d0Spooka return (0);
216686b377d0Spooka }
216786b377d0Spooka }
216886b377d0Spooka
216986b377d0Spooka *str = name;
217086b377d0Spooka
217186b377d0Spooka return (1);
217286b377d0Spooka }
217386b377d0Spooka
217486b377d0Spooka static int
cpp_demangle_read_nested_name(struct cpp_demangle_data * ddata)21754cc2045aSjoerg cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata)
21764cc2045aSjoerg {
21774cc2045aSjoerg struct vector_str *output, v;
21784cc2045aSjoerg size_t limit, p_idx, subst_str_len;
21794cc2045aSjoerg int rtn;
21804cc2045aSjoerg char *subst_str;
21814cc2045aSjoerg
21824cc2045aSjoerg if (ddata == NULL || *ddata->cur != 'N')
21834cc2045aSjoerg return (0);
21844cc2045aSjoerg if (*(++ddata->cur) == '\0')
21854cc2045aSjoerg return (0);
21864cc2045aSjoerg
2187*d678c5d4Sjoerg do {
21884cc2045aSjoerg switch (*ddata->cur) {
21894cc2045aSjoerg case 'r':
21904cc2045aSjoerg ddata->mem_rst = true;
21914cc2045aSjoerg break;
21924cc2045aSjoerg case 'V':
21934cc2045aSjoerg ddata->mem_vat = true;
21944cc2045aSjoerg break;
21954cc2045aSjoerg case 'K':
21964cc2045aSjoerg ddata->mem_cst = true;
21974cc2045aSjoerg break;
2198*d678c5d4Sjoerg case 'R':
2199*d678c5d4Sjoerg ddata->mem_ref = true;
2200*d678c5d4Sjoerg break;
2201*d678c5d4Sjoerg case 'O':
2202*d678c5d4Sjoerg ddata->mem_rref = true;
2203*d678c5d4Sjoerg break;
2204*d678c5d4Sjoerg default:
2205*d678c5d4Sjoerg goto next;
22064cc2045aSjoerg }
2207*d678c5d4Sjoerg } while (*(++ddata->cur));
22084cc2045aSjoerg
2209*d678c5d4Sjoerg next:
2210*d678c5d4Sjoerg output = ddata->cur_output;
22114cc2045aSjoerg if (!vector_str_init(&v))
22124cc2045aSjoerg return (0);
22134cc2045aSjoerg
22144cc2045aSjoerg rtn = 0;
22154cc2045aSjoerg limit = 0;
22164cc2045aSjoerg for (;;) {
22174cc2045aSjoerg p_idx = output->size;
22184cc2045aSjoerg switch (*ddata->cur) {
22194cc2045aSjoerg case 'I':
22204cc2045aSjoerg if (!cpp_demangle_read_tmpl_args(ddata))
22214cc2045aSjoerg goto clean;
22224cc2045aSjoerg break;
22234cc2045aSjoerg case 'S':
22244cc2045aSjoerg if (!cpp_demangle_read_subst(ddata))
22254cc2045aSjoerg goto clean;
22264cc2045aSjoerg break;
22274cc2045aSjoerg case 'T':
22284cc2045aSjoerg if (!cpp_demangle_read_tmpl_param(ddata))
22294cc2045aSjoerg goto clean;
22304cc2045aSjoerg break;
22314cc2045aSjoerg default:
22324cc2045aSjoerg if (!cpp_demangle_read_uqname(ddata))
22334cc2045aSjoerg goto clean;
2234*d678c5d4Sjoerg }
22354cc2045aSjoerg
2236*d678c5d4Sjoerg if (p_idx == output->size)
2237*d678c5d4Sjoerg goto next_comp;
22384cc2045aSjoerg if ((subst_str = vector_str_substr(output, p_idx,
22394cc2045aSjoerg output->size - 1, &subst_str_len)) == NULL)
22404cc2045aSjoerg goto clean;
22414cc2045aSjoerg if (!vector_str_push(&v, subst_str, subst_str_len)) {
22424cc2045aSjoerg free(subst_str);
22434cc2045aSjoerg goto clean;
22444cc2045aSjoerg }
22454cc2045aSjoerg free(subst_str);
22464cc2045aSjoerg
22474cc2045aSjoerg if (!cpp_demangle_push_subst_v(ddata, &v))
22484cc2045aSjoerg goto clean;
2249*d678c5d4Sjoerg
2250*d678c5d4Sjoerg next_comp:
22514cc2045aSjoerg if (*ddata->cur == 'E')
22524cc2045aSjoerg break;
2253*d678c5d4Sjoerg else if (*ddata->cur != 'I' && *ddata->cur != 'C' &&
2254*d678c5d4Sjoerg *ddata->cur != 'D' && p_idx != output->size) {
2255*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "::"))
22564cc2045aSjoerg goto clean;
2257*d678c5d4Sjoerg if (!VEC_PUSH_STR(&v, "::"))
22584cc2045aSjoerg goto clean;
22594cc2045aSjoerg }
22604cc2045aSjoerg if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
22614cc2045aSjoerg goto clean;
22624cc2045aSjoerg }
22634cc2045aSjoerg
22644cc2045aSjoerg ++ddata->cur;
22654cc2045aSjoerg rtn = 1;
22664cc2045aSjoerg
22674cc2045aSjoerg clean:
22684cc2045aSjoerg vector_str_dest(&v);
22694cc2045aSjoerg
22704cc2045aSjoerg return (rtn);
22714cc2045aSjoerg }
22724cc2045aSjoerg
22734cc2045aSjoerg /*
22744cc2045aSjoerg * read number
22754cc2045aSjoerg * number ::= [n] <decimal>
22764cc2045aSjoerg */
22774cc2045aSjoerg static int
cpp_demangle_read_number(struct cpp_demangle_data * ddata,long * rtn)22784cc2045aSjoerg cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn)
22794cc2045aSjoerg {
22804cc2045aSjoerg long len, negative_factor;
22814cc2045aSjoerg
22824cc2045aSjoerg if (ddata == NULL || rtn == NULL)
22834cc2045aSjoerg return (0);
22844cc2045aSjoerg
22854cc2045aSjoerg negative_factor = 1;
22864cc2045aSjoerg if (*ddata->cur == 'n') {
22874cc2045aSjoerg negative_factor = -1;
22884cc2045aSjoerg
22894cc2045aSjoerg ++ddata->cur;
22904cc2045aSjoerg }
22914cc2045aSjoerg if (ELFTC_ISDIGIT(*ddata->cur) == 0)
22924cc2045aSjoerg return (0);
22934cc2045aSjoerg
22944cc2045aSjoerg errno = 0;
22954cc2045aSjoerg if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 &&
22964cc2045aSjoerg errno != 0)
22974cc2045aSjoerg return (0);
22984cc2045aSjoerg
22994cc2045aSjoerg while (ELFTC_ISDIGIT(*ddata->cur) != 0)
23004cc2045aSjoerg ++ddata->cur;
23014cc2045aSjoerg
23024cc2045aSjoerg assert(len >= 0);
23034cc2045aSjoerg assert(negative_factor == 1 || negative_factor == -1);
23044cc2045aSjoerg
23054cc2045aSjoerg *rtn = len * negative_factor;
23064cc2045aSjoerg
23074cc2045aSjoerg return (1);
23084cc2045aSjoerg }
23094cc2045aSjoerg
23104cc2045aSjoerg static int
cpp_demangle_read_number_as_string(struct cpp_demangle_data * ddata,char ** str)231186b377d0Spooka cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str)
231286b377d0Spooka {
231386b377d0Spooka long n;
231486b377d0Spooka
231586b377d0Spooka if (!cpp_demangle_read_number(ddata, &n)) {
231686b377d0Spooka *str = NULL;
231786b377d0Spooka return (0);
231886b377d0Spooka }
231986b377d0Spooka
232086b377d0Spooka if (asprintf(str, "%ld", n) < 0) {
232186b377d0Spooka *str = NULL;
232286b377d0Spooka return (0);
232386b377d0Spooka }
232486b377d0Spooka
232586b377d0Spooka return (1);
232686b377d0Spooka }
232786b377d0Spooka
232886b377d0Spooka static int
cpp_demangle_read_nv_offset(struct cpp_demangle_data * ddata)23294cc2045aSjoerg cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata)
23304cc2045aSjoerg {
23314cc2045aSjoerg
23324cc2045aSjoerg if (ddata == NULL)
23334cc2045aSjoerg return (0);
23344cc2045aSjoerg
2335*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "offset : "))
23364cc2045aSjoerg return (0);
23374cc2045aSjoerg
23384cc2045aSjoerg return (cpp_demangle_read_offset_number(ddata));
23394cc2045aSjoerg }
23404cc2045aSjoerg
23414cc2045aSjoerg /* read offset, offset are nv-offset, v-offset */
23424cc2045aSjoerg static int
cpp_demangle_read_offset(struct cpp_demangle_data * ddata)23434cc2045aSjoerg cpp_demangle_read_offset(struct cpp_demangle_data *ddata)
23444cc2045aSjoerg {
23454cc2045aSjoerg
23464cc2045aSjoerg if (ddata == NULL)
23474cc2045aSjoerg return (0);
23484cc2045aSjoerg
23494cc2045aSjoerg if (*ddata->cur == 'h') {
23504cc2045aSjoerg ++ddata->cur;
23514cc2045aSjoerg return (cpp_demangle_read_nv_offset(ddata));
23524cc2045aSjoerg } else if (*ddata->cur == 'v') {
23534cc2045aSjoerg ++ddata->cur;
23544cc2045aSjoerg return (cpp_demangle_read_v_offset(ddata));
23554cc2045aSjoerg }
23564cc2045aSjoerg
23574cc2045aSjoerg return (0);
23584cc2045aSjoerg }
23594cc2045aSjoerg
23604cc2045aSjoerg static int
cpp_demangle_read_offset_number(struct cpp_demangle_data * ddata)23614cc2045aSjoerg cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata)
23624cc2045aSjoerg {
23634cc2045aSjoerg bool negative;
23644cc2045aSjoerg const char *start;
23654cc2045aSjoerg
23664cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
23674cc2045aSjoerg return (0);
23684cc2045aSjoerg
23694cc2045aSjoerg /* offset could be negative */
23704cc2045aSjoerg if (*ddata->cur == 'n') {
23714cc2045aSjoerg negative = true;
23724cc2045aSjoerg start = ddata->cur + 1;
23734cc2045aSjoerg } else {
23744cc2045aSjoerg negative = false;
23754cc2045aSjoerg start = ddata->cur;
23764cc2045aSjoerg }
23774cc2045aSjoerg
23784cc2045aSjoerg while (*ddata->cur != '_')
23794cc2045aSjoerg ++ddata->cur;
23804cc2045aSjoerg
2381*d678c5d4Sjoerg if (negative && !DEM_PUSH_STR(ddata, "-"))
23824cc2045aSjoerg return (0);
23834cc2045aSjoerg
23844cc2045aSjoerg assert(start != NULL);
23854cc2045aSjoerg
23864cc2045aSjoerg if (!cpp_demangle_push_str(ddata, start, ddata->cur - start))
23874cc2045aSjoerg return (0);
2388*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " "))
23894cc2045aSjoerg return (0);
23904cc2045aSjoerg
23914cc2045aSjoerg ++ddata->cur;
23924cc2045aSjoerg
23934cc2045aSjoerg return (1);
23944cc2045aSjoerg }
23954cc2045aSjoerg
23964cc2045aSjoerg static int
cpp_demangle_read_pointer_to_member(struct cpp_demangle_data * ddata,struct vector_type_qualifier * v)2397*d678c5d4Sjoerg cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata,
2398*d678c5d4Sjoerg struct vector_type_qualifier *v)
23994cc2045aSjoerg {
24004cc2045aSjoerg size_t class_type_len, i, idx, p_idx;
24014cc2045aSjoerg int p_func_type, rtn;
24024cc2045aSjoerg char *class_type;
24034cc2045aSjoerg
24044cc2045aSjoerg if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0')
24054cc2045aSjoerg return (0);
24064cc2045aSjoerg
24074cc2045aSjoerg p_idx = ddata->output.size;
2408*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
24094cc2045aSjoerg return (0);
24104cc2045aSjoerg
24114cc2045aSjoerg if ((class_type = vector_str_substr(&ddata->output, p_idx,
24124cc2045aSjoerg ddata->output.size - 1, &class_type_len)) == NULL)
24134cc2045aSjoerg return (0);
24144cc2045aSjoerg
24154cc2045aSjoerg rtn = 0;
24164cc2045aSjoerg idx = ddata->output.size;
24174cc2045aSjoerg for (i = p_idx; i < idx; ++i)
24184cc2045aSjoerg if (!vector_str_pop(&ddata->output))
24194cc2045aSjoerg goto clean1;
24204cc2045aSjoerg
2421*d678c5d4Sjoerg if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM, v))
24224cc2045aSjoerg goto clean1;
24234cc2045aSjoerg
24244cc2045aSjoerg if (!vector_str_push(&ddata->class_type, class_type, class_type_len))
24254cc2045aSjoerg goto clean2;
24264cc2045aSjoerg
24274cc2045aSjoerg p_func_type = ddata->func_type;
2428*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
24294cc2045aSjoerg goto clean3;
24304cc2045aSjoerg
24314cc2045aSjoerg if (p_func_type == ddata->func_type) {
2432*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " "))
24334cc2045aSjoerg goto clean3;
24344cc2045aSjoerg if (!cpp_demangle_push_str(ddata, class_type, class_type_len))
24354cc2045aSjoerg goto clean3;
2436*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "::*"))
24374cc2045aSjoerg goto clean3;
24384cc2045aSjoerg }
24394cc2045aSjoerg
24404cc2045aSjoerg rtn = 1;
24414cc2045aSjoerg clean3:
24424cc2045aSjoerg if (!vector_str_pop(&ddata->class_type))
24434cc2045aSjoerg rtn = 0;
24444cc2045aSjoerg clean2:
24454cc2045aSjoerg if (!vector_read_cmd_pop(&ddata->cmd))
24464cc2045aSjoerg rtn = 0;
24474cc2045aSjoerg clean1:
24484cc2045aSjoerg free(class_type);
24494cc2045aSjoerg
2450*d678c5d4Sjoerg vector_type_qualifier_dest(v);
2451*d678c5d4Sjoerg if (!vector_type_qualifier_init(v))
2452*d678c5d4Sjoerg return (0);
2453*d678c5d4Sjoerg
24544cc2045aSjoerg return (rtn);
24554cc2045aSjoerg }
24564cc2045aSjoerg
24574cc2045aSjoerg /* read source-name, source-name is <len> <ID> */
24584cc2045aSjoerg static int
cpp_demangle_read_sname(struct cpp_demangle_data * ddata)24594cc2045aSjoerg cpp_demangle_read_sname(struct cpp_demangle_data *ddata)
24604cc2045aSjoerg {
24614cc2045aSjoerg long len;
24625192b81bSjoerg int err;
24634cc2045aSjoerg
24644cc2045aSjoerg if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 ||
24655192b81bSjoerg len <= 0)
24665192b81bSjoerg return (0);
24675192b81bSjoerg
24685192b81bSjoerg if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0))
2469*d678c5d4Sjoerg err = DEM_PUSH_STR(ddata, "(anonymous namespace)");
24705192b81bSjoerg else
24715192b81bSjoerg err = cpp_demangle_push_str(ddata, ddata->cur, len);
24725192b81bSjoerg
24735192b81bSjoerg if (err == 0)
24744cc2045aSjoerg return (0);
24754cc2045aSjoerg
2476*d678c5d4Sjoerg assert(ddata->cur_output->size > 0);
2477*d678c5d4Sjoerg if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL)
24784cc2045aSjoerg ddata->last_sname =
2479*d678c5d4Sjoerg ddata->cur_output->container[ddata->output.size - 1];
24804cc2045aSjoerg
24814cc2045aSjoerg ddata->cur += len;
24824cc2045aSjoerg
24834cc2045aSjoerg return (1);
24844cc2045aSjoerg }
24854cc2045aSjoerg
24864cc2045aSjoerg static int
cpp_demangle_read_subst(struct cpp_demangle_data * ddata)24874cc2045aSjoerg cpp_demangle_read_subst(struct cpp_demangle_data *ddata)
24884cc2045aSjoerg {
24894cc2045aSjoerg long nth;
24904cc2045aSjoerg
24914cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
24924cc2045aSjoerg return (0);
24934cc2045aSjoerg
24944cc2045aSjoerg /* abbreviations of the form Sx */
24954cc2045aSjoerg switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
24964cc2045aSjoerg case SIMPLE_HASH('S', 'a'):
24974cc2045aSjoerg /* std::allocator */
2498*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "std::allocator"))
24994cc2045aSjoerg return (0);
25004cc2045aSjoerg ddata->cur += 2;
25014cc2045aSjoerg if (*ddata->cur == 'I')
25024cc2045aSjoerg return (cpp_demangle_read_subst_stdtmpl(ddata,
2503*d678c5d4Sjoerg "std::allocator"));
25044cc2045aSjoerg return (1);
25054cc2045aSjoerg
25064cc2045aSjoerg case SIMPLE_HASH('S', 'b'):
25074cc2045aSjoerg /* std::basic_string */
2508*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "std::basic_string"))
25094cc2045aSjoerg return (0);
25104cc2045aSjoerg ddata->cur += 2;
25114cc2045aSjoerg if (*ddata->cur == 'I')
25124cc2045aSjoerg return (cpp_demangle_read_subst_stdtmpl(ddata,
2513*d678c5d4Sjoerg "std::basic_string"));
25144cc2045aSjoerg return (1);
25154cc2045aSjoerg
25164cc2045aSjoerg case SIMPLE_HASH('S', 'd'):
25174cc2045aSjoerg /* std::basic_iostream<char, std::char_traits<char> > */
2518*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "std::basic_iostream<char, "
2519*d678c5d4Sjoerg "std::char_traits<char> >"))
25204cc2045aSjoerg return (0);
2521*d678c5d4Sjoerg ddata->last_sname = "basic_iostream";
25224cc2045aSjoerg ddata->cur += 2;
25234cc2045aSjoerg if (*ddata->cur == 'I')
25244cc2045aSjoerg return (cpp_demangle_read_subst_stdtmpl(ddata,
2525*d678c5d4Sjoerg "std::basic_iostream<char, std::char_traits"
2526*d678c5d4Sjoerg "<char> >"));
25274cc2045aSjoerg return (1);
25284cc2045aSjoerg
25294cc2045aSjoerg case SIMPLE_HASH('S', 'i'):
25304cc2045aSjoerg /* std::basic_istream<char, std::char_traits<char> > */
2531*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "std::basic_istream<char, "
2532*d678c5d4Sjoerg "std::char_traits<char> >"))
25334cc2045aSjoerg return (0);
2534*d678c5d4Sjoerg ddata->last_sname = "basic_istream";
25354cc2045aSjoerg ddata->cur += 2;
25364cc2045aSjoerg if (*ddata->cur == 'I')
25374cc2045aSjoerg return (cpp_demangle_read_subst_stdtmpl(ddata,
2538*d678c5d4Sjoerg "std::basic_istream<char, std::char_traits"
2539*d678c5d4Sjoerg "<char> >"));
25404cc2045aSjoerg return (1);
25414cc2045aSjoerg
25424cc2045aSjoerg case SIMPLE_HASH('S', 'o'):
25434cc2045aSjoerg /* std::basic_ostream<char, std::char_traits<char> > */
2544*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "std::basic_ostream<char, "
2545*d678c5d4Sjoerg "std::char_traits<char> >"))
25464cc2045aSjoerg return (0);
2547*d678c5d4Sjoerg ddata->last_sname = "basic_ostream";
25484cc2045aSjoerg ddata->cur += 2;
25494cc2045aSjoerg if (*ddata->cur == 'I')
25504cc2045aSjoerg return (cpp_demangle_read_subst_stdtmpl(ddata,
2551*d678c5d4Sjoerg "std::basic_ostream<char, std::char_traits"
2552*d678c5d4Sjoerg "<char> >"));
25534cc2045aSjoerg return (1);
25544cc2045aSjoerg
25554cc2045aSjoerg case SIMPLE_HASH('S', 's'):
25564cc2045aSjoerg /*
25574cc2045aSjoerg * std::basic_string<char, std::char_traits<char>,
25584cc2045aSjoerg * std::allocator<char> >
25594cc2045aSjoerg *
25604cc2045aSjoerg * a.k.a std::string
25614cc2045aSjoerg */
2562*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "std::basic_string<char, "
2563*d678c5d4Sjoerg "std::char_traits<char>, std::allocator<char> >"))
25644cc2045aSjoerg return (0);
25654cc2045aSjoerg ddata->last_sname = "string";
25664cc2045aSjoerg ddata->cur += 2;
25674cc2045aSjoerg if (*ddata->cur == 'I')
25684cc2045aSjoerg return (cpp_demangle_read_subst_stdtmpl(ddata,
2569*d678c5d4Sjoerg "std::basic_string<char, std::char_traits<char>,"
2570*d678c5d4Sjoerg " std::allocator<char> >"));
25714cc2045aSjoerg return (1);
25724cc2045aSjoerg
25734cc2045aSjoerg case SIMPLE_HASH('S', 't'):
25744cc2045aSjoerg /* std:: */
25754cc2045aSjoerg return (cpp_demangle_read_subst_std(ddata));
2576*d678c5d4Sjoerg }
25774cc2045aSjoerg
25784cc2045aSjoerg if (*(++ddata->cur) == '\0')
25794cc2045aSjoerg return (0);
25804cc2045aSjoerg
2581*d678c5d4Sjoerg /* Skip unknown substitution abbreviations. */
2582*d678c5d4Sjoerg if (!(*ddata->cur >= '0' && *ddata->cur <= '9') &&
2583*d678c5d4Sjoerg !(*ddata->cur >= 'A' && *ddata->cur <= 'Z') &&
2584*d678c5d4Sjoerg *ddata->cur != '_') {
2585*d678c5d4Sjoerg ++ddata->cur;
2586*d678c5d4Sjoerg return (1);
2587*d678c5d4Sjoerg }
2588*d678c5d4Sjoerg
25894cc2045aSjoerg /* substitution */
25904cc2045aSjoerg if (*ddata->cur == '_')
25914cc2045aSjoerg return (cpp_demangle_get_subst(ddata, 0));
25924cc2045aSjoerg else {
25934cc2045aSjoerg errno = 0;
25944cc2045aSjoerg /* substitution number is base 36 */
25954cc2045aSjoerg if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&
25964cc2045aSjoerg errno != 0)
25974cc2045aSjoerg return (0);
25984cc2045aSjoerg
25994cc2045aSjoerg /* first was '_', so increase one */
26004cc2045aSjoerg ++nth;
26014cc2045aSjoerg
26024cc2045aSjoerg while (*ddata->cur != '_')
26034cc2045aSjoerg ++ddata->cur;
26044cc2045aSjoerg
26054cc2045aSjoerg assert(nth > 0);
26064cc2045aSjoerg
26074cc2045aSjoerg return (cpp_demangle_get_subst(ddata, nth));
26084cc2045aSjoerg }
26094cc2045aSjoerg
26104cc2045aSjoerg /* NOTREACHED */
26114cc2045aSjoerg return (0);
26124cc2045aSjoerg }
26134cc2045aSjoerg
26144cc2045aSjoerg static int
cpp_demangle_read_subst_std(struct cpp_demangle_data * ddata)26154cc2045aSjoerg cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata)
26164cc2045aSjoerg {
26174cc2045aSjoerg struct vector_str *output, v;
26184cc2045aSjoerg size_t p_idx, subst_str_len;
26194cc2045aSjoerg int rtn;
26204cc2045aSjoerg char *subst_str;
26214cc2045aSjoerg
26224cc2045aSjoerg if (ddata == NULL)
26234cc2045aSjoerg return (0);
26244cc2045aSjoerg
26254cc2045aSjoerg if (!vector_str_init(&v))
26264cc2045aSjoerg return (0);
26274cc2045aSjoerg
26284cc2045aSjoerg subst_str = NULL;
26294cc2045aSjoerg rtn = 0;
2630*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "std::"))
26314cc2045aSjoerg goto clean;
26324cc2045aSjoerg
2633*d678c5d4Sjoerg if (!VEC_PUSH_STR(&v, "std::"))
26344cc2045aSjoerg goto clean;
26354cc2045aSjoerg
26364cc2045aSjoerg ddata->cur += 2;
26374cc2045aSjoerg
2638*d678c5d4Sjoerg output = ddata->cur_output;
26394cc2045aSjoerg
26404cc2045aSjoerg p_idx = output->size;
26414cc2045aSjoerg if (!cpp_demangle_read_uqname(ddata))
26424cc2045aSjoerg goto clean;
26434cc2045aSjoerg
26444cc2045aSjoerg if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,
26454cc2045aSjoerg &subst_str_len)) == NULL)
26464cc2045aSjoerg goto clean;
26474cc2045aSjoerg
26484cc2045aSjoerg if (!vector_str_push(&v, subst_str, subst_str_len))
26494cc2045aSjoerg goto clean;
26504cc2045aSjoerg
26514cc2045aSjoerg if (!cpp_demangle_push_subst_v(ddata, &v))
26524cc2045aSjoerg goto clean;
26534cc2045aSjoerg
26544cc2045aSjoerg if (*ddata->cur == 'I') {
26554cc2045aSjoerg p_idx = output->size;
26564cc2045aSjoerg if (!cpp_demangle_read_tmpl_args(ddata))
26574cc2045aSjoerg goto clean;
26584cc2045aSjoerg free(subst_str);
26594cc2045aSjoerg if ((subst_str = vector_str_substr(output, p_idx,
26604cc2045aSjoerg output->size - 1, &subst_str_len)) == NULL)
26614cc2045aSjoerg goto clean;
26624cc2045aSjoerg if (!vector_str_push(&v, subst_str, subst_str_len))
26634cc2045aSjoerg goto clean;
26644cc2045aSjoerg if (!cpp_demangle_push_subst_v(ddata, &v))
26654cc2045aSjoerg goto clean;
26664cc2045aSjoerg }
26674cc2045aSjoerg
26684cc2045aSjoerg rtn = 1;
26694cc2045aSjoerg clean:
26704cc2045aSjoerg free(subst_str);
26714cc2045aSjoerg vector_str_dest(&v);
26724cc2045aSjoerg
26735192b81bSjoerg return (rtn);
26744cc2045aSjoerg }
26754cc2045aSjoerg
26764cc2045aSjoerg static int
cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data * ddata,const char * str)26774cc2045aSjoerg cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata,
2678*d678c5d4Sjoerg const char *str)
26794cc2045aSjoerg {
26804cc2045aSjoerg struct vector_str *output;
2681*d678c5d4Sjoerg size_t p_idx, substr_len, len;
26824cc2045aSjoerg int rtn;
26834cc2045aSjoerg char *subst_str, *substr;
26844cc2045aSjoerg
2685*d678c5d4Sjoerg if (ddata == NULL || str == NULL)
26864cc2045aSjoerg return (0);
26874cc2045aSjoerg
2688*d678c5d4Sjoerg if ((len = strlen(str)) == 0)
2689*d678c5d4Sjoerg return (0);
2690*d678c5d4Sjoerg
2691*d678c5d4Sjoerg output = ddata->cur_output;
26924cc2045aSjoerg
26934cc2045aSjoerg p_idx = output->size;
26944cc2045aSjoerg substr = NULL;
26954cc2045aSjoerg subst_str = NULL;
26964cc2045aSjoerg
26974cc2045aSjoerg if (!cpp_demangle_read_tmpl_args(ddata))
26984cc2045aSjoerg return (0);
26994cc2045aSjoerg if ((substr = vector_str_substr(output, p_idx, output->size - 1,
27004cc2045aSjoerg &substr_len)) == NULL)
27014cc2045aSjoerg return (0);
27024cc2045aSjoerg
27034cc2045aSjoerg rtn = 0;
27044cc2045aSjoerg if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) ==
27054cc2045aSjoerg NULL)
27064cc2045aSjoerg goto clean;
27074cc2045aSjoerg
27084cc2045aSjoerg memcpy(subst_str, str, len);
27094cc2045aSjoerg memcpy(subst_str + len, substr, substr_len);
27104cc2045aSjoerg subst_str[substr_len + len] = '\0';
27114cc2045aSjoerg
27124cc2045aSjoerg if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len))
27134cc2045aSjoerg goto clean;
27144cc2045aSjoerg
27154cc2045aSjoerg rtn = 1;
27164cc2045aSjoerg clean:
27174cc2045aSjoerg free(subst_str);
27184cc2045aSjoerg free(substr);
27194cc2045aSjoerg
27204cc2045aSjoerg return (rtn);
27214cc2045aSjoerg }
27224cc2045aSjoerg
27234cc2045aSjoerg static int
cpp_demangle_read_tmpl_arg(struct cpp_demangle_data * ddata)27244cc2045aSjoerg cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata)
27254cc2045aSjoerg {
27264cc2045aSjoerg
27274cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
27284cc2045aSjoerg return (0);
27294cc2045aSjoerg
27304cc2045aSjoerg switch (*ddata->cur) {
27314cc2045aSjoerg case 'L':
27324cc2045aSjoerg return (cpp_demangle_read_expr_primary(ddata));
27334cc2045aSjoerg case 'X':
2734*d678c5d4Sjoerg ++ddata->cur;
2735*d678c5d4Sjoerg if (!cpp_demangle_read_expression(ddata))
2736*d678c5d4Sjoerg return (0);
2737*d678c5d4Sjoerg return (*ddata->cur++ == 'E');
2738*d678c5d4Sjoerg }
27394cc2045aSjoerg
2740*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
27414cc2045aSjoerg }
27424cc2045aSjoerg
27434cc2045aSjoerg static int
cpp_demangle_read_tmpl_args(struct cpp_demangle_data * ddata)27444cc2045aSjoerg cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)
27454cc2045aSjoerg {
27464cc2045aSjoerg struct vector_str *v;
27474cc2045aSjoerg size_t arg_len, idx, limit, size;
27484cc2045aSjoerg char *arg;
27494cc2045aSjoerg
27504cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
27514cc2045aSjoerg return (0);
27524cc2045aSjoerg
27534cc2045aSjoerg ++ddata->cur;
27544cc2045aSjoerg
2755*d678c5d4Sjoerg if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL, NULL))
27564cc2045aSjoerg return (0);
27574cc2045aSjoerg
2758*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "<"))
27594cc2045aSjoerg return (0);
27604cc2045aSjoerg
27614cc2045aSjoerg limit = 0;
2762*d678c5d4Sjoerg v = ddata->cur_output;
27634cc2045aSjoerg for (;;) {
27644cc2045aSjoerg idx = v->size;
27654cc2045aSjoerg if (!cpp_demangle_read_tmpl_arg(ddata))
27664cc2045aSjoerg return (0);
27674cc2045aSjoerg if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) ==
27684cc2045aSjoerg NULL)
27694cc2045aSjoerg return (0);
27704cc2045aSjoerg if (!vector_str_find(&ddata->tmpl, arg, arg_len) &&
27714cc2045aSjoerg !vector_str_push(&ddata->tmpl, arg, arg_len)) {
27724cc2045aSjoerg free(arg);
27734cc2045aSjoerg return (0);
27744cc2045aSjoerg }
27754cc2045aSjoerg
27764cc2045aSjoerg free(arg);
27774cc2045aSjoerg
27784cc2045aSjoerg if (*ddata->cur == 'E') {
27794cc2045aSjoerg ++ddata->cur;
27804cc2045aSjoerg size = v->size;
27814cc2045aSjoerg assert(size > 0);
27824cc2045aSjoerg if (!strncmp(v->container[size - 1], ">", 1)) {
2783*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, " >"))
27844cc2045aSjoerg return (0);
2785*d678c5d4Sjoerg } else if (!DEM_PUSH_STR(ddata, ">"))
27864cc2045aSjoerg return (0);
2787*d678c5d4Sjoerg ddata->is_tmpl = true;
27884cc2045aSjoerg break;
27894cc2045aSjoerg } else if (*ddata->cur != 'I' &&
2790*d678c5d4Sjoerg !DEM_PUSH_STR(ddata, ", "))
27914cc2045aSjoerg return (0);
27924cc2045aSjoerg
27934cc2045aSjoerg if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
27944cc2045aSjoerg return (0);
27954cc2045aSjoerg }
27964cc2045aSjoerg
27974cc2045aSjoerg return (vector_read_cmd_pop(&ddata->cmd));
27984cc2045aSjoerg }
27994cc2045aSjoerg
28004cc2045aSjoerg /*
28014cc2045aSjoerg * Read template parameter that forms in 'T[number]_'.
28024cc2045aSjoerg * This function much like to read_subst but only for types.
28034cc2045aSjoerg */
28044cc2045aSjoerg static int
cpp_demangle_read_tmpl_param(struct cpp_demangle_data * ddata)28054cc2045aSjoerg cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata)
28064cc2045aSjoerg {
28074cc2045aSjoerg long nth;
28084cc2045aSjoerg
28094cc2045aSjoerg if (ddata == NULL || *ddata->cur != 'T')
28104cc2045aSjoerg return (0);
28114cc2045aSjoerg
28124cc2045aSjoerg ++ddata->cur;
28134cc2045aSjoerg
28144cc2045aSjoerg if (*ddata->cur == '_')
28154cc2045aSjoerg return (cpp_demangle_get_tmpl_param(ddata, 0));
28164cc2045aSjoerg else {
28174cc2045aSjoerg
28184cc2045aSjoerg errno = 0;
28194cc2045aSjoerg if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&
28204cc2045aSjoerg errno != 0)
28214cc2045aSjoerg return (0);
28224cc2045aSjoerg
28234cc2045aSjoerg /* T_ is first */
28244cc2045aSjoerg ++nth;
28254cc2045aSjoerg
28264cc2045aSjoerg while (*ddata->cur != '_')
28274cc2045aSjoerg ++ddata->cur;
28284cc2045aSjoerg
28294cc2045aSjoerg assert(nth > 0);
28304cc2045aSjoerg
28314cc2045aSjoerg return (cpp_demangle_get_tmpl_param(ddata, nth));
28324cc2045aSjoerg }
28334cc2045aSjoerg
28344cc2045aSjoerg /* NOTREACHED */
28354cc2045aSjoerg return (0);
28364cc2045aSjoerg }
28374cc2045aSjoerg
28384cc2045aSjoerg static int
cpp_demangle_read_type(struct cpp_demangle_data * ddata,struct type_delimit * td)2839*d678c5d4Sjoerg cpp_demangle_read_type(struct cpp_demangle_data *ddata,
2840*d678c5d4Sjoerg struct type_delimit *td)
28414cc2045aSjoerg {
28424cc2045aSjoerg struct vector_type_qualifier v;
2843*d678c5d4Sjoerg struct vector_str *output, sv;
2844*d678c5d4Sjoerg size_t p_idx, type_str_len, subst_str_len;
28454cc2045aSjoerg int extern_c, is_builtin;
28464cc2045aSjoerg long len;
2847*d678c5d4Sjoerg const char *p;
2848*d678c5d4Sjoerg char *type_str, *exp_str, *num_str, *subst_str;
2849*d678c5d4Sjoerg bool skip_ref_qualifier, omit_void;
28504cc2045aSjoerg
28514cc2045aSjoerg if (ddata == NULL)
28524cc2045aSjoerg return (0);
28534cc2045aSjoerg
2854*d678c5d4Sjoerg output = ddata->cur_output;
2855*d678c5d4Sjoerg if (td) {
2856*d678c5d4Sjoerg if (td->paren == false) {
2857*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "("))
28584cc2045aSjoerg return (0);
28594cc2045aSjoerg if (ddata->output.size < 2)
28604cc2045aSjoerg return (0);
2861*d678c5d4Sjoerg td->paren = true;
28624cc2045aSjoerg }
28634cc2045aSjoerg
2864*d678c5d4Sjoerg if (!td->firstp) {
2865*d678c5d4Sjoerg if (*ddata->cur != 'I') {
2866*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, ", "))
28674cc2045aSjoerg return (0);
28684cc2045aSjoerg }
2869*d678c5d4Sjoerg }
2870*d678c5d4Sjoerg }
28714cc2045aSjoerg
28724cc2045aSjoerg assert(output != NULL);
28734cc2045aSjoerg /*
2874*d678c5d4Sjoerg * [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array
28754cc2045aSjoerg * pointer-to-member, template-param, template-template-param, subst
28764cc2045aSjoerg */
28774cc2045aSjoerg
28784cc2045aSjoerg if (!vector_type_qualifier_init(&v))
28794cc2045aSjoerg return (0);
28804cc2045aSjoerg
28814cc2045aSjoerg extern_c = 0;
28824cc2045aSjoerg is_builtin = 1;
28834cc2045aSjoerg p_idx = output->size;
288486b377d0Spooka type_str = exp_str = num_str = NULL;
2885*d678c5d4Sjoerg skip_ref_qualifier = false;
2886*d678c5d4Sjoerg
28874cc2045aSjoerg again:
2888*d678c5d4Sjoerg
2889*d678c5d4Sjoerg /* Clear ref-qualifier flag */
2890*d678c5d4Sjoerg if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E')
2891*d678c5d4Sjoerg ddata->ref_qualifier = false;
2892*d678c5d4Sjoerg
28934cc2045aSjoerg /* builtin type */
28944cc2045aSjoerg switch (*ddata->cur) {
28954cc2045aSjoerg case 'a':
28964cc2045aSjoerg /* signed char */
2897*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "signed char"))
28984cc2045aSjoerg goto clean;
28994cc2045aSjoerg ++ddata->cur;
29004cc2045aSjoerg goto rtn;
29014cc2045aSjoerg
29024cc2045aSjoerg case 'A':
29034cc2045aSjoerg /* array type */
29044cc2045aSjoerg if (!cpp_demangle_read_array(ddata))
29054cc2045aSjoerg goto clean;
29064cc2045aSjoerg is_builtin = 0;
29074cc2045aSjoerg goto rtn;
29084cc2045aSjoerg
29094cc2045aSjoerg case 'b':
29104cc2045aSjoerg /* bool */
2911*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "bool"))
29124cc2045aSjoerg goto clean;
29134cc2045aSjoerg ++ddata->cur;
29144cc2045aSjoerg goto rtn;
29154cc2045aSjoerg
29164cc2045aSjoerg case 'C':
29174cc2045aSjoerg /* complex pair */
29184cc2045aSjoerg if (!vector_type_qualifier_push(&v, TYPE_CMX))
29194cc2045aSjoerg goto clean;
29204cc2045aSjoerg ++ddata->cur;
2921*d678c5d4Sjoerg if (td)
2922*d678c5d4Sjoerg td->firstp = false;
29234cc2045aSjoerg goto again;
29244cc2045aSjoerg
29254cc2045aSjoerg case 'c':
29264cc2045aSjoerg /* char */
2927*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "char"))
29284cc2045aSjoerg goto clean;
29294cc2045aSjoerg ++ddata->cur;
29304cc2045aSjoerg goto rtn;
29314cc2045aSjoerg
29324cc2045aSjoerg case 'd':
29334cc2045aSjoerg /* double */
2934*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "double"))
29354cc2045aSjoerg goto clean;
29364cc2045aSjoerg ++ddata->cur;
29374cc2045aSjoerg goto rtn;
29384cc2045aSjoerg
293986b377d0Spooka case 'D':
294086b377d0Spooka ++ddata->cur;
294186b377d0Spooka switch (*ddata->cur) {
2942*d678c5d4Sjoerg case 'a':
2943*d678c5d4Sjoerg /* auto */
2944*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "auto"))
2945*d678c5d4Sjoerg goto clean;
2946*d678c5d4Sjoerg ++ddata->cur;
2947*d678c5d4Sjoerg break;
2948*d678c5d4Sjoerg case 'c':
2949*d678c5d4Sjoerg /* decltype(auto) */
2950*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "decltype(auto)"))
2951*d678c5d4Sjoerg goto clean;
2952*d678c5d4Sjoerg ++ddata->cur;
2953*d678c5d4Sjoerg break;
295486b377d0Spooka case 'd':
295586b377d0Spooka /* IEEE 754r decimal floating point (64 bits) */
2956*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "decimal64"))
295786b377d0Spooka goto clean;
295886b377d0Spooka ++ddata->cur;
295986b377d0Spooka break;
296086b377d0Spooka case 'e':
296186b377d0Spooka /* IEEE 754r decimal floating point (128 bits) */
2962*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "decimal128"))
296386b377d0Spooka goto clean;
296486b377d0Spooka ++ddata->cur;
296586b377d0Spooka break;
296686b377d0Spooka case 'f':
296786b377d0Spooka /* IEEE 754r decimal floating point (32 bits) */
2968*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "decimal32"))
296986b377d0Spooka goto clean;
297086b377d0Spooka ++ddata->cur;
297186b377d0Spooka break;
297286b377d0Spooka case 'h':
297386b377d0Spooka /* IEEE 754r half-precision floating point (16 bits) */
2974*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "half"))
297586b377d0Spooka goto clean;
297686b377d0Spooka ++ddata->cur;
297786b377d0Spooka break;
297886b377d0Spooka case 'i':
297986b377d0Spooka /* char32_t */
2980*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "char32_t"))
298186b377d0Spooka goto clean;
298286b377d0Spooka ++ddata->cur;
298386b377d0Spooka break;
298486b377d0Spooka case 'n':
298586b377d0Spooka /* std::nullptr_t (i.e., decltype(nullptr)) */
2986*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "decltype(nullptr)"))
298786b377d0Spooka goto clean;
298886b377d0Spooka ++ddata->cur;
298986b377d0Spooka break;
299086b377d0Spooka case 's':
299186b377d0Spooka /* char16_t */
2992*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "char16_t"))
299386b377d0Spooka goto clean;
299486b377d0Spooka ++ddata->cur;
299586b377d0Spooka break;
299686b377d0Spooka case 'v':
299786b377d0Spooka /* gcc vector_size extension. */
299886b377d0Spooka ++ddata->cur;
299986b377d0Spooka if (*ddata->cur == '_') {
300086b377d0Spooka ++ddata->cur;
300186b377d0Spooka if (!cpp_demangle_read_expression_flat(ddata,
300286b377d0Spooka &exp_str))
300386b377d0Spooka goto clean;
3004*d678c5d4Sjoerg if (!VEC_PUSH_STR(&v.ext_name, exp_str))
300586b377d0Spooka goto clean;
300686b377d0Spooka } else {
300786b377d0Spooka if (!cpp_demangle_read_number_as_string(ddata,
300886b377d0Spooka &num_str))
300986b377d0Spooka goto clean;
3010*d678c5d4Sjoerg if (!VEC_PUSH_STR(&v.ext_name, num_str))
301186b377d0Spooka goto clean;
301286b377d0Spooka }
301386b377d0Spooka if (*ddata->cur != '_')
301486b377d0Spooka goto clean;
301586b377d0Spooka ++ddata->cur;
301686b377d0Spooka if (!vector_type_qualifier_push(&v, TYPE_VEC))
301786b377d0Spooka goto clean;
3018*d678c5d4Sjoerg if (td)
3019*d678c5d4Sjoerg td->firstp = false;
302086b377d0Spooka goto again;
302186b377d0Spooka default:
302286b377d0Spooka goto clean;
302386b377d0Spooka }
302486b377d0Spooka goto rtn;
302586b377d0Spooka
30264cc2045aSjoerg case 'e':
30274cc2045aSjoerg /* long double */
3028*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "long double"))
30294cc2045aSjoerg goto clean;
30304cc2045aSjoerg ++ddata->cur;
30314cc2045aSjoerg goto rtn;
30324cc2045aSjoerg
3033*d678c5d4Sjoerg case 'E':
3034*d678c5d4Sjoerg /* unexpected end except ref-qualifiers */
3035*d678c5d4Sjoerg if (ddata->ref_qualifier && ddata->is_functype) {
3036*d678c5d4Sjoerg skip_ref_qualifier = true;
3037*d678c5d4Sjoerg /* Pop the delimiter. */
3038*d678c5d4Sjoerg cpp_demangle_pop_str(ddata);
3039*d678c5d4Sjoerg goto rtn;
3040*d678c5d4Sjoerg }
3041*d678c5d4Sjoerg goto clean;
3042*d678c5d4Sjoerg
30434cc2045aSjoerg case 'f':
30444cc2045aSjoerg /* float */
3045*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "float"))
30464cc2045aSjoerg goto clean;
30474cc2045aSjoerg ++ddata->cur;
30484cc2045aSjoerg goto rtn;
30494cc2045aSjoerg
30504cc2045aSjoerg case 'F':
30514cc2045aSjoerg /* function */
30524cc2045aSjoerg if (!cpp_demangle_read_function(ddata, &extern_c, &v))
30534cc2045aSjoerg goto clean;
30544cc2045aSjoerg is_builtin = 0;
30554cc2045aSjoerg goto rtn;
30564cc2045aSjoerg
30574cc2045aSjoerg case 'g':
30584cc2045aSjoerg /* __float128 */
3059*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "__float128"))
30604cc2045aSjoerg goto clean;
30614cc2045aSjoerg ++ddata->cur;
30624cc2045aSjoerg goto rtn;
30634cc2045aSjoerg
30644cc2045aSjoerg case 'G':
30654cc2045aSjoerg /* imaginary */
30664cc2045aSjoerg if (!vector_type_qualifier_push(&v, TYPE_IMG))
30674cc2045aSjoerg goto clean;
30684cc2045aSjoerg ++ddata->cur;
3069*d678c5d4Sjoerg if (td)
3070*d678c5d4Sjoerg td->firstp = false;
30714cc2045aSjoerg goto again;
30724cc2045aSjoerg
30734cc2045aSjoerg case 'h':
30744cc2045aSjoerg /* unsigned char */
3075*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "unsigned char"))
30764cc2045aSjoerg goto clean;
30774cc2045aSjoerg ++ddata->cur;
30784cc2045aSjoerg goto rtn;
30794cc2045aSjoerg
30804cc2045aSjoerg case 'i':
30814cc2045aSjoerg /* int */
3082*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "int"))
30834cc2045aSjoerg goto clean;
30844cc2045aSjoerg ++ddata->cur;
30854cc2045aSjoerg goto rtn;
30864cc2045aSjoerg
3087*d678c5d4Sjoerg case 'I':
3088*d678c5d4Sjoerg /* template args. */
3089*d678c5d4Sjoerg /* handles <substitute><template-args> */
3090*d678c5d4Sjoerg p_idx = output->size;
3091*d678c5d4Sjoerg if (!cpp_demangle_read_tmpl_args(ddata))
3092*d678c5d4Sjoerg goto clean;
3093*d678c5d4Sjoerg if ((subst_str = vector_str_substr(output, p_idx,
3094*d678c5d4Sjoerg output->size - 1, &subst_str_len)) == NULL)
3095*d678c5d4Sjoerg goto clean;
3096*d678c5d4Sjoerg if (!vector_str_init(&sv)) {
3097*d678c5d4Sjoerg free(subst_str);
3098*d678c5d4Sjoerg goto clean;
3099*d678c5d4Sjoerg }
3100*d678c5d4Sjoerg if (!vector_str_push(&sv, subst_str, subst_str_len)) {
3101*d678c5d4Sjoerg free(subst_str);
3102*d678c5d4Sjoerg vector_str_dest(&sv);
3103*d678c5d4Sjoerg goto clean;
3104*d678c5d4Sjoerg }
3105*d678c5d4Sjoerg free(subst_str);
3106*d678c5d4Sjoerg if (!cpp_demangle_push_subst_v(ddata, &sv)) {
3107*d678c5d4Sjoerg vector_str_dest(&sv);
3108*d678c5d4Sjoerg goto clean;
3109*d678c5d4Sjoerg }
3110*d678c5d4Sjoerg vector_str_dest(&sv);
3111*d678c5d4Sjoerg goto rtn;
3112*d678c5d4Sjoerg
31134cc2045aSjoerg case 'j':
31144cc2045aSjoerg /* unsigned int */
3115*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "unsigned int"))
31164cc2045aSjoerg goto clean;
31174cc2045aSjoerg ++ddata->cur;
31184cc2045aSjoerg goto rtn;
31194cc2045aSjoerg
31204cc2045aSjoerg case 'K':
31214cc2045aSjoerg /* const */
31224cc2045aSjoerg if (!vector_type_qualifier_push(&v, TYPE_CST))
31234cc2045aSjoerg goto clean;
31244cc2045aSjoerg ++ddata->cur;
3125*d678c5d4Sjoerg if (td)
3126*d678c5d4Sjoerg td->firstp = false;
31274cc2045aSjoerg goto again;
31284cc2045aSjoerg
31294cc2045aSjoerg case 'l':
31304cc2045aSjoerg /* long */
3131*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "long"))
31324cc2045aSjoerg goto clean;
31334cc2045aSjoerg ++ddata->cur;
31344cc2045aSjoerg goto rtn;
31354cc2045aSjoerg
31364cc2045aSjoerg case 'm':
31374cc2045aSjoerg /* unsigned long */
3138*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "unsigned long"))
31394cc2045aSjoerg goto clean;
31404cc2045aSjoerg
31414cc2045aSjoerg ++ddata->cur;
31424cc2045aSjoerg
31434cc2045aSjoerg goto rtn;
31444cc2045aSjoerg case 'M':
31454cc2045aSjoerg /* pointer to member */
3146*d678c5d4Sjoerg if (!cpp_demangle_read_pointer_to_member(ddata, &v))
31474cc2045aSjoerg goto clean;
31484cc2045aSjoerg is_builtin = 0;
31494cc2045aSjoerg goto rtn;
31504cc2045aSjoerg
31514cc2045aSjoerg case 'n':
31524cc2045aSjoerg /* __int128 */
3153*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "__int128"))
31544cc2045aSjoerg goto clean;
31554cc2045aSjoerg ++ddata->cur;
31564cc2045aSjoerg goto rtn;
31574cc2045aSjoerg
31584cc2045aSjoerg case 'o':
31594cc2045aSjoerg /* unsigned __int128 */
3160*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "unsigned __int128"))
31614cc2045aSjoerg goto clean;
31624cc2045aSjoerg ++ddata->cur;
31634cc2045aSjoerg goto rtn;
31644cc2045aSjoerg
3165*d678c5d4Sjoerg case 'O':
3166*d678c5d4Sjoerg /* rvalue reference */
3167*d678c5d4Sjoerg if (ddata->ref_qualifier)
3168*d678c5d4Sjoerg goto clean;
3169*d678c5d4Sjoerg if (!vector_type_qualifier_push(&v, TYPE_RREF))
3170*d678c5d4Sjoerg goto clean;
3171*d678c5d4Sjoerg ddata->ref_qualifier = true;
3172*d678c5d4Sjoerg ddata->ref_qualifier_type = TYPE_RREF;
3173*d678c5d4Sjoerg ++ddata->cur;
3174*d678c5d4Sjoerg if (td)
3175*d678c5d4Sjoerg td->firstp = false;
3176*d678c5d4Sjoerg goto again;
3177*d678c5d4Sjoerg
31784cc2045aSjoerg case 'P':
31794cc2045aSjoerg /* pointer */
31804cc2045aSjoerg if (!vector_type_qualifier_push(&v, TYPE_PTR))
31814cc2045aSjoerg goto clean;
31824cc2045aSjoerg ++ddata->cur;
3183*d678c5d4Sjoerg if (td)
3184*d678c5d4Sjoerg td->firstp = false;
31854cc2045aSjoerg goto again;
31864cc2045aSjoerg
31874cc2045aSjoerg case 'r':
31884cc2045aSjoerg /* restrict */
31894cc2045aSjoerg if (!vector_type_qualifier_push(&v, TYPE_RST))
31904cc2045aSjoerg goto clean;
31914cc2045aSjoerg ++ddata->cur;
3192*d678c5d4Sjoerg if (td)
3193*d678c5d4Sjoerg td->firstp = false;
31944cc2045aSjoerg goto again;
31954cc2045aSjoerg
31964cc2045aSjoerg case 'R':
31974cc2045aSjoerg /* reference */
3198*d678c5d4Sjoerg if (ddata->ref_qualifier)
3199*d678c5d4Sjoerg goto clean;
32004cc2045aSjoerg if (!vector_type_qualifier_push(&v, TYPE_REF))
32014cc2045aSjoerg goto clean;
3202*d678c5d4Sjoerg ddata->ref_qualifier = true;
3203*d678c5d4Sjoerg ddata->ref_qualifier_type = TYPE_REF;
32044cc2045aSjoerg ++ddata->cur;
3205*d678c5d4Sjoerg if (td)
3206*d678c5d4Sjoerg td->firstp = false;
32074cc2045aSjoerg goto again;
32084cc2045aSjoerg
32094cc2045aSjoerg case 's':
32104cc2045aSjoerg /* short, local string */
3211*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "short"))
32124cc2045aSjoerg goto clean;
32134cc2045aSjoerg ++ddata->cur;
32144cc2045aSjoerg goto rtn;
32154cc2045aSjoerg
32164cc2045aSjoerg case 'S':
32174cc2045aSjoerg /* substitution */
32184cc2045aSjoerg if (!cpp_demangle_read_subst(ddata))
32194cc2045aSjoerg goto clean;
32204cc2045aSjoerg is_builtin = 0;
32214cc2045aSjoerg goto rtn;
32224cc2045aSjoerg
32234cc2045aSjoerg case 't':
32244cc2045aSjoerg /* unsigned short */
3225*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "unsigned short"))
32264cc2045aSjoerg goto clean;
32274cc2045aSjoerg ++ddata->cur;
32284cc2045aSjoerg goto rtn;
32294cc2045aSjoerg
32304cc2045aSjoerg case 'T':
32314cc2045aSjoerg /* template parameter */
32324cc2045aSjoerg if (!cpp_demangle_read_tmpl_param(ddata))
32334cc2045aSjoerg goto clean;
32344cc2045aSjoerg is_builtin = 0;
32354cc2045aSjoerg goto rtn;
32364cc2045aSjoerg
32374cc2045aSjoerg case 'u':
32384cc2045aSjoerg /* vendor extended builtin */
32394cc2045aSjoerg ++ddata->cur;
32404cc2045aSjoerg if (!cpp_demangle_read_sname(ddata))
32414cc2045aSjoerg goto clean;
32424cc2045aSjoerg is_builtin = 0;
32434cc2045aSjoerg goto rtn;
32444cc2045aSjoerg
32454cc2045aSjoerg case 'U':
32464cc2045aSjoerg /* vendor extended type qualifier */
3247*d678c5d4Sjoerg ++ddata->cur;
32484cc2045aSjoerg if (!cpp_demangle_read_number(ddata, &len))
32494cc2045aSjoerg goto clean;
32504cc2045aSjoerg if (len <= 0)
32514cc2045aSjoerg goto clean;
32524cc2045aSjoerg if (!vector_str_push(&v.ext_name, ddata->cur, len))
3253*d678c5d4Sjoerg goto clean;
32544cc2045aSjoerg ddata->cur += len;
325586b377d0Spooka if (!vector_type_qualifier_push(&v, TYPE_EXT))
325686b377d0Spooka goto clean;
3257*d678c5d4Sjoerg if (td)
3258*d678c5d4Sjoerg td->firstp = false;
32594cc2045aSjoerg goto again;
32604cc2045aSjoerg
32614cc2045aSjoerg case 'v':
32624cc2045aSjoerg /* void */
3263*d678c5d4Sjoerg omit_void = false;
3264*d678c5d4Sjoerg if (td && td->firstp) {
3265*d678c5d4Sjoerg /*
3266*d678c5d4Sjoerg * peek into next bytes and see if we should omit
3267*d678c5d4Sjoerg * the "void".
3268*d678c5d4Sjoerg */
3269*d678c5d4Sjoerg omit_void = true;
3270*d678c5d4Sjoerg for (p = ddata->cur + 1; *p != '\0'; p++) {
3271*d678c5d4Sjoerg if (*p == 'E')
3272*d678c5d4Sjoerg break;
3273*d678c5d4Sjoerg if (*p != 'R' && *p != 'O') {
3274*d678c5d4Sjoerg omit_void = false;
3275*d678c5d4Sjoerg break;
3276*d678c5d4Sjoerg }
3277*d678c5d4Sjoerg }
3278*d678c5d4Sjoerg }
3279*d678c5d4Sjoerg if (!omit_void && !DEM_PUSH_STR(ddata, "void"))
32804cc2045aSjoerg goto clean;
32814cc2045aSjoerg ++ddata->cur;
32824cc2045aSjoerg goto rtn;
32834cc2045aSjoerg
32844cc2045aSjoerg case 'V':
32854cc2045aSjoerg /* volatile */
32864cc2045aSjoerg if (!vector_type_qualifier_push(&v, TYPE_VAT))
32874cc2045aSjoerg goto clean;
32884cc2045aSjoerg ++ddata->cur;
3289*d678c5d4Sjoerg if (td)
3290*d678c5d4Sjoerg td->firstp = false;
32914cc2045aSjoerg goto again;
32924cc2045aSjoerg
32934cc2045aSjoerg case 'w':
32944cc2045aSjoerg /* wchar_t */
3295*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "wchar_t"))
32964cc2045aSjoerg goto clean;
32974cc2045aSjoerg ++ddata->cur;
32984cc2045aSjoerg goto rtn;
32994cc2045aSjoerg
33004cc2045aSjoerg case 'x':
33014cc2045aSjoerg /* long long */
3302*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "long long"))
33034cc2045aSjoerg goto clean;
33044cc2045aSjoerg ++ddata->cur;
33054cc2045aSjoerg goto rtn;
33064cc2045aSjoerg
33074cc2045aSjoerg case 'y':
33084cc2045aSjoerg /* unsigned long long */
3309*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "unsigned long long"))
33104cc2045aSjoerg goto clean;
33114cc2045aSjoerg ++ddata->cur;
33124cc2045aSjoerg goto rtn;
33134cc2045aSjoerg
33144cc2045aSjoerg case 'z':
33154cc2045aSjoerg /* ellipsis */
3316*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "..."))
33174cc2045aSjoerg goto clean;
33184cc2045aSjoerg ++ddata->cur;
33194cc2045aSjoerg goto rtn;
3320*d678c5d4Sjoerg }
33214cc2045aSjoerg
33224cc2045aSjoerg if (!cpp_demangle_read_name(ddata))
33234cc2045aSjoerg goto clean;
33244cc2045aSjoerg
33254cc2045aSjoerg is_builtin = 0;
33264cc2045aSjoerg rtn:
3327*d678c5d4Sjoerg
3328*d678c5d4Sjoerg type_str = vector_str_substr(output, p_idx, output->size - 1,
3329*d678c5d4Sjoerg &type_str_len);
33304cc2045aSjoerg
33314cc2045aSjoerg if (is_builtin == 0) {
33324cc2045aSjoerg if (!vector_str_find(&ddata->subst, type_str, type_str_len) &&
33334cc2045aSjoerg !vector_str_push(&ddata->subst, type_str, type_str_len))
33344cc2045aSjoerg goto clean;
33354cc2045aSjoerg }
33364cc2045aSjoerg
3337*d678c5d4Sjoerg if (!skip_ref_qualifier &&
3338*d678c5d4Sjoerg !cpp_demangle_push_type_qualifier(ddata, &v, type_str))
33394cc2045aSjoerg goto clean;
33404cc2045aSjoerg
3341*d678c5d4Sjoerg if (td)
3342*d678c5d4Sjoerg td->firstp = false;
3343*d678c5d4Sjoerg
33444cc2045aSjoerg free(type_str);
334586b377d0Spooka free(exp_str);
334686b377d0Spooka free(num_str);
33474cc2045aSjoerg vector_type_qualifier_dest(&v);
33484cc2045aSjoerg
33494cc2045aSjoerg return (1);
33504cc2045aSjoerg clean:
33514cc2045aSjoerg free(type_str);
335286b377d0Spooka free(exp_str);
335386b377d0Spooka free(num_str);
33544cc2045aSjoerg vector_type_qualifier_dest(&v);
33554cc2045aSjoerg
33564cc2045aSjoerg return (0);
33574cc2045aSjoerg }
33584cc2045aSjoerg
335986b377d0Spooka static int
cpp_demangle_read_type_flat(struct cpp_demangle_data * ddata,char ** str)336086b377d0Spooka cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str)
336186b377d0Spooka {
336286b377d0Spooka struct vector_str *output;
336386b377d0Spooka size_t i, p_idx, idx, type_len;
336486b377d0Spooka char *type;
336586b377d0Spooka
3366*d678c5d4Sjoerg output = ddata->cur_output;
336786b377d0Spooka
336886b377d0Spooka p_idx = output->size;
336986b377d0Spooka
3370*d678c5d4Sjoerg if (!cpp_demangle_read_type(ddata, NULL))
337186b377d0Spooka return (0);
337286b377d0Spooka
337386b377d0Spooka if ((type = vector_str_substr(output, p_idx, output->size - 1,
337486b377d0Spooka &type_len)) == NULL)
337586b377d0Spooka return (0);
337686b377d0Spooka
337786b377d0Spooka idx = output->size;
337886b377d0Spooka for (i = p_idx; i < idx; ++i) {
337986b377d0Spooka if (!vector_str_pop(output)) {
338086b377d0Spooka free(type);
338186b377d0Spooka return (0);
338286b377d0Spooka }
338386b377d0Spooka }
338486b377d0Spooka
338586b377d0Spooka *str = type;
338686b377d0Spooka
338786b377d0Spooka return (1);
338886b377d0Spooka }
338986b377d0Spooka
33904cc2045aSjoerg /*
33914cc2045aSjoerg * read unqualified-name, unqualified name are operator-name, ctor-dtor-name,
33924cc2045aSjoerg * source-name
33934cc2045aSjoerg */
33944cc2045aSjoerg static int
cpp_demangle_read_uqname(struct cpp_demangle_data * ddata)33954cc2045aSjoerg cpp_demangle_read_uqname(struct cpp_demangle_data *ddata)
33964cc2045aSjoerg {
33974cc2045aSjoerg size_t len;
33984cc2045aSjoerg
33994cc2045aSjoerg if (ddata == NULL || *ddata->cur == '\0')
34004cc2045aSjoerg return (0);
34014cc2045aSjoerg
34024cc2045aSjoerg /* operator name */
34034cc2045aSjoerg switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
34044cc2045aSjoerg case SIMPLE_HASH('a', 'a'):
34054cc2045aSjoerg /* operator && */
3406*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator&&"))
34074cc2045aSjoerg return (0);
34084cc2045aSjoerg ddata->cur += 2;
34094cc2045aSjoerg return (1);
34104cc2045aSjoerg
34114cc2045aSjoerg case SIMPLE_HASH('a', 'd'):
34124cc2045aSjoerg /* operator & (unary) */
3413*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator&"))
34144cc2045aSjoerg return (0);
34154cc2045aSjoerg ddata->cur += 2;
34164cc2045aSjoerg return (1);
34174cc2045aSjoerg
34184cc2045aSjoerg case SIMPLE_HASH('a', 'n'):
34194cc2045aSjoerg /* operator & */
3420*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator&"))
34214cc2045aSjoerg return (0);
34224cc2045aSjoerg ddata->cur += 2;
34234cc2045aSjoerg return (1);
34244cc2045aSjoerg
34254cc2045aSjoerg case SIMPLE_HASH('a', 'N'):
34264cc2045aSjoerg /* operator &= */
3427*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator&="))
34284cc2045aSjoerg return (0);
34294cc2045aSjoerg ddata->cur += 2;
34304cc2045aSjoerg return (1);
34314cc2045aSjoerg
34324cc2045aSjoerg case SIMPLE_HASH('a', 'S'):
34334cc2045aSjoerg /* operator = */
3434*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator="))
34354cc2045aSjoerg return (0);
34364cc2045aSjoerg ddata->cur += 2;
34374cc2045aSjoerg return (1);
34384cc2045aSjoerg
34394cc2045aSjoerg case SIMPLE_HASH('c', 'l'):
34404cc2045aSjoerg /* operator () */
3441*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator()"))
34424cc2045aSjoerg return (0);
34434cc2045aSjoerg ddata->cur += 2;
34444cc2045aSjoerg return (1);
34454cc2045aSjoerg
34464cc2045aSjoerg case SIMPLE_HASH('c', 'm'):
34474cc2045aSjoerg /* operator , */
3448*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator,"))
34494cc2045aSjoerg return (0);
34504cc2045aSjoerg ddata->cur += 2;
34514cc2045aSjoerg return (1);
34524cc2045aSjoerg
34534cc2045aSjoerg case SIMPLE_HASH('c', 'o'):
34544cc2045aSjoerg /* operator ~ */
3455*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator~"))
34564cc2045aSjoerg return (0);
34574cc2045aSjoerg ddata->cur += 2;
34584cc2045aSjoerg return (1);
34594cc2045aSjoerg
34604cc2045aSjoerg case SIMPLE_HASH('c', 'v'):
34614cc2045aSjoerg /* operator (cast) */
3462*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator(cast)"))
34634cc2045aSjoerg return (0);
34644cc2045aSjoerg ddata->cur += 2;
3465*d678c5d4Sjoerg return (cpp_demangle_read_type(ddata, NULL));
34664cc2045aSjoerg
34674cc2045aSjoerg case SIMPLE_HASH('d', 'a'):
34684cc2045aSjoerg /* operator delete [] */
3469*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator delete []"))
34704cc2045aSjoerg return (0);
34714cc2045aSjoerg ddata->cur += 2;
34724cc2045aSjoerg return (1);
34734cc2045aSjoerg
34744cc2045aSjoerg case SIMPLE_HASH('d', 'e'):
34754cc2045aSjoerg /* operator * (unary) */
3476*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator*"))
34774cc2045aSjoerg return (0);
34784cc2045aSjoerg ddata->cur += 2;
34794cc2045aSjoerg return (1);
34804cc2045aSjoerg
34814cc2045aSjoerg case SIMPLE_HASH('d', 'l'):
34824cc2045aSjoerg /* operator delete */
3483*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator delete"))
34844cc2045aSjoerg return (0);
34854cc2045aSjoerg ddata->cur += 2;
34864cc2045aSjoerg return (1);
34874cc2045aSjoerg
34884cc2045aSjoerg case SIMPLE_HASH('d', 'v'):
34894cc2045aSjoerg /* operator / */
3490*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator/"))
34914cc2045aSjoerg return (0);
34924cc2045aSjoerg ddata->cur += 2;
34934cc2045aSjoerg return (1);
34944cc2045aSjoerg
34954cc2045aSjoerg case SIMPLE_HASH('d', 'V'):
34964cc2045aSjoerg /* operator /= */
3497*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator/="))
34984cc2045aSjoerg return (0);
34994cc2045aSjoerg ddata->cur += 2;
35004cc2045aSjoerg return (1);
35014cc2045aSjoerg
35024cc2045aSjoerg case SIMPLE_HASH('e', 'o'):
35034cc2045aSjoerg /* operator ^ */
3504*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator^"))
35054cc2045aSjoerg return (0);
35064cc2045aSjoerg ddata->cur += 2;
35074cc2045aSjoerg return (1);
35084cc2045aSjoerg
35094cc2045aSjoerg case SIMPLE_HASH('e', 'O'):
35104cc2045aSjoerg /* operator ^= */
3511*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator^="))
35124cc2045aSjoerg return (0);
35134cc2045aSjoerg ddata->cur += 2;
35144cc2045aSjoerg return (1);
35154cc2045aSjoerg
35164cc2045aSjoerg case SIMPLE_HASH('e', 'q'):
35174cc2045aSjoerg /* operator == */
3518*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator=="))
35194cc2045aSjoerg return (0);
35204cc2045aSjoerg ddata->cur += 2;
35214cc2045aSjoerg return (1);
35224cc2045aSjoerg
35234cc2045aSjoerg case SIMPLE_HASH('g', 'e'):
35244cc2045aSjoerg /* operator >= */
3525*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator>="))
35264cc2045aSjoerg return (0);
35274cc2045aSjoerg ddata->cur += 2;
35284cc2045aSjoerg return (1);
35294cc2045aSjoerg
35304cc2045aSjoerg case SIMPLE_HASH('g', 't'):
35314cc2045aSjoerg /* operator > */
3532*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator>"))
35334cc2045aSjoerg return (0);
35344cc2045aSjoerg ddata->cur += 2;
35354cc2045aSjoerg return (1);
35364cc2045aSjoerg
35374cc2045aSjoerg case SIMPLE_HASH('i', 'x'):
35384cc2045aSjoerg /* operator [] */
3539*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator[]"))
35404cc2045aSjoerg return (0);
35414cc2045aSjoerg ddata->cur += 2;
35424cc2045aSjoerg return (1);
35434cc2045aSjoerg
35444cc2045aSjoerg case SIMPLE_HASH('l', 'e'):
35454cc2045aSjoerg /* operator <= */
3546*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator<="))
35474cc2045aSjoerg return (0);
35484cc2045aSjoerg ddata->cur += 2;
35494cc2045aSjoerg return (1);
35504cc2045aSjoerg
35514cc2045aSjoerg case SIMPLE_HASH('l', 's'):
35524cc2045aSjoerg /* operator << */
3553*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator<<"))
35544cc2045aSjoerg return (0);
35554cc2045aSjoerg ddata->cur += 2;
35564cc2045aSjoerg return (1);
35574cc2045aSjoerg
35584cc2045aSjoerg case SIMPLE_HASH('l', 'S'):
35594cc2045aSjoerg /* operator <<= */
3560*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator<<="))
35614cc2045aSjoerg return (0);
35624cc2045aSjoerg ddata->cur += 2;
35634cc2045aSjoerg return (1);
35644cc2045aSjoerg
35654cc2045aSjoerg case SIMPLE_HASH('l', 't'):
35664cc2045aSjoerg /* operator < */
3567*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator<"))
35684cc2045aSjoerg return (0);
35694cc2045aSjoerg ddata->cur += 2;
35704cc2045aSjoerg return (1);
35714cc2045aSjoerg
35724cc2045aSjoerg case SIMPLE_HASH('m', 'i'):
35734cc2045aSjoerg /* operator - */
3574*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator-"))
35754cc2045aSjoerg return (0);
35764cc2045aSjoerg ddata->cur += 2;
35774cc2045aSjoerg return (1);
35784cc2045aSjoerg
35794cc2045aSjoerg case SIMPLE_HASH('m', 'I'):
35804cc2045aSjoerg /* operator -= */
3581*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator-="))
35824cc2045aSjoerg return (0);
35834cc2045aSjoerg ddata->cur += 2;
35844cc2045aSjoerg return (1);
35854cc2045aSjoerg
35864cc2045aSjoerg case SIMPLE_HASH('m', 'l'):
35874cc2045aSjoerg /* operator * */
3588*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator*"))
35894cc2045aSjoerg return (0);
35904cc2045aSjoerg ddata->cur += 2;
35914cc2045aSjoerg return (1);
35924cc2045aSjoerg
35934cc2045aSjoerg case SIMPLE_HASH('m', 'L'):
35944cc2045aSjoerg /* operator *= */
3595*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator*="))
35964cc2045aSjoerg return (0);
35974cc2045aSjoerg ddata->cur += 2;
35984cc2045aSjoerg return (1);
35994cc2045aSjoerg
36004cc2045aSjoerg case SIMPLE_HASH('m', 'm'):
36014cc2045aSjoerg /* operator -- */
3602*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator--"))
36034cc2045aSjoerg return (0);
36044cc2045aSjoerg ddata->cur += 2;
36054cc2045aSjoerg return (1);
36064cc2045aSjoerg
36074cc2045aSjoerg case SIMPLE_HASH('n', 'a'):
36084cc2045aSjoerg /* operator new[] */
3609*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator new []"))
36104cc2045aSjoerg return (0);
36114cc2045aSjoerg ddata->cur += 2;
36124cc2045aSjoerg return (1);
36134cc2045aSjoerg
36144cc2045aSjoerg case SIMPLE_HASH('n', 'e'):
36154cc2045aSjoerg /* operator != */
3616*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator!="))
36174cc2045aSjoerg return (0);
36184cc2045aSjoerg ddata->cur += 2;
36194cc2045aSjoerg return (1);
36204cc2045aSjoerg
36214cc2045aSjoerg case SIMPLE_HASH('n', 'g'):
36224cc2045aSjoerg /* operator - (unary) */
3623*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator-"))
36244cc2045aSjoerg return (0);
36254cc2045aSjoerg ddata->cur += 2;
36264cc2045aSjoerg return (1);
36274cc2045aSjoerg
36284cc2045aSjoerg case SIMPLE_HASH('n', 't'):
36294cc2045aSjoerg /* operator ! */
3630*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator!"))
36314cc2045aSjoerg return (0);
36324cc2045aSjoerg ddata->cur += 2;
36334cc2045aSjoerg return (1);
36344cc2045aSjoerg
36354cc2045aSjoerg case SIMPLE_HASH('n', 'w'):
36364cc2045aSjoerg /* operator new */
3637*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator new"))
36384cc2045aSjoerg return (0);
36394cc2045aSjoerg ddata->cur += 2;
36404cc2045aSjoerg return (1);
36414cc2045aSjoerg
36424cc2045aSjoerg case SIMPLE_HASH('o', 'o'):
36434cc2045aSjoerg /* operator || */
3644*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator||"))
36454cc2045aSjoerg return (0);
36464cc2045aSjoerg ddata->cur += 2;
36474cc2045aSjoerg return (1);
36484cc2045aSjoerg
36494cc2045aSjoerg case SIMPLE_HASH('o', 'r'):
36504cc2045aSjoerg /* operator | */
3651*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator|"))
36524cc2045aSjoerg return (0);
36534cc2045aSjoerg ddata->cur += 2;
36544cc2045aSjoerg return (1);
36554cc2045aSjoerg
36564cc2045aSjoerg case SIMPLE_HASH('o', 'R'):
36574cc2045aSjoerg /* operator |= */
3658*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator|="))
36594cc2045aSjoerg return (0);
36604cc2045aSjoerg ddata->cur += 2;
36614cc2045aSjoerg return (1);
36624cc2045aSjoerg
36634cc2045aSjoerg case SIMPLE_HASH('p', 'l'):
36644cc2045aSjoerg /* operator + */
3665*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator+"))
36664cc2045aSjoerg return (0);
36674cc2045aSjoerg ddata->cur += 2;
36684cc2045aSjoerg return (1);
36694cc2045aSjoerg
36704cc2045aSjoerg case SIMPLE_HASH('p', 'L'):
36714cc2045aSjoerg /* operator += */
3672*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator+="))
36734cc2045aSjoerg return (0);
36744cc2045aSjoerg ddata->cur += 2;
36754cc2045aSjoerg return (1);
36764cc2045aSjoerg
36774cc2045aSjoerg case SIMPLE_HASH('p', 'm'):
36784cc2045aSjoerg /* operator ->* */
3679*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator->*"))
36804cc2045aSjoerg return (0);
36814cc2045aSjoerg ddata->cur += 2;
36824cc2045aSjoerg return (1);
36834cc2045aSjoerg
36844cc2045aSjoerg case SIMPLE_HASH('p', 'p'):
36854cc2045aSjoerg /* operator ++ */
3686*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator++"))
36874cc2045aSjoerg return (0);
36884cc2045aSjoerg ddata->cur += 2;
36894cc2045aSjoerg return (1);
36904cc2045aSjoerg
36914cc2045aSjoerg case SIMPLE_HASH('p', 's'):
36924cc2045aSjoerg /* operator + (unary) */
3693*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator+"))
36944cc2045aSjoerg return (0);
36954cc2045aSjoerg ddata->cur += 2;
36964cc2045aSjoerg return (1);
36974cc2045aSjoerg
36984cc2045aSjoerg case SIMPLE_HASH('p', 't'):
36994cc2045aSjoerg /* operator -> */
3700*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator->"))
37014cc2045aSjoerg return (0);
37024cc2045aSjoerg ddata->cur += 2;
37034cc2045aSjoerg return (1);
37044cc2045aSjoerg
37054cc2045aSjoerg case SIMPLE_HASH('q', 'u'):
37064cc2045aSjoerg /* operator ? */
3707*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator?"))
37084cc2045aSjoerg return (0);
37094cc2045aSjoerg ddata->cur += 2;
37104cc2045aSjoerg return (1);
37114cc2045aSjoerg
37124cc2045aSjoerg case SIMPLE_HASH('r', 'm'):
37134cc2045aSjoerg /* operator % */
3714*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator%"))
37154cc2045aSjoerg return (0);
37164cc2045aSjoerg ddata->cur += 2;
37174cc2045aSjoerg return (1);
37184cc2045aSjoerg
37194cc2045aSjoerg case SIMPLE_HASH('r', 'M'):
37204cc2045aSjoerg /* operator %= */
3721*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator%="))
37224cc2045aSjoerg return (0);
37234cc2045aSjoerg ddata->cur += 2;
37244cc2045aSjoerg return (1);
37254cc2045aSjoerg
37264cc2045aSjoerg case SIMPLE_HASH('r', 's'):
37274cc2045aSjoerg /* operator >> */
3728*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator>>"))
37294cc2045aSjoerg return (0);
37304cc2045aSjoerg ddata->cur += 2;
37314cc2045aSjoerg return (1);
37324cc2045aSjoerg
37334cc2045aSjoerg case SIMPLE_HASH('r', 'S'):
37344cc2045aSjoerg /* operator >>= */
3735*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator>>="))
37364cc2045aSjoerg return (0);
37374cc2045aSjoerg ddata->cur += 2;
37384cc2045aSjoerg return (1);
37394cc2045aSjoerg
37404cc2045aSjoerg case SIMPLE_HASH('r', 'z'):
37414cc2045aSjoerg /* operator sizeof */
3742*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator sizeof "))
37434cc2045aSjoerg return (0);
37444cc2045aSjoerg ddata->cur += 2;
37454cc2045aSjoerg return (1);
37464cc2045aSjoerg
37474cc2045aSjoerg case SIMPLE_HASH('s', 'r'):
37484cc2045aSjoerg /* scope resolution operator */
3749*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "scope resolution operator "))
37504cc2045aSjoerg return (0);
37514cc2045aSjoerg ddata->cur += 2;
37524cc2045aSjoerg return (1);
37534cc2045aSjoerg
37544cc2045aSjoerg case SIMPLE_HASH('s', 'v'):
37554cc2045aSjoerg /* operator sizeof */
3756*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "operator sizeof "))
37574cc2045aSjoerg return (0);
37584cc2045aSjoerg ddata->cur += 2;
37594cc2045aSjoerg return (1);
3760*d678c5d4Sjoerg }
37614cc2045aSjoerg
37624cc2045aSjoerg /* vendor extened operator */
37634cc2045aSjoerg if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) {
3764*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "vendor extened operator "))
37654cc2045aSjoerg return (0);
37664cc2045aSjoerg if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1))
37674cc2045aSjoerg return (0);
37684cc2045aSjoerg ddata->cur += 2;
37694cc2045aSjoerg return (cpp_demangle_read_sname(ddata));
37704cc2045aSjoerg }
37714cc2045aSjoerg
37724cc2045aSjoerg /* ctor-dtor-name */
37734cc2045aSjoerg switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
37744cc2045aSjoerg case SIMPLE_HASH('C', '1'):
37754cc2045aSjoerg case SIMPLE_HASH('C', '2'):
37764cc2045aSjoerg case SIMPLE_HASH('C', '3'):
37774cc2045aSjoerg if (ddata->last_sname == NULL)
37784cc2045aSjoerg return (0);
37794cc2045aSjoerg if ((len = strlen(ddata->last_sname)) == 0)
37804cc2045aSjoerg return (0);
3781*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "::"))
37824cc2045aSjoerg return (0);
37834cc2045aSjoerg if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))
37844cc2045aSjoerg return (0);
37854cc2045aSjoerg ddata->cur +=2;
37864cc2045aSjoerg return (1);
37874cc2045aSjoerg
37884cc2045aSjoerg case SIMPLE_HASH('D', '0'):
37894cc2045aSjoerg case SIMPLE_HASH('D', '1'):
37904cc2045aSjoerg case SIMPLE_HASH('D', '2'):
37914cc2045aSjoerg if (ddata->last_sname == NULL)
37924cc2045aSjoerg return (0);
37934cc2045aSjoerg if ((len = strlen(ddata->last_sname)) == 0)
37944cc2045aSjoerg return (0);
3795*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "::~"))
37964cc2045aSjoerg return (0);
37974cc2045aSjoerg if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))
37984cc2045aSjoerg return (0);
37994cc2045aSjoerg ddata->cur +=2;
38004cc2045aSjoerg return (1);
3801*d678c5d4Sjoerg }
38024cc2045aSjoerg
38034cc2045aSjoerg /* source name */
38044cc2045aSjoerg if (ELFTC_ISDIGIT(*ddata->cur) != 0)
38054cc2045aSjoerg return (cpp_demangle_read_sname(ddata));
38064cc2045aSjoerg
38075192b81bSjoerg /* local source name */
38085192b81bSjoerg if (*ddata->cur == 'L')
38095192b81bSjoerg return (cpp_demangle_local_source_name(ddata));
38105192b81bSjoerg
38115192b81bSjoerg return (1);
38125192b81bSjoerg }
38135192b81bSjoerg
38145192b81bSjoerg /*
38155192b81bSjoerg * Read local source name.
38165192b81bSjoerg *
38175192b81bSjoerg * References:
38185192b81bSjoerg * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
38195192b81bSjoerg * http://gcc.gnu.org/viewcvs?view=rev&revision=124467
38205192b81bSjoerg */
38215192b81bSjoerg static int
cpp_demangle_local_source_name(struct cpp_demangle_data * ddata)38225192b81bSjoerg cpp_demangle_local_source_name(struct cpp_demangle_data *ddata)
38235192b81bSjoerg {
38245192b81bSjoerg /* L */
38255192b81bSjoerg if (ddata == NULL || *ddata->cur != 'L')
38265192b81bSjoerg return (0);
38275192b81bSjoerg ++ddata->cur;
38285192b81bSjoerg
38295192b81bSjoerg /* source name */
38305192b81bSjoerg if (!cpp_demangle_read_sname(ddata))
38315192b81bSjoerg return (0);
38325192b81bSjoerg
38335192b81bSjoerg /* discriminator */
38345192b81bSjoerg if (*ddata->cur == '_') {
38355192b81bSjoerg ++ddata->cur;
38365192b81bSjoerg while (ELFTC_ISDIGIT(*ddata->cur) != 0)
38375192b81bSjoerg ++ddata->cur;
38385192b81bSjoerg }
38395192b81bSjoerg
38404cc2045aSjoerg return (1);
38414cc2045aSjoerg }
38424cc2045aSjoerg
38434cc2045aSjoerg static int
cpp_demangle_read_v_offset(struct cpp_demangle_data * ddata)38444cc2045aSjoerg cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata)
38454cc2045aSjoerg {
38464cc2045aSjoerg
38474cc2045aSjoerg if (ddata == NULL)
38484cc2045aSjoerg return (0);
38494cc2045aSjoerg
3850*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "offset : "))
38514cc2045aSjoerg return (0);
38524cc2045aSjoerg
38534cc2045aSjoerg if (!cpp_demangle_read_offset_number(ddata))
38544cc2045aSjoerg return (0);
38554cc2045aSjoerg
3856*d678c5d4Sjoerg if (!DEM_PUSH_STR(ddata, "virtual offset : "))
38574cc2045aSjoerg return (0);
38584cc2045aSjoerg
38594cc2045aSjoerg return (!cpp_demangle_read_offset_number(ddata));
38604cc2045aSjoerg }
38614cc2045aSjoerg
38624cc2045aSjoerg /*
38634cc2045aSjoerg * Decode floating point representation to string
38644cc2045aSjoerg * Return new allocated string or NULL
38654cc2045aSjoerg *
38664cc2045aSjoerg * Todo
38674cc2045aSjoerg * Replace these functions to macro.
38684cc2045aSjoerg */
38694cc2045aSjoerg static char *
decode_fp_to_double(const char * p,size_t len)38704cc2045aSjoerg decode_fp_to_double(const char *p, size_t len)
38714cc2045aSjoerg {
38724cc2045aSjoerg double f;
38734cc2045aSjoerg size_t rtn_len, limit, i;
38744cc2045aSjoerg int byte;
38754cc2045aSjoerg char *rtn;
38764cc2045aSjoerg
38774cc2045aSjoerg if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double))
38784cc2045aSjoerg return (NULL);
38794cc2045aSjoerg
38804cc2045aSjoerg memset(&f, 0, sizeof(double));
38814cc2045aSjoerg
38824cc2045aSjoerg for (i = 0; i < len / 2; ++i) {
38834cc2045aSjoerg byte = hex_to_dec(p[len - i * 2 - 1]) +
38844cc2045aSjoerg hex_to_dec(p[len - i * 2 - 2]) * 16;
38854cc2045aSjoerg
38864cc2045aSjoerg if (byte < 0 || byte > 255)
38874cc2045aSjoerg return (NULL);
38884cc2045aSjoerg
38894cc2045aSjoerg #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
38904cc2045aSjoerg ((unsigned char *)&f)[i] = (unsigned char)(byte);
38914cc2045aSjoerg #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
38924cc2045aSjoerg ((unsigned char *)&f)[sizeof(double) - i - 1] =
38934cc2045aSjoerg (unsigned char)(byte);
38944cc2045aSjoerg #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
38954cc2045aSjoerg }
38964cc2045aSjoerg
38974cc2045aSjoerg rtn_len = 64;
38984cc2045aSjoerg limit = 0;
38994cc2045aSjoerg again:
39004cc2045aSjoerg if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
39014cc2045aSjoerg return (NULL);
39024cc2045aSjoerg
39034cc2045aSjoerg if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) {
39044cc2045aSjoerg free(rtn);
39054cc2045aSjoerg if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
39064cc2045aSjoerg return (NULL);
39074cc2045aSjoerg rtn_len *= BUFFER_GROWFACTOR;
39084cc2045aSjoerg goto again;
39094cc2045aSjoerg }
39104cc2045aSjoerg
39114cc2045aSjoerg return rtn;
39124cc2045aSjoerg }
39134cc2045aSjoerg
39144cc2045aSjoerg static char *
decode_fp_to_float(const char * p,size_t len)39154cc2045aSjoerg decode_fp_to_float(const char *p, size_t len)
39164cc2045aSjoerg {
39174cc2045aSjoerg size_t i, rtn_len, limit;
39184cc2045aSjoerg float f;
39194cc2045aSjoerg int byte;
39204cc2045aSjoerg char *rtn;
39214cc2045aSjoerg
39224cc2045aSjoerg if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float))
39234cc2045aSjoerg return (NULL);
39244cc2045aSjoerg
39254cc2045aSjoerg memset(&f, 0, sizeof(float));
39264cc2045aSjoerg
39274cc2045aSjoerg for (i = 0; i < len / 2; ++i) {
39284cc2045aSjoerg byte = hex_to_dec(p[len - i * 2 - 1]) +
39294cc2045aSjoerg hex_to_dec(p[len - i * 2 - 2]) * 16;
39304cc2045aSjoerg if (byte < 0 || byte > 255)
39314cc2045aSjoerg return (NULL);
39324cc2045aSjoerg #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
39334cc2045aSjoerg ((unsigned char *)&f)[i] = (unsigned char)(byte);
39344cc2045aSjoerg #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
39354cc2045aSjoerg ((unsigned char *)&f)[sizeof(float) - i - 1] =
39364cc2045aSjoerg (unsigned char)(byte);
39374cc2045aSjoerg #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
39384cc2045aSjoerg }
39394cc2045aSjoerg
39404cc2045aSjoerg rtn_len = 64;
39414cc2045aSjoerg limit = 0;
39424cc2045aSjoerg again:
39434cc2045aSjoerg if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
39444cc2045aSjoerg return (NULL);
39454cc2045aSjoerg
39464cc2045aSjoerg if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) {
39474cc2045aSjoerg free(rtn);
39484cc2045aSjoerg if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
39494cc2045aSjoerg return (NULL);
39504cc2045aSjoerg rtn_len *= BUFFER_GROWFACTOR;
39514cc2045aSjoerg goto again;
39524cc2045aSjoerg }
39534cc2045aSjoerg
39544cc2045aSjoerg return rtn;
39554cc2045aSjoerg }
39564cc2045aSjoerg
39574cc2045aSjoerg static char *
decode_fp_to_float128(const char * p,size_t len)39584cc2045aSjoerg decode_fp_to_float128(const char *p, size_t len)
39594cc2045aSjoerg {
39604cc2045aSjoerg long double f;
39614cc2045aSjoerg size_t rtn_len, limit, i;
39624cc2045aSjoerg int byte;
39634cc2045aSjoerg unsigned char buf[FLOAT_QUADRUPLE_BYTES];
39644cc2045aSjoerg char *rtn;
39654cc2045aSjoerg
39664cc2045aSjoerg switch(sizeof(long double)) {
39674cc2045aSjoerg case FLOAT_QUADRUPLE_BYTES:
39684cc2045aSjoerg return (decode_fp_to_long_double(p, len));
39694cc2045aSjoerg case FLOAT_EXTENED_BYTES:
39704cc2045aSjoerg if (p == NULL || len == 0 || len % 2 != 0 ||
39714cc2045aSjoerg len / 2 > FLOAT_QUADRUPLE_BYTES)
39724cc2045aSjoerg return (NULL);
39734cc2045aSjoerg
39744cc2045aSjoerg memset(buf, 0, FLOAT_QUADRUPLE_BYTES);
39754cc2045aSjoerg
39764cc2045aSjoerg for (i = 0; i < len / 2; ++i) {
39774cc2045aSjoerg byte = hex_to_dec(p[len - i * 2 - 1]) +
39784cc2045aSjoerg hex_to_dec(p[len - i * 2 - 2]) * 16;
39794cc2045aSjoerg if (byte < 0 || byte > 255)
39804cc2045aSjoerg return (NULL);
39814cc2045aSjoerg #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
39824cc2045aSjoerg buf[i] = (unsigned char)(byte);
39834cc2045aSjoerg #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
39844cc2045aSjoerg buf[FLOAT_QUADRUPLE_BYTES - i -1] =
39854cc2045aSjoerg (unsigned char)(byte);
39864cc2045aSjoerg #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
39874cc2045aSjoerg }
39884cc2045aSjoerg memset(&f, 0, FLOAT_EXTENED_BYTES);
39894cc2045aSjoerg
39904cc2045aSjoerg #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
39914cc2045aSjoerg memcpy(&f, buf, FLOAT_EXTENED_BYTES);
39924cc2045aSjoerg #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
39934cc2045aSjoerg memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES);
39944cc2045aSjoerg #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
39954cc2045aSjoerg
39964cc2045aSjoerg rtn_len = 256;
39974cc2045aSjoerg limit = 0;
39984cc2045aSjoerg again:
39994cc2045aSjoerg if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
40004cc2045aSjoerg return (NULL);
40014cc2045aSjoerg
40024cc2045aSjoerg if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
40034cc2045aSjoerg free(rtn);
40044cc2045aSjoerg if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
40054cc2045aSjoerg return (NULL);
40064cc2045aSjoerg rtn_len *= BUFFER_GROWFACTOR;
40074cc2045aSjoerg goto again;
40084cc2045aSjoerg }
40094cc2045aSjoerg
40104cc2045aSjoerg return (rtn);
40114cc2045aSjoerg default:
40124cc2045aSjoerg return (NULL);
40134cc2045aSjoerg }
40144cc2045aSjoerg }
40154cc2045aSjoerg
40164cc2045aSjoerg static char *
decode_fp_to_float80(const char * p,size_t len)40174cc2045aSjoerg decode_fp_to_float80(const char *p, size_t len)
40184cc2045aSjoerg {
40194cc2045aSjoerg long double f;
40204cc2045aSjoerg size_t rtn_len, limit, i;
40214cc2045aSjoerg int byte;
40224cc2045aSjoerg unsigned char buf[FLOAT_EXTENED_BYTES];
40234cc2045aSjoerg char *rtn;
40244cc2045aSjoerg
40254cc2045aSjoerg switch(sizeof(long double)) {
40264cc2045aSjoerg case FLOAT_QUADRUPLE_BYTES:
40274cc2045aSjoerg if (p == NULL || len == 0 || len % 2 != 0 ||
40284cc2045aSjoerg len / 2 > FLOAT_EXTENED_BYTES)
40294cc2045aSjoerg return (NULL);
40304cc2045aSjoerg
40314cc2045aSjoerg memset(buf, 0, FLOAT_EXTENED_BYTES);
40324cc2045aSjoerg
40334cc2045aSjoerg for (i = 0; i < len / 2; ++i) {
40344cc2045aSjoerg byte = hex_to_dec(p[len - i * 2 - 1]) +
40354cc2045aSjoerg hex_to_dec(p[len - i * 2 - 2]) * 16;
40364cc2045aSjoerg
40374cc2045aSjoerg if (byte < 0 || byte > 255)
40384cc2045aSjoerg return (NULL);
40394cc2045aSjoerg
40404cc2045aSjoerg #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
40414cc2045aSjoerg buf[i] = (unsigned char)(byte);
40424cc2045aSjoerg #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
40434cc2045aSjoerg buf[FLOAT_EXTENED_BYTES - i -1] =
40444cc2045aSjoerg (unsigned char)(byte);
40454cc2045aSjoerg #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
40464cc2045aSjoerg }
40474cc2045aSjoerg
4048*d678c5d4Sjoerg memset(&f, 0, FLOAT_QUADRUPLE_BYTES);
40494cc2045aSjoerg
40504cc2045aSjoerg #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
40514cc2045aSjoerg memcpy(&f, buf, FLOAT_EXTENED_BYTES);
40524cc2045aSjoerg #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
40534cc2045aSjoerg memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES);
40544cc2045aSjoerg #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
40554cc2045aSjoerg
40564cc2045aSjoerg rtn_len = 256;
40574cc2045aSjoerg limit = 0;
40584cc2045aSjoerg again:
40594cc2045aSjoerg if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
40604cc2045aSjoerg return (NULL);
40614cc2045aSjoerg
40624cc2045aSjoerg if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
40634cc2045aSjoerg free(rtn);
40644cc2045aSjoerg if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
40654cc2045aSjoerg return (NULL);
40664cc2045aSjoerg rtn_len *= BUFFER_GROWFACTOR;
40674cc2045aSjoerg goto again;
40684cc2045aSjoerg }
40694cc2045aSjoerg
40704cc2045aSjoerg return (rtn);
40714cc2045aSjoerg case FLOAT_EXTENED_BYTES:
40724cc2045aSjoerg return (decode_fp_to_long_double(p, len));
40734cc2045aSjoerg default:
40744cc2045aSjoerg return (NULL);
40754cc2045aSjoerg }
40764cc2045aSjoerg }
40774cc2045aSjoerg
40784cc2045aSjoerg static char *
decode_fp_to_long_double(const char * p,size_t len)40794cc2045aSjoerg decode_fp_to_long_double(const char *p, size_t len)
40804cc2045aSjoerg {
40814cc2045aSjoerg long double f;
40824cc2045aSjoerg size_t rtn_len, limit, i;
40834cc2045aSjoerg int byte;
40844cc2045aSjoerg char *rtn;
40854cc2045aSjoerg
40864cc2045aSjoerg if (p == NULL || len == 0 || len % 2 != 0 ||
40874cc2045aSjoerg len / 2 > sizeof(long double))
40884cc2045aSjoerg return (NULL);
40894cc2045aSjoerg
40904cc2045aSjoerg memset(&f, 0, sizeof(long double));
40914cc2045aSjoerg
40924cc2045aSjoerg for (i = 0; i < len / 2; ++i) {
40934cc2045aSjoerg byte = hex_to_dec(p[len - i * 2 - 1]) +
40944cc2045aSjoerg hex_to_dec(p[len - i * 2 - 2]) * 16;
40954cc2045aSjoerg
40964cc2045aSjoerg if (byte < 0 || byte > 255)
40974cc2045aSjoerg return (NULL);
40984cc2045aSjoerg
40994cc2045aSjoerg #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
41004cc2045aSjoerg ((unsigned char *)&f)[i] = (unsigned char)(byte);
41014cc2045aSjoerg #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
41024cc2045aSjoerg ((unsigned char *)&f)[sizeof(long double) - i - 1] =
41034cc2045aSjoerg (unsigned char)(byte);
41044cc2045aSjoerg #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
41054cc2045aSjoerg }
41064cc2045aSjoerg
41074cc2045aSjoerg rtn_len = 256;
41084cc2045aSjoerg limit = 0;
41094cc2045aSjoerg again:
41104cc2045aSjoerg if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
41114cc2045aSjoerg return (NULL);
41124cc2045aSjoerg
41134cc2045aSjoerg if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
41144cc2045aSjoerg free(rtn);
41154cc2045aSjoerg if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
41164cc2045aSjoerg return (NULL);
41174cc2045aSjoerg rtn_len *= BUFFER_GROWFACTOR;
41184cc2045aSjoerg goto again;
41194cc2045aSjoerg }
41204cc2045aSjoerg
41214cc2045aSjoerg return (rtn);
41224cc2045aSjoerg }
41234cc2045aSjoerg
41244cc2045aSjoerg /* Simple hex to integer function used by decode_to_* function. */
41254cc2045aSjoerg static int
hex_to_dec(char c)41264cc2045aSjoerg hex_to_dec(char c)
41274cc2045aSjoerg {
41284cc2045aSjoerg
41294cc2045aSjoerg switch (c) {
41304cc2045aSjoerg case '0':
41314cc2045aSjoerg return (0);
41324cc2045aSjoerg case '1':
41334cc2045aSjoerg return (1);
41344cc2045aSjoerg case '2':
41354cc2045aSjoerg return (2);
41364cc2045aSjoerg case '3':
41374cc2045aSjoerg return (3);
41384cc2045aSjoerg case '4':
41394cc2045aSjoerg return (4);
41404cc2045aSjoerg case '5':
41414cc2045aSjoerg return (5);
41424cc2045aSjoerg case '6':
41434cc2045aSjoerg return (6);
41444cc2045aSjoerg case '7':
41454cc2045aSjoerg return (7);
41464cc2045aSjoerg case '8':
41474cc2045aSjoerg return (8);
41484cc2045aSjoerg case '9':
41494cc2045aSjoerg return (9);
41504cc2045aSjoerg case 'a':
41514cc2045aSjoerg return (10);
41524cc2045aSjoerg case 'b':
41534cc2045aSjoerg return (11);
41544cc2045aSjoerg case 'c':
41554cc2045aSjoerg return (12);
41564cc2045aSjoerg case 'd':
41574cc2045aSjoerg return (13);
41584cc2045aSjoerg case 'e':
41594cc2045aSjoerg return (14);
41604cc2045aSjoerg case 'f':
41614cc2045aSjoerg return (15);
41624cc2045aSjoerg default:
41634cc2045aSjoerg return (-1);
4164*d678c5d4Sjoerg }
4165*d678c5d4Sjoerg }
4166*d678c5d4Sjoerg
4167*d678c5d4Sjoerg /**
4168*d678c5d4Sjoerg * @brief Test input string is mangled by IA-64 C++ ABI style.
4169*d678c5d4Sjoerg *
4170*d678c5d4Sjoerg * Test string heads with "_Z" or "_GLOBAL__I_".
4171*d678c5d4Sjoerg * @return Return 0 at false.
4172*d678c5d4Sjoerg */
4173*d678c5d4Sjoerg bool
is_cpp_mangled_gnu3(const char * org)4174*d678c5d4Sjoerg is_cpp_mangled_gnu3(const char *org)
4175*d678c5d4Sjoerg {
4176*d678c5d4Sjoerg size_t len;
4177*d678c5d4Sjoerg
4178*d678c5d4Sjoerg len = strlen(org);
4179*d678c5d4Sjoerg return ((len > 2 && *org == '_' && *(org + 1) == 'Z') ||
4180*d678c5d4Sjoerg (len > 11 && !strncmp(org, "_GLOBAL__I_", 11)));
41814cc2045aSjoerg }
41824cc2045aSjoerg
41834cc2045aSjoerg static void
vector_read_cmd_dest(struct vector_read_cmd * v)41844cc2045aSjoerg vector_read_cmd_dest(struct vector_read_cmd *v)
41854cc2045aSjoerg {
41864cc2045aSjoerg
41874cc2045aSjoerg if (v == NULL)
41884cc2045aSjoerg return;
41894cc2045aSjoerg
41904cc2045aSjoerg free(v->r_container);
41914cc2045aSjoerg }
41924cc2045aSjoerg
4193*d678c5d4Sjoerg static struct read_cmd_item *
vector_read_cmd_find(struct vector_read_cmd * v,enum read_cmd dst)41944cc2045aSjoerg vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst)
41954cc2045aSjoerg {
4196*d678c5d4Sjoerg int i;
41974cc2045aSjoerg
41984cc2045aSjoerg if (v == NULL || dst == READ_FAIL)
4199*d678c5d4Sjoerg return (NULL);
42004cc2045aSjoerg
4201*d678c5d4Sjoerg for (i = (int) v->size - 1; i >= 0; i--)
4202*d678c5d4Sjoerg if (v->r_container[i].cmd == dst)
4203*d678c5d4Sjoerg return (&v->r_container[i]);
42044cc2045aSjoerg
4205*d678c5d4Sjoerg return (NULL);
42064cc2045aSjoerg }
42074cc2045aSjoerg
42084cc2045aSjoerg static int
vector_read_cmd_init(struct vector_read_cmd * v)42094cc2045aSjoerg vector_read_cmd_init(struct vector_read_cmd *v)
42104cc2045aSjoerg {
42114cc2045aSjoerg
42124cc2045aSjoerg if (v == NULL)
42134cc2045aSjoerg return (0);
42144cc2045aSjoerg
42154cc2045aSjoerg v->size = 0;
42164cc2045aSjoerg v->capacity = VECTOR_DEF_CAPACITY;
42174cc2045aSjoerg
4218*d678c5d4Sjoerg if ((v->r_container = malloc(sizeof(*v->r_container) * v->capacity))
42194cc2045aSjoerg == NULL)
42204cc2045aSjoerg return (0);
42214cc2045aSjoerg
42224cc2045aSjoerg return (1);
42234cc2045aSjoerg }
42244cc2045aSjoerg
42254cc2045aSjoerg static int
vector_read_cmd_pop(struct vector_read_cmd * v)42264cc2045aSjoerg vector_read_cmd_pop(struct vector_read_cmd *v)
42274cc2045aSjoerg {
42284cc2045aSjoerg
42294cc2045aSjoerg if (v == NULL || v->size == 0)
42304cc2045aSjoerg return (0);
42314cc2045aSjoerg
42324cc2045aSjoerg --v->size;
4233*d678c5d4Sjoerg v->r_container[v->size].cmd = READ_FAIL;
4234*d678c5d4Sjoerg v->r_container[v->size].data = NULL;
42354cc2045aSjoerg
42364cc2045aSjoerg return (1);
42374cc2045aSjoerg }
42384cc2045aSjoerg
42394cc2045aSjoerg static int
vector_read_cmd_push(struct vector_read_cmd * v,enum read_cmd cmd,void * data)4240*d678c5d4Sjoerg vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd, void *data)
42414cc2045aSjoerg {
4242*d678c5d4Sjoerg struct read_cmd_item *tmp_r_ctn;
42434cc2045aSjoerg size_t tmp_cap;
42444cc2045aSjoerg size_t i;
42454cc2045aSjoerg
42464cc2045aSjoerg if (v == NULL)
42474cc2045aSjoerg return (0);
42484cc2045aSjoerg
42494cc2045aSjoerg if (v->size == v->capacity) {
4250*d678c5d4Sjoerg tmp_cap = BUFFER_GROW(v->capacity);
4251*d678c5d4Sjoerg if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL)
42524cc2045aSjoerg return (0);
42534cc2045aSjoerg for (i = 0; i < v->size; ++i)
42544cc2045aSjoerg tmp_r_ctn[i] = v->r_container[i];
42554cc2045aSjoerg free(v->r_container);
42564cc2045aSjoerg v->r_container = tmp_r_ctn;
42574cc2045aSjoerg v->capacity = tmp_cap;
42584cc2045aSjoerg }
42594cc2045aSjoerg
4260*d678c5d4Sjoerg v->r_container[v->size].cmd = cmd;
4261*d678c5d4Sjoerg v->r_container[v->size].data = data;
42624cc2045aSjoerg ++v->size;
42634cc2045aSjoerg
42644cc2045aSjoerg return (1);
42654cc2045aSjoerg }
42664cc2045aSjoerg
42674cc2045aSjoerg static void
vector_type_qualifier_dest(struct vector_type_qualifier * v)42684cc2045aSjoerg vector_type_qualifier_dest(struct vector_type_qualifier *v)
42694cc2045aSjoerg {
42704cc2045aSjoerg
42714cc2045aSjoerg if (v == NULL)
42724cc2045aSjoerg return;
42734cc2045aSjoerg
42744cc2045aSjoerg free(v->q_container);
42754cc2045aSjoerg vector_str_dest(&v->ext_name);
42764cc2045aSjoerg }
42774cc2045aSjoerg
42784cc2045aSjoerg /* size, capacity, ext_name */
42794cc2045aSjoerg static int
vector_type_qualifier_init(struct vector_type_qualifier * v)42804cc2045aSjoerg vector_type_qualifier_init(struct vector_type_qualifier *v)
42814cc2045aSjoerg {
42824cc2045aSjoerg
42834cc2045aSjoerg if (v == NULL)
42844cc2045aSjoerg return (0);
42854cc2045aSjoerg
42864cc2045aSjoerg v->size = 0;
42874cc2045aSjoerg v->capacity = VECTOR_DEF_CAPACITY;
42884cc2045aSjoerg
42894cc2045aSjoerg if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity))
42904cc2045aSjoerg == NULL)
42914cc2045aSjoerg return (0);
42924cc2045aSjoerg
42934cc2045aSjoerg assert(v->q_container != NULL);
42944cc2045aSjoerg
4295*d678c5d4Sjoerg if (!vector_str_init(&v->ext_name)) {
42964cc2045aSjoerg free(v->q_container);
42974cc2045aSjoerg return (0);
42984cc2045aSjoerg }
42994cc2045aSjoerg
43004cc2045aSjoerg return (1);
43014cc2045aSjoerg }
43024cc2045aSjoerg
43034cc2045aSjoerg static int
vector_type_qualifier_push(struct vector_type_qualifier * v,enum type_qualifier t)43044cc2045aSjoerg vector_type_qualifier_push(struct vector_type_qualifier *v,
43054cc2045aSjoerg enum type_qualifier t)
43064cc2045aSjoerg {
43074cc2045aSjoerg enum type_qualifier *tmp_ctn;
43084cc2045aSjoerg size_t tmp_cap;
43094cc2045aSjoerg size_t i;
43104cc2045aSjoerg
43114cc2045aSjoerg if (v == NULL)
43124cc2045aSjoerg return (0);
43134cc2045aSjoerg
43144cc2045aSjoerg if (v->size == v->capacity) {
4315*d678c5d4Sjoerg tmp_cap = BUFFER_GROW(v->capacity);
43164cc2045aSjoerg if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap))
43174cc2045aSjoerg == NULL)
43184cc2045aSjoerg return (0);
43194cc2045aSjoerg for (i = 0; i < v->size; ++i)
43204cc2045aSjoerg tmp_ctn[i] = v->q_container[i];
43214cc2045aSjoerg free(v->q_container);
43224cc2045aSjoerg v->q_container = tmp_ctn;
43234cc2045aSjoerg v->capacity = tmp_cap;
43244cc2045aSjoerg }
43254cc2045aSjoerg
43264cc2045aSjoerg v->q_container[v->size] = t;
43274cc2045aSjoerg ++v->size;
43284cc2045aSjoerg
43294cc2045aSjoerg return (1);
43304cc2045aSjoerg }
4331