also move type_incompatibility_warning and type_to_str.
Unified · Split
| @@ -2429,6 +2429,160 @@ static void gen_opif(int op) · 2428 unmodified lines | ||
| 2429 | 2429 | } |
| 2430 | 2430 | } |
| 2431 | 2431 | |
| 2432 | +/* print a type. If 'varstr' is not NULL, then the variable is also | |
| 2433 | + printed in the type */ | |
| 2434 | +/* XXX: union */ | |
| 2435 | +/* XXX: add array and function pointers */ | |
| 2436 | +static void type_to_str(char *buf, int buf_size, | |
| 2437 | + CType *type, const char *varstr) | |
| 2438 | +{ | |
| 2439 | + int bt, v, t; | |
| 2440 | + Sym *s, *sa; | |
| 2441 | + char buf1[256]; | |
| 2442 | + const char *tstr; | |
| 2443 | + | |
| 2444 | + t = type->t; | |
| 2445 | + bt = t & VT_BTYPE; | |
| 2446 | + buf[0] = '\0'; | |
| 2447 | + | |
| 2448 | + if (t & VT_EXTERN) | |
| 2449 | + pstrcat(buf, buf_size, "extern "); | |
| 2450 | + if (t & VT_STATIC) | |
| 2451 | + pstrcat(buf, buf_size, "static "); | |
| 2452 | + if (t & VT_TYPEDEF) | |
| 2453 | + pstrcat(buf, buf_size, "typedef "); | |
| 2454 | + if (t & VT_INLINE) | |
| 2455 | + pstrcat(buf, buf_size, "inline "); | |
| 2456 | + if (t & VT_VOLATILE) | |
| 2457 | + pstrcat(buf, buf_size, "volatile "); | |
| 2458 | + if (t & VT_CONSTANT) | |
| 2459 | + pstrcat(buf, buf_size, "const "); | |
| 2460 | + | |
| 2461 | + if (((t & VT_DEFSIGN) && bt == VT_BYTE) | |
| 2462 | + || ((t & VT_UNSIGNED) | |
| 2463 | + && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG) | |
| 2464 | + && !IS_ENUM(t) | |
| 2465 | + )) | |
| 2466 | + pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed "); | |
| 2467 | + | |
| 2468 | + buf_size -= strlen(buf); | |
| 2469 | + buf += strlen(buf); | |
| 2470 | + | |
| 2471 | + switch(bt) { | |
| 2472 | + case VT_VOID: | |
| 2473 | + tstr = "void"; | |
| 2474 | + goto add_tstr; | |
| 2475 | + case VT_BOOL: | |
| 2476 | + tstr = "_Bool"; | |
| 2477 | + goto add_tstr; | |
| 2478 | + case VT_BYTE: | |
| 2479 | + tstr = "char"; | |
| 2480 | + goto add_tstr; | |
| 2481 | + case VT_SHORT: | |
| 2482 | + tstr = "short"; | |
| 2483 | + goto add_tstr; | |
| 2484 | + case VT_INT: | |
| 2485 | + tstr = "int"; | |
| 2486 | + goto maybe_long; | |
| 2487 | + case VT_LLONG: | |
| 2488 | + tstr = "long long"; | |
| 2489 | + maybe_long: | |
| 2490 | + if (t & VT_LONG) | |
| 2491 | + tstr = "long"; | |
| 2492 | + if (!IS_ENUM(t)) | |
| 2493 | + goto add_tstr; | |
| 2494 | + tstr = "enum "; | |
| 2495 | + goto tstruct; | |
| 2496 | + case VT_FLOAT: | |
| 2497 | + tstr = "float"; | |
| 2498 | + goto add_tstr; | |
| 2499 | + case VT_DOUBLE: | |
| 2500 | + tstr = "double"; | |
| 2501 | + if (!(t & VT_LONG)) | |
| 2502 | + goto add_tstr; | |
| 2503 | + case VT_LDOUBLE: | |
| 2504 | + tstr = "long double"; | |
| 2505 | + add_tstr: | |
| 2506 | + pstrcat(buf, buf_size, tstr); | |
| 2507 | + break; | |
| 2508 | + case VT_STRUCT: | |
| 2509 | + tstr = "struct "; | |
| 2510 | + if (IS_UNION(t)) | |
| 2511 | + tstr = "union "; | |
| 2512 | + tstruct: | |
| 2513 | + pstrcat(buf, buf_size, tstr); | |
| 2514 | + v = type->ref->v & ~SYM_STRUCT; | |
| 2515 | + if (v >= SYM_FIRST_ANOM) | |
| 2516 | + pstrcat(buf, buf_size, "<anonymous>"); | |
| 2517 | + else | |
| 2518 | + pstrcat(buf, buf_size, get_tok_str(v, NULL)); | |
| 2519 | + break; | |
| 2520 | + case VT_FUNC: | |
| 2521 | + s = type->ref; | |
| 2522 | + buf1[0]=0; | |
| 2523 | + if (varstr && '*' == *varstr) { | |
| 2524 | + pstrcat(buf1, sizeof(buf1), "("); | |
| 2525 | + pstrcat(buf1, sizeof(buf1), varstr); | |
| 2526 | + pstrcat(buf1, sizeof(buf1), ")"); | |
| 2527 | + } | |
| 2528 | + pstrcat(buf1, buf_size, "("); | |
| 2529 | + sa = s->next; | |
| 2530 | + while (sa != NULL) { | |
| 2531 | + char buf2[256]; | |
| 2532 | + type_to_str(buf2, sizeof(buf2), &sa->type, NULL); | |
| 2533 | + pstrcat(buf1, sizeof(buf1), buf2); | |
| 2534 | + sa = sa->next; | |
| 2535 | + if (sa) | |
| 2536 | + pstrcat(buf1, sizeof(buf1), ", "); | |
| 2537 | + } | |
| 2538 | + if (s->f.func_type == FUNC_ELLIPSIS) | |
| 2539 | + pstrcat(buf1, sizeof(buf1), ", ..."); | |
| 2540 | + pstrcat(buf1, sizeof(buf1), ")"); | |
| 2541 | + type_to_str(buf, buf_size, &s->type, buf1); | |
| 2542 | + goto no_var; | |
| 2543 | + case VT_PTR: | |
| 2544 | + s = type->ref; | |
| 2545 | + if (t & VT_ARRAY) { | |
| 2546 | + if (varstr && '*' == *varstr) | |
| 2547 | + snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c); | |
| 2548 | + else | |
| 2549 | + snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c); | |
| 2550 | + type_to_str(buf, buf_size, &s->type, buf1); | |
| 2551 | + goto no_var; | |
| 2552 | + } | |
| 2553 | + pstrcpy(buf1, sizeof(buf1), "*"); | |
| 2554 | + if (t & VT_CONSTANT) | |
| 2555 | + pstrcat(buf1, buf_size, "const "); | |
| 2556 | + if (t & VT_VOLATILE) | |
| 2557 | + pstrcat(buf1, buf_size, "volatile "); | |
| 2558 | + if (varstr) | |
| 2559 | + pstrcat(buf1, sizeof(buf1), varstr); | |
| 2560 | + type_to_str(buf, buf_size, &s->type, buf1); | |
| 2561 | + goto no_var; | |
| 2562 | + } | |
| 2563 | + if (varstr) { | |
| 2564 | + pstrcat(buf, buf_size, " "); | |
| 2565 | + pstrcat(buf, buf_size, varstr); | |
| 2566 | + } | |
| 2567 | + no_var: ; | |
| 2568 | +} | |
| 2569 | + | |
| 2570 | +static void type_incompatibility_error(CType* st, CType* dt, const char* fmt) | |
| 2571 | +{ | |
| 2572 | + char buf1[256], buf2[256]; | |
| 2573 | + type_to_str(buf1, sizeof(buf1), st, NULL); | |
| 2574 | + type_to_str(buf2, sizeof(buf2), dt, NULL); | |
| 2575 | + tcc_error(fmt, buf1, buf2); | |
| 2576 | +} | |
| 2577 | + | |
| 2578 | +static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt) | |
| 2579 | +{ | |
| 2580 | + char buf1[256], buf2[256]; | |
| 2581 | + type_to_str(buf1, sizeof(buf1), st, NULL); | |
| 2582 | + type_to_str(buf2, sizeof(buf2), dt, NULL); | |
| 2583 | + tcc_warning(fmt, buf1, buf2); | |
| 2584 | +} | |
| 2585 | + | |
| 2432 | 2586 | static int pointed_size(CType *type) |
| 2433 | 2587 | { |
| 2434 | 2588 | int align; |
| @@ -3175,160 +3329,6 @@ static int is_compatible_unqualified_types(CType *type1, CType *type2) · 740 unmodified lines | ||
| 3175 | 3329 | return compare_types(type1,type2,1); |
| 3176 | 3330 | } |
| 3177 | 3331 | |
| 3178 | −/* print a type. If 'varstr' is not NULL, then the variable is also | |
| 3179 | − printed in the type */ | |
| 3180 | −/* XXX: union */ | |
| 3181 | −/* XXX: add array and function pointers */ | |
| 3182 | −static void type_to_str(char *buf, int buf_size, | |
| 3183 | − CType *type, const char *varstr) | |
| 3184 | −{ | |
| 3185 | − int bt, v, t; | |
| 3186 | − Sym *s, *sa; | |
| 3187 | − char buf1[256]; | |
| 3188 | − const char *tstr; | |
| 3189 | − | |
| 3190 | − t = type->t; | |
| 3191 | − bt = t & VT_BTYPE; | |
| 3192 | − buf[0] = '\0'; | |
| 3193 | − | |
| 3194 | − if (t & VT_EXTERN) | |
| 3195 | − pstrcat(buf, buf_size, "extern "); | |
| 3196 | − if (t & VT_STATIC) | |
| 3197 | − pstrcat(buf, buf_size, "static "); | |
| 3198 | − if (t & VT_TYPEDEF) | |
| 3199 | − pstrcat(buf, buf_size, "typedef "); | |
| 3200 | − if (t & VT_INLINE) | |
| 3201 | − pstrcat(buf, buf_size, "inline "); | |
| 3202 | − if (t & VT_VOLATILE) | |
| 3203 | − pstrcat(buf, buf_size, "volatile "); | |
| 3204 | − if (t & VT_CONSTANT) | |
| 3205 | − pstrcat(buf, buf_size, "const "); | |
| 3206 | − | |
| 3207 | − if (((t & VT_DEFSIGN) && bt == VT_BYTE) | |
| 3208 | − || ((t & VT_UNSIGNED) | |
| 3209 | − && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG) | |
| 3210 | − && !IS_ENUM(t) | |
| 3211 | − )) | |
| 3212 | − pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed "); | |
| 3213 | − | |
| 3214 | − buf_size -= strlen(buf); | |
| 3215 | − buf += strlen(buf); | |
| 3216 | − | |
| 3217 | − switch(bt) { | |
| 3218 | − case VT_VOID: | |
| 3219 | − tstr = "void"; | |
| 3220 | − goto add_tstr; | |
| 3221 | − case VT_BOOL: | |
| 3222 | − tstr = "_Bool"; | |
| 3223 | − goto add_tstr; | |
| 3224 | − case VT_BYTE: | |
| 3225 | − tstr = "char"; | |
| 3226 | − goto add_tstr; | |
| 3227 | − case VT_SHORT: | |
| 3228 | − tstr = "short"; | |
| 3229 | − goto add_tstr; | |
| 3230 | − case VT_INT: | |
| 3231 | − tstr = "int"; | |
| 3232 | − goto maybe_long; | |
| 3233 | − case VT_LLONG: | |
| 3234 | − tstr = "long long"; | |
| 3235 | − maybe_long: | |
| 3236 | − if (t & VT_LONG) | |
| 3237 | − tstr = "long"; | |
| 3238 | − if (!IS_ENUM(t)) | |
| 3239 | − goto add_tstr; | |
| 3240 | − tstr = "enum "; | |
| 3241 | − goto tstruct; | |
| 3242 | − case VT_FLOAT: | |
| 3243 | − tstr = "float"; | |
| 3244 | − goto add_tstr; | |
| 3245 | − case VT_DOUBLE: | |
| 3246 | − tstr = "double"; | |
| 3247 | − if (!(t & VT_LONG)) | |
| 3248 | − goto add_tstr; | |
| 3249 | − case VT_LDOUBLE: | |
| 3250 | − tstr = "long double"; | |
| 3251 | − add_tstr: | |
| 3252 | − pstrcat(buf, buf_size, tstr); | |
| 3253 | − break; | |
| 3254 | − case VT_STRUCT: | |
| 3255 | − tstr = "struct "; | |
| 3256 | − if (IS_UNION(t)) | |
| 3257 | − tstr = "union "; | |
| 3258 | − tstruct: | |
| 3259 | − pstrcat(buf, buf_size, tstr); | |
| 3260 | − v = type->ref->v & ~SYM_STRUCT; | |
| 3261 | − if (v >= SYM_FIRST_ANOM) | |
| 3262 | − pstrcat(buf, buf_size, "<anonymous>"); | |
| 3263 | − else | |
| 3264 | − pstrcat(buf, buf_size, get_tok_str(v, NULL)); | |
| 3265 | − break; | |
| 3266 | − case VT_FUNC: | |
| 3267 | − s = type->ref; | |
| 3268 | − buf1[0]=0; | |
| 3269 | − if (varstr && '*' == *varstr) { | |
| 3270 | − pstrcat(buf1, sizeof(buf1), "("); | |
| 3271 | − pstrcat(buf1, sizeof(buf1), varstr); | |
| 3272 | − pstrcat(buf1, sizeof(buf1), ")"); | |
| 3273 | − } | |
| 3274 | − pstrcat(buf1, buf_size, "("); | |
| 3275 | − sa = s->next; | |
| 3276 | − while (sa != NULL) { | |
| 3277 | − char buf2[256]; | |
| 3278 | − type_to_str(buf2, sizeof(buf2), &sa->type, NULL); | |
| 3279 | − pstrcat(buf1, sizeof(buf1), buf2); | |
| 3280 | − sa = sa->next; | |
| 3281 | − if (sa) | |
| 3282 | − pstrcat(buf1, sizeof(buf1), ", "); | |
| 3283 | − } | |
| 3284 | − if (s->f.func_type == FUNC_ELLIPSIS) | |
| 3285 | − pstrcat(buf1, sizeof(buf1), ", ..."); | |
| 3286 | − pstrcat(buf1, sizeof(buf1), ")"); | |
| 3287 | − type_to_str(buf, buf_size, &s->type, buf1); | |
| 3288 | − goto no_var; | |
| 3289 | − case VT_PTR: | |
| 3290 | − s = type->ref; | |
| 3291 | − if (t & VT_ARRAY) { | |
| 3292 | − if (varstr && '*' == *varstr) | |
| 3293 | − snprintf(buf1, sizeof(buf1), "(%s)[%d]", varstr, s->c); | |
| 3294 | − else | |
| 3295 | − snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c); | |
| 3296 | − type_to_str(buf, buf_size, &s->type, buf1); | |
| 3297 | − goto no_var; | |
| 3298 | − } | |
| 3299 | − pstrcpy(buf1, sizeof(buf1), "*"); | |
| 3300 | − if (t & VT_CONSTANT) | |
| 3301 | − pstrcat(buf1, buf_size, "const "); | |
| 3302 | − if (t & VT_VOLATILE) | |
| 3303 | − pstrcat(buf1, buf_size, "volatile "); | |
| 3304 | − if (varstr) | |
| 3305 | − pstrcat(buf1, sizeof(buf1), varstr); | |
| 3306 | − type_to_str(buf, buf_size, &s->type, buf1); | |
| 3307 | − goto no_var; | |
| 3308 | − } | |
| 3309 | − if (varstr) { | |
| 3310 | − pstrcat(buf, buf_size, " "); | |
| 3311 | − pstrcat(buf, buf_size, varstr); | |
| 3312 | − } | |
| 3313 | − no_var: ; | |
| 3314 | −} | |
| 3315 | − | |
| 3316 | −static void type_incompatibility_error(CType* st, CType* dt, const char* fmt) | |
| 3317 | −{ | |
| 3318 | − char buf1[256], buf2[256]; | |
| 3319 | − type_to_str(buf1, sizeof(buf1), st, NULL); | |
| 3320 | − type_to_str(buf2, sizeof(buf2), dt, NULL); | |
| 3321 | − tcc_error(fmt, buf1, buf2); | |
| 3322 | −} | |
| 3323 | − | |
| 3324 | −static void type_incompatibility_warning(CType* st, CType* dt, const char* fmt) | |
| 3325 | −{ | |
| 3326 | − char buf1[256], buf2[256]; | |
| 3327 | − type_to_str(buf1, sizeof(buf1), st, NULL); | |
| 3328 | − type_to_str(buf2, sizeof(buf2), dt, NULL); | |
| 3329 | − tcc_warning(fmt, buf1, buf2); | |
| 3330 | −} | |
| 3331 | − | |
| 3332 | 3332 | static void cast_error(CType *st, CType *dt) |
| 3333 | 3333 | { |
| 3334 | 3334 | type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'"); |