static void type_add_str_pre( type *r, int *need_paren, int *need_spc, char **bufp, int *sz) { type *prev_skipped; enum type_qualifier q = qual_none; /* int (**fn())[2] * btype -> array -> ptr -> ptr -> func * ^ parens * * .tmp looks right, down the chain, .ref looks left, up the chain */ *need_paren = r->ref && IS_PTR(r->type) && (prev_skipped = type_skip_all(r->ref))->type != type_btype && !IS_PTR(prev_skipped->type); if(*need_paren){ ADD_SPC(); BUF_ADD("("); } switch(r->type){ case type_ptr: #ifdef SHOW_DECAYED_ARRAYS if(r->bits.ptr.size) break; /* decayed array */ #endif ADD_SPC(); BUF_ADD("*"); break; case type_cast: q = r->bits.cast.qual; break; case type_block: ADD_SPC(); BUF_ADD("^"); break; default:break; } if(q){ ADD_SPC(); BUF_ADD("%s", type_qual_to_str(q, 0)); *need_spc = 1; /* space out after qualifier, e.g. * int *const p; * ^ * int const a; * ^ */ } }
static void print_type_eng(type *ref) { if(!ref) return; print_type_eng(ref->ref); switch(ref->type){ case type_auto: ICE("__auto_type"); case type_cast: if(ref->bits.cast.is_signed_cast) fprintf(cc1_out, "%s ", ref->bits.cast.signed_true ? "signed" : "unsigned"); else fprintf(cc1_out, "%s", type_qual_to_str(ref->bits.cast.qual, 1)); break; case type_ptr: fprintf(cc1_out, "pointer to "); break; case type_block: fprintf(cc1_out, "block returning "); break; case type_func: { #ifdef ENGLISH_PRINT_ARGLIST funcargs *fargs = ref->bits.func.args; decl **iter; #endif fputs("function", cc1_out); #ifdef ENGLISH_PRINT_ARGLIST fputc('(', cc1_out); if(fargs->arglist){ for(iter = fargs->arglist; iter && *iter; iter++){ print_decl(*iter, PDECL_NONE); if(iter[1]) fputs(", ", cc1_out); } if(fargs->variadic) fputs("variadic", cc1_out); }else{ fprintf(cc1_out, "taking %s arguments", fargs->args_void ? "no" : "unspecified"); } fputc(')', cc1_out); #endif fputs(" returning ", cc1_out); break; } case type_array: fputs("array[", cc1_out); if(ref->bits.array.size) print_expr_val(ref->bits.array.size); fputs("] of ", cc1_out); break; case type_btype: fprintf(cc1_out, "%s", btype_to_str(ref->bits.type)); break; case type_tdef: case type_attr: ICE("TODO"); case type_where: break; } }
static void type_add_str( type *r, const char *spel, int *need_spc, char **bufp, int *sz, type *stop_at) { int need_paren; type *array_qual = NULL, *next_ty; if(!r){ /* reached the bottom/end - spel */ if(spel){ ADD_SPC(); BUF_ADD("%s", spel); *need_spc = 0; } return; } if(stop_at && r->tmp == stop_at){ type_add_str(r->tmp, spel, need_spc, bufp, sz, stop_at); return; } type_add_str_pre(r, &need_paren, need_spc, bufp, sz); next_ty = r->tmp; if(r->type == type_array && r->tmp && r->tmp->type == type_cast){ array_qual = r->tmp; next_ty = array_qual->tmp; } type_add_str(next_ty, spel, need_spc, bufp, sz, stop_at); switch(r->type){ case type_auto: ICE("__auto_type"); case type_tdef: /* tdef "aka: %s" handled elsewhere */ case type_attr: /* attribute not handled here */ case type_btype: case type_cast: case type_where: /**/ case type_block: break; case type_func: type_add_funcargs(r->bits.func.args, need_spc, bufp, sz); break; case type_ptr: #ifdef SHOW_DECAYED_ARRAYS if(!r->bits.ptr.size) #endif break; /* fall */ case type_array: { const char *sz_space = ""; BUF_ADD("["); if(r->bits.array.is_vla == 0 && r->bits.array.is_static){ BUF_ADD("static"); sz_space = " "; } if(array_qual){ BUF_ADD("%s%s", sz_space, type_qual_to_str(array_qual->bits.cast.qual, 0)); sz_space = " "; } switch(r->bits.array.is_vla){ case 0: if(r->bits.array.size){ BUF_ADD( "%s%" NUMERIC_FMT_D, sz_space, const_fold_val_i(r->bits.array.size)); } break; case VLA: BUF_ADD("vla"); break; case VLA_STAR: BUF_ADD("*"); break; } BUF_ADD("]"); break; } } if(need_paren) BUF_ADD(")"); #undef IS_PTR }