2 * Copyright (c) 2008 Hyogeol Lee <hyogeollee@gmail.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/types.h>
38 #include "_libelftc.h"
40 ELFTC_VCSID("$Id: libelftc_dem_gnu2.c 3513 2016-12-29 07:04:22Z kaiwang27 $");
43 * @file cpp_demangle_gnu2.c
44 * @brief Decode function name encoding in GNU 2.
46 * Function name encoding in GNU 2 based on ARM style.
50 ENCODE_FUNC, ENCODE_OP, ENCODE_OP_CT, ENCODE_OP_DT, ENCODE_OP_USER,
51 ENCODE_OP_TF, ENCODE_OP_TI, ENCODE_OP_VT
59 struct demangle_data {
60 bool ptr, ref, cnst, array, cnst_fn, class_name;
61 struct cstring array_str;
63 enum encode_type type;
64 struct vector_str vec;
65 struct vector_str arg;
68 #define SIMPLE_HASH(x,y) (64 * x + y)
69 #define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s)))
70 #define CPP_DEMANGLE_GNU2_TRY 128
72 static void dest_cstring(struct cstring *);
73 static void dest_demangle_data(struct demangle_data *);
74 static bool init_cstring(struct cstring *, size_t);
75 static bool init_demangle_data(struct demangle_data *);
76 static bool push_CTDT(const char *, size_t, struct vector_str *);
77 static bool read_array(struct demangle_data *);
78 static bool read_class(struct demangle_data *);
79 static bool read_func(struct demangle_data *);
80 static bool read_func_name(struct demangle_data *);
81 static bool read_func_ptr(struct demangle_data *);
82 static bool read_memptr(struct demangle_data *);
83 static bool read_op(struct demangle_data *);
84 static bool read_op_user(struct demangle_data *);
85 static bool read_qual_name(struct demangle_data *);
86 static int read_subst(struct demangle_data *);
87 static int read_subst_iter(struct demangle_data *);
88 static bool read_type(struct demangle_data *);
91 * @brief Decode the input string by the GNU 2 style.
93 * @return New allocated demangled string or NULL if failed.
96 cpp_demangle_gnu2(const char *org)
98 struct demangle_data d;
99 size_t arg_begin, arg_len;
106 if (init_demangle_data(&d) == false)
113 if (read_func_name(&d) == false)
122 if (push_CTDT("::", 2, &d.vec) == false)
127 if (push_CTDT("::~", 3, &d.vec) == false)
130 if (VEC_PUSH_STR(&d.vec, "(void)") == false)
134 case ENCODE_OP_USER :
143 else if (*d.p == '\0') {
144 if (d.class_name == true) {
145 if (VEC_PUSH_STR(&d.vec, "(void)") == false)
153 /* start argument types */
154 if (VEC_PUSH_STR(&d.vec, "(") == false)
159 const int rtn_subst = read_subst(&d);
163 else if (rtn_subst == 1)
170 const int rtn_subst_iter = read_subst_iter(&d);
172 if (rtn_subst_iter == -1)
174 else if(rtn_subst_iter == 1)
180 arg_begin = d.vec.size;
182 if (read_type(&d) == false)
186 if (VEC_PUSH_STR(&d.vec, "*") == false)
193 if (VEC_PUSH_STR(&d.vec, "&") == false)
199 if (d.cnst == true) {
200 if (VEC_PUSH_STR(&d.vec, " const") == false)
206 if (d.array == true) {
207 if (vector_str_push(&d.vec, d.array_str.buf,
208 d.array_str.size) == false)
211 dest_cstring(&d.array_str);
218 if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1,
222 if (vector_str_push(&d.arg, arg, arg_len) == false) {
229 if (VEC_PUSH_STR(&d.vec, ", ") == false)
232 if (++try > CPP_DEMANGLE_GNU2_TRY)
236 /* end argument types */
237 if (VEC_PUSH_STR(&d.vec, ")") == false)
240 if (d.cnst_fn == true && VEC_PUSH_STR(&d.vec, " const") == false)
243 rtn = vector_str_get_flat(&d.vec, NULL);
245 dest_demangle_data(&d);
251 * @brief Test input string is encoded by the GNU 2 style.
253 * @return True if input string is encoded by the GNU 2 style.
256 is_cpp_mangled_gnu2(const char *org)
264 /* search valid text to end */
265 str = strstr(org, "__");
266 while (str != NULL) {
267 if (*(str + 2) != '\0') {
268 if (*(str + 2) == 'C' ||
271 ELFTC_ISDIGIT(*(str + 2))) {
277 if (*(str + 3) != '\0') {
278 switch (SIMPLE_HASH(*(str + 2), *(str + 3))) {
279 case SIMPLE_HASH('m', 'l') :
280 case SIMPLE_HASH('d', 'v') :
281 case SIMPLE_HASH('m', 'd') :
282 case SIMPLE_HASH('p', 'l') :
283 case SIMPLE_HASH('m', 'i') :
284 case SIMPLE_HASH('l', 's') :
285 case SIMPLE_HASH('r', 's') :
286 case SIMPLE_HASH('e', 'q') :
287 case SIMPLE_HASH('n', 'e') :
288 case SIMPLE_HASH('l', 't') :
289 case SIMPLE_HASH('g', 't') :
290 case SIMPLE_HASH('l', 'e') :
291 case SIMPLE_HASH('g', 'e') :
292 case SIMPLE_HASH('a', 'd') :
293 case SIMPLE_HASH('o', 'r') :
294 case SIMPLE_HASH('e', 'r') :
295 case SIMPLE_HASH('a', 'a') :
296 case SIMPLE_HASH('o', 'o') :
297 case SIMPLE_HASH('n', 't') :
298 case SIMPLE_HASH('c', 'o') :
299 case SIMPLE_HASH('p', 'p') :
300 case SIMPLE_HASH('m', 'm') :
301 case SIMPLE_HASH('a', 's') :
302 case SIMPLE_HASH('r', 'f') :
303 case SIMPLE_HASH('a', 'p') :
304 case SIMPLE_HASH('a', 'm') :
305 case SIMPLE_HASH('a', 'l') :
306 case SIMPLE_HASH('a', 'r') :
307 case SIMPLE_HASH('a', 'o') :
308 case SIMPLE_HASH('a', 'e') :
309 case SIMPLE_HASH('c', 'm') :
310 case SIMPLE_HASH('r', 'm') :
311 case SIMPLE_HASH('c', 'l') :
312 case SIMPLE_HASH('v', 'c') :
313 case SIMPLE_HASH('n', 'w') :
314 case SIMPLE_HASH('d', 'l') :
315 case SIMPLE_HASH('o', 'p') :
316 case SIMPLE_HASH('t', 'f') :
317 case SIMPLE_HASH('t', 'i') :
325 str = strstr(str + 2, "__");
328 rtn |= strstr(org, "_$_") != NULL;
329 rtn |= strstr(org, "_vt$") != NULL;
335 dest_cstring(struct cstring *s)
347 dest_demangle_data(struct demangle_data *d)
351 vector_str_dest(&d->arg);
352 vector_str_dest(&d->vec);
354 dest_cstring(&d->array_str);
359 init_cstring(struct cstring *s, size_t len)
362 if (s == NULL || len <= 1)
365 if ((s->buf = malloc(sizeof(char) * len)) == NULL)
374 init_demangle_data(struct demangle_data *d)
385 d->class_name = false;
387 d->array_str.buf = NULL;
388 d->array_str.size = 0;
390 d->type = ENCODE_FUNC;
392 if (!vector_str_init(&d->vec))
395 if (!vector_str_init(&d->arg)) {
396 vector_str_dest(&d->vec);
404 push_CTDT(const char *s, size_t l, struct vector_str *v)
407 if (s == NULL || l == 0 || v == NULL)
410 if (vector_str_push(v, s, l) == false)
415 return (VEC_PUSH_STR(v, v->container[v->size - 2]));
419 read_array(struct demangle_data *d)
424 if (d == NULL || d->p == NULL)
434 if (ELFTC_ISDIGIT(*end) == 0)
446 dest_cstring(&d->array_str);
447 if (init_cstring(&d->array_str, len + 3) == false)
450 strncpy(d->array_str.buf + 1, d->p, len);
451 *d->array_str.buf = '[';
452 *(d->array_str.buf + len + 1) = ']';
461 read_class(struct demangle_data *d)
469 len = strtol(d->p, &str, 10);
470 if (len == 0 && (errno == EINVAL || errno == ERANGE))
476 if (vector_str_push(&d->vec, str, len) == false)
481 d->class_name = true;
487 read_func(struct demangle_data *d)
496 assert(d->p != NULL && "d->p (org str) is NULL");
497 if ((delim = strstr(d->p, "__")) == NULL)
513 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
516 if (read_qual_name(d) == false)
518 } else if (ELFTC_ISDIGIT(*d->p)) {
519 if (read_class(d) == false)
522 if (VEC_PUSH_STR(&d->vec, "::") == false)
526 return (vector_str_push(&d->vec, name, len));
530 read_func_name(struct demangle_data *d)
542 assert(d->p != NULL && "d->p (org str) is NULL");
544 if (*d->p == '_' && *(d->p + 1) == '_') {
548 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
550 d->type = ENCODE_OP_CT;
552 if (read_qual_name(d) == false)
555 return (vector_str_pop(&d->vec));
556 } else if (ELFTC_ISDIGIT(*d->p)) {
557 d->type = ENCODE_OP_CT;
559 return (read_class(d));
563 if (read_op(d) == false) {
564 /* not good condition, start function name with '__' */
565 d->type = ENCODE_FUNC;
567 if (VEC_PUSH_STR(&d->vec, "__") == false)
570 return (read_func(d));
573 if (d->type == ENCODE_OP_USER ||
574 d->type == ENCODE_OP_TF ||
575 d->type == ENCODE_OP_TI)
587 /* assume delimiter is removed */
588 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
591 assert(d->vec.size > 0);
593 len = strlen(d->vec.container[d->vec.size - 1]);
594 if ((op_name = malloc(sizeof(char) * (len + 1)))
598 snprintf(op_name, len + 1, "%s",
599 d->vec.container[d->vec.size - 1]);
600 vector_str_pop(&d->vec);
602 if (read_qual_name(d) == false)
605 if (VEC_PUSH_STR(&d->vec, "::") == false)
608 if (vector_str_push(&d->vec, op_name, len) == false)
612 } else if (ELFTC_ISDIGIT(*d->p)) {
613 assert(d->vec.size > 0);
615 len = strlen(d->vec.container[d->vec.size - 1]);
616 if ((op_name = malloc(sizeof(char) * (len + 1)))
620 snprintf(op_name, len + 1, "%s",
621 d->vec.container[d->vec.size - 1]);
622 vector_str_pop(&d->vec);
624 if (read_class(d) == false)
627 if (VEC_PUSH_STR(&d->vec, "::") == false)
630 if (vector_str_push(&d->vec, op_name, len) == false)
635 } else if (memcmp(d->p, "_$_", 3) == 0) {
638 d->type = ENCODE_OP_DT;
640 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
643 if (read_qual_name(d) == false)
646 return (vector_str_pop(&d->vec));
647 } else if (ELFTC_ISDIGIT(*d->p))
648 return (read_class(d));
651 } else if (memcmp(d->p, "_vt$", 4) == 0) {
654 d->type = ENCODE_OP_VT;
656 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
659 if (read_qual_name(d) == false)
662 if (vector_str_pop(&d->vec) == false)
664 } else if (ELFTC_ISDIGIT(*d->p)) {
665 if (read_class(d) == false)
669 return (VEC_PUSH_STR(&d->vec, " virtual table"));
671 return (read_func(d));
678 /* Read function ptr type */
680 read_func_ptr(struct demangle_data *d)
682 struct demangle_data fptr;
683 size_t arg_len, rtn_len;
684 char *arg_type, *rtn_type;
690 if (init_demangle_data(&fptr) == false)
699 if (read_type(&fptr) == false) {
700 dest_demangle_data(&fptr);
705 if (fptr.ptr == true) {
706 if (VEC_PUSH_STR(&fptr.vec, "*") == false) {
707 dest_demangle_data(&fptr);
715 if (fptr.ref == true) {
716 if (VEC_PUSH_STR(&fptr.vec, "&") == false) {
717 dest_demangle_data(&fptr);
725 if (fptr.cnst == true) {
726 if (VEC_PUSH_STR(&fptr.vec, " const") == false) {
727 dest_demangle_data(&fptr);
738 if (VEC_PUSH_STR(&fptr.vec, ", ") == false) {
739 dest_demangle_data(&fptr);
744 if (++lim > CPP_DEMANGLE_GNU2_TRY) {
746 dest_demangle_data(&fptr);
752 arg_type = vector_str_get_flat(&fptr.vec, &arg_len);
756 dest_demangle_data(&fptr);
758 if (init_demangle_data(&fptr) == false) {
767 if (read_type(&fptr) == false) {
769 dest_demangle_data(&fptr);
774 rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len);
778 dest_demangle_data(&fptr);
780 if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) {
789 if (VEC_PUSH_STR(&d->vec, " (*)(") == false) {
795 if (vector_str_push(&d->vec, arg_type, arg_len) == false) {
803 return (VEC_PUSH_STR(&d->vec, ")"));
807 read_memptr(struct demangle_data *d)
809 struct demangle_data mptr;
814 if (d == NULL || d->p == NULL)
817 if (init_demangle_data(&mptr) == false)
824 if (*mptr.p == 'Q') {
827 if (read_qual_name(&mptr) == false)
829 } else if (read_class(&mptr) == false)
834 if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL)
837 if (vector_str_push(&d->vec, mptr_str, len) == false)
840 if (VEC_PUSH_STR(&d->vec, "::*") == false)
846 dest_demangle_data(&mptr);
852 read_op(struct demangle_data *d)
858 assert(d->p != NULL && "d->p (org str) is NULL");
860 switch (SIMPLE_HASH(*(d->p), *(d->p+1))) {
861 case SIMPLE_HASH('m', 'l') :
863 return (VEC_PUSH_STR(&d->vec, "operator*"));
864 case SIMPLE_HASH('d', 'v') :
866 return (VEC_PUSH_STR(&d->vec, "operator/"));
867 case SIMPLE_HASH('m', 'd') :
869 return (VEC_PUSH_STR(&d->vec, "operator%"));
870 case SIMPLE_HASH('p', 'l') :
872 return (VEC_PUSH_STR(&d->vec, "operator+"));
873 case SIMPLE_HASH('m', 'i') :
875 return (VEC_PUSH_STR(&d->vec, "operator-"));
876 case SIMPLE_HASH('l', 's') :
878 return (VEC_PUSH_STR(&d->vec, "operator<<"));
879 case SIMPLE_HASH('r', 's') :
881 return (VEC_PUSH_STR(&d->vec, "operator>>"));
882 case SIMPLE_HASH('e', 'q') :
884 return (VEC_PUSH_STR(&d->vec, "operator=="));
885 case SIMPLE_HASH('n', 'e') :
887 return (VEC_PUSH_STR(&d->vec, "operator!="));
888 case SIMPLE_HASH('l', 't') :
890 return (VEC_PUSH_STR(&d->vec, "operator<"));
891 case SIMPLE_HASH('g', 't') :
893 return (VEC_PUSH_STR(&d->vec, "operator>"));
894 case SIMPLE_HASH('l', 'e') :
896 return (VEC_PUSH_STR(&d->vec, "operator<="));
897 case SIMPLE_HASH('g', 'e') :
899 return (VEC_PUSH_STR(&d->vec, "operator>="));
900 case SIMPLE_HASH('a', 'd') :
904 return (VEC_PUSH_STR(&d->vec, "operator/="));
906 return (VEC_PUSH_STR(&d->vec, "operator&"));
907 case SIMPLE_HASH('o', 'r') :
909 return (VEC_PUSH_STR(&d->vec, "operator|"));
910 case SIMPLE_HASH('e', 'r') :
912 return (VEC_PUSH_STR(&d->vec, "operator^"));
913 case SIMPLE_HASH('a', 'a') :
917 return (VEC_PUSH_STR(&d->vec, "operator&="));
919 return (VEC_PUSH_STR(&d->vec, "operator&&"));
920 case SIMPLE_HASH('o', 'o') :
922 return (VEC_PUSH_STR(&d->vec, "operator||"));
923 case SIMPLE_HASH('n', 't') :
925 return (VEC_PUSH_STR(&d->vec, "operator!"));
926 case SIMPLE_HASH('c', 'o') :
928 return (VEC_PUSH_STR(&d->vec, "operator~"));
929 case SIMPLE_HASH('p', 'p') :
931 return (VEC_PUSH_STR(&d->vec, "operator++"));
932 case SIMPLE_HASH('m', 'm') :
934 return (VEC_PUSH_STR(&d->vec, "operator--"));
935 case SIMPLE_HASH('a', 's') :
937 return (VEC_PUSH_STR(&d->vec, "operator="));
938 case SIMPLE_HASH('r', 'f') :
940 return (VEC_PUSH_STR(&d->vec, "operator->"));
941 case SIMPLE_HASH('a', 'p') :
943 if (*(d->p + 2) != 'l')
947 return (VEC_PUSH_STR(&d->vec, "operator+="));
948 case SIMPLE_HASH('a', 'm') :
952 return (VEC_PUSH_STR(&d->vec, "operator-="));
953 } else if (*d->p == 'u') {
955 return (VEC_PUSH_STR(&d->vec, "operator*="));
956 } else if (*d->p == 'd') {
958 return (VEC_PUSH_STR(&d->vec, "operator%="));
962 case SIMPLE_HASH('a', 'l') :
964 if (*(d->p + 2) != 's')
968 return (VEC_PUSH_STR(&d->vec, "operator<<="));
969 case SIMPLE_HASH('a', 'r') :
971 if (*(d->p + 2) != 's')
975 return (VEC_PUSH_STR(&d->vec, "operator>>="));
976 case SIMPLE_HASH('a', 'o') :
978 if (*(d->p + 2) != 'r')
982 return (VEC_PUSH_STR(&d->vec, "operator|="));
983 case SIMPLE_HASH('a', 'e') :
985 if (*(d->p + 2) != 'r')
989 return (VEC_PUSH_STR(&d->vec, "operator^="));
990 case SIMPLE_HASH('c', 'm') :
992 return (VEC_PUSH_STR(&d->vec, "operator,"));
993 case SIMPLE_HASH('r', 'm') :
995 return (VEC_PUSH_STR(&d->vec, "operator->*"));
996 case SIMPLE_HASH('c', 'l') :
998 return (VEC_PUSH_STR(&d->vec, "()"));
999 case SIMPLE_HASH('v', 'c') :
1001 return (VEC_PUSH_STR(&d->vec, "[]"));
1002 case SIMPLE_HASH('n', 'w') :
1004 return (VEC_PUSH_STR(&d->vec, "operator new()"));
1005 case SIMPLE_HASH('d', 'l') :
1007 return (VEC_PUSH_STR(&d->vec, "operator delete()"));
1008 case SIMPLE_HASH('o', 'p') :
1009 /* __op<TO_TYPE>__<FROM_TYPE> */
1012 d->type = ENCODE_OP_USER;
1014 return (read_op_user(d));
1015 case SIMPLE_HASH('t', 'f') :
1017 d->type = ENCODE_OP_TF;
1019 if (read_type(d) == false)
1022 return (VEC_PUSH_STR(&d->vec, " type_info function"));
1023 case SIMPLE_HASH('t', 'i') :
1025 d->type = ENCODE_OP_TI;
1027 if (read_type(d) == false)
1030 return (VEC_PUSH_STR(&d->vec, " type_info node"));
1037 read_op_user(struct demangle_data *d)
1039 struct demangle_data from, to;
1040 size_t from_len, to_len;
1042 char *from_str, *to_str;
1047 if (init_demangle_data(&from) == false)
1053 if (init_demangle_data(&to) == false)
1060 if (read_qual_name(&to) == false)
1064 if (vector_str_pop(&to.vec) == false)
1067 if (read_class(&to) == false)
1074 if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL)
1078 if (*from.p == 'Q') {
1081 if (read_qual_name(&from) == false)
1085 if (vector_str_pop(&from.vec) == false)
1087 } else if (read_class(&from) == false)
1090 if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL)
1093 if (vector_str_push(&d->vec, from_str, from_len) == false)
1096 if (VEC_PUSH_STR(&d->vec, "::operator ") == false)
1099 if (vector_str_push(&d->vec, to_str, to_len) == false)
1102 rtn = VEC_PUSH_STR(&d->vec, "()");
1106 dest_demangle_data(&to);
1107 dest_demangle_data(&from);
1112 /* single digit + class names */
1114 read_qual_name(struct demangle_data *d)
1122 assert(d->p != NULL && "d->p (org str) is NULL");
1123 assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range");
1130 for (i = 0; i < num ; ++i) {
1131 if (read_class(d) == false)
1134 if (VEC_PUSH_STR(&d->vec, "::") == false)
1144 /* Return -1 at fail, 0 at success, and 1 at end */
1146 read_subst(struct demangle_data *d)
1154 idx = strtol(d->p + 1, &str, 10);
1155 if (idx == 0 && (errno == EINVAL || errno == ERANGE))
1159 assert(str != NULL);
1163 if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false)
1166 if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false)
1176 read_subst_iter(struct demangle_data *d)
1187 assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range");
1189 repeat = *d->p - 48;
1195 idx = strtol(d->p, &str, 10);
1196 if (idx == 0 && (errno == EINVAL || errno == ERANGE))
1200 assert(str != NULL);
1204 for (i = 0; i < repeat ; ++i) {
1205 if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false)
1208 if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false)
1211 if (i != repeat - 1 &&
1212 VEC_PUSH_STR(&d->vec, ", ") == false)
1223 read_type(struct demangle_data *d)
1229 assert(d->p != NULL && "d->p (org str) is NULL");
1231 while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' ||
1232 *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' ||
1238 if (VEC_PUSH_STR(&d->vec, "unsigned ") == false)
1248 if (VEC_PUSH_STR(&d->vec, "const ") ==
1257 if (VEC_PUSH_STR(&d->vec, "volatile ") == false)
1264 if (VEC_PUSH_STR(&d->vec, "signed ") == false)
1272 return (read_func_ptr(d));
1288 if (read_array(d) == false)
1295 if (read_memptr(d) == false)
1304 if (ELFTC_ISDIGIT(*d->p))
1305 return (read_class(d));
1311 return (read_qual_name(d));
1315 return (VEC_PUSH_STR(&d->vec, "void"));
1319 return(VEC_PUSH_STR(&d->vec, "bool"));
1323 return (VEC_PUSH_STR(&d->vec, "char"));
1327 return (VEC_PUSH_STR(&d->vec, "short"));
1331 return (VEC_PUSH_STR(&d->vec, "int"));
1335 return (VEC_PUSH_STR(&d->vec, "long"));
1339 return (VEC_PUSH_STR(&d->vec, "float"));
1343 return (VEC_PUSH_STR(&d->vec, "double"));
1347 return (VEC_PUSH_STR(&d->vec, "long double"));
1351 return (VEC_PUSH_STR(&d->vec, "..."));
1355 return (VEC_PUSH_STR(&d->vec, "wchar_t"));
1359 return (VEC_PUSH_STR(&d->vec, "long long"));