pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.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: pike_types.c,v 1.320 2008/04/01 13:20:07 mast Exp $ + || $Id: pike_types.c,v 1.321 2008/04/14 10:14:41 grubba Exp $   */      #include "global.h"   #include <ctype.h>   #include "svalue.h"   #include "pike_types.h"   #include "stralloc.h"   #include "stuff.h"   #include "array.h"   #include "program.h"
pike.git/src/pike_types.c:20:   #include "pike_macros.h"   #include "pike_error.h"   #include "las.h"   #include "lex.h"   #include "pike_memory.h"   #include "bignum.h"   #include "main.h"   #include "opcodes.h"   #include "cyclic.h"   #include "gc.h" + #include "pike_compiler.h"   #include "block_alloc.h"      #ifdef PIKE_DEBUG   #define PIKE_TYPE_DEBUG   #endif /* PIKE_DEBUG */      /*    * Flags used by low_match_types().    */   #define A_EXACT 1
pike.git/src/pike_types.c:48:   #define LE_A_B_SWAPPED 2 /* Argument A and B have been swapped.    * Relevant for markers.    */   #ifdef TYPE_GROUPING   #define LE_A_GROUPED 0/*4*/ /* Argument A has been grouped.    * Perform weaker checking for OR-nodes. */   #define LE_B_GROUPED 0/*8*/ /* Argument B has been grouped.    * Perform weaker checking for OR-nodes. */   #define LE_A_B_GROUPED 0/*12*/ /* Both the above two flags. */   #endif + #define LE_USE_HANDLERS 16 /* Call handlers if appropriate. */      /*    * Flags used by low_get_first_arg_type()    */   #define FILTER_KEEP_VOID 1 /* Keep void during the filtering. */      /*    * Flags used as flag_method to mk_type()    */   #define PT_COPY_CAR 1
pike.git/src/pike_types.c:1864:    fprintf(stderr, "%d", s->type-'0');    break;       case PIKE_T_NAME:    fprintf(stderr, "{ %s = ", ((struct pike_string *)s->car)->str);    simple_describe_type(s->cdr);    fprintf(stderr, " }");    break;       case PIKE_T_ATTRIBUTE: +  { +  struct pike_string *deprecated; +  MAKE_CONST_STRING(deprecated, "deprecated"); +  if (((struct pike_string *)s->car) == deprecated) { +  fprintf(stderr, "__deprecated__("); +  } else {    fprintf(stderr, "__attribute__(\"%s\", ",    ((struct pike_string *)s->car)->str); -  +  }    simple_describe_type(s->cdr);    fprintf(stderr, ")"); -  +  }    break;       case T_SCOPE:    fprintf(stderr, "scope(%"PRINTPTRDIFFT"d, ", CAR_TO_INT(s));    simple_describe_type(s->cdr);    fprintf(stderr, ")");    break;    case T_TUPLE:    fprintf(stderr, "tuple(");    simple_describe_type(s->car);
pike.git/src/pike_types.c:2207:    my_strcat(" = ");    my_describe_type(t->cdr);    my_strcat(" }");    } else {    my_describe_type(t->cdr);    }    break;       case PIKE_T_ATTRIBUTE:    if (!((struct pike_string *)t->car)->size_shift) { +  struct pike_string *deprecated; +  MAKE_CONST_STRING(deprecated, "deprecated"); +  if (((struct pike_string *)t->car) == deprecated) { +  my_strcat("__deprecated__("); +  } else {    my_strcat("__attribute__(\"");    my_binary_strcat(((struct pike_string *)t->car)->str,    ((struct pike_string *)t->car)->len);    my_strcat("\", "); -  +  }    my_describe_type(t->cdr);    my_strcat(")");    } else {    my_describe_type(t->cdr);    }    break;       case T_FUNCTION:    case T_MANY:    {
pike.git/src/pike_types.c:3720:    case PIKE_T_RING:    a = a->car;    goto recurse;       case PIKE_T_SCOPE:   #ifdef TYPE_GROUPING    flags |= LE_A_GROUPED;   #endif    /* FALL_THROUGH */    case PIKE_T_NAME: +  a = a->cdr; +  goto recurse;    case PIKE_T_ATTRIBUTE: -  +  if ((b->type == PIKE_T_ATTRIBUTE) && (a->car == b->car)) {    a = a->cdr; -  +  b = b->cdr;    goto recurse; -  +  } + #if 0 +  if (!flags & LE_USE_HANDLERS) { +  a = a->cdr; +  goto recurse; +  } + #endif /* 0 */ +  if (!low_pike_types_le(a->cdr, b, array_cnt, flags)) return 0; + #if 0 +  ref_push_string((struct pike_string *)a->car); +  ref_push_type_value(a->cdr); +  ref_push_type_value(b); +  push_int(1); +  if (safe_apply_handler("handle_attribute", error_handler, compat_handler, +  4, 0)) { +  if ((Pike_sp[-1].type == T_INT) && +  (Pike_sp[-1].subtype == NUMBER_NUMBER) && +  (!Pike_sp[-1].u.integer)) { +  pop_stack(); +  return 0; +  } +  pop_stack(); +  } + #endif /* 0 */ +  return 1;       case T_NOT:    if (b->type == T_NOT) {    struct pike_type *tmp = a->car;    a = b->car;    b = tmp;    array_cnt = -array_cnt;    flags ^= LE_A_B_SWAPPED   #ifdef TYPE_GROUPING    |LE_A_B_GROUPED
pike.git/src/pike_types.c:3856:   #else    if (ret) return ret;   #endif    b = b->cdr;    goto recurse;       case PIKE_T_RING:    b = b->car;    goto recurse;    +  case PIKE_T_ATTRIBUTE: + #if 0 +  if (!flags & LE_USE_HANDLERS) { +  b = b->cdr; +  goto recurse; +  } + #endif /* 0 */ +  if (!low_pike_types_le(a, b->cdr, array_cnt, flags)) return 0; + #if 0 +  ref_push_string((struct pike_string *)b->car); +  ref_push_type_value(a); +  ref_push_type_value(b->cdr); +  push_int(2); +  if (safe_apply_handler("handle_attribute", error_handler, compat_handler, +  4, 0)) { +  if ((Pike_sp[-1].type == T_INT) && +  (Pike_sp[-1].subtype == NUMBER_NUMBER) && +  (!Pike_sp[-1].u.integer)) { +  pop_stack(); +  return 0; +  } +  pop_stack(); +  } + #endif /* 0 */ +  return 1;    case PIKE_T_SCOPE:   #ifdef TYPE_GROUPING    flags |= LE_B_GROUPED;   #endif    /* FALL_THROUGH */    case PIKE_T_NAME: -  case PIKE_T_ATTRIBUTE: +     b = b->cdr;    goto recurse;       case T_NOT:    /* Some common cases. */    switch(b->car->type) {    case T_NOT:    b = b->car->car;    goto recurse;    case T_MIXED:
pike.git/src/pike_types.c:4311:   int check_soft_cast(struct pike_type *to, struct pike_type *from)   {    return low_pike_types_le(to, from, 0, LE_WEAK_OBJECTS);   }      /*    * Return the return type from a function call.    */   static int low_get_return_type(struct pike_type *a, struct pike_type *b)   { +  struct compilation *c = THIS_COMPILATION;    int tmp; -  +  CHECK_COMPILER();    switch(a->type)    {    case T_OR:    {    struct pike_type *o1, *o2;    o1=o2=0;       type_stack_mark();    if(low_get_return_type(a->car, b))    {
pike.git/src/pike_types.c:4373:    tmp = low_get_return_type(a->car, b);    if(!tmp) return 0;    push_type(T_ARRAY);    return 1;    }       a = low_match_types(a, b, NO_SHORTCUTS);    if(a)    {   #if 0 -  if ((lex.pragmas & ID_STRICT_TYPES) && +  if ((c->lex.pragmas & ID_STRICT_TYPES) &&    !low_pike_types_le(a, b, 0, 0)) {    yywarning("Type mismatch");    }   #endif /* 0 */    switch(a->type)    {    case T_FUNCTION:    a = a->cdr;    while(a->type == T_FUNCTION) {    a = a->cdr;
pike.git/src/pike_types.c:4434:   #define low_index_type debug_low_index_type   #endif      /* FIXME, add the index */   static struct pike_type *debug_low_index_type(struct pike_type *t,    struct pike_type *index_type,    node *n)   {    struct pike_type *tmp;    struct program *p; +  int pragmas = 0;    -  +  if (n) { +  struct compilation *c = THIS_COMPILATION; +  CHECK_COMPILER(); +  pragmas = c->lex.pragmas; +  } +     switch(low_check_indexing(t, index_type, n))    {    case 0: return 0;    case -1:    add_ref(zero_type_string);    return zero_type_string;    }       while((t->type == PIKE_T_NAME) ||    (t->type == PIKE_T_ATTRIBUTE)) {
pike.git/src/pike_types.c:4512:    return ID_FROM_INT(p, i)->type;    }    }    }    }    default:    add_ref(mixed_type_string);    return mixed_type_string;       case T_MIXED: -  if (lex.pragmas & ID_STRICT_TYPES) { +  if (pragmas & ID_STRICT_TYPES) {    yywarning("Indexing mixed.");    }    add_ref(mixed_type_string);    return mixed_type_string;       case T_INT:   #ifdef AUTO_BIGNUM    /* Don't force Gmp.mpz to be loaded here since this function    * is called long before the master object is compiled...    * /Hubbe
pike.git/src/pike_types.c:4626:   #endif      /* FIXME, add the index    *    * FIXME: Is the above fixme valid for this function too?    */   static struct pike_type *debug_low_range_type(struct pike_type *t,    struct pike_type *index1_type,    struct pike_type *index2_type)   { +  struct compilation *c = THIS_COMPILATION;    struct pike_type *tmp;    struct program *p;    -  +  CHECK_COMPILER(); +     while((t->type == PIKE_T_NAME) ||    (t->type == PIKE_T_ATTRIBUTE)) {    t = t->cdr;    }    if (index1_type)    while((index1_type->type == PIKE_T_NAME) ||    (index1_type->type == PIKE_T_ATTRIBUTE)) {    index1_type = index1_type->cdr;    }    if (index2_type)
pike.git/src/pike_types.c:4729:    }    free_type(call_type);       add_ref(mixed_type_string);    return mixed_type_string;    }       yywarning("Ranging object without index operator.");    return 0;    } -  if (lex.pragmas & ID_STRICT_TYPES) { +  if (c->lex.pragmas & ID_STRICT_TYPES) {    yywarning("Ranging generic object.");    }    add_ref(mixed_type_string);    return mixed_type_string;    }       case T_MIXED: -  if (lex.pragmas & ID_STRICT_TYPES) { +  if (c->lex.pragmas & ID_STRICT_TYPES) {    yywarning("Ranging mixed.");    }    add_ref(mixed_type_string);    return mixed_type_string;       case T_INT:    case T_ZERO:    case T_TYPE:    case PIKE_T_RING:    case T_VOID:
pike.git/src/pike_types.c:5885:    push_finished_type_with_markers(fun_type, b_markers, 0);    res = pop_unfinished_type();    if (tmp) free_type(tmp);       if ((Pike_compiler->compiler_pass == 2) && sval) {    while (tmp2->type == PIKE_T_NAME) {    tmp2 = tmp2->cdr;    }       if (tmp2->type == PIKE_T_ATTRIBUTE) { +  struct compilation *c = MAYBE_THIS_COMPILATION;    /* Perform extra argument checking based on the attribute. */    /* FIXME: Support multiple attributes. */    ref_push_string((struct pike_string *)tmp2->car);    push_svalue(sval);    ref_push_type_value(tmp2->cdr);    ref_push_type_value(res); -  if (safe_apply_handler("handle_attribute_constant", error_handler, -  compat_handler, 4, 0)) { +  if (safe_apply_handler("handle_attribute_constant", +  c?c->handler:NULL, +  c?c->compat_handler:NULL, 4, 0)) {    if ((Pike_sp[-1].type == PIKE_T_TYPE)) {    type_stack_mark();    push_finished_type(Pike_sp[-1].u.type);    push_finished_type(res);    push_type(T_AND);    free_type(res);    res = pop_unfinished_type();    }    pop_stack();    }
pike.git/src/pike_types.c:6447:    }       return res;   }      /* NOTE: fun_type loses a reference. */   struct pike_type *new_check_call(struct pike_string *fun_name,    struct pike_type *fun_type,    node *args, INT32 *argno)   { +  struct compilation *c = THIS_COMPILATION;    struct pike_type *tmp = NULL;    struct pike_type *res = NULL;    struct svalue *sval = NULL;    int flags = 0;    -  +  CHECK_COMPILER(); +     debug_malloc_touch(fun_type);       while (args && (args->token == F_ARG_LIST) && fun_type) {    fun_type = new_check_call(fun_name, fun_type, CAR(args), argno);    debug_malloc_touch(fun_type);    args = CDR(args);    }       if (!args || !fun_type) {    debug_malloc_touch(fun_type);
pike.git/src/pike_types.c:6542:    }    free_type(prev);    if (fun_type) {    /* Max args reached or stable type. */    free_type(fun_type);    } else {    /* The splice values are invalid for later arguments. */    if (cnt == 256) {    yywarning("In argument %d to %S: The @-operator argument must be an empty array.",    *argno, fun_name); -  } else if (lex.pragmas & ID_STRICT_TYPES) { +  } else if (c->lex.pragmas & ID_STRICT_TYPES) {    yywarning("In argument %d to %S: The @-operator argument has a max length of %d.",    *argno, fun_name, 256-cnt);    }    }      #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "\n result: ");    simple_describe_type(res);    fprintf(stderr, " OK.\n");
pike.git/src/pike_types.c:6564:   #endif /* PIKE_DEBUG */       return res;    } else if ((res = low_new_check_call(fun_type, args->type, flags, sval))) {    /* OK. */   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, " OK.\n");    }   #endif /* PIKE_DEBUG */ -  if (lex.pragmas & ID_STRICT_TYPES) { +  if (c->lex.pragmas & ID_STRICT_TYPES) {    if (!(tmp = low_new_check_call(fun_type, args->type,    flags|CALL_STRICT, sval))) {    yywarning("Type mismatch in argument %d to %S.",    *argno, fun_name);    if ((tmp = get_first_arg_type(fun_type, 0))) {    yytype_error(NULL, tmp, args->type, YYTE_IS_WARNING);    free_type(tmp);    } else {    yytype_error(NULL, NULL, args->type, YYTE_IS_WARNING);    }