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 | static int pointed_size(CType *type) | 2586 | static int pointed_size(CType *type) |
| 2433 | { | 2587 | { |
| 2434 | int align; | 2588 | int align; |
| @@ -3175,160 +3329,6 @@ static int is_compatible_unqualified_types(CType *type1, CType *type2) · 740 unmodified lines | |||
| 3175 | return compare_types(type1,type2,1); | 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 | static void cast_error(CType *st, CType *dt) | 3332 | static void cast_error(CType *st, CType *dt) |
| 3333 | { | 3333 | { |
| 3334 | type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'"); | 3334 | type_incompatibility_error(st, dt, "cannot convert '%s' to '%s'"); |