1a85fe12eSEd Maste /*- 2a85fe12eSEd Maste * Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com> 318f4c9dbSEd Maste * Copyright (c) 2015-2017 Kai Wang <kaiwang27@gmail.com> 4a85fe12eSEd Maste * All rights reserved. 5a85fe12eSEd Maste * 6a85fe12eSEd Maste * Redistribution and use in source and binary forms, with or without 7a85fe12eSEd Maste * modification, are permitted provided that the following conditions 8a85fe12eSEd Maste * are met: 9a85fe12eSEd Maste * 1. Redistributions of source code must retain the above copyright 10a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer 11a85fe12eSEd Maste * in this position and unchanged. 12a85fe12eSEd Maste * 2. Redistributions in binary form must reproduce the above copyright 13a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer in the 14a85fe12eSEd Maste * documentation and/or other materials provided with the distribution. 15a85fe12eSEd Maste * 16a85fe12eSEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 17a85fe12eSEd Maste * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18a85fe12eSEd Maste * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19a85fe12eSEd Maste * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20a85fe12eSEd Maste * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21a85fe12eSEd Maste * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22a85fe12eSEd Maste * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23a85fe12eSEd Maste * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24a85fe12eSEd Maste * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25a85fe12eSEd Maste * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26a85fe12eSEd Maste */ 27a85fe12eSEd Maste #include <sys/types.h> 28a85fe12eSEd Maste #include <assert.h> 29a85fe12eSEd Maste #include <ctype.h> 30a85fe12eSEd Maste #include <errno.h> 31a85fe12eSEd Maste #include <libelftc.h> 32a85fe12eSEd Maste #include <limits.h> 33a85fe12eSEd Maste #include <stdbool.h> 34a85fe12eSEd Maste #include <stdio.h> 35a85fe12eSEd Maste #include <stdlib.h> 36a85fe12eSEd Maste #include <string.h> 37a85fe12eSEd Maste 38a85fe12eSEd Maste #include "_libelftc.h" 39a85fe12eSEd Maste 40715d1396SEd Maste ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3583 2017-10-15 15:38:47Z emaste $"); 41a85fe12eSEd Maste 42a85fe12eSEd Maste /** 43a85fe12eSEd Maste * @file cpp_demangle.c 44a85fe12eSEd Maste * @brief Decode IA-64 C++ ABI style implementation. 45a85fe12eSEd Maste * 46a85fe12eSEd Maste * IA-64 standard ABI(Itanium C++ ABI) references. 47a85fe12eSEd Maste * 48a85fe12eSEd Maste * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n 49a85fe12eSEd Maste * http://www.codesourcery.com/cxx-abi/abi-mangling.html 50a85fe12eSEd Maste */ 51a85fe12eSEd Maste 52a85fe12eSEd Maste enum type_qualifier { 53a85fe12eSEd Maste TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT, 5418f4c9dbSEd Maste TYPE_CST, TYPE_VEC, TYPE_RREF 55a85fe12eSEd Maste }; 56a85fe12eSEd Maste 57a85fe12eSEd Maste struct vector_type_qualifier { 58a85fe12eSEd Maste size_t size, capacity; 59a85fe12eSEd Maste enum type_qualifier *q_container; 60a85fe12eSEd Maste struct vector_str ext_name; 61a85fe12eSEd Maste }; 62a85fe12eSEd Maste 63a85fe12eSEd Maste enum read_cmd { 64a85fe12eSEd Maste READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL, 65a85fe12eSEd Maste READ_TYPE, READ_FUNC, READ_PTRMEM 66a85fe12eSEd Maste }; 67a85fe12eSEd Maste 6818f4c9dbSEd Maste struct read_cmd_item { 6918f4c9dbSEd Maste enum read_cmd cmd; 7018f4c9dbSEd Maste void *data; 7118f4c9dbSEd Maste }; 7218f4c9dbSEd Maste 73a85fe12eSEd Maste struct vector_read_cmd { 74a85fe12eSEd Maste size_t size, capacity; 7518f4c9dbSEd Maste struct read_cmd_item *r_container; 7618f4c9dbSEd Maste }; 7718f4c9dbSEd Maste 7818f4c9dbSEd Maste enum push_qualifier { 7918f4c9dbSEd Maste PUSH_ALL_QUALIFIER, 8018f4c9dbSEd Maste PUSH_CV_QUALIFIER, 8118f4c9dbSEd Maste PUSH_NON_CV_QUALIFIER, 82a85fe12eSEd Maste }; 83a85fe12eSEd Maste 84a85fe12eSEd Maste struct cpp_demangle_data { 85a85fe12eSEd Maste struct vector_str output; /* output string vector */ 86a85fe12eSEd Maste struct vector_str subst; /* substitution string vector */ 87a85fe12eSEd Maste struct vector_str tmpl; 88a85fe12eSEd Maste struct vector_str class_type; 8918f4c9dbSEd Maste struct vector_str *cur_output; /* ptr to current output vec */ 90a85fe12eSEd Maste struct vector_read_cmd cmd; 91a85fe12eSEd Maste bool mem_rst; /* restrict member function */ 92a85fe12eSEd Maste bool mem_vat; /* volatile member function */ 93a85fe12eSEd Maste bool mem_cst; /* const member function */ 9418f4c9dbSEd Maste bool mem_ref; /* lvalue-ref member func */ 9518f4c9dbSEd Maste bool mem_rref; /* rvalue-ref member func */ 9618f4c9dbSEd Maste bool is_tmpl; /* template args */ 9718f4c9dbSEd Maste bool is_functype; /* function type */ 9818f4c9dbSEd Maste bool ref_qualifier; /* ref qualifier */ 9918f4c9dbSEd Maste enum type_qualifier ref_qualifier_type; /* ref qualifier type */ 10018f4c9dbSEd Maste enum push_qualifier push_qualifier; /* which qualifiers to push */ 101a85fe12eSEd Maste int func_type; 102a85fe12eSEd Maste const char *cur; /* current mangled name ptr */ 103a85fe12eSEd Maste const char *last_sname; /* last source name */ 10418f4c9dbSEd Maste }; 10518f4c9dbSEd Maste 10618f4c9dbSEd Maste struct type_delimit { 10718f4c9dbSEd Maste bool paren; 10818f4c9dbSEd Maste bool firstp; 109a85fe12eSEd Maste }; 110a85fe12eSEd Maste 111a85fe12eSEd Maste #define CPP_DEMANGLE_TRY_LIMIT 128 112a85fe12eSEd Maste #define FLOAT_SPRINTF_TRY_LIMIT 5 113a85fe12eSEd Maste #define FLOAT_QUADRUPLE_BYTES 16 114a85fe12eSEd Maste #define FLOAT_EXTENED_BYTES 10 115a85fe12eSEd Maste 116a85fe12eSEd Maste #define SIMPLE_HASH(x,y) (64 * x + y) 117bee2765cSEd Maste #define DEM_PUSH_STR(d,s) cpp_demangle_push_str((d), (s), strlen((s))) 118bee2765cSEd Maste #define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) 119a85fe12eSEd Maste 120a85fe12eSEd Maste static void cpp_demangle_data_dest(struct cpp_demangle_data *); 121a85fe12eSEd Maste static int cpp_demangle_data_init(struct cpp_demangle_data *, 122a85fe12eSEd Maste const char *); 123a85fe12eSEd Maste static int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t); 124a85fe12eSEd Maste static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t); 125a85fe12eSEd Maste static int cpp_demangle_push_fp(struct cpp_demangle_data *, 126a85fe12eSEd Maste char *(*)(const char *, size_t)); 127a85fe12eSEd Maste static int cpp_demangle_push_str(struct cpp_demangle_data *, const char *, 128a85fe12eSEd Maste size_t); 12918f4c9dbSEd Maste static int cpp_demangle_pop_str(struct cpp_demangle_data *); 130a85fe12eSEd Maste static int cpp_demangle_push_subst(struct cpp_demangle_data *, 131a85fe12eSEd Maste const char *, size_t); 132a85fe12eSEd Maste static int cpp_demangle_push_subst_v(struct cpp_demangle_data *, 133a85fe12eSEd Maste struct vector_str *); 134a85fe12eSEd Maste static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *, 135a85fe12eSEd Maste struct vector_type_qualifier *, const char *); 136a85fe12eSEd Maste static int cpp_demangle_read_array(struct cpp_demangle_data *); 137a85fe12eSEd Maste static int cpp_demangle_read_encoding(struct cpp_demangle_data *); 138a85fe12eSEd Maste static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); 139a85fe12eSEd Maste static int cpp_demangle_read_expression(struct cpp_demangle_data *); 1403ef90571SEd Maste static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *, 1413ef90571SEd Maste char **); 142a85fe12eSEd Maste static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, 143a85fe12eSEd Maste const char *, size_t); 144a85fe12eSEd Maste static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, 145a85fe12eSEd Maste const char *, size_t); 146a85fe12eSEd Maste static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, 147a85fe12eSEd Maste const char *, size_t, const char *, size_t); 148a85fe12eSEd Maste static int cpp_demangle_read_function(struct cpp_demangle_data *, int *, 149a85fe12eSEd Maste struct vector_type_qualifier *); 150a85fe12eSEd Maste static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); 151a85fe12eSEd Maste static int cpp_demangle_read_local_name(struct cpp_demangle_data *); 152a85fe12eSEd Maste static int cpp_demangle_read_name(struct cpp_demangle_data *); 1533ef90571SEd Maste static int cpp_demangle_read_name_flat(struct cpp_demangle_data *, 1543ef90571SEd Maste char**); 155a85fe12eSEd Maste static int cpp_demangle_read_nested_name(struct cpp_demangle_data *); 156a85fe12eSEd Maste static int cpp_demangle_read_number(struct cpp_demangle_data *, long *); 1573ef90571SEd Maste static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *, 1583ef90571SEd Maste char **); 159a85fe12eSEd Maste static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); 160a85fe12eSEd Maste static int cpp_demangle_read_offset(struct cpp_demangle_data *); 161a85fe12eSEd Maste static int cpp_demangle_read_offset_number(struct cpp_demangle_data *); 16218f4c9dbSEd Maste static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *, 16318f4c9dbSEd Maste struct vector_type_qualifier *); 164a85fe12eSEd Maste static int cpp_demangle_read_sname(struct cpp_demangle_data *); 165a85fe12eSEd Maste static int cpp_demangle_read_subst(struct cpp_demangle_data *); 166a85fe12eSEd Maste static int cpp_demangle_read_subst_std(struct cpp_demangle_data *); 167a85fe12eSEd Maste static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *, 16818f4c9dbSEd Maste const char *); 169a85fe12eSEd Maste static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); 170a85fe12eSEd Maste static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); 171a85fe12eSEd Maste static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); 17218f4c9dbSEd Maste static int cpp_demangle_read_type(struct cpp_demangle_data *, 17318f4c9dbSEd Maste struct type_delimit *); 1743ef90571SEd Maste static int cpp_demangle_read_type_flat(struct cpp_demangle_data *, 1753ef90571SEd Maste char **); 176a85fe12eSEd Maste static int cpp_demangle_read_uqname(struct cpp_demangle_data *); 177a85fe12eSEd Maste static int cpp_demangle_read_v_offset(struct cpp_demangle_data *); 178a85fe12eSEd Maste static char *decode_fp_to_double(const char *, size_t); 179a85fe12eSEd Maste static char *decode_fp_to_float(const char *, size_t); 180a85fe12eSEd Maste static char *decode_fp_to_float128(const char *, size_t); 181a85fe12eSEd Maste static char *decode_fp_to_float80(const char *, size_t); 182a85fe12eSEd Maste static char *decode_fp_to_long_double(const char *, size_t); 183a85fe12eSEd Maste static int hex_to_dec(char); 184a85fe12eSEd Maste static void vector_read_cmd_dest(struct vector_read_cmd *); 18518f4c9dbSEd Maste static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *, 18618f4c9dbSEd Maste enum read_cmd); 187a85fe12eSEd Maste static int vector_read_cmd_init(struct vector_read_cmd *); 188a85fe12eSEd Maste static int vector_read_cmd_pop(struct vector_read_cmd *); 18918f4c9dbSEd Maste static int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd, 19018f4c9dbSEd Maste void *); 191a85fe12eSEd Maste static void vector_type_qualifier_dest(struct vector_type_qualifier *); 192a85fe12eSEd Maste static int vector_type_qualifier_init(struct vector_type_qualifier *); 193a85fe12eSEd Maste static int vector_type_qualifier_push(struct vector_type_qualifier *, 194a85fe12eSEd Maste enum type_qualifier); 195a85fe12eSEd Maste 196a85fe12eSEd Maste /** 197a85fe12eSEd Maste * @brief Decode the input string by IA-64 C++ ABI style. 198a85fe12eSEd Maste * 199a85fe12eSEd Maste * GNU GCC v3 use IA-64 standard ABI. 200a85fe12eSEd Maste * @return New allocated demangled string or NULL if failed. 201a85fe12eSEd Maste * @todo 1. Testing and more test case. 2. Code cleaning. 202a85fe12eSEd Maste */ 203a85fe12eSEd Maste char * 204a85fe12eSEd Maste cpp_demangle_gnu3(const char *org) 205a85fe12eSEd Maste { 206a85fe12eSEd Maste struct cpp_demangle_data ddata; 20718f4c9dbSEd Maste struct vector_str ret_type; 20818f4c9dbSEd Maste struct type_delimit td; 209a85fe12eSEd Maste ssize_t org_len; 210a85fe12eSEd Maste unsigned int limit; 211a85fe12eSEd Maste char *rtn; 21218f4c9dbSEd Maste bool has_ret, more_type; 213a85fe12eSEd Maste 214a85fe12eSEd Maste if (org == NULL || (org_len = strlen(org)) < 2) 215a85fe12eSEd Maste return (NULL); 216a85fe12eSEd Maste 217a85fe12eSEd Maste if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { 218a85fe12eSEd Maste if ((rtn = malloc(org_len + 19)) == NULL) 219a85fe12eSEd Maste return (NULL); 220a85fe12eSEd Maste snprintf(rtn, org_len + 19, 221a85fe12eSEd Maste "global constructors keyed to %s", org + 11); 222a85fe12eSEd Maste return (rtn); 223a85fe12eSEd Maste } 224a85fe12eSEd Maste 225a85fe12eSEd Maste if (org[0] != '_' || org[1] != 'Z') 226a85fe12eSEd Maste return (NULL); 227a85fe12eSEd Maste 228a85fe12eSEd Maste if (!cpp_demangle_data_init(&ddata, org + 2)) 229a85fe12eSEd Maste return (NULL); 230a85fe12eSEd Maste 231a85fe12eSEd Maste rtn = NULL; 23218f4c9dbSEd Maste has_ret = more_type = false; 233a85fe12eSEd Maste 234a85fe12eSEd Maste if (!cpp_demangle_read_encoding(&ddata)) 235a85fe12eSEd Maste goto clean; 236a85fe12eSEd Maste 23718f4c9dbSEd Maste /* 23818f4c9dbSEd Maste * Pop function name from substitution candidate list. 23918f4c9dbSEd Maste */ 24018f4c9dbSEd Maste if (*ddata.cur != 0 && ddata.subst.size >= 1) { 24118f4c9dbSEd Maste if (!vector_str_pop(&ddata.subst)) 24218f4c9dbSEd Maste goto clean; 24318f4c9dbSEd Maste } 24418f4c9dbSEd Maste 24518f4c9dbSEd Maste td.paren = false; 24618f4c9dbSEd Maste td.firstp = true; 247a85fe12eSEd Maste limit = 0; 24818f4c9dbSEd Maste 24918f4c9dbSEd Maste /* 25018f4c9dbSEd Maste * The first type is a return type if we just demangled template 25118f4c9dbSEd Maste * args. (the template args is right next to the function name, 25218f4c9dbSEd Maste * which means it's a template function) 25318f4c9dbSEd Maste */ 25418f4c9dbSEd Maste if (ddata.is_tmpl) { 25518f4c9dbSEd Maste ddata.is_tmpl = false; 25618f4c9dbSEd Maste if (!vector_str_init(&ret_type)) 25718f4c9dbSEd Maste goto clean; 25818f4c9dbSEd Maste ddata.cur_output = &ret_type; 25918f4c9dbSEd Maste has_ret = true; 26018f4c9dbSEd Maste } 26118f4c9dbSEd Maste 262a85fe12eSEd Maste while (*ddata.cur != '\0') { 263a85fe12eSEd Maste /* 264a85fe12eSEd Maste * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4 265a85fe12eSEd Maste */ 266a85fe12eSEd Maste if (*ddata.cur == '@' && *(ddata.cur + 1) == '@') 267a85fe12eSEd Maste break; 26818f4c9dbSEd Maste 26918f4c9dbSEd Maste if (has_ret) { 27018f4c9dbSEd Maste /* Read return type */ 27118f4c9dbSEd Maste if (!cpp_demangle_read_type(&ddata, NULL)) 272a85fe12eSEd Maste goto clean; 27318f4c9dbSEd Maste } else { 27418f4c9dbSEd Maste /* Read function arg type */ 27518f4c9dbSEd Maste if (!cpp_demangle_read_type(&ddata, &td)) 276a85fe12eSEd Maste goto clean; 277a85fe12eSEd Maste } 278a85fe12eSEd Maste 27918f4c9dbSEd Maste if (has_ret) { 28018f4c9dbSEd Maste /* Push return type to the beginning */ 28118f4c9dbSEd Maste if (!VEC_PUSH_STR(&ret_type, " ")) 28218f4c9dbSEd Maste goto clean; 28318f4c9dbSEd Maste if (!vector_str_push_vector_head(&ddata.output, 28418f4c9dbSEd Maste &ret_type)) 28518f4c9dbSEd Maste goto clean; 28618f4c9dbSEd Maste ddata.cur_output = &ddata.output; 28718f4c9dbSEd Maste vector_str_dest(&ret_type); 28818f4c9dbSEd Maste has_ret = false; 28918f4c9dbSEd Maste more_type = true; 29018f4c9dbSEd Maste } else if (more_type) 29118f4c9dbSEd Maste more_type = false; 29218f4c9dbSEd Maste if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 29318f4c9dbSEd Maste goto clean; 29418f4c9dbSEd Maste } 29518f4c9dbSEd Maste if (more_type) 29618f4c9dbSEd Maste goto clean; 29718f4c9dbSEd Maste 298a85fe12eSEd Maste if (ddata.output.size == 0) 299a85fe12eSEd Maste goto clean; 30018f4c9dbSEd Maste if (td.paren && !VEC_PUSH_STR(&ddata.output, ")")) 301a85fe12eSEd Maste goto clean; 302bee2765cSEd Maste if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile")) 303a85fe12eSEd Maste goto clean; 304bee2765cSEd Maste if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const")) 305a85fe12eSEd Maste goto clean; 306bee2765cSEd Maste if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict")) 307a85fe12eSEd Maste goto clean; 30818f4c9dbSEd Maste if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &")) 30918f4c9dbSEd Maste goto clean; 31018f4c9dbSEd Maste if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&")) 31118f4c9dbSEd Maste goto clean; 312a85fe12eSEd Maste 313a85fe12eSEd Maste rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); 314a85fe12eSEd Maste 315a85fe12eSEd Maste clean: 31618f4c9dbSEd Maste if (has_ret) 31718f4c9dbSEd Maste vector_str_dest(&ret_type); 31818f4c9dbSEd Maste 319a85fe12eSEd Maste cpp_demangle_data_dest(&ddata); 320a85fe12eSEd Maste 321a85fe12eSEd Maste return (rtn); 322a85fe12eSEd Maste } 323a85fe12eSEd Maste 324a85fe12eSEd Maste static void 325a85fe12eSEd Maste cpp_demangle_data_dest(struct cpp_demangle_data *d) 326a85fe12eSEd Maste { 327a85fe12eSEd Maste 328a85fe12eSEd Maste if (d == NULL) 329a85fe12eSEd Maste return; 330a85fe12eSEd Maste 331a85fe12eSEd Maste vector_read_cmd_dest(&d->cmd); 332a85fe12eSEd Maste vector_str_dest(&d->class_type); 333a85fe12eSEd Maste vector_str_dest(&d->tmpl); 334a85fe12eSEd Maste vector_str_dest(&d->subst); 335a85fe12eSEd Maste vector_str_dest(&d->output); 336a85fe12eSEd Maste } 337a85fe12eSEd Maste 338a85fe12eSEd Maste static int 339a85fe12eSEd Maste cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) 340a85fe12eSEd Maste { 341a85fe12eSEd Maste 342a85fe12eSEd Maste if (d == NULL || cur == NULL) 343a85fe12eSEd Maste return (0); 344a85fe12eSEd Maste 345a85fe12eSEd Maste if (!vector_str_init(&d->output)) 346a85fe12eSEd Maste return (0); 347a85fe12eSEd Maste if (!vector_str_init(&d->subst)) 34818f4c9dbSEd Maste goto clean1; 349a85fe12eSEd Maste if (!vector_str_init(&d->tmpl)) 35018f4c9dbSEd Maste goto clean2; 351a85fe12eSEd Maste if (!vector_str_init(&d->class_type)) 35218f4c9dbSEd Maste goto clean3; 353a85fe12eSEd Maste if (!vector_read_cmd_init(&d->cmd)) 35418f4c9dbSEd Maste goto clean4; 355a85fe12eSEd Maste 356a85fe12eSEd Maste assert(d->output.container != NULL); 357a85fe12eSEd Maste assert(d->subst.container != NULL); 358a85fe12eSEd Maste assert(d->tmpl.container != NULL); 359a85fe12eSEd Maste assert(d->class_type.container != NULL); 360a85fe12eSEd Maste 361a85fe12eSEd Maste d->mem_rst = false; 362a85fe12eSEd Maste d->mem_vat = false; 363a85fe12eSEd Maste d->mem_cst = false; 36418f4c9dbSEd Maste d->mem_ref = false; 36518f4c9dbSEd Maste d->mem_rref = false; 36618f4c9dbSEd Maste d->is_tmpl = false; 36718f4c9dbSEd Maste d->is_functype = false; 36818f4c9dbSEd Maste d->ref_qualifier = false; 36918f4c9dbSEd Maste d->push_qualifier = PUSH_ALL_QUALIFIER; 370a85fe12eSEd Maste d->func_type = 0; 371a85fe12eSEd Maste d->cur = cur; 37218f4c9dbSEd Maste d->cur_output = &d->output; 373a85fe12eSEd Maste d->last_sname = NULL; 374a85fe12eSEd Maste 375a85fe12eSEd Maste return (1); 376a85fe12eSEd Maste 377a85fe12eSEd Maste clean4: 37818f4c9dbSEd Maste vector_str_dest(&d->class_type); 379a85fe12eSEd Maste clean3: 38018f4c9dbSEd Maste vector_str_dest(&d->tmpl); 381a85fe12eSEd Maste clean2: 38218f4c9dbSEd Maste vector_str_dest(&d->subst); 383a85fe12eSEd Maste clean1: 384a85fe12eSEd Maste vector_str_dest(&d->output); 385a85fe12eSEd Maste 386a85fe12eSEd Maste return (0); 387a85fe12eSEd Maste } 388a85fe12eSEd Maste 389a85fe12eSEd Maste static int 390a85fe12eSEd Maste cpp_demangle_push_fp(struct cpp_demangle_data *ddata, 391a85fe12eSEd Maste char *(*decoder)(const char *, size_t)) 392a85fe12eSEd Maste { 393a85fe12eSEd Maste size_t len; 394a85fe12eSEd Maste int rtn; 395a85fe12eSEd Maste const char *fp; 396a85fe12eSEd Maste char *f; 397a85fe12eSEd Maste 398a85fe12eSEd Maste if (ddata == NULL || decoder == NULL) 399a85fe12eSEd Maste return (0); 400a85fe12eSEd Maste 401a85fe12eSEd Maste fp = ddata->cur; 402a85fe12eSEd Maste while (*ddata->cur != 'E') 403a85fe12eSEd Maste ++ddata->cur; 404a85fe12eSEd Maste 405a85fe12eSEd Maste if ((f = decoder(fp, ddata->cur - fp)) == NULL) 406a85fe12eSEd Maste return (0); 407a85fe12eSEd Maste 408a85fe12eSEd Maste rtn = 0; 409a85fe12eSEd Maste if ((len = strlen(f)) > 0) 410a85fe12eSEd Maste rtn = cpp_demangle_push_str(ddata, f, len); 411a85fe12eSEd Maste 412a85fe12eSEd Maste free(f); 413a85fe12eSEd Maste 4143ef90571SEd Maste ++ddata->cur; 4153ef90571SEd Maste 416a85fe12eSEd Maste return (rtn); 417a85fe12eSEd Maste } 418a85fe12eSEd Maste 419a85fe12eSEd Maste static int 420a85fe12eSEd Maste cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, 421a85fe12eSEd Maste size_t len) 422a85fe12eSEd Maste { 423a85fe12eSEd Maste 424a85fe12eSEd Maste if (ddata == NULL || str == NULL || len == 0) 425a85fe12eSEd Maste return (0); 426a85fe12eSEd Maste 42718f4c9dbSEd Maste /* 42818f4c9dbSEd Maste * is_tmpl is used to check if the type (function arg) is right next 42918f4c9dbSEd Maste * to template args, and should always be cleared whenever new string 43018f4c9dbSEd Maste * pushed. 43118f4c9dbSEd Maste */ 43218f4c9dbSEd Maste ddata->is_tmpl = false; 433a85fe12eSEd Maste 43418f4c9dbSEd Maste return (vector_str_push(ddata->cur_output, str, len)); 43518f4c9dbSEd Maste } 43618f4c9dbSEd Maste 43718f4c9dbSEd Maste static int 43818f4c9dbSEd Maste cpp_demangle_pop_str(struct cpp_demangle_data *ddata) 43918f4c9dbSEd Maste { 44018f4c9dbSEd Maste 44118f4c9dbSEd Maste if (ddata == NULL) 44218f4c9dbSEd Maste return (0); 44318f4c9dbSEd Maste 44418f4c9dbSEd Maste return (vector_str_pop(ddata->cur_output)); 445a85fe12eSEd Maste } 446a85fe12eSEd Maste 447a85fe12eSEd Maste static int 448a85fe12eSEd Maste cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, 449a85fe12eSEd Maste size_t len) 450a85fe12eSEd Maste { 451a85fe12eSEd Maste 452a85fe12eSEd Maste if (ddata == NULL || str == NULL || len == 0) 453a85fe12eSEd Maste return (0); 454a85fe12eSEd Maste 455a85fe12eSEd Maste if (!vector_str_find(&ddata->subst, str, len)) 456a85fe12eSEd Maste return (vector_str_push(&ddata->subst, str, len)); 457a85fe12eSEd Maste 458a85fe12eSEd Maste return (1); 459a85fe12eSEd Maste } 460a85fe12eSEd Maste 461a85fe12eSEd Maste static int 462a85fe12eSEd Maste cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) 463a85fe12eSEd Maste { 464a85fe12eSEd Maste size_t str_len; 465a85fe12eSEd Maste int rtn; 466a85fe12eSEd Maste char *str; 467a85fe12eSEd Maste 468a85fe12eSEd Maste if (ddata == NULL || v == NULL) 469a85fe12eSEd Maste return (0); 470a85fe12eSEd Maste 471a85fe12eSEd Maste if ((str = vector_str_get_flat(v, &str_len)) == NULL) 472a85fe12eSEd Maste return (0); 473a85fe12eSEd Maste 474a85fe12eSEd Maste rtn = cpp_demangle_push_subst(ddata, str, str_len); 475a85fe12eSEd Maste 476a85fe12eSEd Maste free(str); 477a85fe12eSEd Maste 478a85fe12eSEd Maste return (rtn); 479a85fe12eSEd Maste } 480a85fe12eSEd Maste 481a85fe12eSEd Maste static int 482a85fe12eSEd Maste cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, 483a85fe12eSEd Maste struct vector_type_qualifier *v, const char *type_str) 484a85fe12eSEd Maste { 485a85fe12eSEd Maste struct vector_str subst_v; 48618f4c9dbSEd Maste enum type_qualifier t; 487a85fe12eSEd Maste size_t idx, e_idx, e_len; 488a85fe12eSEd Maste char *buf; 48918f4c9dbSEd Maste int rtn; 49018f4c9dbSEd Maste bool cv; 491a85fe12eSEd Maste 492a85fe12eSEd Maste if (ddata == NULL || v == NULL) 493a85fe12eSEd Maste return (0); 494a85fe12eSEd Maste 495a85fe12eSEd Maste if ((idx = v->size) == 0) 496a85fe12eSEd Maste return (1); 497a85fe12eSEd Maste 498a85fe12eSEd Maste rtn = 0; 499a85fe12eSEd Maste if (type_str != NULL) { 500a85fe12eSEd Maste if (!vector_str_init(&subst_v)) 501a85fe12eSEd Maste return (0); 502bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, type_str)) 503a85fe12eSEd Maste goto clean; 504a85fe12eSEd Maste } 505a85fe12eSEd Maste 50618f4c9dbSEd Maste cv = true; 507a85fe12eSEd Maste e_idx = 0; 508a85fe12eSEd Maste while (idx > 0) { 509a85fe12eSEd Maste switch (v->q_container[idx - 1]) { 510a85fe12eSEd Maste case TYPE_PTR: 51118f4c9dbSEd Maste cv = false; 51218f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER) 51318f4c9dbSEd Maste break; 514bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "*")) 515a85fe12eSEd Maste goto clean; 516a85fe12eSEd Maste if (type_str != NULL) { 517bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, "*")) 518a85fe12eSEd Maste goto clean; 5193ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 5203ef90571SEd Maste &subst_v)) 521a85fe12eSEd Maste goto clean; 522a85fe12eSEd Maste } 523a85fe12eSEd Maste break; 524a85fe12eSEd Maste 525a85fe12eSEd Maste case TYPE_REF: 52618f4c9dbSEd Maste cv = false; 52718f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER) 52818f4c9dbSEd Maste break; 529bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "&")) 530a85fe12eSEd Maste goto clean; 531a85fe12eSEd Maste if (type_str != NULL) { 532bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, "&")) 533a85fe12eSEd Maste goto clean; 5343ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 5353ef90571SEd Maste &subst_v)) 536a85fe12eSEd Maste goto clean; 537a85fe12eSEd Maste } 538a85fe12eSEd Maste break; 539a85fe12eSEd Maste 54018f4c9dbSEd Maste case TYPE_RREF: 54118f4c9dbSEd Maste cv = false; 54218f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER) 54318f4c9dbSEd Maste break; 54418f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, "&&")) 54518f4c9dbSEd Maste goto clean; 54618f4c9dbSEd Maste if (type_str != NULL) { 54718f4c9dbSEd Maste if (!VEC_PUSH_STR(&subst_v, "&&")) 54818f4c9dbSEd Maste goto clean; 54918f4c9dbSEd Maste if (!cpp_demangle_push_subst_v(ddata, 55018f4c9dbSEd Maste &subst_v)) 55118f4c9dbSEd Maste goto clean; 55218f4c9dbSEd Maste } 55318f4c9dbSEd Maste break; 55418f4c9dbSEd Maste 555a85fe12eSEd Maste case TYPE_CMX: 55618f4c9dbSEd Maste cv = false; 55718f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER) 55818f4c9dbSEd Maste break; 559bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " complex")) 560a85fe12eSEd Maste goto clean; 561a85fe12eSEd Maste if (type_str != NULL) { 562bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, " complex")) 563a85fe12eSEd Maste goto clean; 5643ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 5653ef90571SEd Maste &subst_v)) 566a85fe12eSEd Maste goto clean; 567a85fe12eSEd Maste } 568a85fe12eSEd Maste break; 569a85fe12eSEd Maste 570a85fe12eSEd Maste case TYPE_IMG: 57118f4c9dbSEd Maste cv = false; 57218f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER) 57318f4c9dbSEd Maste break; 574bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " imaginary")) 575a85fe12eSEd Maste goto clean; 576a85fe12eSEd Maste if (type_str != NULL) { 577715d1396SEd Maste if (!VEC_PUSH_STR(&subst_v, " imaginary")) 578a85fe12eSEd Maste goto clean; 5793ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 5803ef90571SEd Maste &subst_v)) 581a85fe12eSEd Maste goto clean; 582a85fe12eSEd Maste } 583a85fe12eSEd Maste break; 584a85fe12eSEd Maste 585a85fe12eSEd Maste case TYPE_EXT: 58618f4c9dbSEd Maste cv = false; 58718f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER) 58818f4c9dbSEd Maste break; 5893ef90571SEd Maste if (v->ext_name.size == 0 || 5903ef90571SEd Maste e_idx > v->ext_name.size - 1) 591a85fe12eSEd Maste goto clean; 5923ef90571SEd Maste if ((e_len = strlen(v->ext_name.container[e_idx])) == 5933ef90571SEd Maste 0) 594a85fe12eSEd Maste goto clean; 5953ef90571SEd Maste if ((buf = malloc(e_len + 2)) == NULL) 596a85fe12eSEd Maste goto clean; 5973ef90571SEd Maste snprintf(buf, e_len + 2, " %s", 5983ef90571SEd Maste v->ext_name.container[e_idx]); 599a85fe12eSEd Maste 600bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, buf)) { 601a85fe12eSEd Maste free(buf); 602a85fe12eSEd Maste goto clean; 603a85fe12eSEd Maste } 604a85fe12eSEd Maste 605a85fe12eSEd Maste if (type_str != NULL) { 606bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, buf)) { 607a85fe12eSEd Maste free(buf); 608a85fe12eSEd Maste goto clean; 609a85fe12eSEd Maste } 6103ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 6113ef90571SEd Maste &subst_v)) { 612a85fe12eSEd Maste free(buf); 613a85fe12eSEd Maste goto clean; 614a85fe12eSEd Maste } 615a85fe12eSEd Maste } 616a85fe12eSEd Maste free(buf); 617a85fe12eSEd Maste ++e_idx; 618a85fe12eSEd Maste break; 619a85fe12eSEd Maste 620a85fe12eSEd Maste case TYPE_RST: 62118f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && 62218f4c9dbSEd Maste cv) 62318f4c9dbSEd Maste break; 62418f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) 62518f4c9dbSEd Maste break; 626bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " restrict")) 627a85fe12eSEd Maste goto clean; 628a85fe12eSEd Maste if (type_str != NULL) { 629bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, " restrict")) 630a85fe12eSEd Maste goto clean; 63118f4c9dbSEd Maste if (idx - 1 > 0) { 63218f4c9dbSEd Maste t = v->q_container[idx - 2]; 63318f4c9dbSEd Maste if (t == TYPE_RST || t == TYPE_VAT || 63418f4c9dbSEd Maste t == TYPE_CST) 63518f4c9dbSEd Maste break; 63618f4c9dbSEd Maste } 6373ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 6383ef90571SEd Maste &subst_v)) 639a85fe12eSEd Maste goto clean; 640a85fe12eSEd Maste } 641a85fe12eSEd Maste break; 642a85fe12eSEd Maste 643a85fe12eSEd Maste case TYPE_VAT: 64418f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && 64518f4c9dbSEd Maste cv) 64618f4c9dbSEd Maste break; 64718f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) 64818f4c9dbSEd Maste break; 649bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " volatile")) 650a85fe12eSEd Maste goto clean; 651a85fe12eSEd Maste if (type_str != NULL) { 652bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, " volatile")) 653a85fe12eSEd Maste goto clean; 65418f4c9dbSEd Maste if (idx - 1 > 0) { 65518f4c9dbSEd Maste t = v->q_container[idx - 2]; 65618f4c9dbSEd Maste if (t == TYPE_RST || t == TYPE_VAT || 65718f4c9dbSEd Maste t == TYPE_CST) 65818f4c9dbSEd Maste break; 65918f4c9dbSEd Maste } 6603ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 6613ef90571SEd Maste &subst_v)) 662a85fe12eSEd Maste goto clean; 663a85fe12eSEd Maste } 664a85fe12eSEd Maste break; 665a85fe12eSEd Maste 666a85fe12eSEd Maste case TYPE_CST: 66718f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && 66818f4c9dbSEd Maste cv) 66918f4c9dbSEd Maste break; 67018f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) 67118f4c9dbSEd Maste break; 672bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " const")) 673a85fe12eSEd Maste goto clean; 674a85fe12eSEd Maste if (type_str != NULL) { 675bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, " const")) 676a85fe12eSEd Maste goto clean; 67718f4c9dbSEd Maste if (idx - 1 > 0) { 67818f4c9dbSEd Maste t = v->q_container[idx - 2]; 67918f4c9dbSEd Maste if (t == TYPE_RST || t == TYPE_VAT || 68018f4c9dbSEd Maste t == TYPE_CST) 68118f4c9dbSEd Maste break; 68218f4c9dbSEd Maste } 6833ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 6843ef90571SEd Maste &subst_v)) 685a85fe12eSEd Maste goto clean; 686a85fe12eSEd Maste } 687a85fe12eSEd Maste break; 688a85fe12eSEd Maste 6893ef90571SEd Maste case TYPE_VEC: 69018f4c9dbSEd Maste cv = false; 69118f4c9dbSEd Maste if (ddata->push_qualifier == PUSH_CV_QUALIFIER) 69218f4c9dbSEd Maste break; 6933ef90571SEd Maste if (v->ext_name.size == 0 || 6943ef90571SEd Maste e_idx > v->ext_name.size - 1) 6953ef90571SEd Maste goto clean; 6963ef90571SEd Maste if ((e_len = strlen(v->ext_name.container[e_idx])) == 6973ef90571SEd Maste 0) 6983ef90571SEd Maste goto clean; 6993ef90571SEd Maste if ((buf = malloc(e_len + 12)) == NULL) 7003ef90571SEd Maste goto clean; 7013ef90571SEd Maste snprintf(buf, e_len + 12, " __vector(%s)", 7023ef90571SEd Maste v->ext_name.container[e_idx]); 703bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, buf)) { 7043ef90571SEd Maste free(buf); 7053ef90571SEd Maste goto clean; 7063ef90571SEd Maste } 7073ef90571SEd Maste if (type_str != NULL) { 708bee2765cSEd Maste if (!VEC_PUSH_STR(&subst_v, buf)) { 7093ef90571SEd Maste free(buf); 7103ef90571SEd Maste goto clean; 7113ef90571SEd Maste } 7123ef90571SEd Maste if (!cpp_demangle_push_subst_v(ddata, 7133ef90571SEd Maste &subst_v)) { 7143ef90571SEd Maste free(buf); 7153ef90571SEd Maste goto clean; 7163ef90571SEd Maste } 7173ef90571SEd Maste } 7183ef90571SEd Maste free(buf); 7193ef90571SEd Maste ++e_idx; 7203ef90571SEd Maste break; 721b6b6f9ccSEd Maste } 722a85fe12eSEd Maste --idx; 723a85fe12eSEd Maste } 724a85fe12eSEd Maste 725a85fe12eSEd Maste rtn = 1; 726a85fe12eSEd Maste clean: 727a85fe12eSEd Maste if (type_str != NULL) 728a85fe12eSEd Maste vector_str_dest(&subst_v); 729a85fe12eSEd Maste 730a85fe12eSEd Maste return (rtn); 731a85fe12eSEd Maste } 732a85fe12eSEd Maste 733a85fe12eSEd Maste static int 734a85fe12eSEd Maste cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx) 735a85fe12eSEd Maste { 736a85fe12eSEd Maste size_t len; 737a85fe12eSEd Maste 738a85fe12eSEd Maste if (ddata == NULL || ddata->subst.size <= idx) 739a85fe12eSEd Maste return (0); 740a85fe12eSEd Maste if ((len = strlen(ddata->subst.container[idx])) == 0) 741a85fe12eSEd Maste return (0); 742a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len)) 743a85fe12eSEd Maste return (0); 744a85fe12eSEd Maste 745a85fe12eSEd Maste /* skip '_' */ 746a85fe12eSEd Maste ++ddata->cur; 747a85fe12eSEd Maste 748a85fe12eSEd Maste return (1); 749a85fe12eSEd Maste } 750a85fe12eSEd Maste 751a85fe12eSEd Maste static int 752a85fe12eSEd Maste cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx) 753a85fe12eSEd Maste { 754a85fe12eSEd Maste size_t len; 755a85fe12eSEd Maste 756a85fe12eSEd Maste if (ddata == NULL || ddata->tmpl.size <= idx) 757a85fe12eSEd Maste return (0); 758a85fe12eSEd Maste if ((len = strlen(ddata->tmpl.container[idx])) == 0) 759a85fe12eSEd Maste return (0); 760a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len)) 761a85fe12eSEd Maste return (0); 762a85fe12eSEd Maste 763a85fe12eSEd Maste ++ddata->cur; 764a85fe12eSEd Maste 765a85fe12eSEd Maste return (1); 766a85fe12eSEd Maste } 767a85fe12eSEd Maste 768a85fe12eSEd Maste static int 769a85fe12eSEd Maste cpp_demangle_read_array(struct cpp_demangle_data *ddata) 770a85fe12eSEd Maste { 771a85fe12eSEd Maste size_t i, num_len, exp_len, p_idx, idx; 772a85fe12eSEd Maste const char *num; 773a85fe12eSEd Maste char *exp; 774a85fe12eSEd Maste 775a85fe12eSEd Maste if (ddata == NULL || *(++ddata->cur) == '\0') 776a85fe12eSEd Maste return (0); 777a85fe12eSEd Maste 778a85fe12eSEd Maste if (*ddata->cur == '_') { 779a85fe12eSEd Maste if (*(++ddata->cur) == '\0') 780a85fe12eSEd Maste return (0); 781a85fe12eSEd Maste 78218f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 783a85fe12eSEd Maste return (0); 784a85fe12eSEd Maste 785bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "[]")) 786a85fe12eSEd Maste return (0); 787a85fe12eSEd Maste } else { 788a85fe12eSEd Maste if (ELFTC_ISDIGIT(*ddata->cur) != 0) { 789a85fe12eSEd Maste num = ddata->cur; 790a85fe12eSEd Maste while (ELFTC_ISDIGIT(*ddata->cur) != 0) 791a85fe12eSEd Maste ++ddata->cur; 792a85fe12eSEd Maste if (*ddata->cur != '_') 793a85fe12eSEd Maste return (0); 794a85fe12eSEd Maste num_len = ddata->cur - num; 795a85fe12eSEd Maste assert(num_len > 0); 796a85fe12eSEd Maste if (*(++ddata->cur) == '\0') 797a85fe12eSEd Maste return (0); 79818f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 799a85fe12eSEd Maste return (0); 800bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "[")) 801a85fe12eSEd Maste return (0); 802a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, num, num_len)) 803a85fe12eSEd Maste return (0); 804bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "]")) 805a85fe12eSEd Maste return (0); 806a85fe12eSEd Maste } else { 807a85fe12eSEd Maste p_idx = ddata->output.size; 808a85fe12eSEd Maste if (!cpp_demangle_read_expression(ddata)) 809a85fe12eSEd Maste return (0); 810a85fe12eSEd Maste if ((exp = vector_str_substr(&ddata->output, p_idx, 811a85fe12eSEd Maste ddata->output.size - 1, &exp_len)) == NULL) 812a85fe12eSEd Maste return (0); 813a85fe12eSEd Maste idx = ddata->output.size; 814a85fe12eSEd Maste for (i = p_idx; i < idx; ++i) 815a85fe12eSEd Maste if (!vector_str_pop(&ddata->output)) { 816a85fe12eSEd Maste free(exp); 817a85fe12eSEd Maste return (0); 818a85fe12eSEd Maste } 819a85fe12eSEd Maste if (*ddata->cur != '_') { 820a85fe12eSEd Maste free(exp); 821a85fe12eSEd Maste return (0); 822a85fe12eSEd Maste } 823a85fe12eSEd Maste ++ddata->cur; 824a85fe12eSEd Maste if (*ddata->cur == '\0') { 825a85fe12eSEd Maste free(exp); 826a85fe12eSEd Maste return (0); 827a85fe12eSEd Maste } 82818f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) { 829a85fe12eSEd Maste free(exp); 830a85fe12eSEd Maste return (0); 831a85fe12eSEd Maste } 832bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "[")) { 833a85fe12eSEd Maste free(exp); 834a85fe12eSEd Maste return (0); 835a85fe12eSEd Maste } 836a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, exp, exp_len)) { 837a85fe12eSEd Maste free(exp); 838a85fe12eSEd Maste return (0); 839a85fe12eSEd Maste } 840bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "]")) { 841a85fe12eSEd Maste free(exp); 842a85fe12eSEd Maste return (0); 843a85fe12eSEd Maste } 844a85fe12eSEd Maste free(exp); 845a85fe12eSEd Maste } 846a85fe12eSEd Maste } 847a85fe12eSEd Maste 848a85fe12eSEd Maste return (1); 849a85fe12eSEd Maste } 850a85fe12eSEd Maste 851a85fe12eSEd Maste static int 852a85fe12eSEd Maste cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) 853a85fe12eSEd Maste { 854a85fe12eSEd Maste const char *num; 855a85fe12eSEd Maste 856a85fe12eSEd Maste if (ddata == NULL || *(++ddata->cur) == '\0') 857a85fe12eSEd Maste return (0); 858a85fe12eSEd Maste 859a85fe12eSEd Maste if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') { 860a85fe12eSEd Maste ddata->cur += 2; 861a85fe12eSEd Maste if (*ddata->cur == '\0') 862a85fe12eSEd Maste return (0); 863a85fe12eSEd Maste if (!cpp_demangle_read_encoding(ddata)) 864a85fe12eSEd Maste return (0); 865a85fe12eSEd Maste ++ddata->cur; 866a85fe12eSEd Maste return (1); 867a85fe12eSEd Maste } 868a85fe12eSEd Maste 869a85fe12eSEd Maste switch (*ddata->cur) { 870a85fe12eSEd Maste case 'b': 8713ef90571SEd Maste if (*(ddata->cur + 2) != 'E') 8723ef90571SEd Maste return (0); 873a85fe12eSEd Maste switch (*(++ddata->cur)) { 874a85fe12eSEd Maste case '0': 8753ef90571SEd Maste ddata->cur += 2; 876bee2765cSEd Maste return (DEM_PUSH_STR(ddata, "false")); 877a85fe12eSEd Maste case '1': 8783ef90571SEd Maste ddata->cur += 2; 879bee2765cSEd Maste return (DEM_PUSH_STR(ddata, "true")); 880a85fe12eSEd Maste default: 881a85fe12eSEd Maste return (0); 882b6b6f9ccSEd Maste } 883a85fe12eSEd Maste 884a85fe12eSEd Maste case 'd': 885a85fe12eSEd Maste ++ddata->cur; 886a85fe12eSEd Maste return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); 887a85fe12eSEd Maste 888a85fe12eSEd Maste case 'e': 889a85fe12eSEd Maste ++ddata->cur; 890a85fe12eSEd Maste if (sizeof(long double) == 10) 891a85fe12eSEd Maste return (cpp_demangle_push_fp(ddata, 892a85fe12eSEd Maste decode_fp_to_double)); 893a85fe12eSEd Maste return (cpp_demangle_push_fp(ddata, decode_fp_to_float80)); 894a85fe12eSEd Maste 895a85fe12eSEd Maste case 'f': 896a85fe12eSEd Maste ++ddata->cur; 897a85fe12eSEd Maste return (cpp_demangle_push_fp(ddata, decode_fp_to_float)); 898a85fe12eSEd Maste 899a85fe12eSEd Maste case 'g': 900a85fe12eSEd Maste ++ddata->cur; 901a85fe12eSEd Maste if (sizeof(long double) == 16) 902a85fe12eSEd Maste return (cpp_demangle_push_fp(ddata, 903a85fe12eSEd Maste decode_fp_to_double)); 904a85fe12eSEd Maste return (cpp_demangle_push_fp(ddata, decode_fp_to_float128)); 905a85fe12eSEd Maste 906a85fe12eSEd Maste case 'i': 907a85fe12eSEd Maste case 'j': 908a85fe12eSEd Maste case 'l': 909a85fe12eSEd Maste case 'm': 910a85fe12eSEd Maste case 'n': 911a85fe12eSEd Maste case 's': 912a85fe12eSEd Maste case 't': 913a85fe12eSEd Maste case 'x': 914a85fe12eSEd Maste case 'y': 915a85fe12eSEd Maste if (*(++ddata->cur) == 'n') { 916bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "-")) 917a85fe12eSEd Maste return (0); 918a85fe12eSEd Maste ++ddata->cur; 919a85fe12eSEd Maste } 920a85fe12eSEd Maste num = ddata->cur; 921a85fe12eSEd Maste while (*ddata->cur != 'E') { 922a85fe12eSEd Maste if (!ELFTC_ISDIGIT(*ddata->cur)) 923a85fe12eSEd Maste return (0); 924a85fe12eSEd Maste ++ddata->cur; 925a85fe12eSEd Maste } 926a85fe12eSEd Maste ++ddata->cur; 9273ef90571SEd Maste return (cpp_demangle_push_str(ddata, num, 9283ef90571SEd Maste ddata->cur - num - 1)); 929a85fe12eSEd Maste 930a85fe12eSEd Maste default: 931a85fe12eSEd Maste return (0); 932b6b6f9ccSEd Maste } 933a85fe12eSEd Maste } 934a85fe12eSEd Maste 935a85fe12eSEd Maste static int 936a85fe12eSEd Maste cpp_demangle_read_expression(struct cpp_demangle_data *ddata) 937a85fe12eSEd Maste { 938a85fe12eSEd Maste 939a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 940a85fe12eSEd Maste return (0); 941a85fe12eSEd Maste 942a85fe12eSEd Maste switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 943a85fe12eSEd Maste case SIMPLE_HASH('s', 't'): 944a85fe12eSEd Maste ddata->cur += 2; 94518f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 946a85fe12eSEd Maste 947a85fe12eSEd Maste case SIMPLE_HASH('s', 'r'): 948a85fe12eSEd Maste ddata->cur += 2; 94918f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 950a85fe12eSEd Maste return (0); 951a85fe12eSEd Maste if (!cpp_demangle_read_uqname(ddata)) 952a85fe12eSEd Maste return (0); 953a85fe12eSEd Maste if (*ddata->cur == 'I') 954a85fe12eSEd Maste return (cpp_demangle_read_tmpl_args(ddata)); 955a85fe12eSEd Maste return (1); 956a85fe12eSEd Maste 957a85fe12eSEd Maste case SIMPLE_HASH('a', 'a'): 958a85fe12eSEd Maste /* operator && */ 959a85fe12eSEd Maste ddata->cur += 2; 960a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "&&", 2)); 961a85fe12eSEd Maste 962a85fe12eSEd Maste case SIMPLE_HASH('a', 'd'): 963a85fe12eSEd Maste /* operator & (unary) */ 964a85fe12eSEd Maste ddata->cur += 2; 965a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "&", 1)); 966a85fe12eSEd Maste 967a85fe12eSEd Maste case SIMPLE_HASH('a', 'n'): 968a85fe12eSEd Maste /* operator & */ 969a85fe12eSEd Maste ddata->cur += 2; 970a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "&", 1)); 971a85fe12eSEd Maste 972a85fe12eSEd Maste case SIMPLE_HASH('a', 'N'): 973a85fe12eSEd Maste /* operator &= */ 974a85fe12eSEd Maste ddata->cur += 2; 975a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "&=", 2)); 976a85fe12eSEd Maste 977a85fe12eSEd Maste case SIMPLE_HASH('a', 'S'): 978a85fe12eSEd Maste /* operator = */ 979a85fe12eSEd Maste ddata->cur += 2; 980a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "=", 1)); 981a85fe12eSEd Maste 982a85fe12eSEd Maste case SIMPLE_HASH('c', 'l'): 983a85fe12eSEd Maste /* operator () */ 984a85fe12eSEd Maste ddata->cur += 2; 985a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "()", 2)); 986a85fe12eSEd Maste 987a85fe12eSEd Maste case SIMPLE_HASH('c', 'm'): 988a85fe12eSEd Maste /* operator , */ 989a85fe12eSEd Maste ddata->cur += 2; 990a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, ",", 1)); 991a85fe12eSEd Maste 992a85fe12eSEd Maste case SIMPLE_HASH('c', 'o'): 993a85fe12eSEd Maste /* operator ~ */ 994a85fe12eSEd Maste ddata->cur += 2; 995a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "~", 1)); 996a85fe12eSEd Maste 997a85fe12eSEd Maste case SIMPLE_HASH('c', 'v'): 998a85fe12eSEd Maste /* operator (cast) */ 999a85fe12eSEd Maste ddata->cur += 2; 1000a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6)); 1001a85fe12eSEd Maste 1002a85fe12eSEd Maste case SIMPLE_HASH('d', 'a'): 1003a85fe12eSEd Maste /* operator delete [] */ 1004a85fe12eSEd Maste ddata->cur += 2; 1005a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "delete []", 9)); 1006a85fe12eSEd Maste 1007a85fe12eSEd Maste case SIMPLE_HASH('d', 'e'): 1008a85fe12eSEd Maste /* operator * (unary) */ 1009a85fe12eSEd Maste ddata->cur += 2; 1010a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "*", 1)); 1011a85fe12eSEd Maste 1012a85fe12eSEd Maste case SIMPLE_HASH('d', 'l'): 1013a85fe12eSEd Maste /* operator delete */ 1014a85fe12eSEd Maste ddata->cur += 2; 1015a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "delete", 6)); 1016a85fe12eSEd Maste 1017a85fe12eSEd Maste case SIMPLE_HASH('d', 'v'): 1018a85fe12eSEd Maste /* operator / */ 1019a85fe12eSEd Maste ddata->cur += 2; 1020a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "/", 1)); 1021a85fe12eSEd Maste 1022a85fe12eSEd Maste case SIMPLE_HASH('d', 'V'): 1023a85fe12eSEd Maste /* operator /= */ 1024a85fe12eSEd Maste ddata->cur += 2; 1025a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "/=", 2)); 1026a85fe12eSEd Maste 1027a85fe12eSEd Maste case SIMPLE_HASH('e', 'o'): 1028a85fe12eSEd Maste /* operator ^ */ 1029a85fe12eSEd Maste ddata->cur += 2; 1030a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "^", 1)); 1031a85fe12eSEd Maste 1032a85fe12eSEd Maste case SIMPLE_HASH('e', 'O'): 1033a85fe12eSEd Maste /* operator ^= */ 1034a85fe12eSEd Maste ddata->cur += 2; 1035a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "^=", 2)); 1036a85fe12eSEd Maste 1037a85fe12eSEd Maste case SIMPLE_HASH('e', 'q'): 1038a85fe12eSEd Maste /* operator == */ 1039a85fe12eSEd Maste ddata->cur += 2; 1040a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "==", 2)); 1041a85fe12eSEd Maste 1042a85fe12eSEd Maste case SIMPLE_HASH('g', 'e'): 1043a85fe12eSEd Maste /* operator >= */ 1044a85fe12eSEd Maste ddata->cur += 2; 1045a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, ">=", 2)); 1046a85fe12eSEd Maste 1047a85fe12eSEd Maste case SIMPLE_HASH('g', 't'): 1048a85fe12eSEd Maste /* operator > */ 1049a85fe12eSEd Maste ddata->cur += 2; 1050a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, ">", 1)); 1051a85fe12eSEd Maste 1052a85fe12eSEd Maste case SIMPLE_HASH('i', 'x'): 1053a85fe12eSEd Maste /* operator [] */ 1054a85fe12eSEd Maste ddata->cur += 2; 1055a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "[]", 2)); 1056a85fe12eSEd Maste 1057a85fe12eSEd Maste case SIMPLE_HASH('l', 'e'): 1058a85fe12eSEd Maste /* operator <= */ 1059a85fe12eSEd Maste ddata->cur += 2; 1060a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "<=", 2)); 1061a85fe12eSEd Maste 1062a85fe12eSEd Maste case SIMPLE_HASH('l', 's'): 1063a85fe12eSEd Maste /* operator << */ 1064a85fe12eSEd Maste ddata->cur += 2; 1065a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "<<", 2)); 1066a85fe12eSEd Maste 1067a85fe12eSEd Maste case SIMPLE_HASH('l', 'S'): 1068a85fe12eSEd Maste /* operator <<= */ 1069a85fe12eSEd Maste ddata->cur += 2; 1070a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "<<=", 3)); 1071a85fe12eSEd Maste 1072a85fe12eSEd Maste case SIMPLE_HASH('l', 't'): 1073a85fe12eSEd Maste /* operator < */ 1074a85fe12eSEd Maste ddata->cur += 2; 1075a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "<", 1)); 1076a85fe12eSEd Maste 1077a85fe12eSEd Maste case SIMPLE_HASH('m', 'i'): 1078a85fe12eSEd Maste /* operator - */ 1079a85fe12eSEd Maste ddata->cur += 2; 1080a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "-", 1)); 1081a85fe12eSEd Maste 1082a85fe12eSEd Maste case SIMPLE_HASH('m', 'I'): 1083a85fe12eSEd Maste /* operator -= */ 1084a85fe12eSEd Maste ddata->cur += 2; 1085a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "-=", 2)); 1086a85fe12eSEd Maste 1087a85fe12eSEd Maste case SIMPLE_HASH('m', 'l'): 1088a85fe12eSEd Maste /* operator * */ 1089a85fe12eSEd Maste ddata->cur += 2; 1090a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "*", 1)); 1091a85fe12eSEd Maste 1092a85fe12eSEd Maste case SIMPLE_HASH('m', 'L'): 1093a85fe12eSEd Maste /* operator *= */ 1094a85fe12eSEd Maste ddata->cur += 2; 1095a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "*=", 2)); 1096a85fe12eSEd Maste 1097a85fe12eSEd Maste case SIMPLE_HASH('m', 'm'): 1098a85fe12eSEd Maste /* operator -- */ 1099a85fe12eSEd Maste ddata->cur += 2; 1100a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "--", 2)); 1101a85fe12eSEd Maste 1102a85fe12eSEd Maste case SIMPLE_HASH('n', 'a'): 1103a85fe12eSEd Maste /* operator new[] */ 1104a85fe12eSEd Maste ddata->cur += 2; 1105a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "new []", 6)); 1106a85fe12eSEd Maste 1107a85fe12eSEd Maste case SIMPLE_HASH('n', 'e'): 1108a85fe12eSEd Maste /* operator != */ 1109a85fe12eSEd Maste ddata->cur += 2; 1110a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "!=", 2)); 1111a85fe12eSEd Maste 1112a85fe12eSEd Maste case SIMPLE_HASH('n', 'g'): 1113a85fe12eSEd Maste /* operator - (unary) */ 1114a85fe12eSEd Maste ddata->cur += 2; 1115a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "-", 1)); 1116a85fe12eSEd Maste 1117a85fe12eSEd Maste case SIMPLE_HASH('n', 't'): 1118a85fe12eSEd Maste /* operator ! */ 1119a85fe12eSEd Maste ddata->cur += 2; 1120a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "!", 1)); 1121a85fe12eSEd Maste 1122a85fe12eSEd Maste case SIMPLE_HASH('n', 'w'): 1123a85fe12eSEd Maste /* operator new */ 1124a85fe12eSEd Maste ddata->cur += 2; 1125a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "new", 3)); 1126a85fe12eSEd Maste 1127a85fe12eSEd Maste case SIMPLE_HASH('o', 'o'): 1128a85fe12eSEd Maste /* operator || */ 1129a85fe12eSEd Maste ddata->cur += 2; 1130a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "||", 2)); 1131a85fe12eSEd Maste 1132a85fe12eSEd Maste case SIMPLE_HASH('o', 'r'): 1133a85fe12eSEd Maste /* operator | */ 1134a85fe12eSEd Maste ddata->cur += 2; 1135a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "|", 1)); 1136a85fe12eSEd Maste 1137a85fe12eSEd Maste case SIMPLE_HASH('o', 'R'): 1138a85fe12eSEd Maste /* operator |= */ 1139a85fe12eSEd Maste ddata->cur += 2; 1140a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "|=", 2)); 1141a85fe12eSEd Maste 1142a85fe12eSEd Maste case SIMPLE_HASH('p', 'l'): 1143a85fe12eSEd Maste /* operator + */ 1144a85fe12eSEd Maste ddata->cur += 2; 1145a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "+", 1)); 1146a85fe12eSEd Maste 1147a85fe12eSEd Maste case SIMPLE_HASH('p', 'L'): 1148a85fe12eSEd Maste /* operator += */ 1149a85fe12eSEd Maste ddata->cur += 2; 1150a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "+=", 2)); 1151a85fe12eSEd Maste 1152a85fe12eSEd Maste case SIMPLE_HASH('p', 'm'): 1153a85fe12eSEd Maste /* operator ->* */ 1154a85fe12eSEd Maste ddata->cur += 2; 1155a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "->*", 3)); 1156a85fe12eSEd Maste 1157a85fe12eSEd Maste case SIMPLE_HASH('p', 'p'): 1158a85fe12eSEd Maste /* operator ++ */ 1159a85fe12eSEd Maste ddata->cur += 2; 1160a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "++", 2)); 1161a85fe12eSEd Maste 1162a85fe12eSEd Maste case SIMPLE_HASH('p', 's'): 1163a85fe12eSEd Maste /* operator + (unary) */ 1164a85fe12eSEd Maste ddata->cur += 2; 1165a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "+", 1)); 1166a85fe12eSEd Maste 1167a85fe12eSEd Maste case SIMPLE_HASH('p', 't'): 1168a85fe12eSEd Maste /* operator -> */ 1169a85fe12eSEd Maste ddata->cur += 2; 1170a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "->", 2)); 1171a85fe12eSEd Maste 1172a85fe12eSEd Maste case SIMPLE_HASH('q', 'u'): 1173a85fe12eSEd Maste /* operator ? */ 1174a85fe12eSEd Maste ddata->cur += 2; 1175a85fe12eSEd Maste return (cpp_demangle_read_expression_trinary(ddata, "?", 1, 1176a85fe12eSEd Maste ":", 1)); 1177a85fe12eSEd Maste 1178a85fe12eSEd Maste case SIMPLE_HASH('r', 'm'): 1179a85fe12eSEd Maste /* operator % */ 1180a85fe12eSEd Maste ddata->cur += 2; 1181a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "%", 1)); 1182a85fe12eSEd Maste 1183a85fe12eSEd Maste case SIMPLE_HASH('r', 'M'): 1184a85fe12eSEd Maste /* operator %= */ 1185a85fe12eSEd Maste ddata->cur += 2; 1186a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, "%=", 2)); 1187a85fe12eSEd Maste 1188a85fe12eSEd Maste case SIMPLE_HASH('r', 's'): 1189a85fe12eSEd Maste /* operator >> */ 1190a85fe12eSEd Maste ddata->cur += 2; 1191a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, ">>", 2)); 1192a85fe12eSEd Maste 1193a85fe12eSEd Maste case SIMPLE_HASH('r', 'S'): 1194a85fe12eSEd Maste /* operator >>= */ 1195a85fe12eSEd Maste ddata->cur += 2; 1196a85fe12eSEd Maste return (cpp_demangle_read_expression_binary(ddata, ">>=", 3)); 1197a85fe12eSEd Maste 1198a85fe12eSEd Maste case SIMPLE_HASH('r', 'z'): 1199a85fe12eSEd Maste /* operator sizeof */ 1200a85fe12eSEd Maste ddata->cur += 2; 1201a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 1202a85fe12eSEd Maste 1203a85fe12eSEd Maste case SIMPLE_HASH('s', 'v'): 1204a85fe12eSEd Maste /* operator sizeof */ 1205a85fe12eSEd Maste ddata->cur += 2; 1206a85fe12eSEd Maste return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 1207b6b6f9ccSEd Maste } 1208a85fe12eSEd Maste 1209a85fe12eSEd Maste switch (*ddata->cur) { 1210a85fe12eSEd Maste case 'L': 1211a85fe12eSEd Maste return (cpp_demangle_read_expr_primary(ddata)); 1212a85fe12eSEd Maste case 'T': 1213a85fe12eSEd Maste return (cpp_demangle_read_tmpl_param(ddata)); 1214b6b6f9ccSEd Maste } 1215a85fe12eSEd Maste 1216a85fe12eSEd Maste return (0); 1217a85fe12eSEd Maste } 1218a85fe12eSEd Maste 1219a85fe12eSEd Maste static int 12203ef90571SEd Maste cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str) 12213ef90571SEd Maste { 12223ef90571SEd Maste struct vector_str *output; 12233ef90571SEd Maste size_t i, p_idx, idx, exp_len; 12243ef90571SEd Maste char *exp; 12253ef90571SEd Maste 122618f4c9dbSEd Maste output = &ddata->output; 12273ef90571SEd Maste 12283ef90571SEd Maste p_idx = output->size; 12293ef90571SEd Maste 12303ef90571SEd Maste if (!cpp_demangle_read_expression(ddata)) 12313ef90571SEd Maste return (0); 12323ef90571SEd Maste 12333ef90571SEd Maste if ((exp = vector_str_substr(output, p_idx, output->size - 1, 12343ef90571SEd Maste &exp_len)) == NULL) 12353ef90571SEd Maste return (0); 12363ef90571SEd Maste 12373ef90571SEd Maste idx = output->size; 12383ef90571SEd Maste for (i = p_idx; i < idx; ++i) { 12393ef90571SEd Maste if (!vector_str_pop(output)) { 12403ef90571SEd Maste free(exp); 12413ef90571SEd Maste return (0); 12423ef90571SEd Maste } 12433ef90571SEd Maste } 12443ef90571SEd Maste 12453ef90571SEd Maste *str = exp; 12463ef90571SEd Maste 12473ef90571SEd Maste return (1); 12483ef90571SEd Maste } 12493ef90571SEd Maste 12503ef90571SEd Maste static int 1251a85fe12eSEd Maste cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, 1252a85fe12eSEd Maste const char *name, size_t len) 1253a85fe12eSEd Maste { 1254a85fe12eSEd Maste 1255a85fe12eSEd Maste if (ddata == NULL || name == NULL || len == 0) 1256a85fe12eSEd Maste return (0); 1257a85fe12eSEd Maste if (!cpp_demangle_read_expression(ddata)) 1258a85fe12eSEd Maste return (0); 1259a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, name, len)) 1260a85fe12eSEd Maste return (0); 1261a85fe12eSEd Maste 1262a85fe12eSEd Maste return (cpp_demangle_read_expression(ddata)); 1263a85fe12eSEd Maste } 1264a85fe12eSEd Maste 1265a85fe12eSEd Maste static int 1266a85fe12eSEd Maste cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata, 1267a85fe12eSEd Maste const char *name, size_t len) 1268a85fe12eSEd Maste { 1269a85fe12eSEd Maste 1270a85fe12eSEd Maste if (ddata == NULL || name == NULL || len == 0) 1271a85fe12eSEd Maste return (0); 1272a85fe12eSEd Maste if (!cpp_demangle_read_expression(ddata)) 1273a85fe12eSEd Maste return (0); 1274a85fe12eSEd Maste 1275a85fe12eSEd Maste return (cpp_demangle_push_str(ddata, name, len)); 1276a85fe12eSEd Maste } 1277a85fe12eSEd Maste 1278a85fe12eSEd Maste static int 1279a85fe12eSEd Maste cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata, 1280a85fe12eSEd Maste const char *name1, size_t len1, const char *name2, size_t len2) 1281a85fe12eSEd Maste { 1282a85fe12eSEd Maste 1283a85fe12eSEd Maste if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL || 1284a85fe12eSEd Maste len2 == 0) 1285a85fe12eSEd Maste return (0); 1286a85fe12eSEd Maste 1287a85fe12eSEd Maste if (!cpp_demangle_read_expression(ddata)) 1288a85fe12eSEd Maste return (0); 1289a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, name1, len1)) 1290a85fe12eSEd Maste return (0); 1291a85fe12eSEd Maste if (!cpp_demangle_read_expression(ddata)) 1292a85fe12eSEd Maste return (0); 1293a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, name2, len2)) 1294a85fe12eSEd Maste return (0); 1295a85fe12eSEd Maste 1296a85fe12eSEd Maste return (cpp_demangle_read_expression(ddata)); 1297a85fe12eSEd Maste } 1298a85fe12eSEd Maste 1299a85fe12eSEd Maste static int 1300a85fe12eSEd Maste cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, 1301a85fe12eSEd Maste struct vector_type_qualifier *v) 1302a85fe12eSEd Maste { 130318f4c9dbSEd Maste struct type_delimit td; 130418f4c9dbSEd Maste struct read_cmd_item *rc; 1305a85fe12eSEd Maste size_t class_type_size, class_type_len, limit; 1306a85fe12eSEd Maste const char *class_type; 130718f4c9dbSEd Maste int i; 130818f4c9dbSEd Maste bool paren, non_cv_qualifier; 1309a85fe12eSEd Maste 1310a85fe12eSEd Maste if (ddata == NULL || *ddata->cur != 'F' || v == NULL) 1311a85fe12eSEd Maste return (0); 1312a85fe12eSEd Maste 1313a85fe12eSEd Maste ++ddata->cur; 1314a85fe12eSEd Maste if (*ddata->cur == 'Y') { 1315a85fe12eSEd Maste if (ext_c != NULL) 1316a85fe12eSEd Maste *ext_c = 1; 1317a85fe12eSEd Maste ++ddata->cur; 1318a85fe12eSEd Maste } 131918f4c9dbSEd Maste 132018f4c9dbSEd Maste /* Return type */ 132118f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 1322a85fe12eSEd Maste return (0); 132318f4c9dbSEd Maste 1324a85fe12eSEd Maste if (*ddata->cur != 'E') { 132518f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, " ")) 132618f4c9dbSEd Maste return (0); 132718f4c9dbSEd Maste 132818f4c9dbSEd Maste non_cv_qualifier = false; 132918f4c9dbSEd Maste if (v->size > 0) { 133018f4c9dbSEd Maste for (i = 0; (size_t) i < v->size; i++) { 133118f4c9dbSEd Maste if (v->q_container[i] != TYPE_RST && 133218f4c9dbSEd Maste v->q_container[i] != TYPE_VAT && 133318f4c9dbSEd Maste v->q_container[i] != TYPE_CST) { 133418f4c9dbSEd Maste non_cv_qualifier = true; 133518f4c9dbSEd Maste break; 133618f4c9dbSEd Maste } 133718f4c9dbSEd Maste } 133818f4c9dbSEd Maste } 133918f4c9dbSEd Maste 134018f4c9dbSEd Maste paren = false; 134118f4c9dbSEd Maste rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM); 134218f4c9dbSEd Maste if (non_cv_qualifier || rc != NULL) { 1343bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "(")) 1344a85fe12eSEd Maste return (0); 134518f4c9dbSEd Maste paren = true; 134618f4c9dbSEd Maste } 134718f4c9dbSEd Maste 134818f4c9dbSEd Maste /* Push non-cv qualifiers. */ 134918f4c9dbSEd Maste ddata->push_qualifier = PUSH_NON_CV_QUALIFIER; 135018f4c9dbSEd Maste if (!cpp_demangle_push_type_qualifier(ddata, v, NULL)) 135118f4c9dbSEd Maste return (0); 135218f4c9dbSEd Maste 135318f4c9dbSEd Maste if (rc) { 135418f4c9dbSEd Maste if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " ")) 135518f4c9dbSEd Maste return (0); 1356a85fe12eSEd Maste if ((class_type_size = ddata->class_type.size) == 0) 1357a85fe12eSEd Maste return (0); 1358a85fe12eSEd Maste class_type = 1359a85fe12eSEd Maste ddata->class_type.container[class_type_size - 1]; 1360a85fe12eSEd Maste if (class_type == NULL) 1361a85fe12eSEd Maste return (0); 1362a85fe12eSEd Maste if ((class_type_len = strlen(class_type)) == 0) 1363a85fe12eSEd Maste return (0); 1364a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, class_type, 1365a85fe12eSEd Maste class_type_len)) 1366a85fe12eSEd Maste return (0); 1367bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "::*")) 1368a85fe12eSEd Maste return (0); 136918f4c9dbSEd Maste /* Push pointer-to-member qualifiers. */ 137018f4c9dbSEd Maste ddata->push_qualifier = PUSH_ALL_QUALIFIER; 137118f4c9dbSEd Maste if (!cpp_demangle_push_type_qualifier(ddata, rc->data, 137218f4c9dbSEd Maste NULL)) 137318f4c9dbSEd Maste return (0); 1374a85fe12eSEd Maste ++ddata->func_type; 1375a85fe12eSEd Maste } 1376a85fe12eSEd Maste 137718f4c9dbSEd Maste if (paren) { 137818f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, ")")) 1379a85fe12eSEd Maste return (0); 138018f4c9dbSEd Maste paren = false; 138118f4c9dbSEd Maste } 1382a85fe12eSEd Maste 138318f4c9dbSEd Maste td.paren = false; 138418f4c9dbSEd Maste td.firstp = true; 1385a85fe12eSEd Maste limit = 0; 138618f4c9dbSEd Maste ddata->is_functype = true; 1387a85fe12eSEd Maste for (;;) { 138818f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, &td)) 1389a85fe12eSEd Maste return (0); 1390a85fe12eSEd Maste if (*ddata->cur == 'E') 1391a85fe12eSEd Maste break; 1392a85fe12eSEd Maste if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1393a85fe12eSEd Maste return (0); 1394a85fe12eSEd Maste } 139518f4c9dbSEd Maste ddata->is_functype = false; 139618f4c9dbSEd Maste if (td.paren) { 139718f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, ")")) 1398a85fe12eSEd Maste return (0); 139918f4c9dbSEd Maste td.paren = false; 140018f4c9dbSEd Maste } 140118f4c9dbSEd Maste 140218f4c9dbSEd Maste /* Push CV qualifiers. */ 140318f4c9dbSEd Maste ddata->push_qualifier = PUSH_CV_QUALIFIER; 140418f4c9dbSEd Maste if (!cpp_demangle_push_type_qualifier(ddata, v, NULL)) 140518f4c9dbSEd Maste return (0); 140618f4c9dbSEd Maste 140718f4c9dbSEd Maste ddata->push_qualifier = PUSH_ALL_QUALIFIER; 140818f4c9dbSEd Maste 140918f4c9dbSEd Maste /* Release type qualifier vector. */ 1410a85fe12eSEd Maste vector_type_qualifier_dest(v); 1411a85fe12eSEd Maste if (!vector_type_qualifier_init(v)) 1412a85fe12eSEd Maste return (0); 1413a85fe12eSEd Maste 141418f4c9dbSEd Maste /* Push ref-qualifiers. */ 141518f4c9dbSEd Maste if (ddata->ref_qualifier) { 141618f4c9dbSEd Maste switch (ddata->ref_qualifier_type) { 141718f4c9dbSEd Maste case TYPE_REF: 141818f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, " &")) 1419a85fe12eSEd Maste return (0); 142018f4c9dbSEd Maste break; 142118f4c9dbSEd Maste case TYPE_RREF: 142218f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, " &&")) 142318f4c9dbSEd Maste return (0); 142418f4c9dbSEd Maste break; 142518f4c9dbSEd Maste default: 142618f4c9dbSEd Maste return (0); 142718f4c9dbSEd Maste } 142818f4c9dbSEd Maste ddata->ref_qualifier = false; 142918f4c9dbSEd Maste } 1430a85fe12eSEd Maste } 1431a85fe12eSEd Maste 1432a85fe12eSEd Maste ++ddata->cur; 1433a85fe12eSEd Maste 1434a85fe12eSEd Maste return (1); 1435a85fe12eSEd Maste } 1436a85fe12eSEd Maste 1437a85fe12eSEd Maste /* read encoding, encoding are function name, data name, special-name */ 1438a85fe12eSEd Maste static int 1439a85fe12eSEd Maste cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) 1440a85fe12eSEd Maste { 14413ef90571SEd Maste char *name, *type, *num_str; 14423ef90571SEd Maste long offset; 14433ef90571SEd Maste int rtn; 1444a85fe12eSEd Maste 1445a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 1446a85fe12eSEd Maste return (0); 1447a85fe12eSEd Maste 1448a85fe12eSEd Maste /* special name */ 1449a85fe12eSEd Maste switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 14503ef90571SEd Maste case SIMPLE_HASH('G', 'A'): 1451bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "hidden alias for ")) 14523ef90571SEd Maste return (0); 14533ef90571SEd Maste ddata->cur += 2; 14543ef90571SEd Maste if (*ddata->cur == '\0') 14553ef90571SEd Maste return (0); 14563ef90571SEd Maste return (cpp_demangle_read_encoding(ddata)); 14573ef90571SEd Maste 14583ef90571SEd Maste case SIMPLE_HASH('G', 'R'): 1459bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "reference temporary #")) 14603ef90571SEd Maste return (0); 14613ef90571SEd Maste ddata->cur += 2; 14623ef90571SEd Maste if (*ddata->cur == '\0') 14633ef90571SEd Maste return (0); 14643ef90571SEd Maste if (!cpp_demangle_read_name_flat(ddata, &name)) 14653ef90571SEd Maste return (0); 14663ef90571SEd Maste rtn = 0; 14673ef90571SEd Maste if (!cpp_demangle_read_number_as_string(ddata, &num_str)) 14683ef90571SEd Maste goto clean1; 1469bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, num_str)) 14703ef90571SEd Maste goto clean2; 1471bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " for ")) 14723ef90571SEd Maste goto clean2; 1473bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, name)) 14743ef90571SEd Maste goto clean2; 14753ef90571SEd Maste rtn = 1; 14763ef90571SEd Maste clean2: 14773ef90571SEd Maste free(num_str); 14783ef90571SEd Maste clean1: 14793ef90571SEd Maste free(name); 14803ef90571SEd Maste return (rtn); 14813ef90571SEd Maste 14823ef90571SEd Maste case SIMPLE_HASH('G', 'T'): 14833ef90571SEd Maste ddata->cur += 2; 14843ef90571SEd Maste if (*ddata->cur == '\0') 14853ef90571SEd Maste return (0); 14863ef90571SEd Maste switch (*ddata->cur) { 14873ef90571SEd Maste case 'n': 1488bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "non-transaction clone for ")) 14893ef90571SEd Maste return (0); 1490839529caSEd Maste break; 14913ef90571SEd Maste case 't': 14923ef90571SEd Maste default: 1493bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "transaction clone for ")) 14943ef90571SEd Maste return (0); 1495839529caSEd Maste break; 14963ef90571SEd Maste } 14973ef90571SEd Maste ++ddata->cur; 14983ef90571SEd Maste return (cpp_demangle_read_encoding(ddata)); 14993ef90571SEd Maste 1500a85fe12eSEd Maste case SIMPLE_HASH('G', 'V'): 1501a85fe12eSEd Maste /* sentry object for 1 time init */ 1502bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "guard variable for ")) 1503a85fe12eSEd Maste return (0); 1504a85fe12eSEd Maste ddata->cur += 2; 1505a85fe12eSEd Maste break; 1506a85fe12eSEd Maste 1507a85fe12eSEd Maste case SIMPLE_HASH('T', 'c'): 1508a85fe12eSEd Maste /* virtual function covariant override thunk */ 1509bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, 1510bee2765cSEd Maste "virtual function covariant override ")) 1511a85fe12eSEd Maste return (0); 1512a85fe12eSEd Maste ddata->cur += 2; 1513a85fe12eSEd Maste if (*ddata->cur == '\0') 1514a85fe12eSEd Maste return (0); 1515a85fe12eSEd Maste if (!cpp_demangle_read_offset(ddata)) 1516a85fe12eSEd Maste return (0); 1517a85fe12eSEd Maste if (!cpp_demangle_read_offset(ddata)) 1518a85fe12eSEd Maste return (0); 1519a85fe12eSEd Maste return (cpp_demangle_read_encoding(ddata)); 1520a85fe12eSEd Maste 15213ef90571SEd Maste case SIMPLE_HASH('T', 'C'): 15223ef90571SEd Maste /* construction vtable */ 1523bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "construction vtable for ")) 15243ef90571SEd Maste return (0); 15253ef90571SEd Maste ddata->cur += 2; 15263ef90571SEd Maste if (*ddata->cur == '\0') 15273ef90571SEd Maste return (0); 15283ef90571SEd Maste if (!cpp_demangle_read_type_flat(ddata, &type)) 15293ef90571SEd Maste return (0); 15303ef90571SEd Maste rtn = 0; 15313ef90571SEd Maste if (!cpp_demangle_read_number(ddata, &offset)) 15323ef90571SEd Maste goto clean3; 15333ef90571SEd Maste if (*ddata->cur++ != '_') 15343ef90571SEd Maste goto clean3; 153518f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 15363ef90571SEd Maste goto clean3; 1537bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "-in-")) 15383ef90571SEd Maste goto clean3; 1539bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, type)) 15403ef90571SEd Maste goto clean3; 15413ef90571SEd Maste rtn = 1; 15423ef90571SEd Maste clean3: 15433ef90571SEd Maste free(type); 15443ef90571SEd Maste return (rtn); 15453ef90571SEd Maste 1546a85fe12eSEd Maste case SIMPLE_HASH('T', 'D'): 1547a85fe12eSEd Maste /* typeinfo common proxy */ 1548a85fe12eSEd Maste break; 1549a85fe12eSEd Maste 15503ef90571SEd Maste case SIMPLE_HASH('T', 'F'): 15513ef90571SEd Maste /* typeinfo fn */ 1552bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "typeinfo fn for ")) 15533ef90571SEd Maste return (0); 15543ef90571SEd Maste ddata->cur += 2; 15553ef90571SEd Maste if (*ddata->cur == '\0') 15563ef90571SEd Maste return (0); 155718f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 15583ef90571SEd Maste 1559a85fe12eSEd Maste case SIMPLE_HASH('T', 'h'): 1560a85fe12eSEd Maste /* virtual function non-virtual override thunk */ 1561bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, 1562bee2765cSEd Maste "virtual function non-virtual override ")) 1563a85fe12eSEd Maste return (0); 1564a85fe12eSEd Maste ddata->cur += 2; 1565a85fe12eSEd Maste if (*ddata->cur == '\0') 1566a85fe12eSEd Maste return (0); 1567a85fe12eSEd Maste if (!cpp_demangle_read_nv_offset(ddata)) 1568a85fe12eSEd Maste return (0); 1569a85fe12eSEd Maste return (cpp_demangle_read_encoding(ddata)); 1570a85fe12eSEd Maste 15713ef90571SEd Maste case SIMPLE_HASH('T', 'H'): 15723ef90571SEd Maste /* TLS init function */ 1573bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "TLS init function for ")) 1574a85fe12eSEd Maste return (0); 1575a85fe12eSEd Maste ddata->cur += 2; 1576a85fe12eSEd Maste if (*ddata->cur == '\0') 1577a85fe12eSEd Maste return (0); 15783ef90571SEd Maste break; 15793ef90571SEd Maste 15803ef90571SEd Maste case SIMPLE_HASH('T', 'I'): 15813ef90571SEd Maste /* typeinfo structure */ 1582bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "typeinfo for ")) 15833ef90571SEd Maste return (0); 15843ef90571SEd Maste ddata->cur += 2; 15853ef90571SEd Maste if (*ddata->cur == '\0') 15863ef90571SEd Maste return (0); 158718f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 15883ef90571SEd Maste 15893ef90571SEd Maste case SIMPLE_HASH('T', 'J'): 15903ef90571SEd Maste /* java class */ 1591bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "java Class for ")) 15923ef90571SEd Maste return (0); 15933ef90571SEd Maste ddata->cur += 2; 15943ef90571SEd Maste if (*ddata->cur == '\0') 15953ef90571SEd Maste return (0); 159618f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 15973ef90571SEd Maste 15983ef90571SEd Maste case SIMPLE_HASH('T', 'S'): 15993ef90571SEd Maste /* RTTI name (NTBS) */ 1600bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "typeinfo name for ")) 16013ef90571SEd Maste return (0); 16023ef90571SEd Maste ddata->cur += 2; 16033ef90571SEd Maste if (*ddata->cur == '\0') 16043ef90571SEd Maste return (0); 160518f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 1606a85fe12eSEd Maste 1607a85fe12eSEd Maste case SIMPLE_HASH('T', 'T'): 1608a85fe12eSEd Maste /* VTT table */ 1609bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "VTT for ")) 1610a85fe12eSEd Maste return (0); 1611a85fe12eSEd Maste ddata->cur += 2; 16123ef90571SEd Maste if (*ddata->cur == '\0') 16133ef90571SEd Maste return (0); 161418f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 1615a85fe12eSEd Maste 1616a85fe12eSEd Maste case SIMPLE_HASH('T', 'v'): 1617a85fe12eSEd Maste /* virtual function virtual override thunk */ 1618715d1396SEd Maste if (!DEM_PUSH_STR(ddata, "virtual function virtual override ")) 1619a85fe12eSEd Maste return (0); 1620a85fe12eSEd Maste ddata->cur += 2; 1621a85fe12eSEd Maste if (*ddata->cur == '\0') 1622a85fe12eSEd Maste return (0); 1623a85fe12eSEd Maste if (!cpp_demangle_read_v_offset(ddata)) 1624a85fe12eSEd Maste return (0); 1625a85fe12eSEd Maste return (cpp_demangle_read_encoding(ddata)); 1626a85fe12eSEd Maste 1627a85fe12eSEd Maste case SIMPLE_HASH('T', 'V'): 1628a85fe12eSEd Maste /* virtual table */ 1629bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "vtable for ")) 1630a85fe12eSEd Maste return (0); 1631a85fe12eSEd Maste ddata->cur += 2; 1632a85fe12eSEd Maste if (*ddata->cur == '\0') 1633a85fe12eSEd Maste return (0); 163418f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 16353ef90571SEd Maste 16363ef90571SEd Maste case SIMPLE_HASH('T', 'W'): 16373ef90571SEd Maste /* TLS wrapper function */ 1638bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "TLS wrapper function for ")) 16393ef90571SEd Maste return (0); 16403ef90571SEd Maste ddata->cur += 2; 16413ef90571SEd Maste if (*ddata->cur == '\0') 16423ef90571SEd Maste return (0); 16433ef90571SEd Maste break; 1644b6b6f9ccSEd Maste } 1645a85fe12eSEd Maste 1646a85fe12eSEd Maste return (cpp_demangle_read_name(ddata)); 1647a85fe12eSEd Maste } 1648a85fe12eSEd Maste 1649a85fe12eSEd Maste static int 1650a85fe12eSEd Maste cpp_demangle_read_local_name(struct cpp_demangle_data *ddata) 1651a85fe12eSEd Maste { 165218f4c9dbSEd Maste struct vector_str local_name; 165318f4c9dbSEd Maste struct type_delimit td; 1654a85fe12eSEd Maste size_t limit; 165518f4c9dbSEd Maste bool more_type; 1656a85fe12eSEd Maste 1657a85fe12eSEd Maste if (ddata == NULL) 1658a85fe12eSEd Maste return (0); 1659a85fe12eSEd Maste if (*(++ddata->cur) == '\0') 1660a85fe12eSEd Maste return (0); 1661a85fe12eSEd Maste 1662334f09a6SMark Johnston if (!vector_str_init(&local_name)) 1663334f09a6SMark Johnston return (0); 166418f4c9dbSEd Maste ddata->cur_output = &local_name; 166518f4c9dbSEd Maste 166618f4c9dbSEd Maste if (!cpp_demangle_read_encoding(ddata)) { 166718f4c9dbSEd Maste vector_str_dest(&local_name); 1668a85fe12eSEd Maste return (0); 166918f4c9dbSEd Maste } 167018f4c9dbSEd Maste 167118f4c9dbSEd Maste ddata->cur_output = &ddata->output; 167218f4c9dbSEd Maste 167318f4c9dbSEd Maste td.paren = false; 167418f4c9dbSEd Maste td.firstp = true; 167518f4c9dbSEd Maste more_type = false; 167618f4c9dbSEd Maste limit = 0; 167718f4c9dbSEd Maste 167818f4c9dbSEd Maste /* 167918f4c9dbSEd Maste * The first type is a return type if we just demangled template 168018f4c9dbSEd Maste * args. (the template args is right next to the function name, 168118f4c9dbSEd Maste * which means it's a template function) 168218f4c9dbSEd Maste */ 168318f4c9dbSEd Maste if (ddata->is_tmpl) { 168418f4c9dbSEd Maste ddata->is_tmpl = false; 168518f4c9dbSEd Maste 168618f4c9dbSEd Maste /* Read return type */ 168718f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) { 168818f4c9dbSEd Maste vector_str_dest(&local_name); 168918f4c9dbSEd Maste return (0); 169018f4c9dbSEd Maste } 169118f4c9dbSEd Maste 169218f4c9dbSEd Maste more_type = true; 169318f4c9dbSEd Maste } 169418f4c9dbSEd Maste 169518f4c9dbSEd Maste /* Now we can push the name after possible return type is handled. */ 169618f4c9dbSEd Maste if (!vector_str_push_vector(&ddata->output, &local_name)) { 169718f4c9dbSEd Maste vector_str_dest(&local_name); 169818f4c9dbSEd Maste return (0); 169918f4c9dbSEd Maste } 170018f4c9dbSEd Maste vector_str_dest(&local_name); 170118f4c9dbSEd Maste 170218f4c9dbSEd Maste while (*ddata->cur != '\0') { 170318f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, &td)) 170418f4c9dbSEd Maste return (0); 170518f4c9dbSEd Maste if (more_type) 170618f4c9dbSEd Maste more_type = false; 1707a85fe12eSEd Maste if (*ddata->cur == 'E') 1708a85fe12eSEd Maste break; 1709a85fe12eSEd Maste if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1710a85fe12eSEd Maste return (0); 1711a85fe12eSEd Maste } 171218f4c9dbSEd Maste if (more_type) 171318f4c9dbSEd Maste return (0); 171418f4c9dbSEd Maste 1715a85fe12eSEd Maste if (*(++ddata->cur) == '\0') 1716a85fe12eSEd Maste return (0); 171718f4c9dbSEd Maste if (td.paren == true) { 1718bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, ")")) 1719a85fe12eSEd Maste return (0); 172018f4c9dbSEd Maste td.paren = false; 1721a85fe12eSEd Maste } 1722a85fe12eSEd Maste if (*ddata->cur == 's') 1723a85fe12eSEd Maste ++ddata->cur; 1724a85fe12eSEd Maste else { 1725bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "::")) 1726a85fe12eSEd Maste return (0); 1727a85fe12eSEd Maste if (!cpp_demangle_read_name(ddata)) 1728a85fe12eSEd Maste return (0); 1729a85fe12eSEd Maste } 1730a85fe12eSEd Maste if (*ddata->cur == '_') { 1731a85fe12eSEd Maste ++ddata->cur; 1732a85fe12eSEd Maste while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1733a85fe12eSEd Maste ++ddata->cur; 1734a85fe12eSEd Maste } 1735a85fe12eSEd Maste 1736a85fe12eSEd Maste return (1); 1737a85fe12eSEd Maste } 1738a85fe12eSEd Maste 1739a85fe12eSEd Maste static int 1740a85fe12eSEd Maste cpp_demangle_read_name(struct cpp_demangle_data *ddata) 1741a85fe12eSEd Maste { 1742a85fe12eSEd Maste struct vector_str *output, v; 1743a85fe12eSEd Maste size_t p_idx, subst_str_len; 1744a85fe12eSEd Maste int rtn; 1745a85fe12eSEd Maste char *subst_str; 1746a85fe12eSEd Maste 1747a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 1748a85fe12eSEd Maste return (0); 1749a85fe12eSEd Maste 175018f4c9dbSEd Maste output = ddata->cur_output; 1751a85fe12eSEd Maste 1752a85fe12eSEd Maste subst_str = NULL; 1753a85fe12eSEd Maste 1754a85fe12eSEd Maste switch (*ddata->cur) { 1755a85fe12eSEd Maste case 'S': 1756a85fe12eSEd Maste return (cpp_demangle_read_subst(ddata)); 1757a85fe12eSEd Maste case 'N': 1758a85fe12eSEd Maste return (cpp_demangle_read_nested_name(ddata)); 1759a85fe12eSEd Maste case 'Z': 1760a85fe12eSEd Maste return (cpp_demangle_read_local_name(ddata)); 1761b6b6f9ccSEd Maste } 1762a85fe12eSEd Maste 1763a85fe12eSEd Maste if (!vector_str_init(&v)) 1764a85fe12eSEd Maste return (0); 1765a85fe12eSEd Maste 1766a85fe12eSEd Maste p_idx = output->size; 1767a85fe12eSEd Maste rtn = 0; 1768a85fe12eSEd Maste if (!cpp_demangle_read_uqname(ddata)) 1769a85fe12eSEd Maste goto clean; 1770a85fe12eSEd Maste if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 1771a85fe12eSEd Maste &subst_str_len)) == NULL) 1772a85fe12eSEd Maste goto clean; 1773a85fe12eSEd Maste if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) { 1774a85fe12eSEd Maste rtn = 1; 1775a85fe12eSEd Maste goto clean; 1776a85fe12eSEd Maste } 1777a85fe12eSEd Maste if (!vector_str_push(&v, subst_str, subst_str_len)) 1778a85fe12eSEd Maste goto clean; 1779a85fe12eSEd Maste if (!cpp_demangle_push_subst_v(ddata, &v)) 1780a85fe12eSEd Maste goto clean; 1781a85fe12eSEd Maste 1782a85fe12eSEd Maste if (*ddata->cur == 'I') { 1783a85fe12eSEd Maste p_idx = output->size; 1784a85fe12eSEd Maste if (!cpp_demangle_read_tmpl_args(ddata)) 1785a85fe12eSEd Maste goto clean; 1786a85fe12eSEd Maste free(subst_str); 1787a85fe12eSEd Maste if ((subst_str = vector_str_substr(output, p_idx, 1788a85fe12eSEd Maste output->size - 1, &subst_str_len)) == NULL) 1789a85fe12eSEd Maste goto clean; 1790a85fe12eSEd Maste if (!vector_str_push(&v, subst_str, subst_str_len)) 1791a85fe12eSEd Maste goto clean; 1792a85fe12eSEd Maste if (!cpp_demangle_push_subst_v(ddata, &v)) 1793a85fe12eSEd Maste goto clean; 1794a85fe12eSEd Maste } 1795a85fe12eSEd Maste 1796a85fe12eSEd Maste rtn = 1; 1797a85fe12eSEd Maste 1798a85fe12eSEd Maste clean: 1799a85fe12eSEd Maste free(subst_str); 1800a85fe12eSEd Maste vector_str_dest(&v); 1801a85fe12eSEd Maste 1802a85fe12eSEd Maste return (rtn); 1803a85fe12eSEd Maste } 1804a85fe12eSEd Maste 1805a85fe12eSEd Maste static int 18063ef90571SEd Maste cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str) 18073ef90571SEd Maste { 18083ef90571SEd Maste struct vector_str *output; 18093ef90571SEd Maste size_t i, p_idx, idx, name_len; 18103ef90571SEd Maste char *name; 18113ef90571SEd Maste 181218f4c9dbSEd Maste output = ddata->cur_output; 18133ef90571SEd Maste 18143ef90571SEd Maste p_idx = output->size; 18153ef90571SEd Maste 18163ef90571SEd Maste if (!cpp_demangle_read_name(ddata)) 18173ef90571SEd Maste return (0); 18183ef90571SEd Maste 18193ef90571SEd Maste if ((name = vector_str_substr(output, p_idx, output->size - 1, 18203ef90571SEd Maste &name_len)) == NULL) 18213ef90571SEd Maste return (0); 18223ef90571SEd Maste 18233ef90571SEd Maste idx = output->size; 18243ef90571SEd Maste for (i = p_idx; i < idx; ++i) { 18253ef90571SEd Maste if (!vector_str_pop(output)) { 18263ef90571SEd Maste free(name); 18273ef90571SEd Maste return (0); 18283ef90571SEd Maste } 18293ef90571SEd Maste } 18303ef90571SEd Maste 18313ef90571SEd Maste *str = name; 18323ef90571SEd Maste 18333ef90571SEd Maste return (1); 18343ef90571SEd Maste } 18353ef90571SEd Maste 18363ef90571SEd Maste static int 1837a85fe12eSEd Maste cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) 1838a85fe12eSEd Maste { 1839a85fe12eSEd Maste struct vector_str *output, v; 1840a85fe12eSEd Maste size_t limit, p_idx, subst_str_len; 1841a85fe12eSEd Maste int rtn; 1842a85fe12eSEd Maste char *subst_str; 1843a85fe12eSEd Maste 1844a85fe12eSEd Maste if (ddata == NULL || *ddata->cur != 'N') 1845a85fe12eSEd Maste return (0); 1846a85fe12eSEd Maste if (*(++ddata->cur) == '\0') 1847a85fe12eSEd Maste return (0); 1848a85fe12eSEd Maste 184918f4c9dbSEd Maste do { 1850a85fe12eSEd Maste switch (*ddata->cur) { 1851a85fe12eSEd Maste case 'r': 1852a85fe12eSEd Maste ddata->mem_rst = true; 1853a85fe12eSEd Maste break; 1854a85fe12eSEd Maste case 'V': 1855a85fe12eSEd Maste ddata->mem_vat = true; 1856a85fe12eSEd Maste break; 1857a85fe12eSEd Maste case 'K': 1858a85fe12eSEd Maste ddata->mem_cst = true; 1859a85fe12eSEd Maste break; 186018f4c9dbSEd Maste case 'R': 186118f4c9dbSEd Maste ddata->mem_ref = true; 186218f4c9dbSEd Maste break; 186318f4c9dbSEd Maste case 'O': 186418f4c9dbSEd Maste ddata->mem_rref = true; 186518f4c9dbSEd Maste break; 186618f4c9dbSEd Maste default: 186718f4c9dbSEd Maste goto next; 1868b6b6f9ccSEd Maste } 186918f4c9dbSEd Maste } while (*(++ddata->cur)); 1870a85fe12eSEd Maste 187118f4c9dbSEd Maste next: 187218f4c9dbSEd Maste output = ddata->cur_output; 1873a85fe12eSEd Maste if (!vector_str_init(&v)) 1874a85fe12eSEd Maste return (0); 1875a85fe12eSEd Maste 1876a85fe12eSEd Maste rtn = 0; 1877a85fe12eSEd Maste limit = 0; 1878a85fe12eSEd Maste for (;;) { 1879a85fe12eSEd Maste p_idx = output->size; 1880a85fe12eSEd Maste switch (*ddata->cur) { 1881a85fe12eSEd Maste case 'I': 1882a85fe12eSEd Maste if (!cpp_demangle_read_tmpl_args(ddata)) 1883a85fe12eSEd Maste goto clean; 1884a85fe12eSEd Maste break; 1885a85fe12eSEd Maste case 'S': 1886a85fe12eSEd Maste if (!cpp_demangle_read_subst(ddata)) 1887a85fe12eSEd Maste goto clean; 1888a85fe12eSEd Maste break; 1889a85fe12eSEd Maste case 'T': 1890a85fe12eSEd Maste if (!cpp_demangle_read_tmpl_param(ddata)) 1891a85fe12eSEd Maste goto clean; 1892a85fe12eSEd Maste break; 1893a85fe12eSEd Maste default: 1894a85fe12eSEd Maste if (!cpp_demangle_read_uqname(ddata)) 1895a85fe12eSEd Maste goto clean; 1896b6b6f9ccSEd Maste } 1897a85fe12eSEd Maste 189818f4c9dbSEd Maste if (p_idx == output->size) 189918f4c9dbSEd Maste goto next_comp; 1900a85fe12eSEd Maste if ((subst_str = vector_str_substr(output, p_idx, 1901a85fe12eSEd Maste output->size - 1, &subst_str_len)) == NULL) 1902a85fe12eSEd Maste goto clean; 1903a85fe12eSEd Maste if (!vector_str_push(&v, subst_str, subst_str_len)) { 1904a85fe12eSEd Maste free(subst_str); 1905a85fe12eSEd Maste goto clean; 1906a85fe12eSEd Maste } 1907a85fe12eSEd Maste free(subst_str); 1908a85fe12eSEd Maste 1909a85fe12eSEd Maste if (!cpp_demangle_push_subst_v(ddata, &v)) 1910a85fe12eSEd Maste goto clean; 191118f4c9dbSEd Maste 191218f4c9dbSEd Maste next_comp: 1913a85fe12eSEd Maste if (*ddata->cur == 'E') 1914a85fe12eSEd Maste break; 191518f4c9dbSEd Maste else if (*ddata->cur != 'I' && *ddata->cur != 'C' && 191618f4c9dbSEd Maste *ddata->cur != 'D' && p_idx != output->size) { 1917bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "::")) 1918a85fe12eSEd Maste goto clean; 1919bee2765cSEd Maste if (!VEC_PUSH_STR(&v, "::")) 1920a85fe12eSEd Maste goto clean; 1921a85fe12eSEd Maste } 1922a85fe12eSEd Maste if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1923a85fe12eSEd Maste goto clean; 1924a85fe12eSEd Maste } 1925a85fe12eSEd Maste 1926a85fe12eSEd Maste ++ddata->cur; 1927a85fe12eSEd Maste rtn = 1; 1928a85fe12eSEd Maste 1929a85fe12eSEd Maste clean: 1930a85fe12eSEd Maste vector_str_dest(&v); 1931a85fe12eSEd Maste 1932a85fe12eSEd Maste return (rtn); 1933a85fe12eSEd Maste } 1934a85fe12eSEd Maste 1935a85fe12eSEd Maste /* 1936a85fe12eSEd Maste * read number 1937a85fe12eSEd Maste * number ::= [n] <decimal> 1938a85fe12eSEd Maste */ 1939a85fe12eSEd Maste static int 1940a85fe12eSEd Maste cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) 1941a85fe12eSEd Maste { 1942a85fe12eSEd Maste long len, negative_factor; 1943a85fe12eSEd Maste 1944a85fe12eSEd Maste if (ddata == NULL || rtn == NULL) 1945a85fe12eSEd Maste return (0); 1946a85fe12eSEd Maste 1947a85fe12eSEd Maste negative_factor = 1; 1948a85fe12eSEd Maste if (*ddata->cur == 'n') { 1949a85fe12eSEd Maste negative_factor = -1; 1950a85fe12eSEd Maste 1951a85fe12eSEd Maste ++ddata->cur; 1952a85fe12eSEd Maste } 1953a85fe12eSEd Maste if (ELFTC_ISDIGIT(*ddata->cur) == 0) 1954a85fe12eSEd Maste return (0); 1955a85fe12eSEd Maste 1956a85fe12eSEd Maste errno = 0; 1957a85fe12eSEd Maste if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 && 1958a85fe12eSEd Maste errno != 0) 1959a85fe12eSEd Maste return (0); 1960a85fe12eSEd Maste 1961a85fe12eSEd Maste while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1962a85fe12eSEd Maste ++ddata->cur; 1963a85fe12eSEd Maste 1964a85fe12eSEd Maste assert(len >= 0); 1965a85fe12eSEd Maste assert(negative_factor == 1 || negative_factor == -1); 1966a85fe12eSEd Maste 1967a85fe12eSEd Maste *rtn = len * negative_factor; 1968a85fe12eSEd Maste 1969a85fe12eSEd Maste return (1); 1970a85fe12eSEd Maste } 1971a85fe12eSEd Maste 1972a85fe12eSEd Maste static int 19733ef90571SEd Maste cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str) 19743ef90571SEd Maste { 19753ef90571SEd Maste long n; 19763ef90571SEd Maste 19773ef90571SEd Maste if (!cpp_demangle_read_number(ddata, &n)) { 19783ef90571SEd Maste *str = NULL; 19793ef90571SEd Maste return (0); 19803ef90571SEd Maste } 19813ef90571SEd Maste 19823ef90571SEd Maste if (asprintf(str, "%ld", n) < 0) { 19833ef90571SEd Maste *str = NULL; 19843ef90571SEd Maste return (0); 19853ef90571SEd Maste } 19863ef90571SEd Maste 19873ef90571SEd Maste return (1); 19883ef90571SEd Maste } 19893ef90571SEd Maste 19903ef90571SEd Maste static int 1991a85fe12eSEd Maste cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) 1992a85fe12eSEd Maste { 1993a85fe12eSEd Maste 1994a85fe12eSEd Maste if (ddata == NULL) 1995a85fe12eSEd Maste return (0); 1996a85fe12eSEd Maste 1997bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "offset : ")) 1998a85fe12eSEd Maste return (0); 1999a85fe12eSEd Maste 2000a85fe12eSEd Maste return (cpp_demangle_read_offset_number(ddata)); 2001a85fe12eSEd Maste } 2002a85fe12eSEd Maste 2003a85fe12eSEd Maste /* read offset, offset are nv-offset, v-offset */ 2004a85fe12eSEd Maste static int 2005a85fe12eSEd Maste cpp_demangle_read_offset(struct cpp_demangle_data *ddata) 2006a85fe12eSEd Maste { 2007a85fe12eSEd Maste 2008a85fe12eSEd Maste if (ddata == NULL) 2009a85fe12eSEd Maste return (0); 2010a85fe12eSEd Maste 2011a85fe12eSEd Maste if (*ddata->cur == 'h') { 2012a85fe12eSEd Maste ++ddata->cur; 2013a85fe12eSEd Maste return (cpp_demangle_read_nv_offset(ddata)); 2014a85fe12eSEd Maste } else if (*ddata->cur == 'v') { 2015a85fe12eSEd Maste ++ddata->cur; 2016a85fe12eSEd Maste return (cpp_demangle_read_v_offset(ddata)); 2017a85fe12eSEd Maste } 2018a85fe12eSEd Maste 2019a85fe12eSEd Maste return (0); 2020a85fe12eSEd Maste } 2021a85fe12eSEd Maste 2022a85fe12eSEd Maste static int 2023a85fe12eSEd Maste cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata) 2024a85fe12eSEd Maste { 2025a85fe12eSEd Maste bool negative; 2026a85fe12eSEd Maste const char *start; 2027a85fe12eSEd Maste 2028a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 2029a85fe12eSEd Maste return (0); 2030a85fe12eSEd Maste 2031a85fe12eSEd Maste /* offset could be negative */ 2032a85fe12eSEd Maste if (*ddata->cur == 'n') { 2033a85fe12eSEd Maste negative = true; 2034a85fe12eSEd Maste start = ddata->cur + 1; 2035a85fe12eSEd Maste } else { 2036a85fe12eSEd Maste negative = false; 2037a85fe12eSEd Maste start = ddata->cur; 2038a85fe12eSEd Maste } 2039a85fe12eSEd Maste 2040a85fe12eSEd Maste while (*ddata->cur != '_') 2041a85fe12eSEd Maste ++ddata->cur; 2042a85fe12eSEd Maste 2043bee2765cSEd Maste if (negative && !DEM_PUSH_STR(ddata, "-")) 2044a85fe12eSEd Maste return (0); 2045a85fe12eSEd Maste 2046a85fe12eSEd Maste assert(start != NULL); 2047a85fe12eSEd Maste 2048a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, start, ddata->cur - start)) 2049a85fe12eSEd Maste return (0); 2050bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " ")) 2051a85fe12eSEd Maste return (0); 2052a85fe12eSEd Maste 2053a85fe12eSEd Maste ++ddata->cur; 2054a85fe12eSEd Maste 2055a85fe12eSEd Maste return (1); 2056a85fe12eSEd Maste } 2057a85fe12eSEd Maste 2058a85fe12eSEd Maste static int 205918f4c9dbSEd Maste cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata, 206018f4c9dbSEd Maste struct vector_type_qualifier *v) 2061a85fe12eSEd Maste { 2062a85fe12eSEd Maste size_t class_type_len, i, idx, p_idx; 2063a85fe12eSEd Maste int p_func_type, rtn; 2064a85fe12eSEd Maste char *class_type; 2065a85fe12eSEd Maste 2066a85fe12eSEd Maste if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0') 2067a85fe12eSEd Maste return (0); 2068a85fe12eSEd Maste 2069a85fe12eSEd Maste p_idx = ddata->output.size; 207018f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 2071a85fe12eSEd Maste return (0); 2072a85fe12eSEd Maste 2073a85fe12eSEd Maste if ((class_type = vector_str_substr(&ddata->output, p_idx, 2074a85fe12eSEd Maste ddata->output.size - 1, &class_type_len)) == NULL) 2075a85fe12eSEd Maste return (0); 2076a85fe12eSEd Maste 2077a85fe12eSEd Maste rtn = 0; 2078a85fe12eSEd Maste idx = ddata->output.size; 2079a85fe12eSEd Maste for (i = p_idx; i < idx; ++i) 2080a85fe12eSEd Maste if (!vector_str_pop(&ddata->output)) 2081a85fe12eSEd Maste goto clean1; 2082a85fe12eSEd Maste 208318f4c9dbSEd Maste if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM, v)) 2084a85fe12eSEd Maste goto clean1; 2085a85fe12eSEd Maste 2086a85fe12eSEd Maste if (!vector_str_push(&ddata->class_type, class_type, class_type_len)) 2087a85fe12eSEd Maste goto clean2; 2088a85fe12eSEd Maste 2089a85fe12eSEd Maste p_func_type = ddata->func_type; 209018f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 2091a85fe12eSEd Maste goto clean3; 2092a85fe12eSEd Maste 2093a85fe12eSEd Maste if (p_func_type == ddata->func_type) { 2094bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " ")) 2095a85fe12eSEd Maste goto clean3; 2096a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) 2097a85fe12eSEd Maste goto clean3; 2098bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "::*")) 2099a85fe12eSEd Maste goto clean3; 2100a85fe12eSEd Maste } 2101a85fe12eSEd Maste 2102a85fe12eSEd Maste rtn = 1; 2103a85fe12eSEd Maste clean3: 2104a85fe12eSEd Maste if (!vector_str_pop(&ddata->class_type)) 2105a85fe12eSEd Maste rtn = 0; 2106a85fe12eSEd Maste clean2: 2107a85fe12eSEd Maste if (!vector_read_cmd_pop(&ddata->cmd)) 2108a85fe12eSEd Maste rtn = 0; 2109a85fe12eSEd Maste clean1: 2110a85fe12eSEd Maste free(class_type); 2111a85fe12eSEd Maste 211218f4c9dbSEd Maste vector_type_qualifier_dest(v); 211318f4c9dbSEd Maste if (!vector_type_qualifier_init(v)) 211418f4c9dbSEd Maste return (0); 211518f4c9dbSEd Maste 2116a85fe12eSEd Maste return (rtn); 2117a85fe12eSEd Maste } 2118a85fe12eSEd Maste 2119a85fe12eSEd Maste /* read source-name, source-name is <len> <ID> */ 2120a85fe12eSEd Maste static int 2121a85fe12eSEd Maste cpp_demangle_read_sname(struct cpp_demangle_data *ddata) 2122a85fe12eSEd Maste { 2123a85fe12eSEd Maste long len; 21243ef90571SEd Maste int err; 2125a85fe12eSEd Maste 2126a85fe12eSEd Maste if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || 21273ef90571SEd Maste len <= 0) 21283ef90571SEd Maste return (0); 21293ef90571SEd Maste 21303ef90571SEd Maste if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) 2131bee2765cSEd Maste err = DEM_PUSH_STR(ddata, "(anonymous namespace)"); 21323ef90571SEd Maste else 21333ef90571SEd Maste err = cpp_demangle_push_str(ddata, ddata->cur, len); 21343ef90571SEd Maste 21353ef90571SEd Maste if (err == 0) 2136a85fe12eSEd Maste return (0); 2137a85fe12eSEd Maste 2138c2bffd0aSDimitry Andric assert(ddata->cur_output->size > 0); 213918f4c9dbSEd Maste if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL) 2140a85fe12eSEd Maste ddata->last_sname = 2141c2bffd0aSDimitry Andric ddata->cur_output->container[ddata->output.size - 1]; 2142a85fe12eSEd Maste 2143a85fe12eSEd Maste ddata->cur += len; 2144a85fe12eSEd Maste 2145a85fe12eSEd Maste return (1); 2146a85fe12eSEd Maste } 2147a85fe12eSEd Maste 2148a85fe12eSEd Maste static int 2149a85fe12eSEd Maste cpp_demangle_read_subst(struct cpp_demangle_data *ddata) 2150a85fe12eSEd Maste { 2151a85fe12eSEd Maste long nth; 2152a85fe12eSEd Maste 2153a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 2154a85fe12eSEd Maste return (0); 2155a85fe12eSEd Maste 2156a85fe12eSEd Maste /* abbreviations of the form Sx */ 2157a85fe12eSEd Maste switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 2158a85fe12eSEd Maste case SIMPLE_HASH('S', 'a'): 2159a85fe12eSEd Maste /* std::allocator */ 2160bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "std::allocator")) 2161a85fe12eSEd Maste return (0); 2162a85fe12eSEd Maste ddata->cur += 2; 2163a85fe12eSEd Maste if (*ddata->cur == 'I') 2164a85fe12eSEd Maste return (cpp_demangle_read_subst_stdtmpl(ddata, 216518f4c9dbSEd Maste "std::allocator")); 2166a85fe12eSEd Maste return (1); 2167a85fe12eSEd Maste 2168a85fe12eSEd Maste case SIMPLE_HASH('S', 'b'): 2169a85fe12eSEd Maste /* std::basic_string */ 2170bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "std::basic_string")) 2171a85fe12eSEd Maste return (0); 2172a85fe12eSEd Maste ddata->cur += 2; 2173a85fe12eSEd Maste if (*ddata->cur == 'I') 2174a85fe12eSEd Maste return (cpp_demangle_read_subst_stdtmpl(ddata, 217518f4c9dbSEd Maste "std::basic_string")); 2176a85fe12eSEd Maste return (1); 2177a85fe12eSEd Maste 2178a85fe12eSEd Maste case SIMPLE_HASH('S', 'd'): 2179a85fe12eSEd Maste /* std::basic_iostream<char, std::char_traits<char> > */ 218018f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, "std::basic_iostream<char, " 218118f4c9dbSEd Maste "std::char_traits<char> >")) 2182a85fe12eSEd Maste return (0); 2183839529caSEd Maste ddata->last_sname = "basic_iostream"; 2184a85fe12eSEd Maste ddata->cur += 2; 2185a85fe12eSEd Maste if (*ddata->cur == 'I') 2186a85fe12eSEd Maste return (cpp_demangle_read_subst_stdtmpl(ddata, 218718f4c9dbSEd Maste "std::basic_iostream<char, std::char_traits" 218818f4c9dbSEd Maste "<char> >")); 2189a85fe12eSEd Maste return (1); 2190a85fe12eSEd Maste 2191a85fe12eSEd Maste case SIMPLE_HASH('S', 'i'): 2192a85fe12eSEd Maste /* std::basic_istream<char, std::char_traits<char> > */ 219318f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, "std::basic_istream<char, " 219418f4c9dbSEd Maste "std::char_traits<char> >")) 2195a85fe12eSEd Maste return (0); 2196839529caSEd Maste ddata->last_sname = "basic_istream"; 2197a85fe12eSEd Maste ddata->cur += 2; 2198a85fe12eSEd Maste if (*ddata->cur == 'I') 2199a85fe12eSEd Maste return (cpp_demangle_read_subst_stdtmpl(ddata, 220018f4c9dbSEd Maste "std::basic_istream<char, std::char_traits" 220118f4c9dbSEd Maste "<char> >")); 2202a85fe12eSEd Maste return (1); 2203a85fe12eSEd Maste 2204a85fe12eSEd Maste case SIMPLE_HASH('S', 'o'): 2205a85fe12eSEd Maste /* std::basic_ostream<char, std::char_traits<char> > */ 220618f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, "std::basic_ostream<char, " 220718f4c9dbSEd Maste "std::char_traits<char> >")) 2208a85fe12eSEd Maste return (0); 2209839529caSEd Maste ddata->last_sname = "basic_ostream"; 2210a85fe12eSEd Maste ddata->cur += 2; 2211a85fe12eSEd Maste if (*ddata->cur == 'I') 2212a85fe12eSEd Maste return (cpp_demangle_read_subst_stdtmpl(ddata, 221318f4c9dbSEd Maste "std::basic_ostream<char, std::char_traits" 221418f4c9dbSEd Maste "<char> >")); 2215a85fe12eSEd Maste return (1); 2216a85fe12eSEd Maste 2217a85fe12eSEd Maste case SIMPLE_HASH('S', 's'): 2218a85fe12eSEd Maste /* 2219a85fe12eSEd Maste * std::basic_string<char, std::char_traits<char>, 2220a85fe12eSEd Maste * std::allocator<char> > 2221a85fe12eSEd Maste * 2222a85fe12eSEd Maste * a.k.a std::string 2223a85fe12eSEd Maste */ 222418f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, "std::basic_string<char, " 222518f4c9dbSEd Maste "std::char_traits<char>, std::allocator<char> >")) 2226a85fe12eSEd Maste return (0); 2227a85fe12eSEd Maste ddata->last_sname = "string"; 2228a85fe12eSEd Maste ddata->cur += 2; 2229a85fe12eSEd Maste if (*ddata->cur == 'I') 2230a85fe12eSEd Maste return (cpp_demangle_read_subst_stdtmpl(ddata, 223118f4c9dbSEd Maste "std::basic_string<char, std::char_traits<char>," 223218f4c9dbSEd Maste " std::allocator<char> >")); 2233a85fe12eSEd Maste return (1); 2234a85fe12eSEd Maste 2235a85fe12eSEd Maste case SIMPLE_HASH('S', 't'): 2236a85fe12eSEd Maste /* std:: */ 2237a85fe12eSEd Maste return (cpp_demangle_read_subst_std(ddata)); 2238b6b6f9ccSEd Maste } 2239a85fe12eSEd Maste 2240a85fe12eSEd Maste if (*(++ddata->cur) == '\0') 2241a85fe12eSEd Maste return (0); 2242a85fe12eSEd Maste 224318f4c9dbSEd Maste /* Skip unknown substitution abbreviations. */ 224418f4c9dbSEd Maste if (!(*ddata->cur >= '0' && *ddata->cur <= '9') && 224518f4c9dbSEd Maste !(*ddata->cur >= 'A' && *ddata->cur <= 'Z') && 224618f4c9dbSEd Maste *ddata->cur != '_') { 224718f4c9dbSEd Maste ++ddata->cur; 224818f4c9dbSEd Maste return (1); 224918f4c9dbSEd Maste } 225018f4c9dbSEd Maste 2251a85fe12eSEd Maste /* substitution */ 2252a85fe12eSEd Maste if (*ddata->cur == '_') 2253a85fe12eSEd Maste return (cpp_demangle_get_subst(ddata, 0)); 2254a85fe12eSEd Maste else { 2255a85fe12eSEd Maste errno = 0; 2256a85fe12eSEd Maste /* substitution number is base 36 */ 2257a85fe12eSEd Maste if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 2258a85fe12eSEd Maste errno != 0) 2259a85fe12eSEd Maste return (0); 2260a85fe12eSEd Maste 2261a85fe12eSEd Maste /* first was '_', so increase one */ 2262a85fe12eSEd Maste ++nth; 2263a85fe12eSEd Maste 2264a85fe12eSEd Maste while (*ddata->cur != '_') 2265a85fe12eSEd Maste ++ddata->cur; 2266a85fe12eSEd Maste 2267a85fe12eSEd Maste assert(nth > 0); 2268a85fe12eSEd Maste 2269a85fe12eSEd Maste return (cpp_demangle_get_subst(ddata, nth)); 2270a85fe12eSEd Maste } 2271a85fe12eSEd Maste 2272a85fe12eSEd Maste /* NOTREACHED */ 2273a85fe12eSEd Maste return (0); 2274a85fe12eSEd Maste } 2275a85fe12eSEd Maste 2276a85fe12eSEd Maste static int 2277a85fe12eSEd Maste cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) 2278a85fe12eSEd Maste { 2279a85fe12eSEd Maste struct vector_str *output, v; 2280a85fe12eSEd Maste size_t p_idx, subst_str_len; 2281a85fe12eSEd Maste int rtn; 2282a85fe12eSEd Maste char *subst_str; 2283a85fe12eSEd Maste 2284a85fe12eSEd Maste if (ddata == NULL) 2285a85fe12eSEd Maste return (0); 2286a85fe12eSEd Maste 2287a85fe12eSEd Maste if (!vector_str_init(&v)) 2288a85fe12eSEd Maste return (0); 2289a85fe12eSEd Maste 2290a85fe12eSEd Maste subst_str = NULL; 2291a85fe12eSEd Maste rtn = 0; 2292bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "std::")) 2293a85fe12eSEd Maste goto clean; 2294a85fe12eSEd Maste 2295bee2765cSEd Maste if (!VEC_PUSH_STR(&v, "std::")) 2296a85fe12eSEd Maste goto clean; 2297a85fe12eSEd Maste 2298a85fe12eSEd Maste ddata->cur += 2; 2299a85fe12eSEd Maste 230018f4c9dbSEd Maste output = ddata->cur_output; 2301a85fe12eSEd Maste 2302a85fe12eSEd Maste p_idx = output->size; 2303a85fe12eSEd Maste if (!cpp_demangle_read_uqname(ddata)) 2304a85fe12eSEd Maste goto clean; 2305a85fe12eSEd Maste 2306a85fe12eSEd Maste if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 2307a85fe12eSEd Maste &subst_str_len)) == NULL) 2308a85fe12eSEd Maste goto clean; 2309a85fe12eSEd Maste 2310a85fe12eSEd Maste if (!vector_str_push(&v, subst_str, subst_str_len)) 2311a85fe12eSEd Maste goto clean; 2312a85fe12eSEd Maste 2313a85fe12eSEd Maste if (!cpp_demangle_push_subst_v(ddata, &v)) 2314a85fe12eSEd Maste goto clean; 2315a85fe12eSEd Maste 2316a85fe12eSEd Maste if (*ddata->cur == 'I') { 2317a85fe12eSEd Maste p_idx = output->size; 2318a85fe12eSEd Maste if (!cpp_demangle_read_tmpl_args(ddata)) 2319a85fe12eSEd Maste goto clean; 2320a85fe12eSEd Maste free(subst_str); 2321a85fe12eSEd Maste if ((subst_str = vector_str_substr(output, p_idx, 2322a85fe12eSEd Maste output->size - 1, &subst_str_len)) == NULL) 2323a85fe12eSEd Maste goto clean; 2324a85fe12eSEd Maste if (!vector_str_push(&v, subst_str, subst_str_len)) 2325a85fe12eSEd Maste goto clean; 2326a85fe12eSEd Maste if (!cpp_demangle_push_subst_v(ddata, &v)) 2327a85fe12eSEd Maste goto clean; 2328a85fe12eSEd Maste } 2329a85fe12eSEd Maste 2330a85fe12eSEd Maste rtn = 1; 2331a85fe12eSEd Maste clean: 2332a85fe12eSEd Maste free(subst_str); 2333a85fe12eSEd Maste vector_str_dest(&v); 2334a85fe12eSEd Maste 2335a85fe12eSEd Maste return (rtn); 2336a85fe12eSEd Maste } 2337a85fe12eSEd Maste 2338a85fe12eSEd Maste static int 2339a85fe12eSEd Maste cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, 234018f4c9dbSEd Maste const char *str) 2341a85fe12eSEd Maste { 2342a85fe12eSEd Maste struct vector_str *output; 234318f4c9dbSEd Maste size_t p_idx, substr_len, len; 2344a85fe12eSEd Maste int rtn; 2345a85fe12eSEd Maste char *subst_str, *substr; 2346a85fe12eSEd Maste 234718f4c9dbSEd Maste if (ddata == NULL || str == NULL) 2348a85fe12eSEd Maste return (0); 2349a85fe12eSEd Maste 235018f4c9dbSEd Maste if ((len = strlen(str)) == 0) 235118f4c9dbSEd Maste return (0); 235218f4c9dbSEd Maste 235318f4c9dbSEd Maste output = ddata->cur_output; 2354a85fe12eSEd Maste 2355a85fe12eSEd Maste p_idx = output->size; 2356a85fe12eSEd Maste substr = NULL; 2357a85fe12eSEd Maste subst_str = NULL; 2358a85fe12eSEd Maste 2359a85fe12eSEd Maste if (!cpp_demangle_read_tmpl_args(ddata)) 2360a85fe12eSEd Maste return (0); 2361a85fe12eSEd Maste if ((substr = vector_str_substr(output, p_idx, output->size - 1, 2362a85fe12eSEd Maste &substr_len)) == NULL) 2363a85fe12eSEd Maste return (0); 2364a85fe12eSEd Maste 2365a85fe12eSEd Maste rtn = 0; 2366a85fe12eSEd Maste if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) == 2367a85fe12eSEd Maste NULL) 2368a85fe12eSEd Maste goto clean; 2369a85fe12eSEd Maste 2370a85fe12eSEd Maste memcpy(subst_str, str, len); 2371a85fe12eSEd Maste memcpy(subst_str + len, substr, substr_len); 2372a85fe12eSEd Maste subst_str[substr_len + len] = '\0'; 2373a85fe12eSEd Maste 2374a85fe12eSEd Maste if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len)) 2375a85fe12eSEd Maste goto clean; 2376a85fe12eSEd Maste 2377a85fe12eSEd Maste rtn = 1; 2378a85fe12eSEd Maste clean: 2379a85fe12eSEd Maste free(subst_str); 2380a85fe12eSEd Maste free(substr); 2381a85fe12eSEd Maste 2382a85fe12eSEd Maste return (rtn); 2383a85fe12eSEd Maste } 2384a85fe12eSEd Maste 2385a85fe12eSEd Maste static int 2386a85fe12eSEd Maste cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata) 2387a85fe12eSEd Maste { 2388a85fe12eSEd Maste 2389a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 2390a85fe12eSEd Maste return (0); 2391a85fe12eSEd Maste 2392a85fe12eSEd Maste switch (*ddata->cur) { 2393a85fe12eSEd Maste case 'L': 2394a85fe12eSEd Maste return (cpp_demangle_read_expr_primary(ddata)); 2395a85fe12eSEd Maste case 'X': 239618f4c9dbSEd Maste ++ddata->cur; 239718f4c9dbSEd Maste if (!cpp_demangle_read_expression(ddata)) 239818f4c9dbSEd Maste return (0); 239918f4c9dbSEd Maste return (*ddata->cur++ == 'E'); 2400b6b6f9ccSEd Maste } 2401a85fe12eSEd Maste 240218f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 2403a85fe12eSEd Maste } 2404a85fe12eSEd Maste 2405a85fe12eSEd Maste static int 2406a85fe12eSEd Maste cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) 2407a85fe12eSEd Maste { 2408a85fe12eSEd Maste struct vector_str *v; 2409a85fe12eSEd Maste size_t arg_len, idx, limit, size; 2410a85fe12eSEd Maste char *arg; 2411a85fe12eSEd Maste 2412a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 2413a85fe12eSEd Maste return (0); 2414a85fe12eSEd Maste 2415a85fe12eSEd Maste ++ddata->cur; 2416a85fe12eSEd Maste 241718f4c9dbSEd Maste if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL, NULL)) 2418a85fe12eSEd Maste return (0); 2419a85fe12eSEd Maste 2420bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "<")) 2421a85fe12eSEd Maste return (0); 2422a85fe12eSEd Maste 2423a85fe12eSEd Maste limit = 0; 2424c2bffd0aSDimitry Andric v = ddata->cur_output; 2425a85fe12eSEd Maste for (;;) { 2426a85fe12eSEd Maste idx = v->size; 2427a85fe12eSEd Maste if (!cpp_demangle_read_tmpl_arg(ddata)) 2428a85fe12eSEd Maste return (0); 2429a85fe12eSEd Maste if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) == 2430a85fe12eSEd Maste NULL) 2431a85fe12eSEd Maste return (0); 2432a85fe12eSEd Maste if (!vector_str_find(&ddata->tmpl, arg, arg_len) && 2433a85fe12eSEd Maste !vector_str_push(&ddata->tmpl, arg, arg_len)) { 2434a85fe12eSEd Maste free(arg); 2435a85fe12eSEd Maste return (0); 2436a85fe12eSEd Maste } 2437a85fe12eSEd Maste 2438a85fe12eSEd Maste free(arg); 2439a85fe12eSEd Maste 2440a85fe12eSEd Maste if (*ddata->cur == 'E') { 2441a85fe12eSEd Maste ++ddata->cur; 2442a85fe12eSEd Maste size = v->size; 2443a85fe12eSEd Maste assert(size > 0); 2444a85fe12eSEd Maste if (!strncmp(v->container[size - 1], ">", 1)) { 2445bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, " >")) 2446a85fe12eSEd Maste return (0); 2447bee2765cSEd Maste } else if (!DEM_PUSH_STR(ddata, ">")) 2448a85fe12eSEd Maste return (0); 244918f4c9dbSEd Maste ddata->is_tmpl = true; 2450a85fe12eSEd Maste break; 2451a85fe12eSEd Maste } else if (*ddata->cur != 'I' && 2452bee2765cSEd Maste !DEM_PUSH_STR(ddata, ", ")) 2453a85fe12eSEd Maste return (0); 2454a85fe12eSEd Maste 2455a85fe12eSEd Maste if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 2456a85fe12eSEd Maste return (0); 2457a85fe12eSEd Maste } 2458a85fe12eSEd Maste 2459a85fe12eSEd Maste return (vector_read_cmd_pop(&ddata->cmd)); 2460a85fe12eSEd Maste } 2461a85fe12eSEd Maste 2462a85fe12eSEd Maste /* 2463a85fe12eSEd Maste * Read template parameter that forms in 'T[number]_'. 2464a85fe12eSEd Maste * This function much like to read_subst but only for types. 2465a85fe12eSEd Maste */ 2466a85fe12eSEd Maste static int 2467a85fe12eSEd Maste cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata) 2468a85fe12eSEd Maste { 2469a85fe12eSEd Maste long nth; 2470a85fe12eSEd Maste 2471a85fe12eSEd Maste if (ddata == NULL || *ddata->cur != 'T') 2472a85fe12eSEd Maste return (0); 2473a85fe12eSEd Maste 2474a85fe12eSEd Maste ++ddata->cur; 2475a85fe12eSEd Maste 2476a85fe12eSEd Maste if (*ddata->cur == '_') 2477a85fe12eSEd Maste return (cpp_demangle_get_tmpl_param(ddata, 0)); 2478a85fe12eSEd Maste else { 2479a85fe12eSEd Maste 2480a85fe12eSEd Maste errno = 0; 2481a85fe12eSEd Maste if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 2482a85fe12eSEd Maste errno != 0) 2483a85fe12eSEd Maste return (0); 2484a85fe12eSEd Maste 2485a85fe12eSEd Maste /* T_ is first */ 2486a85fe12eSEd Maste ++nth; 2487a85fe12eSEd Maste 2488a85fe12eSEd Maste while (*ddata->cur != '_') 2489a85fe12eSEd Maste ++ddata->cur; 2490a85fe12eSEd Maste 2491a85fe12eSEd Maste assert(nth > 0); 2492a85fe12eSEd Maste 2493a85fe12eSEd Maste return (cpp_demangle_get_tmpl_param(ddata, nth)); 2494a85fe12eSEd Maste } 2495a85fe12eSEd Maste 2496a85fe12eSEd Maste /* NOTREACHED */ 2497a85fe12eSEd Maste return (0); 2498a85fe12eSEd Maste } 2499a85fe12eSEd Maste 2500a85fe12eSEd Maste static int 250118f4c9dbSEd Maste cpp_demangle_read_type(struct cpp_demangle_data *ddata, 250218f4c9dbSEd Maste struct type_delimit *td) 2503a85fe12eSEd Maste { 2504a85fe12eSEd Maste struct vector_type_qualifier v; 250518f4c9dbSEd Maste struct vector_str *output, sv; 250618f4c9dbSEd Maste size_t p_idx, type_str_len, subst_str_len; 2507a85fe12eSEd Maste int extern_c, is_builtin; 2508a85fe12eSEd Maste long len; 250918f4c9dbSEd Maste const char *p; 251018f4c9dbSEd Maste char *type_str, *exp_str, *num_str, *subst_str; 251118f4c9dbSEd Maste bool skip_ref_qualifier, omit_void; 2512a85fe12eSEd Maste 2513a85fe12eSEd Maste if (ddata == NULL) 2514a85fe12eSEd Maste return (0); 2515a85fe12eSEd Maste 251618f4c9dbSEd Maste output = ddata->cur_output; 251718f4c9dbSEd Maste if (td) { 251818f4c9dbSEd Maste if (td->paren == false) { 2519bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "(")) 2520a85fe12eSEd Maste return (0); 2521a85fe12eSEd Maste if (ddata->output.size < 2) 2522a85fe12eSEd Maste return (0); 252318f4c9dbSEd Maste td->paren = true; 2524a85fe12eSEd Maste } 2525a85fe12eSEd Maste 252618f4c9dbSEd Maste if (!td->firstp) { 252718f4c9dbSEd Maste if (*ddata->cur != 'I') { 252818f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, ", ")) 2529a85fe12eSEd Maste return (0); 2530a85fe12eSEd Maste } 253118f4c9dbSEd Maste } 253218f4c9dbSEd Maste } 2533a85fe12eSEd Maste 2534a85fe12eSEd Maste assert(output != NULL); 2535a85fe12eSEd Maste /* 253618f4c9dbSEd Maste * [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array 2537a85fe12eSEd Maste * pointer-to-member, template-param, template-template-param, subst 2538a85fe12eSEd Maste */ 2539a85fe12eSEd Maste 2540a85fe12eSEd Maste if (!vector_type_qualifier_init(&v)) 2541a85fe12eSEd Maste return (0); 2542a85fe12eSEd Maste 2543a85fe12eSEd Maste extern_c = 0; 2544a85fe12eSEd Maste is_builtin = 1; 2545a85fe12eSEd Maste p_idx = output->size; 25463ef90571SEd Maste type_str = exp_str = num_str = NULL; 254718f4c9dbSEd Maste skip_ref_qualifier = false; 254818f4c9dbSEd Maste 2549a85fe12eSEd Maste again: 255018f4c9dbSEd Maste 255118f4c9dbSEd Maste /* Clear ref-qualifier flag */ 255218f4c9dbSEd Maste if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E') 255318f4c9dbSEd Maste ddata->ref_qualifier = false; 255418f4c9dbSEd Maste 2555a85fe12eSEd Maste /* builtin type */ 2556a85fe12eSEd Maste switch (*ddata->cur) { 2557a85fe12eSEd Maste case 'a': 2558a85fe12eSEd Maste /* signed char */ 2559bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "signed char")) 2560a85fe12eSEd Maste goto clean; 2561a85fe12eSEd Maste ++ddata->cur; 2562a85fe12eSEd Maste goto rtn; 2563a85fe12eSEd Maste 2564a85fe12eSEd Maste case 'A': 2565a85fe12eSEd Maste /* array type */ 2566a85fe12eSEd Maste if (!cpp_demangle_read_array(ddata)) 2567a85fe12eSEd Maste goto clean; 2568a85fe12eSEd Maste is_builtin = 0; 2569a85fe12eSEd Maste goto rtn; 2570a85fe12eSEd Maste 2571a85fe12eSEd Maste case 'b': 2572a85fe12eSEd Maste /* bool */ 2573bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "bool")) 2574a85fe12eSEd Maste goto clean; 2575a85fe12eSEd Maste ++ddata->cur; 2576a85fe12eSEd Maste goto rtn; 2577a85fe12eSEd Maste 2578a85fe12eSEd Maste case 'C': 2579a85fe12eSEd Maste /* complex pair */ 2580a85fe12eSEd Maste if (!vector_type_qualifier_push(&v, TYPE_CMX)) 2581a85fe12eSEd Maste goto clean; 2582a85fe12eSEd Maste ++ddata->cur; 258318f4c9dbSEd Maste if (td) 258418f4c9dbSEd Maste td->firstp = false; 2585a85fe12eSEd Maste goto again; 2586a85fe12eSEd Maste 2587a85fe12eSEd Maste case 'c': 2588a85fe12eSEd Maste /* char */ 2589bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "char")) 2590a85fe12eSEd Maste goto clean; 2591a85fe12eSEd Maste ++ddata->cur; 2592a85fe12eSEd Maste goto rtn; 2593a85fe12eSEd Maste 2594a85fe12eSEd Maste case 'd': 2595a85fe12eSEd Maste /* double */ 2596bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "double")) 2597a85fe12eSEd Maste goto clean; 2598a85fe12eSEd Maste ++ddata->cur; 2599a85fe12eSEd Maste goto rtn; 2600a85fe12eSEd Maste 26013ef90571SEd Maste case 'D': 26023ef90571SEd Maste ++ddata->cur; 26033ef90571SEd Maste switch (*ddata->cur) { 260418f4c9dbSEd Maste case 'a': 260518f4c9dbSEd Maste /* auto */ 260618f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, "auto")) 260718f4c9dbSEd Maste goto clean; 260818f4c9dbSEd Maste ++ddata->cur; 260918f4c9dbSEd Maste break; 261018f4c9dbSEd Maste case 'c': 261118f4c9dbSEd Maste /* decltype(auto) */ 261218f4c9dbSEd Maste if (!DEM_PUSH_STR(ddata, "decltype(auto)")) 261318f4c9dbSEd Maste goto clean; 261418f4c9dbSEd Maste ++ddata->cur; 261518f4c9dbSEd Maste break; 26163ef90571SEd Maste case 'd': 26173ef90571SEd Maste /* IEEE 754r decimal floating point (64 bits) */ 2618bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "decimal64")) 26193ef90571SEd Maste goto clean; 26203ef90571SEd Maste ++ddata->cur; 26213ef90571SEd Maste break; 26223ef90571SEd Maste case 'e': 26233ef90571SEd Maste /* IEEE 754r decimal floating point (128 bits) */ 2624bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "decimal128")) 26253ef90571SEd Maste goto clean; 26263ef90571SEd Maste ++ddata->cur; 26273ef90571SEd Maste break; 26283ef90571SEd Maste case 'f': 26293ef90571SEd Maste /* IEEE 754r decimal floating point (32 bits) */ 2630bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "decimal32")) 26313ef90571SEd Maste goto clean; 26323ef90571SEd Maste ++ddata->cur; 26333ef90571SEd Maste break; 26343ef90571SEd Maste case 'h': 26353ef90571SEd Maste /* IEEE 754r half-precision floating point (16 bits) */ 2636bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "half")) 26373ef90571SEd Maste goto clean; 26383ef90571SEd Maste ++ddata->cur; 26393ef90571SEd Maste break; 26403ef90571SEd Maste case 'i': 26413ef90571SEd Maste /* char32_t */ 2642bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "char32_t")) 26433ef90571SEd Maste goto clean; 26443ef90571SEd Maste ++ddata->cur; 26453ef90571SEd Maste break; 26463ef90571SEd Maste case 'n': 26473ef90571SEd Maste /* std::nullptr_t (i.e., decltype(nullptr)) */ 2648bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "decltype(nullptr)")) 26493ef90571SEd Maste goto clean; 26503ef90571SEd Maste ++ddata->cur; 26513ef90571SEd Maste break; 26523ef90571SEd Maste case 's': 26533ef90571SEd Maste /* char16_t */ 2654bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "char16_t")) 26553ef90571SEd Maste goto clean; 26563ef90571SEd Maste ++ddata->cur; 26573ef90571SEd Maste break; 26583ef90571SEd Maste case 'v': 26593ef90571SEd Maste /* gcc vector_size extension. */ 26603ef90571SEd Maste ++ddata->cur; 26613ef90571SEd Maste if (*ddata->cur == '_') { 26623ef90571SEd Maste ++ddata->cur; 26633ef90571SEd Maste if (!cpp_demangle_read_expression_flat(ddata, 26643ef90571SEd Maste &exp_str)) 26653ef90571SEd Maste goto clean; 2666bee2765cSEd Maste if (!VEC_PUSH_STR(&v.ext_name, exp_str)) 26673ef90571SEd Maste goto clean; 26683ef90571SEd Maste } else { 26693ef90571SEd Maste if (!cpp_demangle_read_number_as_string(ddata, 26703ef90571SEd Maste &num_str)) 26713ef90571SEd Maste goto clean; 2672bee2765cSEd Maste if (!VEC_PUSH_STR(&v.ext_name, num_str)) 26733ef90571SEd Maste goto clean; 26743ef90571SEd Maste } 26753ef90571SEd Maste if (*ddata->cur != '_') 26763ef90571SEd Maste goto clean; 26773ef90571SEd Maste ++ddata->cur; 26783ef90571SEd Maste if (!vector_type_qualifier_push(&v, TYPE_VEC)) 26793ef90571SEd Maste goto clean; 268018f4c9dbSEd Maste if (td) 268118f4c9dbSEd Maste td->firstp = false; 26823ef90571SEd Maste goto again; 26833ef90571SEd Maste default: 26843ef90571SEd Maste goto clean; 26853ef90571SEd Maste } 26863ef90571SEd Maste goto rtn; 26873ef90571SEd Maste 2688a85fe12eSEd Maste case 'e': 2689a85fe12eSEd Maste /* long double */ 2690bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "long double")) 2691a85fe12eSEd Maste goto clean; 2692a85fe12eSEd Maste ++ddata->cur; 2693a85fe12eSEd Maste goto rtn; 2694a85fe12eSEd Maste 269518f4c9dbSEd Maste case 'E': 269618f4c9dbSEd Maste /* unexpected end except ref-qualifiers */ 269718f4c9dbSEd Maste if (ddata->ref_qualifier && ddata->is_functype) { 269818f4c9dbSEd Maste skip_ref_qualifier = true; 269918f4c9dbSEd Maste /* Pop the delimiter. */ 270018f4c9dbSEd Maste cpp_demangle_pop_str(ddata); 270118f4c9dbSEd Maste goto rtn; 270218f4c9dbSEd Maste } 270318f4c9dbSEd Maste goto clean; 270418f4c9dbSEd Maste 2705a85fe12eSEd Maste case 'f': 2706a85fe12eSEd Maste /* float */ 2707bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "float")) 2708a85fe12eSEd Maste goto clean; 2709a85fe12eSEd Maste ++ddata->cur; 2710a85fe12eSEd Maste goto rtn; 2711a85fe12eSEd Maste 2712a85fe12eSEd Maste case 'F': 2713a85fe12eSEd Maste /* function */ 2714a85fe12eSEd Maste if (!cpp_demangle_read_function(ddata, &extern_c, &v)) 2715a85fe12eSEd Maste goto clean; 2716a85fe12eSEd Maste is_builtin = 0; 2717a85fe12eSEd Maste goto rtn; 2718a85fe12eSEd Maste 2719a85fe12eSEd Maste case 'g': 2720a85fe12eSEd Maste /* __float128 */ 2721bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "__float128")) 2722a85fe12eSEd Maste goto clean; 2723a85fe12eSEd Maste ++ddata->cur; 2724a85fe12eSEd Maste goto rtn; 2725a85fe12eSEd Maste 2726a85fe12eSEd Maste case 'G': 2727a85fe12eSEd Maste /* imaginary */ 2728a85fe12eSEd Maste if (!vector_type_qualifier_push(&v, TYPE_IMG)) 2729a85fe12eSEd Maste goto clean; 2730a85fe12eSEd Maste ++ddata->cur; 273118f4c9dbSEd Maste if (td) 273218f4c9dbSEd Maste td->firstp = false; 2733a85fe12eSEd Maste goto again; 2734a85fe12eSEd Maste 2735a85fe12eSEd Maste case 'h': 2736a85fe12eSEd Maste /* unsigned char */ 2737bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "unsigned char")) 2738a85fe12eSEd Maste goto clean; 2739a85fe12eSEd Maste ++ddata->cur; 2740a85fe12eSEd Maste goto rtn; 2741a85fe12eSEd Maste 2742a85fe12eSEd Maste case 'i': 2743a85fe12eSEd Maste /* int */ 2744bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "int")) 2745a85fe12eSEd Maste goto clean; 2746a85fe12eSEd Maste ++ddata->cur; 2747a85fe12eSEd Maste goto rtn; 2748a85fe12eSEd Maste 274918f4c9dbSEd Maste case 'I': 275018f4c9dbSEd Maste /* template args. */ 275118f4c9dbSEd Maste /* handles <substitute><template-args> */ 275218f4c9dbSEd Maste p_idx = output->size; 275318f4c9dbSEd Maste if (!cpp_demangle_read_tmpl_args(ddata)) 275418f4c9dbSEd Maste goto clean; 275518f4c9dbSEd Maste if ((subst_str = vector_str_substr(output, p_idx, 275618f4c9dbSEd Maste output->size - 1, &subst_str_len)) == NULL) 275718f4c9dbSEd Maste goto clean; 275818f4c9dbSEd Maste if (!vector_str_init(&sv)) { 275918f4c9dbSEd Maste free(subst_str); 276018f4c9dbSEd Maste goto clean; 276118f4c9dbSEd Maste } 276218f4c9dbSEd Maste if (!vector_str_push(&sv, subst_str, subst_str_len)) { 276318f4c9dbSEd Maste free(subst_str); 276418f4c9dbSEd Maste vector_str_dest(&sv); 276518f4c9dbSEd Maste goto clean; 276618f4c9dbSEd Maste } 276718f4c9dbSEd Maste free(subst_str); 276818f4c9dbSEd Maste if (!cpp_demangle_push_subst_v(ddata, &sv)) { 276918f4c9dbSEd Maste vector_str_dest(&sv); 277018f4c9dbSEd Maste goto clean; 277118f4c9dbSEd Maste } 277218f4c9dbSEd Maste vector_str_dest(&sv); 277318f4c9dbSEd Maste goto rtn; 277418f4c9dbSEd Maste 2775a85fe12eSEd Maste case 'j': 2776a85fe12eSEd Maste /* unsigned int */ 2777bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "unsigned int")) 2778a85fe12eSEd Maste goto clean; 2779a85fe12eSEd Maste ++ddata->cur; 2780a85fe12eSEd Maste goto rtn; 2781a85fe12eSEd Maste 2782a85fe12eSEd Maste case 'K': 2783a85fe12eSEd Maste /* const */ 2784a85fe12eSEd Maste if (!vector_type_qualifier_push(&v, TYPE_CST)) 2785a85fe12eSEd Maste goto clean; 2786a85fe12eSEd Maste ++ddata->cur; 278718f4c9dbSEd Maste if (td) 278818f4c9dbSEd Maste td->firstp = false; 2789a85fe12eSEd Maste goto again; 2790a85fe12eSEd Maste 2791a85fe12eSEd Maste case 'l': 2792a85fe12eSEd Maste /* long */ 2793bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "long")) 2794a85fe12eSEd Maste goto clean; 2795a85fe12eSEd Maste ++ddata->cur; 2796a85fe12eSEd Maste goto rtn; 2797a85fe12eSEd Maste 2798a85fe12eSEd Maste case 'm': 2799a85fe12eSEd Maste /* unsigned long */ 2800bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "unsigned long")) 2801a85fe12eSEd Maste goto clean; 2802a85fe12eSEd Maste 2803a85fe12eSEd Maste ++ddata->cur; 2804a85fe12eSEd Maste 2805a85fe12eSEd Maste goto rtn; 2806a85fe12eSEd Maste case 'M': 2807a85fe12eSEd Maste /* pointer to member */ 280818f4c9dbSEd Maste if (!cpp_demangle_read_pointer_to_member(ddata, &v)) 2809a85fe12eSEd Maste goto clean; 2810a85fe12eSEd Maste is_builtin = 0; 2811a85fe12eSEd Maste goto rtn; 2812a85fe12eSEd Maste 2813a85fe12eSEd Maste case 'n': 2814a85fe12eSEd Maste /* __int128 */ 2815bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "__int128")) 2816a85fe12eSEd Maste goto clean; 2817a85fe12eSEd Maste ++ddata->cur; 2818a85fe12eSEd Maste goto rtn; 2819a85fe12eSEd Maste 2820a85fe12eSEd Maste case 'o': 2821a85fe12eSEd Maste /* unsigned __int128 */ 2822bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "unsigned __int128")) 2823a85fe12eSEd Maste goto clean; 2824a85fe12eSEd Maste ++ddata->cur; 2825a85fe12eSEd Maste goto rtn; 2826a85fe12eSEd Maste 282718f4c9dbSEd Maste case 'O': 282818f4c9dbSEd Maste /* rvalue reference */ 282918f4c9dbSEd Maste if (ddata->ref_qualifier) 283018f4c9dbSEd Maste goto clean; 283118f4c9dbSEd Maste if (!vector_type_qualifier_push(&v, TYPE_RREF)) 283218f4c9dbSEd Maste goto clean; 283318f4c9dbSEd Maste ddata->ref_qualifier = true; 283418f4c9dbSEd Maste ddata->ref_qualifier_type = TYPE_RREF; 283518f4c9dbSEd Maste ++ddata->cur; 283618f4c9dbSEd Maste if (td) 283718f4c9dbSEd Maste td->firstp = false; 283818f4c9dbSEd Maste goto again; 283918f4c9dbSEd Maste 2840a85fe12eSEd Maste case 'P': 2841a85fe12eSEd Maste /* pointer */ 2842a85fe12eSEd Maste if (!vector_type_qualifier_push(&v, TYPE_PTR)) 2843a85fe12eSEd Maste goto clean; 2844a85fe12eSEd Maste ++ddata->cur; 284518f4c9dbSEd Maste if (td) 284618f4c9dbSEd Maste td->firstp = false; 2847a85fe12eSEd Maste goto again; 2848a85fe12eSEd Maste 2849a85fe12eSEd Maste case 'r': 2850a85fe12eSEd Maste /* restrict */ 2851a85fe12eSEd Maste if (!vector_type_qualifier_push(&v, TYPE_RST)) 2852a85fe12eSEd Maste goto clean; 2853a85fe12eSEd Maste ++ddata->cur; 285418f4c9dbSEd Maste if (td) 285518f4c9dbSEd Maste td->firstp = false; 2856a85fe12eSEd Maste goto again; 2857a85fe12eSEd Maste 2858a85fe12eSEd Maste case 'R': 2859a85fe12eSEd Maste /* reference */ 286018f4c9dbSEd Maste if (ddata->ref_qualifier) 286118f4c9dbSEd Maste goto clean; 2862a85fe12eSEd Maste if (!vector_type_qualifier_push(&v, TYPE_REF)) 2863a85fe12eSEd Maste goto clean; 286418f4c9dbSEd Maste ddata->ref_qualifier = true; 286518f4c9dbSEd Maste ddata->ref_qualifier_type = TYPE_REF; 2866a85fe12eSEd Maste ++ddata->cur; 286718f4c9dbSEd Maste if (td) 286818f4c9dbSEd Maste td->firstp = false; 2869a85fe12eSEd Maste goto again; 2870a85fe12eSEd Maste 2871a85fe12eSEd Maste case 's': 2872a85fe12eSEd Maste /* short, local string */ 2873bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "short")) 2874a85fe12eSEd Maste goto clean; 2875a85fe12eSEd Maste ++ddata->cur; 2876a85fe12eSEd Maste goto rtn; 2877a85fe12eSEd Maste 2878a85fe12eSEd Maste case 'S': 2879a85fe12eSEd Maste /* substitution */ 2880a85fe12eSEd Maste if (!cpp_demangle_read_subst(ddata)) 2881a85fe12eSEd Maste goto clean; 2882a85fe12eSEd Maste is_builtin = 0; 2883a85fe12eSEd Maste goto rtn; 2884a85fe12eSEd Maste 2885a85fe12eSEd Maste case 't': 2886a85fe12eSEd Maste /* unsigned short */ 2887bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "unsigned short")) 2888a85fe12eSEd Maste goto clean; 2889a85fe12eSEd Maste ++ddata->cur; 2890a85fe12eSEd Maste goto rtn; 2891a85fe12eSEd Maste 2892a85fe12eSEd Maste case 'T': 2893a85fe12eSEd Maste /* template parameter */ 2894a85fe12eSEd Maste if (!cpp_demangle_read_tmpl_param(ddata)) 2895a85fe12eSEd Maste goto clean; 2896a85fe12eSEd Maste is_builtin = 0; 2897a85fe12eSEd Maste goto rtn; 2898a85fe12eSEd Maste 2899a85fe12eSEd Maste case 'u': 2900a85fe12eSEd Maste /* vendor extended builtin */ 2901a85fe12eSEd Maste ++ddata->cur; 2902a85fe12eSEd Maste if (!cpp_demangle_read_sname(ddata)) 2903a85fe12eSEd Maste goto clean; 2904a85fe12eSEd Maste is_builtin = 0; 2905a85fe12eSEd Maste goto rtn; 2906a85fe12eSEd Maste 2907a85fe12eSEd Maste case 'U': 2908a85fe12eSEd Maste /* vendor extended type qualifier */ 290918f4c9dbSEd Maste ++ddata->cur; 2910a85fe12eSEd Maste if (!cpp_demangle_read_number(ddata, &len)) 2911a85fe12eSEd Maste goto clean; 2912a85fe12eSEd Maste if (len <= 0) 2913a85fe12eSEd Maste goto clean; 2914a85fe12eSEd Maste if (!vector_str_push(&v.ext_name, ddata->cur, len)) 2915c364ccf9SMark Johnston goto clean; 2916a85fe12eSEd Maste ddata->cur += len; 29173ef90571SEd Maste if (!vector_type_qualifier_push(&v, TYPE_EXT)) 29183ef90571SEd Maste goto clean; 291918f4c9dbSEd Maste if (td) 292018f4c9dbSEd Maste td->firstp = false; 2921a85fe12eSEd Maste goto again; 2922a85fe12eSEd Maste 2923a85fe12eSEd Maste case 'v': 2924a85fe12eSEd Maste /* void */ 292518f4c9dbSEd Maste omit_void = false; 292618f4c9dbSEd Maste if (td && td->firstp) { 292718f4c9dbSEd Maste /* 292818f4c9dbSEd Maste * peek into next bytes and see if we should omit 292918f4c9dbSEd Maste * the "void". 293018f4c9dbSEd Maste */ 293118f4c9dbSEd Maste omit_void = true; 293218f4c9dbSEd Maste for (p = ddata->cur + 1; *p != '\0'; p++) { 293318f4c9dbSEd Maste if (*p == 'E') 293418f4c9dbSEd Maste break; 293518f4c9dbSEd Maste if (*p != 'R' && *p != 'O') { 293618f4c9dbSEd Maste omit_void = false; 293718f4c9dbSEd Maste break; 293818f4c9dbSEd Maste } 293918f4c9dbSEd Maste } 294018f4c9dbSEd Maste } 294118f4c9dbSEd Maste if (!omit_void && !DEM_PUSH_STR(ddata, "void")) 2942a85fe12eSEd Maste goto clean; 2943a85fe12eSEd Maste ++ddata->cur; 2944a85fe12eSEd Maste goto rtn; 2945a85fe12eSEd Maste 2946a85fe12eSEd Maste case 'V': 2947a85fe12eSEd Maste /* volatile */ 2948a85fe12eSEd Maste if (!vector_type_qualifier_push(&v, TYPE_VAT)) 2949a85fe12eSEd Maste goto clean; 2950a85fe12eSEd Maste ++ddata->cur; 295118f4c9dbSEd Maste if (td) 295218f4c9dbSEd Maste td->firstp = false; 2953a85fe12eSEd Maste goto again; 2954a85fe12eSEd Maste 2955a85fe12eSEd Maste case 'w': 2956a85fe12eSEd Maste /* wchar_t */ 2957bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "wchar_t")) 2958a85fe12eSEd Maste goto clean; 2959a85fe12eSEd Maste ++ddata->cur; 2960a85fe12eSEd Maste goto rtn; 2961a85fe12eSEd Maste 2962a85fe12eSEd Maste case 'x': 2963a85fe12eSEd Maste /* long long */ 2964bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "long long")) 2965a85fe12eSEd Maste goto clean; 2966a85fe12eSEd Maste ++ddata->cur; 2967a85fe12eSEd Maste goto rtn; 2968a85fe12eSEd Maste 2969a85fe12eSEd Maste case 'y': 2970a85fe12eSEd Maste /* unsigned long long */ 2971bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "unsigned long long")) 2972a85fe12eSEd Maste goto clean; 2973a85fe12eSEd Maste ++ddata->cur; 2974a85fe12eSEd Maste goto rtn; 2975a85fe12eSEd Maste 2976a85fe12eSEd Maste case 'z': 2977a85fe12eSEd Maste /* ellipsis */ 2978bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "...")) 2979a85fe12eSEd Maste goto clean; 2980a85fe12eSEd Maste ++ddata->cur; 2981a85fe12eSEd Maste goto rtn; 2982b6b6f9ccSEd Maste } 2983a85fe12eSEd Maste 2984a85fe12eSEd Maste if (!cpp_demangle_read_name(ddata)) 2985a85fe12eSEd Maste goto clean; 2986a85fe12eSEd Maste 2987a85fe12eSEd Maste is_builtin = 0; 2988a85fe12eSEd Maste rtn: 298918f4c9dbSEd Maste 299018f4c9dbSEd Maste type_str = vector_str_substr(output, p_idx, output->size - 1, 299118f4c9dbSEd Maste &type_str_len); 2992a85fe12eSEd Maste 2993a85fe12eSEd Maste if (is_builtin == 0) { 2994a85fe12eSEd Maste if (!vector_str_find(&ddata->subst, type_str, type_str_len) && 2995a85fe12eSEd Maste !vector_str_push(&ddata->subst, type_str, type_str_len)) 2996a85fe12eSEd Maste goto clean; 2997a85fe12eSEd Maste } 2998a85fe12eSEd Maste 299918f4c9dbSEd Maste if (!skip_ref_qualifier && 300018f4c9dbSEd Maste !cpp_demangle_push_type_qualifier(ddata, &v, type_str)) 3001a85fe12eSEd Maste goto clean; 3002a85fe12eSEd Maste 300318f4c9dbSEd Maste if (td) 300418f4c9dbSEd Maste td->firstp = false; 300518f4c9dbSEd Maste 3006a85fe12eSEd Maste free(type_str); 30073ef90571SEd Maste free(exp_str); 30083ef90571SEd Maste free(num_str); 3009a85fe12eSEd Maste vector_type_qualifier_dest(&v); 3010a85fe12eSEd Maste 3011a85fe12eSEd Maste return (1); 3012a85fe12eSEd Maste clean: 3013a85fe12eSEd Maste free(type_str); 30143ef90571SEd Maste free(exp_str); 30153ef90571SEd Maste free(num_str); 3016a85fe12eSEd Maste vector_type_qualifier_dest(&v); 3017a85fe12eSEd Maste 3018a85fe12eSEd Maste return (0); 3019a85fe12eSEd Maste } 3020a85fe12eSEd Maste 30213ef90571SEd Maste static int 30223ef90571SEd Maste cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str) 30233ef90571SEd Maste { 30243ef90571SEd Maste struct vector_str *output; 30253ef90571SEd Maste size_t i, p_idx, idx, type_len; 30263ef90571SEd Maste char *type; 30273ef90571SEd Maste 302818f4c9dbSEd Maste output = ddata->cur_output; 30293ef90571SEd Maste 30303ef90571SEd Maste p_idx = output->size; 30313ef90571SEd Maste 303218f4c9dbSEd Maste if (!cpp_demangle_read_type(ddata, NULL)) 30333ef90571SEd Maste return (0); 30343ef90571SEd Maste 30353ef90571SEd Maste if ((type = vector_str_substr(output, p_idx, output->size - 1, 30363ef90571SEd Maste &type_len)) == NULL) 30373ef90571SEd Maste return (0); 30383ef90571SEd Maste 30393ef90571SEd Maste idx = output->size; 30403ef90571SEd Maste for (i = p_idx; i < idx; ++i) { 30413ef90571SEd Maste if (!vector_str_pop(output)) { 30423ef90571SEd Maste free(type); 30433ef90571SEd Maste return (0); 30443ef90571SEd Maste } 30453ef90571SEd Maste } 30463ef90571SEd Maste 30473ef90571SEd Maste *str = type; 30483ef90571SEd Maste 30493ef90571SEd Maste return (1); 30503ef90571SEd Maste } 30513ef90571SEd Maste 3052a85fe12eSEd Maste /* 3053a85fe12eSEd Maste * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, 3054a85fe12eSEd Maste * source-name 3055a85fe12eSEd Maste */ 3056a85fe12eSEd Maste static int 3057a85fe12eSEd Maste cpp_demangle_read_uqname(struct cpp_demangle_data *ddata) 3058a85fe12eSEd Maste { 3059a85fe12eSEd Maste size_t len; 3060a85fe12eSEd Maste 3061a85fe12eSEd Maste if (ddata == NULL || *ddata->cur == '\0') 3062a85fe12eSEd Maste return (0); 3063a85fe12eSEd Maste 3064a85fe12eSEd Maste /* operator name */ 3065a85fe12eSEd Maste switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 3066a85fe12eSEd Maste case SIMPLE_HASH('a', 'a'): 3067a85fe12eSEd Maste /* operator && */ 3068bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator&&")) 3069a85fe12eSEd Maste return (0); 3070a85fe12eSEd Maste ddata->cur += 2; 3071a85fe12eSEd Maste return (1); 3072a85fe12eSEd Maste 3073a85fe12eSEd Maste case SIMPLE_HASH('a', 'd'): 3074a85fe12eSEd Maste /* operator & (unary) */ 3075bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator&")) 3076a85fe12eSEd Maste return (0); 3077a85fe12eSEd Maste ddata->cur += 2; 3078a85fe12eSEd Maste return (1); 3079a85fe12eSEd Maste 3080a85fe12eSEd Maste case SIMPLE_HASH('a', 'n'): 3081a85fe12eSEd Maste /* operator & */ 3082bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator&")) 3083a85fe12eSEd Maste return (0); 3084a85fe12eSEd Maste ddata->cur += 2; 3085a85fe12eSEd Maste return (1); 3086a85fe12eSEd Maste 3087a85fe12eSEd Maste case SIMPLE_HASH('a', 'N'): 3088a85fe12eSEd Maste /* operator &= */ 3089bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator&=")) 3090a85fe12eSEd Maste return (0); 3091a85fe12eSEd Maste ddata->cur += 2; 3092a85fe12eSEd Maste return (1); 3093a85fe12eSEd Maste 3094a85fe12eSEd Maste case SIMPLE_HASH('a', 'S'): 3095a85fe12eSEd Maste /* operator = */ 3096bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator=")) 3097a85fe12eSEd Maste return (0); 3098a85fe12eSEd Maste ddata->cur += 2; 3099a85fe12eSEd Maste return (1); 3100a85fe12eSEd Maste 3101a85fe12eSEd Maste case SIMPLE_HASH('c', 'l'): 3102a85fe12eSEd Maste /* operator () */ 3103bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator()")) 3104a85fe12eSEd Maste return (0); 3105a85fe12eSEd Maste ddata->cur += 2; 3106a85fe12eSEd Maste return (1); 3107a85fe12eSEd Maste 3108a85fe12eSEd Maste case SIMPLE_HASH('c', 'm'): 3109a85fe12eSEd Maste /* operator , */ 3110bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator,")) 3111a85fe12eSEd Maste return (0); 3112a85fe12eSEd Maste ddata->cur += 2; 3113a85fe12eSEd Maste return (1); 3114a85fe12eSEd Maste 3115a85fe12eSEd Maste case SIMPLE_HASH('c', 'o'): 3116a85fe12eSEd Maste /* operator ~ */ 3117bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator~")) 3118a85fe12eSEd Maste return (0); 3119a85fe12eSEd Maste ddata->cur += 2; 3120a85fe12eSEd Maste return (1); 3121a85fe12eSEd Maste 3122a85fe12eSEd Maste case SIMPLE_HASH('c', 'v'): 3123a85fe12eSEd Maste /* operator (cast) */ 3124bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator(cast)")) 3125a85fe12eSEd Maste return (0); 3126a85fe12eSEd Maste ddata->cur += 2; 312718f4c9dbSEd Maste return (cpp_demangle_read_type(ddata, NULL)); 3128a85fe12eSEd Maste 3129a85fe12eSEd Maste case SIMPLE_HASH('d', 'a'): 3130a85fe12eSEd Maste /* operator delete [] */ 3131bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator delete []")) 3132a85fe12eSEd Maste return (0); 3133a85fe12eSEd Maste ddata->cur += 2; 3134a85fe12eSEd Maste return (1); 3135a85fe12eSEd Maste 3136a85fe12eSEd Maste case SIMPLE_HASH('d', 'e'): 3137a85fe12eSEd Maste /* operator * (unary) */ 3138bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator*")) 3139a85fe12eSEd Maste return (0); 3140a85fe12eSEd Maste ddata->cur += 2; 3141a85fe12eSEd Maste return (1); 3142a85fe12eSEd Maste 3143a85fe12eSEd Maste case SIMPLE_HASH('d', 'l'): 3144a85fe12eSEd Maste /* operator delete */ 3145bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator delete")) 3146a85fe12eSEd Maste return (0); 3147a85fe12eSEd Maste ddata->cur += 2; 3148a85fe12eSEd Maste return (1); 3149a85fe12eSEd Maste 3150a85fe12eSEd Maste case SIMPLE_HASH('d', 'v'): 3151a85fe12eSEd Maste /* operator / */ 3152bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator/")) 3153a85fe12eSEd Maste return (0); 3154a85fe12eSEd Maste ddata->cur += 2; 3155a85fe12eSEd Maste return (1); 3156a85fe12eSEd Maste 3157a85fe12eSEd Maste case SIMPLE_HASH('d', 'V'): 3158a85fe12eSEd Maste /* operator /= */ 3159bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator/=")) 3160a85fe12eSEd Maste return (0); 3161a85fe12eSEd Maste ddata->cur += 2; 3162a85fe12eSEd Maste return (1); 3163a85fe12eSEd Maste 3164a85fe12eSEd Maste case SIMPLE_HASH('e', 'o'): 3165a85fe12eSEd Maste /* operator ^ */ 3166bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator^")) 3167a85fe12eSEd Maste return (0); 3168a85fe12eSEd Maste ddata->cur += 2; 3169a85fe12eSEd Maste return (1); 3170a85fe12eSEd Maste 3171a85fe12eSEd Maste case SIMPLE_HASH('e', 'O'): 3172a85fe12eSEd Maste /* operator ^= */ 3173bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator^=")) 3174a85fe12eSEd Maste return (0); 3175a85fe12eSEd Maste ddata->cur += 2; 3176a85fe12eSEd Maste return (1); 3177a85fe12eSEd Maste 3178a85fe12eSEd Maste case SIMPLE_HASH('e', 'q'): 3179a85fe12eSEd Maste /* operator == */ 3180bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator==")) 3181a85fe12eSEd Maste return (0); 3182a85fe12eSEd Maste ddata->cur += 2; 3183a85fe12eSEd Maste return (1); 3184a85fe12eSEd Maste 3185a85fe12eSEd Maste case SIMPLE_HASH('g', 'e'): 3186a85fe12eSEd Maste /* operator >= */ 3187bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator>=")) 3188a85fe12eSEd Maste return (0); 3189a85fe12eSEd Maste ddata->cur += 2; 3190a85fe12eSEd Maste return (1); 3191a85fe12eSEd Maste 3192a85fe12eSEd Maste case SIMPLE_HASH('g', 't'): 3193a85fe12eSEd Maste /* operator > */ 3194bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator>")) 3195a85fe12eSEd Maste return (0); 3196a85fe12eSEd Maste ddata->cur += 2; 3197a85fe12eSEd Maste return (1); 3198a85fe12eSEd Maste 3199a85fe12eSEd Maste case SIMPLE_HASH('i', 'x'): 3200a85fe12eSEd Maste /* operator [] */ 3201bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator[]")) 3202a85fe12eSEd Maste return (0); 3203a85fe12eSEd Maste ddata->cur += 2; 3204a85fe12eSEd Maste return (1); 3205a85fe12eSEd Maste 3206a85fe12eSEd Maste case SIMPLE_HASH('l', 'e'): 3207a85fe12eSEd Maste /* operator <= */ 3208bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator<=")) 3209a85fe12eSEd Maste return (0); 3210a85fe12eSEd Maste ddata->cur += 2; 3211a85fe12eSEd Maste return (1); 3212a85fe12eSEd Maste 3213a85fe12eSEd Maste case SIMPLE_HASH('l', 's'): 3214a85fe12eSEd Maste /* operator << */ 3215bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator<<")) 3216a85fe12eSEd Maste return (0); 3217a85fe12eSEd Maste ddata->cur += 2; 3218a85fe12eSEd Maste return (1); 3219a85fe12eSEd Maste 3220a85fe12eSEd Maste case SIMPLE_HASH('l', 'S'): 3221a85fe12eSEd Maste /* operator <<= */ 3222bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator<<=")) 3223a85fe12eSEd Maste return (0); 3224a85fe12eSEd Maste ddata->cur += 2; 3225a85fe12eSEd Maste return (1); 3226a85fe12eSEd Maste 3227a85fe12eSEd Maste case SIMPLE_HASH('l', 't'): 3228a85fe12eSEd Maste /* operator < */ 3229bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator<")) 3230a85fe12eSEd Maste return (0); 3231a85fe12eSEd Maste ddata->cur += 2; 3232a85fe12eSEd Maste return (1); 3233a85fe12eSEd Maste 3234a85fe12eSEd Maste case SIMPLE_HASH('m', 'i'): 3235a85fe12eSEd Maste /* operator - */ 3236bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator-")) 3237a85fe12eSEd Maste return (0); 3238a85fe12eSEd Maste ddata->cur += 2; 3239a85fe12eSEd Maste return (1); 3240a85fe12eSEd Maste 3241a85fe12eSEd Maste case SIMPLE_HASH('m', 'I'): 3242a85fe12eSEd Maste /* operator -= */ 3243bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator-=")) 3244a85fe12eSEd Maste return (0); 3245a85fe12eSEd Maste ddata->cur += 2; 3246a85fe12eSEd Maste return (1); 3247a85fe12eSEd Maste 3248a85fe12eSEd Maste case SIMPLE_HASH('m', 'l'): 3249a85fe12eSEd Maste /* operator * */ 3250bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator*")) 3251a85fe12eSEd Maste return (0); 3252a85fe12eSEd Maste ddata->cur += 2; 3253a85fe12eSEd Maste return (1); 3254a85fe12eSEd Maste 3255a85fe12eSEd Maste case SIMPLE_HASH('m', 'L'): 3256a85fe12eSEd Maste /* operator *= */ 3257bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator*=")) 3258a85fe12eSEd Maste return (0); 3259a85fe12eSEd Maste ddata->cur += 2; 3260a85fe12eSEd Maste return (1); 3261a85fe12eSEd Maste 3262a85fe12eSEd Maste case SIMPLE_HASH('m', 'm'): 3263a85fe12eSEd Maste /* operator -- */ 3264bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator--")) 3265a85fe12eSEd Maste return (0); 3266a85fe12eSEd Maste ddata->cur += 2; 3267a85fe12eSEd Maste return (1); 3268a85fe12eSEd Maste 3269a85fe12eSEd Maste case SIMPLE_HASH('n', 'a'): 3270a85fe12eSEd Maste /* operator new[] */ 3271bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator new []")) 3272a85fe12eSEd Maste return (0); 3273a85fe12eSEd Maste ddata->cur += 2; 3274a85fe12eSEd Maste return (1); 3275a85fe12eSEd Maste 3276a85fe12eSEd Maste case SIMPLE_HASH('n', 'e'): 3277a85fe12eSEd Maste /* operator != */ 3278bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator!=")) 3279a85fe12eSEd Maste return (0); 3280a85fe12eSEd Maste ddata->cur += 2; 3281a85fe12eSEd Maste return (1); 3282a85fe12eSEd Maste 3283a85fe12eSEd Maste case SIMPLE_HASH('n', 'g'): 3284a85fe12eSEd Maste /* operator - (unary) */ 3285bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator-")) 3286a85fe12eSEd Maste return (0); 3287a85fe12eSEd Maste ddata->cur += 2; 3288a85fe12eSEd Maste return (1); 3289a85fe12eSEd Maste 3290a85fe12eSEd Maste case SIMPLE_HASH('n', 't'): 3291a85fe12eSEd Maste /* operator ! */ 3292bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator!")) 3293a85fe12eSEd Maste return (0); 3294a85fe12eSEd Maste ddata->cur += 2; 3295a85fe12eSEd Maste return (1); 3296a85fe12eSEd Maste 3297a85fe12eSEd Maste case SIMPLE_HASH('n', 'w'): 3298a85fe12eSEd Maste /* operator new */ 3299bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator new")) 3300a85fe12eSEd Maste return (0); 3301a85fe12eSEd Maste ddata->cur += 2; 3302a85fe12eSEd Maste return (1); 3303a85fe12eSEd Maste 3304a85fe12eSEd Maste case SIMPLE_HASH('o', 'o'): 3305a85fe12eSEd Maste /* operator || */ 3306bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator||")) 3307a85fe12eSEd Maste return (0); 3308a85fe12eSEd Maste ddata->cur += 2; 3309a85fe12eSEd Maste return (1); 3310a85fe12eSEd Maste 3311a85fe12eSEd Maste case SIMPLE_HASH('o', 'r'): 3312a85fe12eSEd Maste /* operator | */ 3313bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator|")) 3314a85fe12eSEd Maste return (0); 3315a85fe12eSEd Maste ddata->cur += 2; 3316a85fe12eSEd Maste return (1); 3317a85fe12eSEd Maste 3318a85fe12eSEd Maste case SIMPLE_HASH('o', 'R'): 3319a85fe12eSEd Maste /* operator |= */ 3320bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator|=")) 3321a85fe12eSEd Maste return (0); 3322a85fe12eSEd Maste ddata->cur += 2; 3323a85fe12eSEd Maste return (1); 3324a85fe12eSEd Maste 3325a85fe12eSEd Maste case SIMPLE_HASH('p', 'l'): 3326a85fe12eSEd Maste /* operator + */ 3327bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator+")) 3328a85fe12eSEd Maste return (0); 3329a85fe12eSEd Maste ddata->cur += 2; 3330a85fe12eSEd Maste return (1); 3331a85fe12eSEd Maste 3332a85fe12eSEd Maste case SIMPLE_HASH('p', 'L'): 3333a85fe12eSEd Maste /* operator += */ 3334bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator+=")) 3335a85fe12eSEd Maste return (0); 3336a85fe12eSEd Maste ddata->cur += 2; 3337a85fe12eSEd Maste return (1); 3338a85fe12eSEd Maste 3339a85fe12eSEd Maste case SIMPLE_HASH('p', 'm'): 3340a85fe12eSEd Maste /* operator ->* */ 3341bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator->*")) 3342a85fe12eSEd Maste return (0); 3343a85fe12eSEd Maste ddata->cur += 2; 3344a85fe12eSEd Maste return (1); 3345a85fe12eSEd Maste 3346a85fe12eSEd Maste case SIMPLE_HASH('p', 'p'): 3347a85fe12eSEd Maste /* operator ++ */ 3348bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator++")) 3349a85fe12eSEd Maste return (0); 3350a85fe12eSEd Maste ddata->cur += 2; 3351a85fe12eSEd Maste return (1); 3352a85fe12eSEd Maste 3353a85fe12eSEd Maste case SIMPLE_HASH('p', 's'): 3354a85fe12eSEd Maste /* operator + (unary) */ 3355bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator+")) 3356a85fe12eSEd Maste return (0); 3357a85fe12eSEd Maste ddata->cur += 2; 3358a85fe12eSEd Maste return (1); 3359a85fe12eSEd Maste 3360a85fe12eSEd Maste case SIMPLE_HASH('p', 't'): 3361a85fe12eSEd Maste /* operator -> */ 3362bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator->")) 3363a85fe12eSEd Maste return (0); 3364a85fe12eSEd Maste ddata->cur += 2; 3365a85fe12eSEd Maste return (1); 3366a85fe12eSEd Maste 3367a85fe12eSEd Maste case SIMPLE_HASH('q', 'u'): 3368a85fe12eSEd Maste /* operator ? */ 3369bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator?")) 3370a85fe12eSEd Maste return (0); 3371a85fe12eSEd Maste ddata->cur += 2; 3372a85fe12eSEd Maste return (1); 3373a85fe12eSEd Maste 3374a85fe12eSEd Maste case SIMPLE_HASH('r', 'm'): 3375a85fe12eSEd Maste /* operator % */ 3376bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator%")) 3377a85fe12eSEd Maste return (0); 3378a85fe12eSEd Maste ddata->cur += 2; 3379a85fe12eSEd Maste return (1); 3380a85fe12eSEd Maste 3381a85fe12eSEd Maste case SIMPLE_HASH('r', 'M'): 3382a85fe12eSEd Maste /* operator %= */ 3383bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator%=")) 3384a85fe12eSEd Maste return (0); 3385a85fe12eSEd Maste ddata->cur += 2; 3386a85fe12eSEd Maste return (1); 3387a85fe12eSEd Maste 3388a85fe12eSEd Maste case SIMPLE_HASH('r', 's'): 3389a85fe12eSEd Maste /* operator >> */ 3390bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator>>")) 3391a85fe12eSEd Maste return (0); 3392a85fe12eSEd Maste ddata->cur += 2; 3393a85fe12eSEd Maste return (1); 3394a85fe12eSEd Maste 3395a85fe12eSEd Maste case SIMPLE_HASH('r', 'S'): 3396a85fe12eSEd Maste /* operator >>= */ 3397bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator>>=")) 3398a85fe12eSEd Maste return (0); 3399a85fe12eSEd Maste ddata->cur += 2; 3400a85fe12eSEd Maste return (1); 3401a85fe12eSEd Maste 3402a85fe12eSEd Maste case SIMPLE_HASH('r', 'z'): 3403a85fe12eSEd Maste /* operator sizeof */ 3404bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator sizeof ")) 3405a85fe12eSEd Maste return (0); 3406a85fe12eSEd Maste ddata->cur += 2; 3407a85fe12eSEd Maste return (1); 3408a85fe12eSEd Maste 3409a85fe12eSEd Maste case SIMPLE_HASH('s', 'r'): 3410a85fe12eSEd Maste /* scope resolution operator */ 3411bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "scope resolution operator ")) 3412a85fe12eSEd Maste return (0); 3413a85fe12eSEd Maste ddata->cur += 2; 3414a85fe12eSEd Maste return (1); 3415a85fe12eSEd Maste 3416a85fe12eSEd Maste case SIMPLE_HASH('s', 'v'): 3417a85fe12eSEd Maste /* operator sizeof */ 3418bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "operator sizeof ")) 3419a85fe12eSEd Maste return (0); 3420a85fe12eSEd Maste ddata->cur += 2; 3421a85fe12eSEd Maste return (1); 3422b6b6f9ccSEd Maste } 3423a85fe12eSEd Maste 3424a85fe12eSEd Maste /* vendor extened operator */ 3425a85fe12eSEd Maste if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) { 3426bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "vendor extened operator ")) 3427a85fe12eSEd Maste return (0); 3428a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1)) 3429a85fe12eSEd Maste return (0); 3430a85fe12eSEd Maste ddata->cur += 2; 3431a85fe12eSEd Maste return (cpp_demangle_read_sname(ddata)); 3432a85fe12eSEd Maste } 3433a85fe12eSEd Maste 3434a85fe12eSEd Maste /* ctor-dtor-name */ 3435a85fe12eSEd Maste switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 3436a85fe12eSEd Maste case SIMPLE_HASH('C', '1'): 3437a85fe12eSEd Maste case SIMPLE_HASH('C', '2'): 3438a85fe12eSEd Maste case SIMPLE_HASH('C', '3'): 3439a85fe12eSEd Maste if (ddata->last_sname == NULL) 3440a85fe12eSEd Maste return (0); 3441a85fe12eSEd Maste if ((len = strlen(ddata->last_sname)) == 0) 3442a85fe12eSEd Maste return (0); 3443bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "::")) 3444a85fe12eSEd Maste return (0); 3445a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 3446a85fe12eSEd Maste return (0); 3447a85fe12eSEd Maste ddata->cur +=2; 3448a85fe12eSEd Maste return (1); 3449a85fe12eSEd Maste 3450a85fe12eSEd Maste case SIMPLE_HASH('D', '0'): 3451a85fe12eSEd Maste case SIMPLE_HASH('D', '1'): 3452a85fe12eSEd Maste case SIMPLE_HASH('D', '2'): 3453a85fe12eSEd Maste if (ddata->last_sname == NULL) 3454a85fe12eSEd Maste return (0); 3455a85fe12eSEd Maste if ((len = strlen(ddata->last_sname)) == 0) 3456a85fe12eSEd Maste return (0); 3457bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "::~")) 3458a85fe12eSEd Maste return (0); 3459a85fe12eSEd Maste if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 3460a85fe12eSEd Maste return (0); 3461a85fe12eSEd Maste ddata->cur +=2; 3462a85fe12eSEd Maste return (1); 3463b6b6f9ccSEd Maste } 3464a85fe12eSEd Maste 3465a85fe12eSEd Maste /* source name */ 3466a85fe12eSEd Maste if (ELFTC_ISDIGIT(*ddata->cur) != 0) 3467a85fe12eSEd Maste return (cpp_demangle_read_sname(ddata)); 3468a85fe12eSEd Maste 3469a85fe12eSEd Maste /* local source name */ 3470a85fe12eSEd Maste if (*ddata->cur == 'L') 3471a85fe12eSEd Maste return (cpp_demangle_local_source_name(ddata)); 3472a85fe12eSEd Maste 3473a85fe12eSEd Maste return (1); 3474a85fe12eSEd Maste } 3475a85fe12eSEd Maste 3476a85fe12eSEd Maste /* 3477a85fe12eSEd Maste * Read local source name. 3478a85fe12eSEd Maste * 3479a85fe12eSEd Maste * References: 3480a85fe12eSEd Maste * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 3481a85fe12eSEd Maste * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 3482a85fe12eSEd Maste */ 3483a85fe12eSEd Maste static int 3484a85fe12eSEd Maste cpp_demangle_local_source_name(struct cpp_demangle_data *ddata) 3485a85fe12eSEd Maste { 3486a85fe12eSEd Maste /* L */ 3487a85fe12eSEd Maste if (ddata == NULL || *ddata->cur != 'L') 3488a85fe12eSEd Maste return (0); 3489a85fe12eSEd Maste ++ddata->cur; 3490a85fe12eSEd Maste 3491a85fe12eSEd Maste /* source name */ 3492a85fe12eSEd Maste if (!cpp_demangle_read_sname(ddata)) 3493a85fe12eSEd Maste return (0); 3494a85fe12eSEd Maste 3495a85fe12eSEd Maste /* discriminator */ 3496a85fe12eSEd Maste if (*ddata->cur == '_') { 3497a85fe12eSEd Maste ++ddata->cur; 3498a85fe12eSEd Maste while (ELFTC_ISDIGIT(*ddata->cur) != 0) 3499a85fe12eSEd Maste ++ddata->cur; 3500a85fe12eSEd Maste } 3501a85fe12eSEd Maste 3502a85fe12eSEd Maste return (1); 3503a85fe12eSEd Maste } 3504a85fe12eSEd Maste 3505a85fe12eSEd Maste static int 3506a85fe12eSEd Maste cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata) 3507a85fe12eSEd Maste { 3508a85fe12eSEd Maste 3509a85fe12eSEd Maste if (ddata == NULL) 3510a85fe12eSEd Maste return (0); 3511a85fe12eSEd Maste 3512bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "offset : ")) 3513a85fe12eSEd Maste return (0); 3514a85fe12eSEd Maste 3515a85fe12eSEd Maste if (!cpp_demangle_read_offset_number(ddata)) 3516a85fe12eSEd Maste return (0); 3517a85fe12eSEd Maste 3518bee2765cSEd Maste if (!DEM_PUSH_STR(ddata, "virtual offset : ")) 3519a85fe12eSEd Maste return (0); 3520a85fe12eSEd Maste 3521a85fe12eSEd Maste return (!cpp_demangle_read_offset_number(ddata)); 3522a85fe12eSEd Maste } 3523a85fe12eSEd Maste 3524a85fe12eSEd Maste /* 3525a85fe12eSEd Maste * Decode floating point representation to string 3526a85fe12eSEd Maste * Return new allocated string or NULL 3527a85fe12eSEd Maste * 3528a85fe12eSEd Maste * Todo 3529a85fe12eSEd Maste * Replace these functions to macro. 3530a85fe12eSEd Maste */ 3531a85fe12eSEd Maste static char * 3532a85fe12eSEd Maste decode_fp_to_double(const char *p, size_t len) 3533a85fe12eSEd Maste { 3534a85fe12eSEd Maste double f; 3535a85fe12eSEd Maste size_t rtn_len, limit, i; 3536a85fe12eSEd Maste int byte; 3537a85fe12eSEd Maste char *rtn; 3538a85fe12eSEd Maste 3539a85fe12eSEd Maste if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double)) 3540a85fe12eSEd Maste return (NULL); 3541a85fe12eSEd Maste 3542a85fe12eSEd Maste memset(&f, 0, sizeof(double)); 3543a85fe12eSEd Maste 3544a85fe12eSEd Maste for (i = 0; i < len / 2; ++i) { 3545a85fe12eSEd Maste byte = hex_to_dec(p[len - i * 2 - 1]) + 3546a85fe12eSEd Maste hex_to_dec(p[len - i * 2 - 2]) * 16; 3547a85fe12eSEd Maste 3548a85fe12eSEd Maste if (byte < 0 || byte > 255) 3549a85fe12eSEd Maste return (NULL); 3550a85fe12eSEd Maste 3551a85fe12eSEd Maste #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3552a85fe12eSEd Maste ((unsigned char *)&f)[i] = (unsigned char)(byte); 3553a85fe12eSEd Maste #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3554a85fe12eSEd Maste ((unsigned char *)&f)[sizeof(double) - i - 1] = 3555a85fe12eSEd Maste (unsigned char)(byte); 3556a85fe12eSEd Maste #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3557a85fe12eSEd Maste } 3558a85fe12eSEd Maste 3559a85fe12eSEd Maste rtn_len = 64; 3560a85fe12eSEd Maste limit = 0; 3561a85fe12eSEd Maste again: 3562a85fe12eSEd Maste if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3563a85fe12eSEd Maste return (NULL); 3564a85fe12eSEd Maste 3565a85fe12eSEd Maste if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) { 3566a85fe12eSEd Maste free(rtn); 3567a85fe12eSEd Maste if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3568a85fe12eSEd Maste return (NULL); 3569a85fe12eSEd Maste rtn_len *= BUFFER_GROWFACTOR; 3570a85fe12eSEd Maste goto again; 3571a85fe12eSEd Maste } 3572a85fe12eSEd Maste 3573a85fe12eSEd Maste return rtn; 3574a85fe12eSEd Maste } 3575a85fe12eSEd Maste 3576a85fe12eSEd Maste static char * 3577a85fe12eSEd Maste decode_fp_to_float(const char *p, size_t len) 3578a85fe12eSEd Maste { 3579a85fe12eSEd Maste size_t i, rtn_len, limit; 3580a85fe12eSEd Maste float f; 3581a85fe12eSEd Maste int byte; 3582a85fe12eSEd Maste char *rtn; 3583a85fe12eSEd Maste 3584a85fe12eSEd Maste if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float)) 3585a85fe12eSEd Maste return (NULL); 3586a85fe12eSEd Maste 3587a85fe12eSEd Maste memset(&f, 0, sizeof(float)); 3588a85fe12eSEd Maste 3589a85fe12eSEd Maste for (i = 0; i < len / 2; ++i) { 3590a85fe12eSEd Maste byte = hex_to_dec(p[len - i * 2 - 1]) + 3591a85fe12eSEd Maste hex_to_dec(p[len - i * 2 - 2]) * 16; 3592a85fe12eSEd Maste if (byte < 0 || byte > 255) 3593a85fe12eSEd Maste return (NULL); 3594a85fe12eSEd Maste #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3595a85fe12eSEd Maste ((unsigned char *)&f)[i] = (unsigned char)(byte); 3596a85fe12eSEd Maste #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3597a85fe12eSEd Maste ((unsigned char *)&f)[sizeof(float) - i - 1] = 3598a85fe12eSEd Maste (unsigned char)(byte); 3599a85fe12eSEd Maste #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3600a85fe12eSEd Maste } 3601a85fe12eSEd Maste 3602a85fe12eSEd Maste rtn_len = 64; 3603a85fe12eSEd Maste limit = 0; 3604a85fe12eSEd Maste again: 3605a85fe12eSEd Maste if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3606a85fe12eSEd Maste return (NULL); 3607a85fe12eSEd Maste 3608a85fe12eSEd Maste if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) { 3609a85fe12eSEd Maste free(rtn); 3610a85fe12eSEd Maste if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3611a85fe12eSEd Maste return (NULL); 3612a85fe12eSEd Maste rtn_len *= BUFFER_GROWFACTOR; 3613a85fe12eSEd Maste goto again; 3614a85fe12eSEd Maste } 3615a85fe12eSEd Maste 3616a85fe12eSEd Maste return rtn; 3617a85fe12eSEd Maste } 3618a85fe12eSEd Maste 3619a85fe12eSEd Maste static char * 3620a85fe12eSEd Maste decode_fp_to_float128(const char *p, size_t len) 3621a85fe12eSEd Maste { 3622a85fe12eSEd Maste long double f; 3623a85fe12eSEd Maste size_t rtn_len, limit, i; 3624a85fe12eSEd Maste int byte; 3625a85fe12eSEd Maste unsigned char buf[FLOAT_QUADRUPLE_BYTES]; 3626a85fe12eSEd Maste char *rtn; 3627a85fe12eSEd Maste 3628a85fe12eSEd Maste switch(sizeof(long double)) { 3629a85fe12eSEd Maste case FLOAT_QUADRUPLE_BYTES: 3630a85fe12eSEd Maste return (decode_fp_to_long_double(p, len)); 3631a85fe12eSEd Maste case FLOAT_EXTENED_BYTES: 3632a85fe12eSEd Maste if (p == NULL || len == 0 || len % 2 != 0 || 3633a85fe12eSEd Maste len / 2 > FLOAT_QUADRUPLE_BYTES) 3634a85fe12eSEd Maste return (NULL); 3635a85fe12eSEd Maste 3636a85fe12eSEd Maste memset(buf, 0, FLOAT_QUADRUPLE_BYTES); 3637a85fe12eSEd Maste 3638a85fe12eSEd Maste for (i = 0; i < len / 2; ++i) { 3639a85fe12eSEd Maste byte = hex_to_dec(p[len - i * 2 - 1]) + 3640a85fe12eSEd Maste hex_to_dec(p[len - i * 2 - 2]) * 16; 3641a85fe12eSEd Maste if (byte < 0 || byte > 255) 3642a85fe12eSEd Maste return (NULL); 3643a85fe12eSEd Maste #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3644a85fe12eSEd Maste buf[i] = (unsigned char)(byte); 3645a85fe12eSEd Maste #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3646a85fe12eSEd Maste buf[FLOAT_QUADRUPLE_BYTES - i -1] = 3647a85fe12eSEd Maste (unsigned char)(byte); 3648a85fe12eSEd Maste #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3649a85fe12eSEd Maste } 3650a85fe12eSEd Maste memset(&f, 0, FLOAT_EXTENED_BYTES); 3651a85fe12eSEd Maste 3652a85fe12eSEd Maste #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3653a85fe12eSEd Maste memcpy(&f, buf, FLOAT_EXTENED_BYTES); 3654a85fe12eSEd Maste #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3655a85fe12eSEd Maste memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES); 3656a85fe12eSEd Maste #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3657a85fe12eSEd Maste 3658a85fe12eSEd Maste rtn_len = 256; 3659a85fe12eSEd Maste limit = 0; 3660a85fe12eSEd Maste again: 3661a85fe12eSEd Maste if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3662a85fe12eSEd Maste return (NULL); 3663a85fe12eSEd Maste 3664a85fe12eSEd Maste if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3665a85fe12eSEd Maste free(rtn); 3666a85fe12eSEd Maste if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3667a85fe12eSEd Maste return (NULL); 3668a85fe12eSEd Maste rtn_len *= BUFFER_GROWFACTOR; 3669a85fe12eSEd Maste goto again; 3670a85fe12eSEd Maste } 3671a85fe12eSEd Maste 3672a85fe12eSEd Maste return (rtn); 3673a85fe12eSEd Maste default: 3674a85fe12eSEd Maste return (NULL); 3675a85fe12eSEd Maste } 3676a85fe12eSEd Maste } 3677a85fe12eSEd Maste 3678a85fe12eSEd Maste static char * 3679a85fe12eSEd Maste decode_fp_to_float80(const char *p, size_t len) 3680a85fe12eSEd Maste { 3681a85fe12eSEd Maste long double f; 3682a85fe12eSEd Maste size_t rtn_len, limit, i; 3683a85fe12eSEd Maste int byte; 3684a85fe12eSEd Maste unsigned char buf[FLOAT_EXTENED_BYTES]; 3685a85fe12eSEd Maste char *rtn; 3686a85fe12eSEd Maste 3687a85fe12eSEd Maste switch(sizeof(long double)) { 3688a85fe12eSEd Maste case FLOAT_QUADRUPLE_BYTES: 3689a85fe12eSEd Maste if (p == NULL || len == 0 || len % 2 != 0 || 3690a85fe12eSEd Maste len / 2 > FLOAT_EXTENED_BYTES) 3691a85fe12eSEd Maste return (NULL); 3692a85fe12eSEd Maste 3693a85fe12eSEd Maste memset(buf, 0, FLOAT_EXTENED_BYTES); 3694a85fe12eSEd Maste 3695a85fe12eSEd Maste for (i = 0; i < len / 2; ++i) { 3696a85fe12eSEd Maste byte = hex_to_dec(p[len - i * 2 - 1]) + 3697a85fe12eSEd Maste hex_to_dec(p[len - i * 2 - 2]) * 16; 3698a85fe12eSEd Maste 3699a85fe12eSEd Maste if (byte < 0 || byte > 255) 3700a85fe12eSEd Maste return (NULL); 3701a85fe12eSEd Maste 3702a85fe12eSEd Maste #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3703a85fe12eSEd Maste buf[i] = (unsigned char)(byte); 3704a85fe12eSEd Maste #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3705a85fe12eSEd Maste buf[FLOAT_EXTENED_BYTES - i -1] = 3706a85fe12eSEd Maste (unsigned char)(byte); 3707a85fe12eSEd Maste #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3708a85fe12eSEd Maste } 3709a85fe12eSEd Maste 3710a85fe12eSEd Maste memset(&f, 0, FLOAT_QUADRUPLE_BYTES); 3711a85fe12eSEd Maste 3712a85fe12eSEd Maste #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3713a85fe12eSEd Maste memcpy(&f, buf, FLOAT_EXTENED_BYTES); 3714a85fe12eSEd Maste #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3715a85fe12eSEd Maste memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES); 3716a85fe12eSEd Maste #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3717a85fe12eSEd Maste 3718a85fe12eSEd Maste rtn_len = 256; 3719a85fe12eSEd Maste limit = 0; 3720a85fe12eSEd Maste again: 3721a85fe12eSEd Maste if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3722a85fe12eSEd Maste return (NULL); 3723a85fe12eSEd Maste 3724a85fe12eSEd Maste if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3725a85fe12eSEd Maste free(rtn); 3726a85fe12eSEd Maste if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3727a85fe12eSEd Maste return (NULL); 3728a85fe12eSEd Maste rtn_len *= BUFFER_GROWFACTOR; 3729a85fe12eSEd Maste goto again; 3730a85fe12eSEd Maste } 3731a85fe12eSEd Maste 3732a85fe12eSEd Maste return (rtn); 3733a85fe12eSEd Maste case FLOAT_EXTENED_BYTES: 3734a85fe12eSEd Maste return (decode_fp_to_long_double(p, len)); 3735a85fe12eSEd Maste default: 3736a85fe12eSEd Maste return (NULL); 3737a85fe12eSEd Maste } 3738a85fe12eSEd Maste } 3739a85fe12eSEd Maste 3740a85fe12eSEd Maste static char * 3741a85fe12eSEd Maste decode_fp_to_long_double(const char *p, size_t len) 3742a85fe12eSEd Maste { 3743a85fe12eSEd Maste long double f; 3744a85fe12eSEd Maste size_t rtn_len, limit, i; 3745a85fe12eSEd Maste int byte; 3746a85fe12eSEd Maste char *rtn; 3747a85fe12eSEd Maste 3748a85fe12eSEd Maste if (p == NULL || len == 0 || len % 2 != 0 || 3749a85fe12eSEd Maste len / 2 > sizeof(long double)) 3750a85fe12eSEd Maste return (NULL); 3751a85fe12eSEd Maste 3752a85fe12eSEd Maste memset(&f, 0, sizeof(long double)); 3753a85fe12eSEd Maste 3754a85fe12eSEd Maste for (i = 0; i < len / 2; ++i) { 3755a85fe12eSEd Maste byte = hex_to_dec(p[len - i * 2 - 1]) + 3756a85fe12eSEd Maste hex_to_dec(p[len - i * 2 - 2]) * 16; 3757a85fe12eSEd Maste 3758a85fe12eSEd Maste if (byte < 0 || byte > 255) 3759a85fe12eSEd Maste return (NULL); 3760a85fe12eSEd Maste 3761a85fe12eSEd Maste #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3762a85fe12eSEd Maste ((unsigned char *)&f)[i] = (unsigned char)(byte); 3763a85fe12eSEd Maste #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3764a85fe12eSEd Maste ((unsigned char *)&f)[sizeof(long double) - i - 1] = 3765a85fe12eSEd Maste (unsigned char)(byte); 3766a85fe12eSEd Maste #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3767a85fe12eSEd Maste } 3768a85fe12eSEd Maste 3769a85fe12eSEd Maste rtn_len = 256; 3770a85fe12eSEd Maste limit = 0; 3771a85fe12eSEd Maste again: 3772a85fe12eSEd Maste if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3773a85fe12eSEd Maste return (NULL); 3774a85fe12eSEd Maste 3775a85fe12eSEd Maste if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3776a85fe12eSEd Maste free(rtn); 3777a85fe12eSEd Maste if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3778a85fe12eSEd Maste return (NULL); 3779a85fe12eSEd Maste rtn_len *= BUFFER_GROWFACTOR; 3780a85fe12eSEd Maste goto again; 3781a85fe12eSEd Maste } 3782a85fe12eSEd Maste 3783a85fe12eSEd Maste return (rtn); 3784a85fe12eSEd Maste } 3785a85fe12eSEd Maste 3786a85fe12eSEd Maste /* Simple hex to integer function used by decode_to_* function. */ 3787a85fe12eSEd Maste static int 3788a85fe12eSEd Maste hex_to_dec(char c) 3789a85fe12eSEd Maste { 3790a85fe12eSEd Maste 3791a85fe12eSEd Maste switch (c) { 3792a85fe12eSEd Maste case '0': 3793a85fe12eSEd Maste return (0); 3794a85fe12eSEd Maste case '1': 3795a85fe12eSEd Maste return (1); 3796a85fe12eSEd Maste case '2': 3797a85fe12eSEd Maste return (2); 3798a85fe12eSEd Maste case '3': 3799a85fe12eSEd Maste return (3); 3800a85fe12eSEd Maste case '4': 3801a85fe12eSEd Maste return (4); 3802a85fe12eSEd Maste case '5': 3803a85fe12eSEd Maste return (5); 3804a85fe12eSEd Maste case '6': 3805a85fe12eSEd Maste return (6); 3806a85fe12eSEd Maste case '7': 3807a85fe12eSEd Maste return (7); 3808a85fe12eSEd Maste case '8': 3809a85fe12eSEd Maste return (8); 3810a85fe12eSEd Maste case '9': 3811a85fe12eSEd Maste return (9); 3812a85fe12eSEd Maste case 'a': 3813a85fe12eSEd Maste return (10); 3814a85fe12eSEd Maste case 'b': 3815a85fe12eSEd Maste return (11); 3816a85fe12eSEd Maste case 'c': 3817a85fe12eSEd Maste return (12); 3818a85fe12eSEd Maste case 'd': 3819a85fe12eSEd Maste return (13); 3820a85fe12eSEd Maste case 'e': 3821a85fe12eSEd Maste return (14); 3822a85fe12eSEd Maste case 'f': 3823a85fe12eSEd Maste return (15); 3824a85fe12eSEd Maste default: 3825a85fe12eSEd Maste return (-1); 3826b6b6f9ccSEd Maste } 3827a85fe12eSEd Maste } 3828a85fe12eSEd Maste 3829a85fe12eSEd Maste /** 3830a85fe12eSEd Maste * @brief Test input string is mangled by IA-64 C++ ABI style. 3831a85fe12eSEd Maste * 3832a85fe12eSEd Maste * Test string heads with "_Z" or "_GLOBAL__I_". 3833a85fe12eSEd Maste * @return Return 0 at false. 3834a85fe12eSEd Maste */ 3835a85fe12eSEd Maste bool 3836a85fe12eSEd Maste is_cpp_mangled_gnu3(const char *org) 3837a85fe12eSEd Maste { 3838a85fe12eSEd Maste size_t len; 3839a85fe12eSEd Maste 3840a85fe12eSEd Maste len = strlen(org); 3841a85fe12eSEd Maste return ((len > 2 && *org == '_' && *(org + 1) == 'Z') || 3842a85fe12eSEd Maste (len > 11 && !strncmp(org, "_GLOBAL__I_", 11))); 3843a85fe12eSEd Maste } 3844a85fe12eSEd Maste 3845a85fe12eSEd Maste static void 3846a85fe12eSEd Maste vector_read_cmd_dest(struct vector_read_cmd *v) 3847a85fe12eSEd Maste { 3848a85fe12eSEd Maste 3849a85fe12eSEd Maste if (v == NULL) 3850a85fe12eSEd Maste return; 3851a85fe12eSEd Maste 3852a85fe12eSEd Maste free(v->r_container); 3853a85fe12eSEd Maste } 3854a85fe12eSEd Maste 385518f4c9dbSEd Maste static struct read_cmd_item * 3856a85fe12eSEd Maste vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst) 3857a85fe12eSEd Maste { 385818f4c9dbSEd Maste int i; 3859a85fe12eSEd Maste 3860a85fe12eSEd Maste if (v == NULL || dst == READ_FAIL) 386118f4c9dbSEd Maste return (NULL); 3862a85fe12eSEd Maste 386318f4c9dbSEd Maste for (i = (int) v->size - 1; i >= 0; i--) 386418f4c9dbSEd Maste if (v->r_container[i].cmd == dst) 386518f4c9dbSEd Maste return (&v->r_container[i]); 3866a85fe12eSEd Maste 386718f4c9dbSEd Maste return (NULL); 3868a85fe12eSEd Maste } 3869a85fe12eSEd Maste 3870a85fe12eSEd Maste static int 3871a85fe12eSEd Maste vector_read_cmd_init(struct vector_read_cmd *v) 3872a85fe12eSEd Maste { 3873a85fe12eSEd Maste 3874a85fe12eSEd Maste if (v == NULL) 3875a85fe12eSEd Maste return (0); 3876a85fe12eSEd Maste 3877a85fe12eSEd Maste v->size = 0; 3878a85fe12eSEd Maste v->capacity = VECTOR_DEF_CAPACITY; 3879a85fe12eSEd Maste 388018f4c9dbSEd Maste if ((v->r_container = malloc(sizeof(*v->r_container) * v->capacity)) 3881a85fe12eSEd Maste == NULL) 3882a85fe12eSEd Maste return (0); 3883a85fe12eSEd Maste 3884a85fe12eSEd Maste return (1); 3885a85fe12eSEd Maste } 3886a85fe12eSEd Maste 3887a85fe12eSEd Maste static int 3888a85fe12eSEd Maste vector_read_cmd_pop(struct vector_read_cmd *v) 3889a85fe12eSEd Maste { 3890a85fe12eSEd Maste 3891a85fe12eSEd Maste if (v == NULL || v->size == 0) 3892a85fe12eSEd Maste return (0); 3893a85fe12eSEd Maste 3894a85fe12eSEd Maste --v->size; 389518f4c9dbSEd Maste v->r_container[v->size].cmd = READ_FAIL; 389618f4c9dbSEd Maste v->r_container[v->size].data = NULL; 3897a85fe12eSEd Maste 3898a85fe12eSEd Maste return (1); 3899a85fe12eSEd Maste } 3900a85fe12eSEd Maste 3901a85fe12eSEd Maste static int 390218f4c9dbSEd Maste vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd, void *data) 3903a85fe12eSEd Maste { 390418f4c9dbSEd Maste struct read_cmd_item *tmp_r_ctn; 3905a85fe12eSEd Maste size_t tmp_cap; 3906a85fe12eSEd Maste size_t i; 3907a85fe12eSEd Maste 3908a85fe12eSEd Maste if (v == NULL) 3909a85fe12eSEd Maste return (0); 3910a85fe12eSEd Maste 3911a85fe12eSEd Maste if (v->size == v->capacity) { 3912c2bffd0aSDimitry Andric tmp_cap = BUFFER_GROW(v->capacity); 391318f4c9dbSEd Maste if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL) 3914a85fe12eSEd Maste return (0); 3915a85fe12eSEd Maste for (i = 0; i < v->size; ++i) 3916a85fe12eSEd Maste tmp_r_ctn[i] = v->r_container[i]; 3917a85fe12eSEd Maste free(v->r_container); 3918a85fe12eSEd Maste v->r_container = tmp_r_ctn; 3919a85fe12eSEd Maste v->capacity = tmp_cap; 3920a85fe12eSEd Maste } 3921a85fe12eSEd Maste 392218f4c9dbSEd Maste v->r_container[v->size].cmd = cmd; 392318f4c9dbSEd Maste v->r_container[v->size].data = data; 3924a85fe12eSEd Maste ++v->size; 3925a85fe12eSEd Maste 3926a85fe12eSEd Maste return (1); 3927a85fe12eSEd Maste } 3928a85fe12eSEd Maste 3929a85fe12eSEd Maste static void 3930a85fe12eSEd Maste vector_type_qualifier_dest(struct vector_type_qualifier *v) 3931a85fe12eSEd Maste { 3932a85fe12eSEd Maste 3933a85fe12eSEd Maste if (v == NULL) 3934a85fe12eSEd Maste return; 3935a85fe12eSEd Maste 3936a85fe12eSEd Maste free(v->q_container); 3937a85fe12eSEd Maste vector_str_dest(&v->ext_name); 3938a85fe12eSEd Maste } 3939a85fe12eSEd Maste 3940a85fe12eSEd Maste /* size, capacity, ext_name */ 3941a85fe12eSEd Maste static int 3942a85fe12eSEd Maste vector_type_qualifier_init(struct vector_type_qualifier *v) 3943a85fe12eSEd Maste { 3944a85fe12eSEd Maste 3945a85fe12eSEd Maste if (v == NULL) 3946a85fe12eSEd Maste return (0); 3947a85fe12eSEd Maste 3948a85fe12eSEd Maste v->size = 0; 3949a85fe12eSEd Maste v->capacity = VECTOR_DEF_CAPACITY; 3950a85fe12eSEd Maste 3951a85fe12eSEd Maste if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity)) 3952a85fe12eSEd Maste == NULL) 3953a85fe12eSEd Maste return (0); 3954a85fe12eSEd Maste 3955a85fe12eSEd Maste assert(v->q_container != NULL); 3956a85fe12eSEd Maste 3957334f09a6SMark Johnston if (!vector_str_init(&v->ext_name)) { 3958a85fe12eSEd Maste free(v->q_container); 3959a85fe12eSEd Maste return (0); 3960a85fe12eSEd Maste } 3961a85fe12eSEd Maste 3962a85fe12eSEd Maste return (1); 3963a85fe12eSEd Maste } 3964a85fe12eSEd Maste 3965a85fe12eSEd Maste static int 3966a85fe12eSEd Maste vector_type_qualifier_push(struct vector_type_qualifier *v, 3967a85fe12eSEd Maste enum type_qualifier t) 3968a85fe12eSEd Maste { 3969a85fe12eSEd Maste enum type_qualifier *tmp_ctn; 3970a85fe12eSEd Maste size_t tmp_cap; 3971a85fe12eSEd Maste size_t i; 3972a85fe12eSEd Maste 3973a85fe12eSEd Maste if (v == NULL) 3974a85fe12eSEd Maste return (0); 3975a85fe12eSEd Maste 3976a85fe12eSEd Maste if (v->size == v->capacity) { 3977c2bffd0aSDimitry Andric tmp_cap = BUFFER_GROW(v->capacity); 3978a85fe12eSEd Maste if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap)) 3979a85fe12eSEd Maste == NULL) 3980a85fe12eSEd Maste return (0); 3981a85fe12eSEd Maste for (i = 0; i < v->size; ++i) 3982a85fe12eSEd Maste tmp_ctn[i] = v->q_container[i]; 3983a85fe12eSEd Maste free(v->q_container); 3984a85fe12eSEd Maste v->q_container = tmp_ctn; 3985a85fe12eSEd Maste v->capacity = tmp_cap; 3986a85fe12eSEd Maste } 3987a85fe12eSEd Maste 3988a85fe12eSEd Maste v->q_container[v->size] = t; 3989a85fe12eSEd Maste ++v->size; 3990a85fe12eSEd Maste 3991a85fe12eSEd Maste return (1); 3992a85fe12eSEd Maste } 3993