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 2065 2011-10-26 15:24:47Z jkoshy $");
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 CPP_DEMANGLE_GNU2_TRY 128
71 static void dest_cstring(struct cstring *);
72 static void dest_demangle_data(struct demangle_data *);
73 static bool init_cstring(struct cstring *, size_t);
74 static bool init_demangle_data(struct demangle_data *);
75 static bool push_CTDT(const char *, size_t, struct vector_str *);
76 static bool read_array(struct demangle_data *);
77 static bool read_class(struct demangle_data *);
78 static bool read_func(struct demangle_data *);
79 static bool read_func_name(struct demangle_data *);
80 static bool read_func_ptr(struct demangle_data *);
81 static bool read_memptr(struct demangle_data *);
82 static bool read_op(struct demangle_data *);
83 static bool read_op_user(struct demangle_data *);
84 static bool read_qual_name(struct demangle_data *);
85 static int read_subst(struct demangle_data *);
86 static int read_subst_iter(struct demangle_data *);
87 static bool read_type(struct demangle_data *);
90 * @brief Decode the input string by the GNU 2 style.
92 * @return New allocated demangled string or NULL if failed.
95 cpp_demangle_gnu2(const char *org)
97 struct demangle_data d;
98 size_t arg_begin, arg_len;
105 if (init_demangle_data(&d) == false)
112 if (read_func_name(&d) == false)
121 if (push_CTDT("::", 2, &d.vec) == false)
126 if (push_CTDT("::~", 3, &d.vec) == false)
129 if (vector_str_push(&d.vec, "(void)", 6) == false)
133 case ENCODE_OP_USER :
142 else if (*d.p == '\0') {
143 if (d.class_name == true) {
144 if (vector_str_push(&d.vec, "(void)", 6) == false)
152 /* start argument types */
153 if (vector_str_push(&d.vec, "(", 1) == false)
158 const int rtn_subst = read_subst(&d);
162 else if (rtn_subst == 1)
169 const int rtn_subst_iter = read_subst_iter(&d);
171 if (rtn_subst_iter == -1)
173 else if(rtn_subst_iter == 1)
179 arg_begin = d.vec.size;
181 if (read_type(&d) == false)
185 if (vector_str_push(&d.vec, "*", 1) == false)
192 if (vector_str_push(&d.vec, "&", 1) == false)
198 if (d.cnst == true) {
199 if (vector_str_push(&d.vec, " const", 6) == false)
205 if (d.array == true) {
206 if (vector_str_push(&d.vec, d.array_str.buf,
207 d.array_str.size) == false)
210 dest_cstring(&d.array_str);
217 if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1,
221 if (vector_str_push(&d.arg, arg, arg_len) == false)
226 if (vector_str_push(&d.vec, ", ", 2) == false)
229 if (++try > CPP_DEMANGLE_GNU2_TRY)
233 /* end argument types */
234 if (vector_str_push(&d.vec, ")", 1) == false)
237 if (d.cnst_fn == true && vector_str_push(&d.vec, " const", 6) == false)
240 rtn = vector_str_get_flat(&d.vec, NULL);
242 dest_demangle_data(&d);
248 * @brief Test input string is encoded by the GNU 2 style.
250 * @return True if input string is encoded by the GNU 2 style.
253 is_cpp_mangled_gnu2(const char *org)
261 /* search valid text to end */
262 str = strstr(org, "__");
263 while (str != NULL) {
264 if (*(str + 2) != '\0') {
265 if (*(str + 2) == 'C' ||
268 ELFTC_ISDIGIT(*(str + 2))) {
274 if (*(str + 3) != '\0') {
275 switch (SIMPLE_HASH(*(str + 2), *(str + 3))) {
276 case SIMPLE_HASH('m', 'l') :
277 case SIMPLE_HASH('d', 'v') :
278 case SIMPLE_HASH('m', 'd') :
279 case SIMPLE_HASH('p', 'l') :
280 case SIMPLE_HASH('m', 'i') :
281 case SIMPLE_HASH('l', 's') :
282 case SIMPLE_HASH('r', 's') :
283 case SIMPLE_HASH('e', 'q') :
284 case SIMPLE_HASH('n', 'e') :
285 case SIMPLE_HASH('l', 't') :
286 case SIMPLE_HASH('g', 't') :
287 case SIMPLE_HASH('l', 'e') :
288 case SIMPLE_HASH('g', 'e') :
289 case SIMPLE_HASH('a', 'd') :
290 case SIMPLE_HASH('o', 'r') :
291 case SIMPLE_HASH('e', 'r') :
292 case SIMPLE_HASH('a', 'a') :
293 case SIMPLE_HASH('o', 'o') :
294 case SIMPLE_HASH('n', 't') :
295 case SIMPLE_HASH('c', 'o') :
296 case SIMPLE_HASH('p', 'p') :
297 case SIMPLE_HASH('m', 'm') :
298 case SIMPLE_HASH('a', 's') :
299 case SIMPLE_HASH('r', 'f') :
300 case SIMPLE_HASH('a', 'p') :
301 case SIMPLE_HASH('a', 'm') :
302 case SIMPLE_HASH('a', 'l') :
303 case SIMPLE_HASH('a', 'r') :
304 case SIMPLE_HASH('a', 'o') :
305 case SIMPLE_HASH('a', 'e') :
306 case SIMPLE_HASH('c', 'm') :
307 case SIMPLE_HASH('r', 'm') :
308 case SIMPLE_HASH('c', 'l') :
309 case SIMPLE_HASH('v', 'c') :
310 case SIMPLE_HASH('n', 'w') :
311 case SIMPLE_HASH('d', 'l') :
312 case SIMPLE_HASH('o', 'p') :
313 case SIMPLE_HASH('t', 'f') :
314 case SIMPLE_HASH('t', 'i') :
322 str = strstr(str + 2, "__");
325 rtn |= strstr(org, "_$_") != NULL;
326 rtn |= strstr(org, "_vt$") != NULL;
332 dest_cstring(struct cstring *s)
344 dest_demangle_data(struct demangle_data *d)
348 vector_str_dest(&d->arg);
349 vector_str_dest(&d->vec);
351 dest_cstring(&d->array_str);
356 init_cstring(struct cstring *s, size_t len)
359 if (s == NULL || len <= 1)
362 if ((s->buf = malloc(sizeof(char) * len)) == NULL)
371 init_demangle_data(struct demangle_data *d)
382 d->class_name = false;
384 d->array_str.buf = NULL;
385 d->array_str.size = 0;
387 d->type = ENCODE_FUNC;
389 if (vector_str_init(&d->vec) == false)
392 if (vector_str_init(&d->arg) == false) {
393 vector_str_dest(&d->vec);
402 push_CTDT(const char *s, size_t l, struct vector_str *v)
405 if (s == NULL || l == 0 || v == NULL)
408 if (vector_str_push(v, s, l) == false)
413 return (vector_str_push(v, v->container[v->size - 2],
414 strlen(v->container[v->size - 2])));
418 read_array(struct demangle_data *d)
423 if (d == NULL || d->p == NULL)
433 if (ELFTC_ISDIGIT(*end) == 0)
445 dest_cstring(&d->array_str);
446 if (init_cstring(&d->array_str, len + 3) == false)
449 strncpy(d->array_str.buf + 1, d->p, len);
450 *d->array_str.buf = '[';
451 *(d->array_str.buf + len + 1) = ']';
460 read_class(struct demangle_data *d)
468 len = strtol(d->p, &str, 10);
469 if (len == 0 && (errno == EINVAL || errno == ERANGE))
475 if (vector_str_push(&d->vec, str, len) == false)
480 d->class_name = true;
486 read_func(struct demangle_data *d)
495 assert(d->p != NULL && "d->p (org str) is NULL");
496 if ((delim = strstr(d->p, "__")) == NULL)
512 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
515 if (read_qual_name(d) == false)
517 } else if (ELFTC_ISDIGIT(*d->p)) {
518 if (read_class(d) == false)
521 if (vector_str_push(&d->vec, "::", 2) == false)
525 return (vector_str_push(&d->vec, name, len));
529 read_func_name(struct demangle_data *d)
541 assert(d->p != NULL && "d->p (org str) is NULL");
543 if (*d->p == '_' && *(d->p + 1) == '_') {
547 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
549 d->type = ENCODE_OP_CT;
551 if (read_qual_name(d) == false)
554 return (vector_str_pop(&d->vec));
555 } else if (ELFTC_ISDIGIT(*d->p)) {
556 d->type = ENCODE_OP_CT;
558 return (read_class(d));
562 if (read_op(d) == false) {
563 /* not good condition, start function name with '__' */
564 d->type = ENCODE_FUNC;
566 if (vector_str_push(&d->vec, "__", 2) == false)
569 return (read_func(d));
572 if (d->type == ENCODE_OP_USER ||
573 d->type == ENCODE_OP_TF ||
574 d->type == ENCODE_OP_TI)
586 /* assume delimiter is removed */
587 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
590 assert(d->vec.size > 0);
592 len = strlen(d->vec.container[d->vec.size - 1]);
593 if ((op_name = malloc(sizeof(char) * (len + 1)))
597 snprintf(op_name, len + 1, "%s",
598 d->vec.container[d->vec.size - 1]);
599 vector_str_pop(&d->vec);
601 if (read_qual_name(d) == false)
604 if (vector_str_push(&d->vec, "::", 2) == false)
607 if (vector_str_push(&d->vec, op_name, len) == false)
611 } else if (ELFTC_ISDIGIT(*d->p)) {
612 assert(d->vec.size > 0);
614 len = strlen(d->vec.container[d->vec.size - 1]);
615 if ((op_name = malloc(sizeof(char) * (len + 1)))
619 snprintf(op_name, len + 1, "%s",
620 d->vec.container[d->vec.size - 1]);
621 vector_str_pop(&d->vec);
623 if (read_class(d) == false)
626 if (vector_str_push(&d->vec, "::", 2) == false)
629 if (vector_str_push(&d->vec, op_name, len) == false)
634 } else if (memcmp(d->p, "_$_", 3) == 0) {
637 d->type = ENCODE_OP_DT;
639 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
642 if (read_qual_name(d) == false)
645 return (vector_str_pop(&d->vec));
646 } else if (ELFTC_ISDIGIT(*d->p))
647 return (read_class(d));
650 } else if (memcmp(d->p, "_vt$", 4) == 0) {
653 d->type = ENCODE_OP_VT;
655 if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) {
658 if (read_qual_name(d) == false)
661 if (vector_str_pop(&d->vec) == false)
663 } else if (ELFTC_ISDIGIT(*d->p)) {
664 if (read_class(d) == false)
668 return (vector_str_push(&d->vec, " virtual table", 14));
670 return (read_func(d));
677 /* Read function ptr type */
679 read_func_ptr(struct demangle_data *d)
681 struct demangle_data fptr;
682 size_t arg_len, rtn_len;
683 char *arg_type, *rtn_type;
689 if (init_demangle_data(&fptr) == false)
698 if (read_type(&fptr) == false) {
699 dest_demangle_data(&fptr);
704 if (fptr.ptr == true) {
705 if (vector_str_push(&fptr.vec, "*", 1) == false) {
706 dest_demangle_data(&fptr);
714 if (fptr.ref == true) {
715 if (vector_str_push(&fptr.vec, "&", 1) == false) {
716 dest_demangle_data(&fptr);
724 if (fptr.cnst == true) {
725 if (vector_str_push(&fptr.vec, " const", 6) == false) {
726 dest_demangle_data(&fptr);
737 if (vector_str_push(&fptr.vec, ", ", 2) == false) {
738 dest_demangle_data(&fptr);
743 if (++lim > CPP_DEMANGLE_GNU2_TRY) {
745 dest_demangle_data(&fptr);
751 arg_type = vector_str_get_flat(&fptr.vec, &arg_len);
755 dest_demangle_data(&fptr);
757 if (init_demangle_data(&fptr) == false) {
766 if (read_type(&fptr) == false) {
768 dest_demangle_data(&fptr);
773 rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len);
777 dest_demangle_data(&fptr);
779 if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) {
788 if (vector_str_push(&d->vec, " (*)(", 5) == false) {
794 if (vector_str_push(&d->vec, arg_type, arg_len) == false) {
802 return (vector_str_push(&d->vec, ")", 1));
806 read_memptr(struct demangle_data *d)
808 struct demangle_data mptr;
813 if (d == NULL || d->p == NULL)
816 if (init_demangle_data(&mptr) == false)
823 if (*mptr.p == 'Q') {
826 if (read_qual_name(&mptr) == false)
828 } else if (read_class(&mptr) == false)
833 if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL)
836 if (vector_str_push(&d->vec, mptr_str, len) == false)
839 if (vector_str_push(&d->vec, "::*", 3) == false)
845 dest_demangle_data(&mptr);
851 read_op(struct demangle_data *d)
857 assert(d->p != NULL && "d->p (org str) is NULL");
859 switch (SIMPLE_HASH(*(d->p), *(d->p+1))) {
860 case SIMPLE_HASH('m', 'l') :
862 return (vector_str_push(&d->vec, "operator*", 9));
863 case SIMPLE_HASH('d', 'v') :
865 return (vector_str_push(&d->vec, "operator/", 9));
866 case SIMPLE_HASH('m', 'd') :
868 return (vector_str_push(&d->vec, "operator%", 9));
869 case SIMPLE_HASH('p', 'l') :
871 return (vector_str_push(&d->vec, "operator+", 9));
872 case SIMPLE_HASH('m', 'i') :
874 return (vector_str_push(&d->vec, "operator-", 9));
875 case SIMPLE_HASH('l', 's') :
877 return (vector_str_push(&d->vec, "operator<<", 10));
878 case SIMPLE_HASH('r', 's') :
880 return (vector_str_push(&d->vec, "operator>>", 10));
881 case SIMPLE_HASH('e', 'q') :
883 return (vector_str_push(&d->vec, "operator==", 10));
884 case SIMPLE_HASH('n', 'e') :
886 return (vector_str_push(&d->vec, "operator!=", 10));
887 case SIMPLE_HASH('l', 't') :
889 return (vector_str_push(&d->vec, "operator<", 9));
890 case SIMPLE_HASH('g', 't') :
892 return (vector_str_push(&d->vec, "operator>", 9));
893 case SIMPLE_HASH('l', 'e') :
895 return (vector_str_push(&d->vec, "operator<=", 10));
896 case SIMPLE_HASH('g', 'e') :
898 return (vector_str_push(&d->vec, "operator>=", 10));
899 case SIMPLE_HASH('a', 'd') :
903 return (vector_str_push(&d->vec, "operator/=",
906 return (vector_str_push(&d->vec, "operator&", 9));
907 case SIMPLE_HASH('o', 'r') :
909 return (vector_str_push(&d->vec, "operator|", 9));
910 case SIMPLE_HASH('e', 'r') :
912 return (vector_str_push(&d->vec, "operator^", 9));
913 case SIMPLE_HASH('a', 'a') :
917 return (vector_str_push(&d->vec, "operator&=",
920 return (vector_str_push(&d->vec, "operator&&",
922 case SIMPLE_HASH('o', 'o') :
924 return (vector_str_push(&d->vec, "operator||", 10));
925 case SIMPLE_HASH('n', 't') :
927 return (vector_str_push(&d->vec, "operator!", 9));
928 case SIMPLE_HASH('c', 'o') :
930 return (vector_str_push(&d->vec, "operator~", 9));
931 case SIMPLE_HASH('p', 'p') :
933 return (vector_str_push(&d->vec, "operator++", 10));
934 case SIMPLE_HASH('m', 'm') :
936 return (vector_str_push(&d->vec, "operator--", 10));
937 case SIMPLE_HASH('a', 's') :
939 return (vector_str_push(&d->vec, "operator=", 9));
940 case SIMPLE_HASH('r', 'f') :
942 return (vector_str_push(&d->vec, "operator->", 10));
943 case SIMPLE_HASH('a', 'p') :
945 if (*(d->p + 2) != 'l')
949 return (vector_str_push(&d->vec, "operator+=", 10));
950 case SIMPLE_HASH('a', 'm') :
954 return (vector_str_push(&d->vec, "operator-=",
956 } else if (*d->p == 'u') {
958 return (vector_str_push(&d->vec, "operator*=",
960 } else if (*d->p == 'd') {
962 return (vector_str_push(&d->vec, "operator%=",
967 case SIMPLE_HASH('a', 'l') :
969 if (*(d->p + 2) != 's')
973 return (vector_str_push(&d->vec, "operator<<=", 11));
974 case SIMPLE_HASH('a', 'r') :
976 if (*(d->p + 2) != 's')
980 return (vector_str_push(&d->vec, "operator>>=", 11));
981 case SIMPLE_HASH('a', 'o') :
983 if (*(d->p + 2) != 'r')
987 return (vector_str_push(&d->vec, "operator|=", 10));
988 case SIMPLE_HASH('a', 'e') :
990 if (*(d->p + 2) != 'r')
994 return (vector_str_push(&d->vec, "operator^=", 10));
995 case SIMPLE_HASH('c', 'm') :
997 return (vector_str_push(&d->vec, "operator,", 9));
998 case SIMPLE_HASH('r', 'm') :
1000 return (vector_str_push(&d->vec, "operator->*", 11));
1001 case SIMPLE_HASH('c', 'l') :
1003 return (vector_str_push(&d->vec, "()", 2));
1004 case SIMPLE_HASH('v', 'c') :
1006 return (vector_str_push(&d->vec, "[]", 2));
1007 case SIMPLE_HASH('n', 'w') :
1009 return (vector_str_push(&d->vec, "operator new()", 14));
1010 case SIMPLE_HASH('d', 'l') :
1012 return (vector_str_push(&d->vec, "operator delete()",
1014 case SIMPLE_HASH('o', 'p') :
1015 /* __op<TO_TYPE>__<FROM_TYPE> */
1018 d->type = ENCODE_OP_USER;
1020 return (read_op_user(d));
1021 case SIMPLE_HASH('t', 'f') :
1023 d->type = ENCODE_OP_TF;
1025 if (read_type(d) == false)
1028 return (vector_str_push(&d->vec, " type_info function", 19));
1029 case SIMPLE_HASH('t', 'i') :
1031 d->type = ENCODE_OP_TI;
1033 if (read_type(d) == false)
1036 return (vector_str_push(&d->vec, " type_info node", 15));
1043 read_op_user(struct demangle_data *d)
1045 struct demangle_data from, to;
1046 size_t from_len, to_len;
1048 char *from_str, *to_str;
1053 if (init_demangle_data(&from) == false)
1059 if (init_demangle_data(&to) == false)
1066 if (read_qual_name(&to) == false)
1070 if (vector_str_pop(&to.vec) == false)
1073 if (read_class(&to) == false)
1080 if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL)
1084 if (*from.p == 'Q') {
1087 if (read_qual_name(&from) == false)
1091 if (vector_str_pop(&from.vec) == false)
1093 } else if (read_class(&from) == false)
1096 if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL)
1099 if (vector_str_push(&d->vec, from_str, from_len) == false)
1102 if (vector_str_push(&d->vec, "::operator ", 11) == false)
1105 if (vector_str_push(&d->vec, to_str, to_len) == false)
1108 rtn = vector_str_push(&d->vec, "()", 2);
1112 dest_demangle_data(&to);
1113 dest_demangle_data(&from);
1118 /* single digit + class names */
1120 read_qual_name(struct demangle_data *d)
1128 assert(d->p != NULL && "d->p (org str) is NULL");
1129 assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range");
1136 for (i = 0; i < num ; ++i) {
1137 if (read_class(d) == false)
1140 if (vector_str_push(&d->vec, "::", 2) == false)
1150 /* Return -1 at fail, 0 at success, and 1 at end */
1152 read_subst(struct demangle_data *d)
1160 idx = strtol(d->p + 1, &str, 10);
1161 if (idx == 0 && (errno == EINVAL || errno == ERANGE))
1165 assert(str != NULL);
1169 if (vector_str_push(&d->vec, d->arg.container[idx - 1],
1170 strlen(d->arg.container[idx - 1])) == false)
1173 if (vector_str_push(&d->arg, d->arg.container[idx - 1],
1174 strlen(d->arg.container[idx - 1])) == false)
1184 read_subst_iter(struct demangle_data *d)
1195 assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range");
1197 repeat = *d->p - 48;
1203 idx = strtol(d->p, &str, 10);
1204 if (idx == 0 && (errno == EINVAL || errno == ERANGE))
1208 assert(str != NULL);
1212 for (i = 0; i < repeat ; ++i) {
1213 if (vector_str_push(&d->vec, d->arg.container[idx - 1],
1214 strlen(d->arg.container[idx - 1])) == false)
1217 if (vector_str_push(&d->arg, d->arg.container[idx - 1],
1218 strlen(d->arg.container[idx - 1])) == false)
1221 if (i != repeat - 1 &&
1222 vector_str_push(&d->vec, ", ", 2) == false)
1233 read_type(struct demangle_data *d)
1239 assert(d->p != NULL && "d->p (org str) is NULL");
1241 while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' ||
1242 *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' ||
1248 if (vector_str_push(&d->vec, "unsigned ", 9) == false)
1258 if (vector_str_push(&d->vec, "const ", 6) ==
1267 if (vector_str_push(&d->vec, "volatile ", 9) == false)
1274 if (vector_str_push(&d->vec, "signed ", 7) == false)
1282 return (read_func_ptr(d));
1298 if (read_array(d) == false)
1305 if (read_memptr(d) == false)
1314 if (ELFTC_ISDIGIT(*d->p))
1315 return (read_class(d));
1321 return (read_qual_name(d));
1325 return (vector_str_push(&d->vec, "void", 4));
1329 return(vector_str_push(&d->vec, "bool", 4));
1333 return (vector_str_push(&d->vec, "char", 4));
1337 return (vector_str_push(&d->vec, "short", 5));
1341 return (vector_str_push(&d->vec, "int", 3));
1345 return (vector_str_push(&d->vec, "long", 4));
1349 return (vector_str_push(&d->vec, "float", 5));
1353 return (vector_str_push(&d->vec, "double", 6));
1357 return (vector_str_push(&d->vec, "long double", 11));
1361 return (vector_str_push(&d->vec, "...", 3));
1365 return (vector_str_push(&d->vec, "wchar_t", 7));
1369 return (vector_str_push(&d->vec, "long long", 9));