| @@ -1,376 +1,376 @@ | | | @@ -1,376 +1,376 @@ |
1 | /* $NetBSD: tyname.c,v 1.25 2021/01/24 11:55:57 rillig Exp $ */ | | 1 | /* $NetBSD: tyname.c,v 1.26 2021/01/26 18:38:57 rillig Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2005 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2005 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Christos Zoulas. | | 8 | * by Christos Zoulas. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright | | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the | | 16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. | | 17 | * documentation and/or other materials provided with the distribution. |
18 | * | | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #if HAVE_NBTOOL_CONFIG_H | | 32 | #if HAVE_NBTOOL_CONFIG_H |
33 | #include "nbtool_config.h" | | 33 | #include "nbtool_config.h" |
34 | #endif | | 34 | #endif |
35 | | | 35 | |
36 | #include <sys/cdefs.h> | | 36 | #include <sys/cdefs.h> |
37 | #if defined(__RCSID) && !defined(lint) | | 37 | #if defined(__RCSID) && !defined(lint) |
38 | __RCSID("$NetBSD: tyname.c,v 1.25 2021/01/24 11:55:57 rillig Exp $"); | | 38 | __RCSID("$NetBSD: tyname.c,v 1.26 2021/01/26 18:38:57 rillig Exp $"); |
39 | #endif | | 39 | #endif |
40 | | | 40 | |
41 | #include <limits.h> | | 41 | #include <limits.h> |
42 | #include <string.h> | | 42 | #include <string.h> |
43 | #include <stdlib.h> | | 43 | #include <stdlib.h> |
44 | #include <err.h> | | 44 | #include <err.h> |
45 | | | 45 | |
46 | #include PASS | | 46 | #include PASS |
47 | | | 47 | |
48 | #ifndef LERROR | | 48 | #ifndef LERROR |
49 | #define LERROR(fmt, args...) \ | | 49 | #define LERROR(fmt, args...) \ |
50 | do { \ | | 50 | do { \ |
51 | (void)warnx("%s, %d: " fmt, __FILE__, __LINE__, ##args); \ | | 51 | (void)warnx("%s, %d: " fmt, __FILE__, __LINE__, ##args); \ |
52 | abort(); \ | | 52 | abort(); \ |
53 | } while (/*CONSTCOND*/false) | | 53 | } while (/*CONSTCOND*/false) |
54 | #endif | | 54 | #endif |
55 | | | 55 | |
56 | /* A tree of strings. */ | | 56 | /* A tree of strings. */ |
57 | typedef struct name_tree_node { | | 57 | typedef struct name_tree_node { |
58 | char *ntn_name; | | 58 | char *ntn_name; |
59 | struct name_tree_node *ntn_less; | | 59 | struct name_tree_node *ntn_less; |
60 | struct name_tree_node *ntn_greater; | | 60 | struct name_tree_node *ntn_greater; |
61 | } name_tree_node; | | 61 | } name_tree_node; |
62 | | | 62 | |
63 | /* A growable string buffer. */ | | 63 | /* A growable string buffer. */ |
64 | typedef struct buffer { | | 64 | typedef struct buffer { |
65 | size_t len; | | 65 | size_t len; |
66 | size_t cap; | | 66 | size_t cap; |
67 | char * data; | | 67 | char * data; |
68 | } buffer; | | 68 | } buffer; |
69 | | | 69 | |
70 | static name_tree_node *type_names; | | 70 | static name_tree_node *type_names; |
71 | | | 71 | |
72 | static name_tree_node * | | 72 | static name_tree_node * |
73 | new_name_tree_node(const char *name) | | 73 | new_name_tree_node(const char *name) |
74 | { | | 74 | { |
75 | name_tree_node *n; | | 75 | name_tree_node *n; |
76 | | | 76 | |
77 | n = xmalloc(sizeof(*n)); | | 77 | n = xmalloc(sizeof(*n)); |
78 | n->ntn_name = xstrdup(name); | | 78 | n->ntn_name = xstrdup(name); |
79 | n->ntn_less = NULL; | | 79 | n->ntn_less = NULL; |
80 | n->ntn_greater = NULL; | | 80 | n->ntn_greater = NULL; |
81 | return n; | | 81 | return n; |
82 | } | | 82 | } |
83 | | | 83 | |
84 | /* Return the canonical instance of the string, with unlimited life time. */ | | 84 | /* Return the canonical instance of the string, with unlimited life time. */ |
85 | static const char * __noinline | | 85 | static const char * |
86 | intern(const char *name) | | 86 | intern(const char *name) |
87 | { | | 87 | { |
88 | name_tree_node *n = type_names, **next; | | 88 | name_tree_node *n = type_names, **next; |
89 | int cmp; | | 89 | int cmp; |
90 | | | 90 | |
91 | if (n == NULL) { | | 91 | if (n == NULL) { |
92 | n = new_name_tree_node(name); | | 92 | n = new_name_tree_node(name); |
93 | type_names = n; | | 93 | type_names = n; |
94 | return n->ntn_name; | | 94 | return n->ntn_name; |
95 | } | | 95 | } |
96 | | | 96 | |
97 | while ((cmp = strcmp(name, n->ntn_name)) != 0) { | | 97 | while ((cmp = strcmp(name, n->ntn_name)) != 0) { |
98 | next = cmp < 0 ? &n->ntn_less : &n->ntn_greater; | | 98 | next = cmp < 0 ? &n->ntn_less : &n->ntn_greater; |
99 | if (*next == NULL) { | | 99 | if (*next == NULL) { |
100 | *next = new_name_tree_node(name); | | 100 | *next = new_name_tree_node(name); |
101 | return (*next)->ntn_name; | | 101 | return (*next)->ntn_name; |
102 | } | | 102 | } |
103 | n = *next; | | 103 | n = *next; |
104 | } | | 104 | } |
105 | return n->ntn_name; | | 105 | return n->ntn_name; |
106 | } | | 106 | } |
107 | | | 107 | |
108 | static void | | 108 | static void |
109 | buf_init(buffer *buf) | | 109 | buf_init(buffer *buf) |
110 | { | | 110 | { |
111 | buf->len = 0; | | 111 | buf->len = 0; |
112 | buf->cap = 128; | | 112 | buf->cap = 128; |
113 | buf->data = xmalloc(buf->cap); | | 113 | buf->data = xmalloc(buf->cap); |
114 | buf->data[0] = '\0'; | | 114 | buf->data[0] = '\0'; |
115 | } | | 115 | } |
116 | | | 116 | |
117 | static void | | 117 | static void |
118 | buf_done(buffer *buf) | | 118 | buf_done(buffer *buf) |
119 | { | | 119 | { |
120 | free(buf->data); | | 120 | free(buf->data); |
121 | } | | 121 | } |
122 | | | 122 | |
123 | static void | | 123 | static void |
124 | buf_add(buffer *buf, const char *s) | | 124 | buf_add(buffer *buf, const char *s) |
125 | { | | 125 | { |
126 | size_t len = strlen(s); | | 126 | size_t len = strlen(s); |
127 | | | 127 | |
128 | while (buf->len + len + 1 >= buf->cap) { | | 128 | while (buf->len + len + 1 >= buf->cap) { |
129 | buf->data = xrealloc(buf->data, 2 * buf->cap); | | 129 | buf->data = xrealloc(buf->data, 2 * buf->cap); |
130 | buf->cap = 2 * buf->cap; | | 130 | buf->cap = 2 * buf->cap; |
131 | } | | 131 | } |
132 | | | 132 | |
133 | memcpy(buf->data + buf->len, s, len + 1); | | 133 | memcpy(buf->data + buf->len, s, len + 1); |
134 | buf->len += len; | | 134 | buf->len += len; |
135 | } | | 135 | } |
136 | | | 136 | |
137 | static void | | 137 | static void |
138 | buf_add_int(buffer *buf, int n) | | 138 | buf_add_int(buffer *buf, int n) |
139 | { | | 139 | { |
140 | char num[1 + sizeof(n) * CHAR_BIT + 1]; | | 140 | char num[1 + sizeof(n) * CHAR_BIT + 1]; |
141 | | | 141 | |
142 | snprintf(num, sizeof num, "%d", n); | | 142 | snprintf(num, sizeof num, "%d", n); |
143 | buf_add(buf, num); | | 143 | buf_add(buf, num); |
144 | } | | 144 | } |
145 | | | 145 | |
146 | const char * | | 146 | const char * |
147 | tspec_name(tspec_t t) | | 147 | tspec_name(tspec_t t) |
148 | { | | 148 | { |
149 | switch (t) { | | 149 | switch (t) { |
150 | case SIGNED: return "signed"; | | 150 | case SIGNED: return "signed"; |
151 | case UNSIGN: return "unsigned"; | | 151 | case UNSIGN: return "unsigned"; |
152 | case BOOL: return "_Bool"; | | 152 | case BOOL: return "_Bool"; |
153 | case CHAR: return "char"; | | 153 | case CHAR: return "char"; |
154 | case SCHAR: return "signed char"; | | 154 | case SCHAR: return "signed char"; |
155 | case UCHAR: return "unsigned char"; | | 155 | case UCHAR: return "unsigned char"; |
156 | case SHORT: return "short"; | | 156 | case SHORT: return "short"; |
157 | case USHORT: return "unsigned short"; | | 157 | case USHORT: return "unsigned short"; |
158 | case INT: return "int"; | | 158 | case INT: return "int"; |
159 | case UINT: return "unsigned int"; | | 159 | case UINT: return "unsigned int"; |
160 | case LONG: return "long"; | | 160 | case LONG: return "long"; |
161 | case ULONG: return "unsigned long"; | | 161 | case ULONG: return "unsigned long"; |
162 | case QUAD: return "long long"; | | 162 | case QUAD: return "long long"; |
163 | case UQUAD: return "unsigned long long"; | | 163 | case UQUAD: return "unsigned long long"; |
164 | #ifdef INT128_SIZE | | 164 | #ifdef INT128_SIZE |
165 | case INT128: return "__int128_t"; | | 165 | case INT128: return "__int128_t"; |
166 | case UINT128: return "__uint128_t"; | | 166 | case UINT128: return "__uint128_t"; |
167 | #endif | | 167 | #endif |
168 | case FLOAT: return "float"; | | 168 | case FLOAT: return "float"; |
169 | case DOUBLE: return "double"; | | 169 | case DOUBLE: return "double"; |
170 | case LDOUBLE: return "long double"; | | 170 | case LDOUBLE: return "long double"; |
171 | case VOID: return "void"; | | 171 | case VOID: return "void"; |
172 | case STRUCT: return "struct"; | | 172 | case STRUCT: return "struct"; |
173 | case UNION: return "union"; | | 173 | case UNION: return "union"; |
174 | case ENUM: return "enum"; | | 174 | case ENUM: return "enum"; |
175 | case PTR: return "pointer"; | | 175 | case PTR: return "pointer"; |
176 | case ARRAY: return "array"; | | 176 | case ARRAY: return "array"; |
177 | case FUNC: return "function"; | | 177 | case FUNC: return "function"; |
178 | case COMPLEX: return "_Complex"; | | 178 | case COMPLEX: return "_Complex"; |
179 | case FCOMPLEX: return "float _Complex"; | | 179 | case FCOMPLEX: return "float _Complex"; |
180 | case DCOMPLEX: return "double _Complex"; | | 180 | case DCOMPLEX: return "double _Complex"; |
181 | case LCOMPLEX: return "long double _Complex"; | | 181 | case LCOMPLEX: return "long double _Complex"; |
182 | default: | | 182 | default: |
183 | LERROR("tspec_name(%d)", t); | | 183 | LERROR("tspec_name(%d)", t); |
184 | return NULL; | | 184 | return NULL; |
185 | } | | 185 | } |
186 | } | | 186 | } |
187 | | | 187 | |
188 | bool | | 188 | bool |
189 | sametype(const type_t *t1, const type_t *t2) | | 189 | sametype(const type_t *t1, const type_t *t2) |
190 | { | | 190 | { |
191 | tspec_t t; | | 191 | tspec_t t; |
192 | | | 192 | |
193 | if (t1->t_tspec != t2->t_tspec) | | 193 | if (t1->t_tspec != t2->t_tspec) |
194 | return false; | | 194 | return false; |
195 | | | 195 | |
196 | /* Ignore const/void */ | | 196 | /* Ignore const/void */ |
197 | | | 197 | |
198 | switch (t = t1->t_tspec) { | | 198 | switch (t = t1->t_tspec) { |
199 | case BOOL: | | 199 | case BOOL: |
200 | case CHAR: | | 200 | case CHAR: |
201 | case UCHAR: | | 201 | case UCHAR: |
202 | case SCHAR: | | 202 | case SCHAR: |
203 | case SHORT: | | 203 | case SHORT: |
204 | case USHORT: | | 204 | case USHORT: |
205 | case INT: | | 205 | case INT: |
206 | case UINT: | | 206 | case UINT: |
207 | case LONG: | | 207 | case LONG: |
208 | case ULONG: | | 208 | case ULONG: |
209 | case QUAD: | | 209 | case QUAD: |
210 | case UQUAD: | | 210 | case UQUAD: |
211 | #ifdef INT128_SIZE | | 211 | #ifdef INT128_SIZE |
212 | case INT128: | | 212 | case INT128: |
213 | case UINT128: | | 213 | case UINT128: |
214 | #endif | | 214 | #endif |
215 | case FLOAT: | | 215 | case FLOAT: |
216 | case DOUBLE: | | 216 | case DOUBLE: |
217 | case LDOUBLE: | | 217 | case LDOUBLE: |
218 | case VOID: | | 218 | case VOID: |
219 | case FUNC: | | 219 | case FUNC: |
220 | case COMPLEX: | | 220 | case COMPLEX: |
221 | case FCOMPLEX: | | 221 | case FCOMPLEX: |
222 | case DCOMPLEX: | | 222 | case DCOMPLEX: |
223 | case LCOMPLEX: | | 223 | case LCOMPLEX: |
224 | return true; | | 224 | return true; |
225 | case ARRAY: | | 225 | case ARRAY: |
226 | if (t1->t_dim != t2->t_dim) | | 226 | if (t1->t_dim != t2->t_dim) |
227 | return false; | | 227 | return false; |
228 | /*FALLTHROUGH*/ | | 228 | /*FALLTHROUGH*/ |
229 | case PTR: | | 229 | case PTR: |
230 | return sametype(t1->t_subt, t2->t_subt); | | 230 | return sametype(t1->t_subt, t2->t_subt); |
231 | case ENUM: | | 231 | case ENUM: |
232 | #ifdef t_enum | | 232 | #ifdef t_enum |
233 | return strcmp(t1->t_enum->etag->s_name, | | 233 | return strcmp(t1->t_enum->etag->s_name, |
234 | t2->t_enum->etag->s_name) == 0; | | 234 | t2->t_enum->etag->s_name) == 0; |
235 | #else | | 235 | #else |
236 | return true; | | 236 | return true; |
237 | #endif | | 237 | #endif |
238 | case STRUCT: | | 238 | case STRUCT: |
239 | case UNION: | | 239 | case UNION: |
240 | #ifdef t_str | | 240 | #ifdef t_str |
241 | return strcmp(t1->t_str->stag->s_name, | | 241 | return strcmp(t1->t_str->stag->s_name, |
242 | t2->t_str->stag->s_name) == 0; | | 242 | t2->t_str->stag->s_name) == 0; |
243 | #else | | 243 | #else |
244 | return true; | | 244 | return true; |
245 | #endif | | 245 | #endif |
246 | default: | | 246 | default: |
247 | LERROR("tyname(%d)", t); | | 247 | LERROR("tyname(%d)", t); |
248 | return false; | | 248 | return false; |
249 | } | | 249 | } |
250 | } | | 250 | } |
251 | | | 251 | |
252 | static void | | 252 | static void |
253 | type_name_of_function(buffer *buf, const type_t *tp) | | 253 | type_name_of_function(buffer *buf, const type_t *tp) |
254 | { | | 254 | { |
255 | const char *sep = ""; | | 255 | const char *sep = ""; |
256 | | | 256 | |
257 | buf_add(buf, "("); | | 257 | buf_add(buf, "("); |
258 | if (tp->t_proto) { | | 258 | if (tp->t_proto) { |
259 | #ifdef t_enum /* lint1 */ | | 259 | #ifdef t_enum /* lint1 */ |
260 | sym_t *arg; | | 260 | sym_t *arg; |
261 | | | 261 | |
262 | for (arg = tp->t_args; arg != NULL; arg = arg->s_next) { | | 262 | for (arg = tp->t_args; arg != NULL; arg = arg->s_next) { |
263 | buf_add(buf, sep), sep = ", "; | | 263 | buf_add(buf, sep), sep = ", "; |
264 | buf_add(buf, type_name(arg->s_type)); | | 264 | buf_add(buf, type_name(arg->s_type)); |
265 | } | | 265 | } |
266 | #else /* lint2 */ | | 266 | #else /* lint2 */ |
267 | type_t **argtype; | | 267 | type_t **argtype; |
268 | | | 268 | |
269 | for (argtype = tp->t_args; *argtype != NULL; argtype++) { | | 269 | for (argtype = tp->t_args; *argtype != NULL; argtype++) { |
270 | buf_add(buf, sep), sep = ", "; | | 270 | buf_add(buf, sep), sep = ", "; |
271 | buf_add(buf, type_name(*argtype)); | | 271 | buf_add(buf, type_name(*argtype)); |
272 | } | | 272 | } |
273 | #endif | | 273 | #endif |
274 | } | | 274 | } |
275 | if (tp->t_vararg) { | | 275 | if (tp->t_vararg) { |
276 | buf_add(buf, sep); | | 276 | buf_add(buf, sep); |
277 | buf_add(buf, "..."); | | 277 | buf_add(buf, "..."); |
278 | } | | 278 | } |
279 | buf_add(buf, ") returning "); | | 279 | buf_add(buf, ") returning "); |
280 | buf_add(buf, type_name(tp->t_subt)); | | 280 | buf_add(buf, type_name(tp->t_subt)); |
281 | } | | 281 | } |
282 | | | 282 | |
283 | const char * | | 283 | const char * |
284 | type_name(const type_t *tp) | | 284 | type_name(const type_t *tp) |
285 | { | | 285 | { |
286 | tspec_t t; | | 286 | tspec_t t; |
287 | buffer buf; | | 287 | buffer buf; |
288 | const char *name; | | 288 | const char *name; |
289 | | | 289 | |
290 | if (tp == NULL) | | 290 | if (tp == NULL) |
291 | return "(null)"; | | 291 | return "(null)"; |
292 | | | 292 | |
293 | /* | | 293 | /* |
294 | * XXX: Why is this necessary, and in which cases does this apply? | | 294 | * XXX: Why is this necessary, and in which cases does this apply? |
295 | * Shouldn't the type be an ENUM from the beginning? | | 295 | * Shouldn't the type be an ENUM from the beginning? |
296 | */ | | 296 | */ |
297 | if ((t = tp->t_tspec) == INT && tp->t_isenum) | | 297 | if ((t = tp->t_tspec) == INT && tp->t_isenum) |
298 | t = ENUM; | | 298 | t = ENUM; |
299 | | | 299 | |
300 | buf_init(&buf); | | 300 | buf_init(&buf); |
301 | if (tp->t_const) | | 301 | if (tp->t_const) |
302 | buf_add(&buf, "const "); | | 302 | buf_add(&buf, "const "); |
303 | if (tp->t_volatile) | | 303 | if (tp->t_volatile) |
304 | buf_add(&buf, "volatile "); | | 304 | buf_add(&buf, "volatile "); |
305 | buf_add(&buf, tspec_name(t)); | | 305 | buf_add(&buf, tspec_name(t)); |
306 | | | 306 | |
307 | switch (t) { | | 307 | switch (t) { |
308 | case BOOL: | | 308 | case BOOL: |
309 | case CHAR: | | 309 | case CHAR: |
310 | case UCHAR: | | 310 | case UCHAR: |
311 | case SCHAR: | | 311 | case SCHAR: |
312 | case SHORT: | | 312 | case SHORT: |
313 | case USHORT: | | 313 | case USHORT: |
314 | case INT: | | 314 | case INT: |
315 | case UINT: | | 315 | case UINT: |
316 | case LONG: | | 316 | case LONG: |
317 | case ULONG: | | 317 | case ULONG: |
318 | case QUAD: | | 318 | case QUAD: |
319 | case UQUAD: | | 319 | case UQUAD: |
320 | #ifdef INT128_SIZE | | 320 | #ifdef INT128_SIZE |
321 | case INT128: | | 321 | case INT128: |
322 | case UINT128: | | 322 | case UINT128: |
323 | #endif | | 323 | #endif |
324 | case FLOAT: | | 324 | case FLOAT: |
325 | case DOUBLE: | | 325 | case DOUBLE: |
326 | case LDOUBLE: | | 326 | case LDOUBLE: |
327 | case VOID: | | 327 | case VOID: |
328 | case COMPLEX: | | 328 | case COMPLEX: |
329 | case FCOMPLEX: | | 329 | case FCOMPLEX: |
330 | case DCOMPLEX: | | 330 | case DCOMPLEX: |
331 | case LCOMPLEX: | | 331 | case LCOMPLEX: |
332 | case SIGNED: | | 332 | case SIGNED: |
333 | case UNSIGN: | | 333 | case UNSIGN: |
334 | break; | | 334 | break; |
335 | case PTR: | | 335 | case PTR: |
336 | buf_add(&buf, " to "); | | 336 | buf_add(&buf, " to "); |
337 | buf_add(&buf, type_name(tp->t_subt)); | | 337 | buf_add(&buf, type_name(tp->t_subt)); |
338 | break; | | 338 | break; |
339 | case ENUM: | | 339 | case ENUM: |
340 | buf_add(&buf, " "); | | 340 | buf_add(&buf, " "); |
341 | #ifdef t_enum | | 341 | #ifdef t_enum |
342 | buf_add(&buf, tp->t_enum->etag->s_name); | | 342 | buf_add(&buf, tp->t_enum->etag->s_name); |
343 | #else | | 343 | #else |
344 | buf_add(&buf, | | 344 | buf_add(&buf, |
345 | tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name); | | 345 | tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name); |
346 | #endif | | 346 | #endif |
347 | break; | | 347 | break; |
348 | case STRUCT: | | 348 | case STRUCT: |
349 | case UNION: | | 349 | case UNION: |
350 | buf_add(&buf, " "); | | 350 | buf_add(&buf, " "); |
351 | #ifdef t_str | | 351 | #ifdef t_str |
352 | buf_add(&buf, tp->t_str->stag->s_name); | | 352 | buf_add(&buf, tp->t_str->stag->s_name); |
353 | #else | | 353 | #else |
354 | buf_add(&buf, | | 354 | buf_add(&buf, |
355 | tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name); | | 355 | tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name); |
356 | #endif | | 356 | #endif |
357 | break; | | 357 | break; |
358 | case ARRAY: | | 358 | case ARRAY: |
359 | buf_add(&buf, " of "); | | 359 | buf_add(&buf, " of "); |
360 | buf_add(&buf, type_name(tp->t_subt)); | | 360 | buf_add(&buf, type_name(tp->t_subt)); |
361 | buf_add(&buf, "["); | | 361 | buf_add(&buf, "["); |
362 | buf_add_int(&buf, tp->t_dim); | | 362 | buf_add_int(&buf, tp->t_dim); |
363 | buf_add(&buf, "]"); | | 363 | buf_add(&buf, "]"); |
364 | break; | | 364 | break; |
365 | case FUNC: | | 365 | case FUNC: |
366 | type_name_of_function(&buf, tp); | | 366 | type_name_of_function(&buf, tp); |
367 | break; | | 367 | break; |
368 | | | 368 | |
369 | default: | | 369 | default: |
370 | LERROR("type_name(%d)", t); | | 370 | LERROR("type_name(%d)", t); |
371 | } | | 371 | } |
372 | | | 372 | |
373 | name = intern(buf.data); | | 373 | name = intern(buf.data); |
374 | buf_done(&buf); | | 374 | buf_done(&buf); |
375 | return name; | | 375 | return name; |
376 | } | | 376 | } |