pike.git / src / program.c

version» Context lines:

pike.git/src/program.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: program.c,v 1.621 2007/09/29 15:09:02 grubba Exp $ + || $Id: program.c,v 1.622 2007/10/11 15:46:57 grubba Exp $   */      #include "global.h"   #include "program.h"   #include "object.h"   #include "dynamic_buffer.h"   #include "pike_types.h"   #include "stralloc.h"   #include "las.h"   #include "lex.h"
pike.git/src/program.c:1924: Inside #if defined(PIKE_DEBUG) and #if defined(DEBUG_MALLOC)
   return make_shared_string(tmp);    }    }    }   #endif       return get_program_line(p, line);   }   #endif    - int override_identifier (struct reference *ref, struct pike_string *name) + int override_identifier (struct reference *new_ref, struct pike_string *name)   { -  int id = -1, cur_id = 0; +  int id = -1, cur_id = 0, is_used = 0;       int new_is_variable =    IDENTIFIER_IS_VARIABLE(ID_FROM_PTR(Pike_compiler->new_program, -  ref)->identifier_flags); +  new_ref)->identifier_flags);       /* This loop could possibly be optimized by looping over    * each inherit and looking up 'name' in each inherit    * and then see if should be overwritten    * /Hubbe    */       for(;cur_id<Pike_compiler->new_program->num_identifier_references;cur_id++)    { -  +  struct reference *ref = +  Pike_compiler->new_program->identifier_references + cur_id; +  struct identifier *i; +  +  /* No need to do anything for ourselves. */ +  if (ref == new_ref) continue; +     /* Do not zapp hidden identifiers */ -  if(Pike_compiler->new_program->identifier_references[cur_id].id_flags & ID_HIDDEN) -  continue; +  if(ref->id_flags & ID_HIDDEN) continue;       /* Do not zapp inherited inline ('local') identifiers */ -  if((Pike_compiler->new_program->identifier_references[cur_id].id_flags & -  (ID_INLINE|ID_INHERITED)) == (ID_INLINE|ID_INHERITED)) +  if((ref->id_flags & (ID_INLINE|ID_INHERITED)) == (ID_INLINE|ID_INHERITED))    continue;       /* Do not zapp functions with the wrong name... */ -  if(ID_FROM_INT(Pike_compiler->new_program, cur_id)->name != name) +  if((i = ID_FROM_PTR(Pike_compiler->new_program, ref))->name != name)    continue;      #ifdef PROGRAM_BUILD_DEBUG    fprintf(stderr, "%.*soverloaded reference %d (id_flags:0x%04x)\n", -  compilation_depth, " ", cur_id, -  Pike_compiler->new_program->identifier_references[cur_id].id_flags); +  compilation_depth, " ", cur_id, ref->id_flags);   #endif    -  if (!new_is_variable && -  IDENTIFIER_IS_VARIABLE(ID_FROM_INT(Pike_compiler->new_program, -  cur_id)->identifier_flags)) { +  if (!new_is_variable && IDENTIFIER_IS_VARIABLE(i->identifier_flags)) {    /* Overloading a variable with a constant or a function.    * This is generally a bad idea.    */ -  Pike_compiler->new_program->identifier_references[cur_id].id_flags |= -  ID_INLINE|ID_HIDDEN; +  ref->id_flags |= ID_INLINE|ID_HIDDEN;    yywarning("Attempt to override a non local variable %S " -  "with a non variable.", name); +  "with a non-variable.", name);    continue;    }    -  Pike_compiler->new_program->identifier_references[cur_id]=*ref; +  if ((ref->id_flags & (ID_INHERITED|ID_USED)) == (ID_INHERITED|ID_USED)) { +  struct inherit *inh = INHERIT_FROM_PTR(Pike_compiler->new_program, ref); +  struct reference *sub_ref; +  +  /* Find the inherit one level away. */ +  while (inh->inherit_level > 1) inh--; +  + #ifdef PIKE_DEBUG +  if (!inh->inherit_level) { +  Pike_fatal("Inherit without intermediate levels.\n"); +  } + #endif +  +  sub_ref = PTR_FROM_INT(inh->prog, cur_id - inh->identifier_level); +  +  /* Check if the symbol was used before it was inherited. */ +  if (sub_ref->id_flags & ID_USED) { +  if (!pike_types_le(ID_FROM_PTR(inh->prog, sub_ref)->type, +  ID_FROM_PTR(Pike_compiler->new_program, +  new_ref)->type)) { +  yywarning("Type mismatch when overloading %S.", name); +  yytype_error(NULL, +  ID_FROM_PTR(inh->prog, sub_ref)->type, +  ID_FROM_PTR(Pike_compiler->new_program, new_ref)->type, +  YYTE_IS_WARNING); +  } +  } +  } +  is_used = ref->id_flags & ID_USED; +  +  *ref=*new_ref; +  ref->id_flags |= is_used;    id = cur_id;    }       return id;   }      void fixate_program(void)   {    INT32 i,e,t;    struct program *p=Pike_compiler->new_program;
pike.git/src/program.c:2010:    p->identifiers[i].run_time_type = T_FUNCTION;    }    }       /* Fixup identifier overrides. */    for (i = 0; i < p->num_identifier_references; i++) {    struct reference *ref = p->identifier_references + i;    if (ref->id_flags & ID_HIDDEN) continue;    if (ref->inherit_offset != 0) continue;    override_identifier (ref, ID_FROM_PTR (p, ref)->name); +  +  if ((ref->id_flags & (ID_HIDDEN|ID_PRIVATE|ID_USED)) == ID_PRIVATE) { +  yywarning("%S is private but not used anywhere.", +  ID_FROM_PTR(p, ref)->name);    } -  +  }       /* Ok, sort for binsearch */    for(e=i=0;i<(int)p->num_identifier_references;i++)    {    struct reference *funp;    struct identifier *fun;    funp=p->identifier_references+i;    if(funp->id_flags & ID_HIDDEN) continue;    fun=ID_FROM_PTR(p, funp);    if(funp->id_flags & ID_INHERITED)
pike.git/src/program.c:2052:    found_better=t;       /* FIXME: Is this stuff needed?    * It looks like it already is done by define_function().    *    * Yes -- It's needed in case of mixin.    */    if(funa_is_prototype && (funb->func.offset != -1) &&    !(funp->id_flags & ID_INLINE))    { +  if (funp->id_flags & ID_USED) { +  /* Verify that the types are compatible. */ +  if (!pike_types_le(fun->type, funb->type)) { +  yywarning("Type mismatch when overloading %S.", fun->name); +  yytype_error(NULL, fun->type, funb->type, YYTE_IS_WARNING); +  } +  }    funp->inherit_offset = funpb->inherit_offset;    funp->identifier_offset = funpb->identifier_offset;    }    if(!funa_is_prototype && funb->func.offset == -1)    { -  +  if (funpb->id_flags & ID_USED) { +  /* Verify that the types are compatible. */ +  if (!pike_types_le(funb->type, fun->type)) { +  yywarning("Type mismatch when overloading %S.", fun->name); +  yytype_error(NULL, funb->type, fun->type, YYTE_IS_WARNING); +  } +  }    funpb->inherit_offset = funp->inherit_offset;    funpb->identifier_offset = funp->identifier_offset;    }    }    }    if(found_better!=-1)    continue;    }    if ((fun->func.offset == -1) && (funp->id_flags & ID_INLINE) &&    IDENTIFIER_IS_PIKE_FUNCTION(fun->identifier_flags)) {
pike.git/src/program.c:3665:    funp.inherit_offset += e;    funp.id_flags = (funp.id_flags & ~ID_INHERITED) | ID_INLINE|ID_HIDDEN;       num_id_refs = np->num_identifier_references;       for(d = 0; d < num_id_refs; d++)    {    struct reference *refp;    refp = np->identifier_references + d;    -  if(!MEMCMP((char *)refp,(char *)&funp,sizeof funp)) return d; +  if ((refp->inherit_offset == funp.inherit_offset) && +  (refp->identifier_offset == funp.identifier_offset) && +  ((refp->id_flags | ID_USED) == (funp.id_flags | ID_USED))) +  return d;    }       if(q)    low_add_to_identifier_references(q,funp);    else    add_to_identifier_references(funp);    /* NOTE: np->num_identifier_references has been increased by one by    * {low_,}add_to_identifier_references().    */   #ifdef PIKE_DEBUG
pike.git/src/program.c:4569:    struct pike_string *n;    struct pike_type *t;      #ifdef PROGRAM_BUILD_DEBUG    fprintf (stderr, "%.*sdefining variable (pass=%d): %s %s\n",    compilation_depth, " ", Pike_compiler->compiler_pass, type, name);   #endif       n=make_shared_string(name);    t=parse_type(type); -  ret=low_define_variable(n,t,flags,offset,run_time_type); +  ret=low_define_variable(n,t,flags|ID_USED,offset,run_time_type);    free_string(n);    free_type(t);    return ret;   }      PMOD_EXPORT int quick_map_variable(const char *name,    int name_length,    size_t offset,    const char *type,    int type_length,
pike.git/src/program.c:4602: Inside #if defined(PROGRAM_BUILD_DEBUG)
   struct pike_string *d = describe_type (t);    fprintf (stderr, "%.*sdefining variable (pass=%d): %s ",    compilation_depth, " ", Pike_compiler->compiler_pass, d->str);    free_string (d);    push_string (n);    print_svalue (stderr, --Pike_sp);    putc ('\n', stderr);    }   #endif    -  ret=low_define_variable(n,t,flags,offset,run_time_type); +  ret=low_define_variable(n,t,flags|ID_USED,offset,run_time_type);    free_string(n);    free_type(t);    return ret;   }      /* argument must be a shared string */   int define_variable(struct pike_string *name,    struct pike_type *type,    INT32 flags)   {
pike.git/src/program.c:4981:    /* not inherited */    if(Pike_compiler->new_program->identifier_references[n].inherit_offset == 0)    {    my_yyerror("Identifier %S defined twice.", name);    return n;    }       /* override */    if ((overridden = override_identifier (&ref, name)) >= 0) {   #ifdef PIKE_DEBUG -  if(MEMCMP(Pike_compiler->new_program->identifier_references+n, &ref,sizeof(ref))) +  struct reference *oref = +  Pike_compiler->new_program->identifier_references+overridden; +  if((oref->inherit_offset != ref.inherit_offset) || +  (oref->identifier_offset != ref.identifier_offset) || +  ((oref->id_flags | ID_USED) != (ref.id_flags | ID_USED))) {    Pike_fatal("New constant overriding algorithm failed!\n"); -  +  }   #endif    return overridden;    }    }    n=Pike_compiler->new_program->num_identifier_references;    add_to_identifier_references(ref);       return n;   }   
pike.git/src/program.c:5250:    id_flags & ID_INHERITED)) {    /* Not an inherited symbol. */    struct identifier *id = ID_FROM_INT(Pike_compiler->new_program, i);    if (!IDENTIFIER_IS_VARIABLE(id->identifier_flags)) {    my_yyerror("Illegal to redefine function %S with variable.", symbol);    getter_setter_offset = -1;    } else if (id->run_time_type != PIKE_T_GET_SET) {    my_yyerror("Illegal to redefine a current variable with a getter/setter: %S.", symbol);    getter_setter_offset = -1;    } else { -  if (ref->id_flags != flags) { +  if ((ref->id_flags | ID_USED) != (flags | ID_USED)) {    if (Pike_compiler->compiler_pass == 1) {    yywarning("Modifier mismatch for variable %S.", symbol);    } -  ref->id_flags &= flags; +  ref->id_flags &= flags | ID_USED;    }    getter_setter_offset += id->func.offset;    }    /* FIXME: Update id->type here. */    } else {    INT32 offset = Pike_compiler->new_program->num_program;    getter_setter_offset += offset;    /* Get/set information.    * reference number to getter.    * reference number to setter.
pike.git/src/program.c:5415:    fun.opt_flags = opt_flags;       ref.identifier_offset=Pike_compiler->new_program->num_identifiers;    debug_add_to_identifiers(fun);    }       ref.inherit_offset = 0;    ref.id_flags = flags;    if ((overridden = override_identifier (&ref, name)) >= 0) {   #ifdef PIKE_DEBUG -  if(MEMCMP(Pike_compiler->new_program->identifier_references+i, &ref,sizeof(ref))) +  struct reference *oref = +  Pike_compiler->new_program->identifier_references+overridden; +  if((oref->inherit_offset != ref.inherit_offset) || +  (oref->identifier_offset != ref.identifier_offset) || +  ((oref->id_flags | ID_USED) != (ref.id_flags | ID_USED))) { +  fprintf(stderr, +  "ref: %d:%d 0x%04x\n" +  "got: %d:%d 0x%04x (%d)\n", +  ref.inherit_offset, ref.identifier_offset, +  ref.id_flags, +  oref->inherit_offset, +  oref->identifier_offset, +  oref->id_flags, +  overridden);    Pike_fatal("New function overloading algorithm failed!\n"); -  +  }   #endif       if (getter_setter_offset >= 0) {    INT32 old_i = (INT32)read_pointer(getter_setter_offset);    if ((old_i >= 0) && (old_i != overridden)) {    my_yyerror("Multiple definitions for %S.", name);    }    upd_pointer(getter_setter_offset, overridden);    }    return overridden;
pike.git/src/program.c:5506: Inside #if 0
     int add_ext_ref(struct program_state *state, struct program *target, int i)   {    struct reference ref, *r;    int j;    if (state->new_program == target) return i;    i = add_ext_ref(state->previous, target, i);    for (r = state->new_program->identifier_references, j = 0;    j < state->new_program->num_identifier_references;    j++, r++) { -  if (((r->id_flags & ID_PARENT_REF|ID_STATIC|ID_PRIVATE|ID_HIDDEN) == +  if (((r->id_flags & (ID_PARENT_REF|ID_STATIC|ID_PRIVATE|ID_HIDDEN)) ==    ID_PARENT_REF|ID_STATIC|ID_PRIVATE|ID_HIDDEN) &&    (r->identifier_offset == i) &&    (!(r->inherit_offset))) {    return j;    }    }    ref.id_flags = ID_PARENT_REF|ID_STATIC|ID_PRIVATE|ID_HIDDEN;    ref.identifier_offset = i;    ref.inherit_offset = 0;    add_to_identifier_references(ref);
pike.git/src/program.c:6237: Inside #if defined(PIKE_DEBUG)
   for (;start < cnt; start++) {    fprintf(stderr, "%02x ", *((unsigned char *)start));    }    fprintf(stderr, "\n");    }    }       if(Pike_compiler->last_line != line ||    Pike_compiler->last_pc != off ||    (Pike_compiler->last_file && file && -  memcmp(Pike_compiler->last_file->str, file, len<<shift))) +  MEMCMP(Pike_compiler->last_file->str, file, len<<shift)))    {    Pike_fatal("Line numbering out of whack\n"    " (line : %d ?= %d)!\n"    " ( pc : %d ?= %d)!\n"    " (shift: %d ?= %d)!\n"    " (len : %"PRINTSIZET"d ?= %"PRINTSIZET"d)!\n"    " (file : %s ?= %s)!\n",    Pike_compiler->last_line, line,    Pike_compiler->last_pc, off,    Pike_compiler->last_file?Pike_compiler->last_file->size_shift:0,
pike.git/src/program.c:8299: Inside #if 0
   return i;    }    }    }    return -1;   }   #endif /* 0 */      void yywarning(char *fmt, ...)   { +  struct string_builder s; +  struct pike_string *msg; +  va_list args; +     /* If we have parse errors we might get erroneous warnings,    * so don't print them.    * This has the additional benefit of making it easier to    * visually locate the actual error message.    */    if (Pike_compiler->num_parse_error) return;    -  /* Don't bother generating the warning message if we don't have -  * anywhere to report it... -  */ -  if ((error_handler && error_handler->prog) || get_master()) { -  struct string_builder s; -  va_list args; -  +     init_string_builder(&s, 0);    va_start(args,fmt);    string_builder_vsprintf(&s, fmt, args);    va_end(args); -  +  msg = finish_string_builder(&s);    -  +  if (master_object) {    ref_push_string(lex.current_file);    push_int(lex.current_line); -  push_string(finish_string_builder(&s)); +  push_string(msg);       low_safe_apply_handler("compile_warning",    error_handler, compat_handler, 3);    pop_stack(); -  +  } else { +  if (!msg->size_shift) { +  fprintf(stderr, "%s:%d: Warning: %s\n", +  lex.current_file->str, lex.current_line, msg->str);    } -  +  free_string(msg);    } -  + }            /* returns 1 if a implements b */   static int low_implements(struct program *a, struct program *b)   {    int e;    struct pike_string *s=findstring("__INIT");    for(e=0;e<b->num_identifier_references;e++)    {