void newfunc_typed(int storage, char *n, int type) { int idx; SYMBOL *symbol; char an[NAMESIZE]; fexitlab = getlabel(); if ((idx = find_global(n)) > -1) { symbol = &symbol_table[idx]; if (symbol->identity != FUNCTION) multidef(n); } else { /* extern implies global scope */ idx = add_global(n, FUNCTION, CINT, 0, storage == EXTERN ? PUBLIC : storage); symbol = &symbol_table[idx]; } local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; argstk = 0; // ANSI style argument declaration if (doAnsiArguments()) { if (storage == EXTERN) { need_semicolon(); return; } /* No body .. just a definition */ if (match(";")) return; } else { // K&R style argument declaration while (!match(")")) { if (symname(an)) { if (find_locale(an) > -1) multidef(an); else { /* FIXME: struct */ add_local(an, 0, 0, argstk, AUTO); argstk = argstk + INTSIZE; } } else { error("illegal argument name"); junk(); } blanks(); if (!streq(line + lptr, ")")) { if (!match(",")) error("expected comma"); } if (endst()) break; } if (storage == EXTERN) { need_semicolon(); return; } /* No body .. just a definition */ if (match(";")) return; stkp = 0; argtop = argstk; while (argstk) { if ((type = get_type()) != -1) { notvoid(type); getarg(type); need_semicolon(); } else { error("wrong number args"); break; } } } if (symbol->offset == FUNCTION) multidef(n); symbol->offset = FUNCTION; output_string(n); output_label_terminator(); newline(); gen_prologue(); statement(YES); print_label(fexitlab); output_label_terminator(); newline(); gen_epilogue(); gen_modify_stack(0); gen_ret(); stkp = 0; local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; }
/** * declare a static variable * @param type * @param storage * @param mtag tag of struct whose members are being declared, or zero * @param otag tag of struct object being declared. only matters if mtag is non-zero * @param is_struct struct or union or no meaning * @return 1 if a function was parsed */ int declare_global(int type, int storage, TAG_SYMBOL *mtag, int otag, int is_struct) { int dim, identity; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst ()) return 0; dim = 1; if (match ("*")) { identity = POINTER; } else { identity = VARIABLE; } if (!symname (sname)) illname (); if (match ("(")) { /* FIXME: We need to deal with pointer types properly here */ if (identity == POINTER) type = CINT; newfunc_typed(storage, sname, type); /* Can't int foo(x){blah),a=4; */ return 1; } /* FIXME: we need to deal with extern properly here */ if (find_global (sname) > -1) multidef (sname); if (identity == VARIABLE) notvoid(type); if (match ("[")) { dim = needsub (); //if (dim || storage == EXTERN) { identity = ARRAY; //} else { // identity = POINTER; //} } // add symbol if (mtag == 0) { // real variable, not a struct/union member identity = initials(sname, type, identity, dim, otag); add_global (sname, identity, type, (dim == 0 ? -1 : dim), storage); if (type == STRUCT) { symbol_table[current_symbol_table_idx].tagidx = otag; } break; } else if (is_struct) { // structure member, mtag->size is offset add_member(sname, identity, type, mtag->size, storage); // store (correctly scaled) size of member in tag table entry if (identity == POINTER) type = CINT; scale_const(type, otag, &dim); mtag->size += dim; } else { // union member, offset is always zero add_member(sname, identity, type, 0, storage); // store maximum member size in tag table entry if (identity == POINTER) type = CINT; scale_const(type, otag, &dim); if (mtag->size < dim) mtag->size = dim; } } if (!match (",")) return 0; } }