this revision breaks parrot on msvc (and i suspect other c89-compliant compilers--sometimes i wonder if there are any others!)
in particular, in the following chunk (snipped from overall patch for brevity) the UNUSED(foo) macro is used before variables are declared in the body of the find_outer() function. fixing that (by moving C<UNUSED(interp);> below the declarations leads to problems with another chunk, which i describe after this one. Modified: trunk/compilers/imcc/pbc.c ============================================================================== --- trunk/compilers/imcc/pbc.c (original) +++ trunk/compilers/imcc/pbc.c Wed May 16 13:58:40 2007 @@ -565,71 +600,87 @@ lex_info = pmc_new_noinit(interp, lex_info_id); VTABLE_init_pmc(interp, lex_info, sub); } + + /* at least one lexical name */ n = r->reg; - assert(n); /* at least one lexical name */ + assert(n); + while (n) { k = n->color; assert(k >= 0); + lex_name = constants[k]->u.string; assert(PObj_is_string_TEST(lex_name)); + IMCC_debug(interp, DEBUG_PBC_CONST, "add lexical '%s' to sub name '%s'\n", n->name, (char*)PMC_sub(sub)->name->strstart); - (decl_func)(interp, - lex_info, lex_name, r->color); + + (decl_func)(interp, lex_info, lex_name, r->color); + /* next possible name */ n = n->reg; } } } } + if (!lex_info && (unit->outer || need_lex)) { lex_info = pmc_new_noinit(interp, lex_info_id); VTABLE_init_pmc(interp, lex_info, sub); } + return lex_info; } static PMC* find_outer(Interp *interp, IMC_Unit *unit) { - struct subs *s; + UNUSED(interp); + + subs_t *s; SymReg *sub; - size_t len; - PMC *current; + size_t len; + PMC *current; STRING *cur_name; if (!unit->outer) return NULL; + /* * we need that the :outer sub is already compiled, * because we are freezing the outer Sub PMC along with this * one */ - UNUSED(interp); + len = strlen(unit->outer->name); + if (!len) return NULL; + for (s = globals.cs->first; s; s = s->next) { sub = s->unit->instructions->r[0]; + if (!strcmp(sub->name, unit->outer->name)) { PObj_get_FLAGS(s->unit->sub_pmc) |= SUB_FLAG_IS_OUTER; return s->unit->sub_pmc; } } - /* - * could be eval too - look, if :outer is the currentsub - */ + + /* could be eval too; check if :outer is the current sub */ current = CONTEXT(interp->ctx)->current_sub; + if (! current) IMCC_fatal(interp, 1, "Undefined :outer sub '%s'.\n", unit->outer->name); + cur_name = PMC_sub(current)->name; + if (cur_name->strlen == len && - !memcmp((char*)cur_name->strstart, unit->outer->name, len)) { + !memcmp((char*)cur_name->strstart, unit->outer->name, len)) return current; - } + return NULL; } the chunk below causes msvc to output the following: compilers\imcc\pbc.c compilers\imcc\pbc.c(921) : error C2275: 'SymReg' : illegal use of this type as an expression d:\usr\local\parrot\head\compilers\imcc\symreg.h(80) : see declaration o f 'SymReg' compilers\imcc\pbc.c(921) : error C2065: 'reg' : undeclared identifier compilers\imcc\pbc.c(923) : error C2223: left of '->nextkey' must point to struc t/union compilers\imcc\pbc.c(927) : warning C4047: '=' : 'SymReg *' differs in levels of indirection from 'int' NMAKE : fatal error U1077: 'D:\usr\local\perl\bin\perl.exe' : return code '0x2' Stop. i've tried various things to get this to work, but i can't find the magic incantation. @@ -834,47 +898,57 @@ build_key(Interp *interp, SymReg *key_reg) { #define KEYLEN 21 - opcode_t key[KEYLEN], *pc, size; - char s_key[KEYLEN*10]; - int key_length; /* P0["hi;there"; S0; 2] has length 3 */ - char *s; - int k; - SymReg *r, *reg; - int var_type, slice_bits, type; - - pc = key + 1; /* 0 is length */ - s = s_key; /* stringified key */ - *s = 0; - reg = key_reg->set == 'K' ? key_reg->nextkey : key_reg; + char s_key[KEYLEN * 10]; + opcode_t key[KEYLEN]; + opcode_t size; + int key_length; /* P0["hi;there"; S0; 2] has length 3 */ + int k; + SymReg *r; + int var_type, slice_bits, type; + + /* 0 is length */ + opcode_t *pc = key + 1; + + /* stringified key */ + char *s = s_key; + *s = 0; + + SymReg *reg = key_reg->set == 'K' ? key_reg->nextkey : key_reg; for (key_length = 0; reg ; reg = reg->nextkey, key_length++) { if ((pc - key - 2) >= KEYLEN) IMCC_fatal(interp, 1, "build_key:" "key too complex increase KEYLEN\n"); r = reg; + /* if key is a register, the original sym is in r->reg */ type = r->type; + if (r->reg) r = r->reg; - var_type = type & ~VT_SLICE_BITS; - slice_bits = type & VT_SLICE_BITS; + + var_type = type & ~VT_SLICE_BITS; + slice_bits = type & VT_SLICE_BITS; + switch (var_type) { case VTIDENTIFIER: /* P[S0] */ - case VTPASM: /* P[S0] */ - case VTREG: /* P[S0] */ + case VTPASM: /* P[S0] */ + case VTREG: /* P[S0] */ if (r->set == 'I') *pc++ = PARROT_ARG_I | slice_bits; /* register type */ else if (r->set == 'S') *pc++ = PARROT_ARG_S | slice_bits; else - IMCC_fatal(interp, 1, "build_key: " - "wrong register set\n"); + IMCC_fatal(interp, 1, "build_key: wrong register set\n"); + /* don't emit mapped regs in key parts */ if (r->color < 0) *pc++ = -1 - r->color; else *pc++ = r->color; + sprintf(s+strlen(s), "%c%d", r->set, (int)r->color); + IMCC_debug(interp, DEBUG_PBC_CONST, " keypart reg %s %c%d slice %s\n", r->name, r->set, (int)r->color, this situation is *extremely* frustrating. the temporary workaround is to revert this patch until it works everywhere. the solution is to find a way to make gcc (and other) compilers comply with our most important coding standard: C89 compliance. i have all too often experienced broken builds because somebody has committed non-C89 code. i'm tired of being punished for having a strict compiler. gcc has flags for this--let's use them! i'll happily pitch in to the extent that i'm able, but i can't be responsible for the whole effort. we need the whole team to focus on this problem, so we can finally resolve this long-standing issue. ~jerry