int symtab_fold(symtable *tab, int current) { const int this_start = current; if(tab->decls){ const int word_size = platform_word_size(); decl **diter; int arg_offset; arg_offset = 0; /* need to walk backwards for args */ for(diter = tab->decls; *diter; diter++); for(diter--; diter >= tab->decls; diter--){ sym *s = (*diter)->sym; /*enum type_primitive last = type_int; TODO: packing */ if(s->type == sym_local && (s->decl->type->spec & (spec_extern | spec_static)) == 0){ int siz = decl_size(s->decl); if(siz <= word_size) s->offset = current; else s->offset = current + siz - word_size; /* an array and structs start at the bottom */ /* need to increase by a multiple of word_size */ if(siz % word_size) siz += word_size - siz % word_size; current += siz; /* static analysis on sym (only auto-vars) */ if(s->nwrites == 0 && !decl_has_array(s->decl)){ cc1_warn_at(&s->decl->where, 0, WARN_SYM_NEVER_WRITTEN, "\"%s\" never written to", s->decl->spel); s->nwrites++; /* only warn once */ } }else if(s->type == sym_arg){ s->offset = arg_offset; arg_offset += word_size; } } } { symtable **tabi; int subtab_max = 0; for(tabi = tab->children; tabi && *tabi; tabi++){ int this = symtab_fold(*tabi, current); if(this > subtab_max) subtab_max = this; } tab->auto_total_size = current - this_start + subtab_max; } return tab->auto_total_size; }
void gen_expr_sizeof(expr *e, symtable *stab) { decl *d = e->expr->tree_type; (void)stab; asm_temp(1, "push %d ; sizeof %s%s", decl_size(d), e->expr->expr_is_sizeof ? "type " : "", decl_to_str(d)); }
void asm_declare_decl_init(decl *d) { enum section_type sec; if((d->store & STORE_MASK_STORE) == store_extern){ asm_predeclare_extern(d); return; } sec = type_is_const(d->ref) ? SECTION_RODATA : SECTION_DATA; if(d->bits.var.init.dinit && !decl_init_is_zero(d->bits.var.init.dinit)){ asm_nam_begin(sec, d); asm_declare_init(sec, d->bits.var.init.dinit, d->ref); asm_out_section(sec, "\n"); }else if(d->bits.var.init.compiler_generated && fopt_mode & FOPT_COMMON){ const char *common_prefix = "comm "; /* section doesn't matter */ sec = SECTION_BSS; if(decl_linkage(d) == linkage_internal){ if(AS_SUPPORTS_LOCAL_COMMON){ asm_out_section(sec, ".local %s\n", decl_asm_spel(d)); }else{ common_prefix = "zerofill __DATA,__bss,"; } } asm_out_section(sec, ".%s%s,%u,%u\n", common_prefix, decl_asm_spel(d), decl_size(d), decl_align(d)); }else{ /* always resB, since we use decl_size() */ asm_nam_begin(SECTION_BSS, d); asm_reserve_bytes(SECTION_BSS, decl_size(d)); } }
void print_decl(decl *d, enum pdeclargs mode) { if(mode & PDECL_INDENT) idt_print(); if(d->store) fprintf(cc1_out, "%s ", decl_store_to_str(d->store)); if(fopt_mode & FOPT_ENGLISH){ print_decl_eng(d); }else{ print_type(d->ref, d); } if(mode & PDECL_SYM_OFFSET){ if(d->sym){ const int off = d->sym->type == sym_arg ? d->sym->loc.arg_offset : (int)d->sym->loc.stack_pos; fprintf(cc1_out, " (sym %s, pos = %d)", sym_to_str(d->sym->type), off); }else{ fprintf(cc1_out, " (no sym)"); } } if(mode & PDECL_SIZE && !type_is(d->ref, type_func)){ if(type_is_complete(d->ref)){ const unsigned sz = decl_size(d); const unsigned align = decl_align(d); fprintf(cc1_out, " size %u, align %u", sz, align); }else{ fprintf(cc1_out, " incomplete decl"); } } if(mode & PDECL_NEWLINE) fputc('\n', cc1_out); if(!type_is(d->ref, type_func) && d->bits.var.init.dinit && mode & PDECL_PINIT) { gen_str_indent++; print_decl_init(d->bits.var.init.dinit); gen_str_indent--; } if(mode & PDECL_ATTR){ gen_str_indent++; if(!type_is(d->ref, type_func) && d->bits.var.align) idt_printf("[align={as_int=%d, resolved=%d}]\n", d->bits.var.align->as_int, d->bits.var.align->resolved); print_attribute(d->attr); print_type_attr(d->ref); gen_str_indent--; } if((mode & PDECL_FUNC_DESCEND) && DECL_HAS_FUNC_CODE(d)){ decl **iter; gen_str_indent++; for(iter = d->bits.func.code->symtab->decls; iter && *iter; iter++){ sym *s = (*iter)->sym; if(s) idt_printf("offset of %s = %d\n", (*iter)->spel, s->loc.stack_pos); } idt_printf("function stack space %d\n", d->bits.func.code->symtab->auto_total_size); print_stmt(d->bits.func.code); gen_str_indent--; } }