pike.git / src / pike_compiler.cmod

version» Context lines:

pike.git/src/pike_compiler.cmod:2121:    ((fun = find_identifier("handle_import", handler->prog)) != -1))) {    apply_low(handler, fun, args);    } else {   #endif /* SUPPORT_COMPILER_HANDLERS */    apply_external(1, CE_HANDLE_IMPORT_FUN_NUM, args);   #ifdef SUPPORT_COMPILER_HANDLERS    }   #endif /* SUPPORT_COMPILER_HANDLERS */   }    - /*! @decl int(0..1) pop_type_attribute(string attribute, type a, type b) + /*! @decl int(0..1)|type(mixed) pop_type_attribute(string attribute, @ +  *! type a, type b, @ +  *! mapping|void state)    *!    *! Type attribute handler.    *!    *! Called during type checking when @expr{a <= b@} and    *! @[a] had the type attribute @[attribute] before the    *! comparison.    *!    *! The default implementation implements the "deprecated"    *! attribute.    *!    *! @returns -  *! Returns @expr{1@} if the type check should be allowed -  *! (ie @expr{__attribute__(attribute, a) <= b@}), and -  *! @expr{0@} (zero) otherwise. +  *! Returns one of: +  *! @mixed +  *! @type type(mixed) +  *! An alternative type for @[a] against which @[b] +  *! will be matched again. +  *! @type int(1..1) +  *! Allow the check (ie @expr{__attribute__(attribute, a) <= b@}). +  *! @type int(0..0) +  *! Do not allow the check. +  *! @endmixed    *!    *! @seealso    *! @[push_type_attribute()], @[index_type_attribute()]    */   static void f_compilation_pop_type_attribute(INT32 args)   {    struct pike_string *attr;    struct svalue *a, *b;    struct compilation *c = THIS_COMPILATION;    struct pike_string *deprecated_string; -  +  struct mapping *state = NULL;    -  get_all_args(NULL, args, "%W%*%*", &attr, &a, &b); + #if 0 +  fprintf(stderr, "f_compilation_pop_type_attribute(%d)\n", args); +  { +  int i; +  for (i = 0; i < args; i++) { +  fprintf(stderr, " arg #%d: ", i+1); +  safe_print_svalue(stderr, Pike_sp+i-args); +  fprintf(stderr, "\n"); +  } +  } + #endif    -  +  get_all_args(NULL, args, "%W%*%*.%m", &attr, &a, &b, &state); +     if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST) {    MAKE_CONST_STRING(deprecated_string, "deprecated");    if ((attr == deprecated_string) &&    !(c->lex.pragmas & ID_NO_DEPRECATION_WARNINGS)) {    push_svalue(a);    yytype_report(REPORT_WARNING, NULL, 0, NULL,    NULL, 0, NULL,    1, "Using deprecated %O value.");    }    }
pike.git/src/pike_compiler.cmod:2223:    */   static void f_compilation_suppress_deprecation_warnings(INT32 args)   {    struct compilation *c = THIS_COMPILATION;       pop_n_elems(args);    push_int(Pike_compiler->compiler_pass != COMPILER_PASS_LAST ||    c->lex.pragmas & ID_NO_DEPRECATION_WARNINGS);   }    - /*! @decl int(0..1) push_type_attribute(string attribute, type a, type b) + /*! @decl int(0..1)|type(mixed) push_type_attribute(string attribute, @ +  *! type a, type b, @ +  *! mapping|void state)    *!    *! Type attribute handler.    *!    *! Called during type checking when @expr{a <= b@} and    *! @[b] had the type attribute @[attribute] before the    *! comparison.    *!    *! The default implementation implements the "deprecated"    *! attribute.    *!    *! @returns -  *! Returns @expr{1@} if the type check should be allowed -  *! (ie @expr{a <= __attribute__(attribute, b)@}), and -  *! @expr{0@} (zero) otherwise. +  *! Returns one of: +  *! @mixed +  *! @type type(mixed) +  *! An alternative type for @[b] against which @[a] +  *! will be matched again. +  *! @type int(1..1) +  *! Allow the check (ie @expr{a <= __attribute__(attribute, b)@}). +  *! @type int(0..0) +  *! Do not allow the check. +  *! @endmixed    *!    *! @seealso    *! @[pop_type_attribute()], @[index_type_attribute()]    */   static void f_compilation_push_type_attribute(INT32 args)   {    struct pike_string *attr;    struct svalue *a, *b;    struct compilation *c = THIS_COMPILATION; -  struct pike_string *deprecated_string; +  struct pike_string *test; +  struct mapping *state = NULL; +  int funarg = 0;    -  get_all_args(NULL, args, "%W%*%*", &attr, &a, &b); + #if 0 +  fprintf(stderr, "f_compilation_push_type_attribute(%d)\n", args); +  { +  int i; +  for (i = 0; i < args; i++) { +  fprintf(stderr, " arg #%d: ", i+1); +  safe_print_svalue(stderr, Pike_sp+i-args); +  fprintf(stderr, "\n"); +  } +  } + #endif    -  +  get_all_args(NULL, args, "%W%*%*.%m%d", &attr, &a, &b, &state, &funarg); +  +  if (TYPEOF(*a) != PIKE_T_TYPE) { +  SIMPLE_ARG_TYPE_ERROR(NULL, 2, "type"); +  } +  if (TYPEOF(*b) != PIKE_T_TYPE) { +  SIMPLE_ARG_TYPE_ERROR(NULL, 3, "type"); +  } +  +     if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST) { -  MAKE_CONST_STRING(deprecated_string, "deprecated"); -  if ((attr == deprecated_string) && +  MAKE_CONST_STRING(test, "deprecated"); +  if ((attr == test) &&    !(c->lex.pragmas & ID_NO_DEPRECATION_WARNINGS) &&    !((TYPEOF(*a) == PIKE_T_TYPE) && (a->u.type == zero_type_string))) {    /* Don't warn about setting deprecated values to zero. */    push_svalue(b);    yytype_report(REPORT_WARNING, NULL, 0, NULL,    NULL, 0, NULL,    1, "Using deprecated %O value.");    }    }    pop_n_elems(args);    push_int(1);   }      /*! @decl int(0..1) apply_type_attribute(string attribute, @ -  *! type a, type|zero b, @ +  *! type a, @    *! mapping|void state) -  *! @decl int(0..1) apply_type_attribute(string attribute, type a) +     *!    *! Type attribute handler.    *!    *! @param attribute    *! Attribute that @[a] had.    *!    *! @param a -  *! Type of the value being called. +  *! Continuation of the function being called or @[UNDEFINED] +  *! indicating that there are no further arguments.    *! -  *! @param b -  *! Type of the first argument in the call, or -  *! @[UNDEFINED] if no more arguments. -  *! -  *! Called during type checking when @[a] has been successfully -  *! had a partial evaluation with the argument @[b] and -  *! @[a] had the type attribute @[attribute] before the -  *! evaluation. -  *! -  *! The default implementation implements the "deprecated" -  *! attribute. -  *! +     *! @param state    *! Mapping intended to hold state during checking of multiple    *! arguments.    *! -  +  *! Called during type checking when there has been successfull +  *! partial evaluation of a function type that had the type +  *! attribute @[attribute] before the evaluation. +  *! +  *! The default implementation implements the attributes: +  *! +  *! @dl +  *! @item @expr{__deprecated__@} +  *! @enddl +  *!    *! @returns    *! Returns @expr{1@} if the type check should be allowed    *! (ie @expr{__attribute__(attribute, a)(b)@}) is valid,    *! and @expr{0@} (zero) otherwise.    *!    *! @seealso    *! @[pop_type_attribute()], @[push_type_attribute()]    */   static void f_compilation_apply_type_attribute(INT32 args)   {    struct pike_string *attr; -  struct svalue *a, *b = NULL; +  struct svalue *a = NULL;    struct compilation *c = THIS_COMPILATION; -  struct pike_string *deprecated_string; +  struct pike_string *test;    struct mapping *state = NULL;    -  get_all_args(NULL, args, "%W%*.%*%m", &attr, &a, &b, &state); + #if 0 +  fprintf(stderr, "f_compilation_apply_type_attribute(%d)\n", args); +  { +  int i; +  for (i = 0; i < args; i++) { +  fprintf(stderr, " arg #%d: ", i+1); +  safe_print_svalue(stderr, Pike_sp+i-args); +  fprintf(stderr, "\n"); +  } +  } + #endif    -  +  get_all_args(NULL, args, "%W%*.%m", &attr, &a, &state); +  +  if (a && (TYPEOF(*a) != PIKE_T_TYPE)) { +  a = NULL; +  } +     if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST) { -  MAKE_CONST_STRING(deprecated_string, "deprecated"); -  if ((attr == deprecated_string) && -  !(c->lex.pragmas & ID_NO_DEPRECATION_WARNINGS) && -  (!b || -  ((TYPEOF(*b) == T_INT) && (SUBTYPEOF(*b) == NUMBER_UNDEFINED) && -  (!b->u.integer)))) { -  /* push_svalue(a); */ +  MAKE_CONST_STRING(test, "deprecated"); +  if ((attr == test) && !a && +  !(c->lex.pragmas & ID_NO_DEPRECATION_WARNINGS)) {    yytype_report(REPORT_WARNING, NULL, 0, NULL,    NULL, 0, NULL,    0, "Calling a deprecated value.");    }    }    pop_n_elems(args);    push_int(1);   }      /*! @decl type(mixed) apply_attribute_constant(string attr, @
pike.git/src/pike_compiler.cmod:2351:    *!    *! @param value    *! Constant value sent as parameter.    *!    *! @param arg_type    *! Declared type of the function argument.    *!    *! @param cont_type    *! Continuation function type after the current argument.    *! +  *! @param state +  *! Mapping intended to hold state during checking of multiple +  *! arguments. +  *!    *! This function is called when a function is called    *! with the constant value @[value] and it has been    *! successfully matched against @[arg_type],    *! and @[arg_type] had the type attribute @[attr].    *!    *! This function is typically used to perform specialized    *! argument checking and to allow for a strengthening    *! of the function type based on @[value].    *!    *! The default implementation implements the @expr{"sprintf_format"@},
pike.git/src/pike_compiler.cmod:2381:    *!    *! @seealso    *! @[pop_type_attribute()], @[push_type_attribute()]    */   static void f_compilation_apply_attribute_constant(INT32 args)   {    struct compilation *c = THIS_COMPILATION;    struct pike_string *attribute;    struct pike_string *test;    struct svalue *sval; +  + #if 0 +  fprintf(stderr, "f_compilation_apply_attribute_constant(%d)\n", args); +  { +  int i; +  for (i = 0; i < args; i++) { +  fprintf(stderr, " arg #%d: ", i+1); +  safe_print_svalue(stderr, Pike_sp+i-args); +  fprintf(stderr, "\n"); +  } +  } + #endif +     get_all_args(NULL, args, "%S%*", &attribute, &sval);       MAKE_CONST_STRING(test, "sscanf_input");    if (attribute == test) {    f___handle_sscanf_format(args);    return;    }    -  +  /* +  * Attributes after this require a valid sval. +  */ +     if ((TYPEOF(*sval) == T_INT) && !sval->u.integer) {    pop_n_elems(args);    push_undefined();    return;    }       MAKE_CONST_STRING(test, "sprintf_format");    if (attribute == test) {    f___handle_sprintf_format(args);    return;
pike.git/src/pike_compiler.cmod:2419:    }    MAKE_CONST_STRING(test, "sscanf_76_format");    if (attribute == test) {    f___handle_sscanf_format(args);    return;    }    pop_n_elems(args);    push_undefined();   }    + /*! @decl type(mixed) eval_type_attribute(string attribute, @ +  *! type t, +  *! mapping state) +  */ + static void f_compilation_eval_type_attribute(INT32 args) + { +  struct compilation *c; +  struct pike_string *attribute; +  struct pike_string *test; +  struct svalue *sval; +  struct mapping *state; +  + #if 0 +  fprintf(stderr, "f_compilation_eval_type_attribute(%d)\n", args); +  { +  int i; +  for (i = 0; i < args; i++) { +  fprintf(stderr, " arg #%d: ", i+1); +  safe_print_svalue(stderr, Pike_sp+i-args); +  fprintf(stderr, "\n"); +  } +  } + #endif +  +  get_all_args(NULL, args, "%S%*%m", &attribute, &sval, &state); +  +  if (sval && (TYPEOF(*sval) != PIKE_T_TYPE)) { +  sval = NULL; +  } +  +  pop_n_elems(args); +  push_undefined(); + } +    static void f_compilation__sprintf(INT32 args)   {    struct compilation *c = THIS_COMPILATION;    struct string_builder buf;    init_string_builder_alloc(&buf, 50, 0);    string_builder_strcat(&buf, "PikeCompiler(");    if (c->prog) {    string_builder_strcat(&buf, "\"\", ");    } else {    string_builder_strcat(&buf, "UNDEFINED, ");
pike.git/src/pike_compiler.cmod:2963:    f_compilation_change_compiler_compatibility,    tFunc(tInt tInt, tVoid), 0);       ADD_FUNCTION("handle_inherit", f_compilation_handle_inherit,    tFunc(tStr, tPrg(tObj)), 0);       ADD_FUNCTION("handle_import", f_compilation_handle_import,    tFunc(tStr, tPrg(tObj)), 0);       ADD_FUNCTION("pop_type_attribute", f_compilation_pop_type_attribute, -  tFunc(tStr tType(tMix) tType(tMix), tInt01), 0); +  tFunc(tStr tType(tMix) tType(tMix) +  tOr(tMapping, tVoid), tOr(tInt01, tType(tMix))), 0);       ADD_FUNCTION("push_type_attribute", f_compilation_push_type_attribute, -  tFunc(tStr tType(tMix) tType(tMix), tInt01), 0); +  tFunc(tStr tType(tMix) tType(tMix) +  tOr(tMapping, tVoid), tOr(tInt01, tType(tMix))), 0);       ADD_FUNCTION("index_type_attribute", f_compilation_index_type_attribute,    tFunc(tStr tType(tMix) tType(tMix), tInt01), 0);       ADD_FUNCTION("apply_type_attribute", f_compilation_apply_type_attribute, -  tFunc(tStr tType(tMix) tOr(tType(tMix), tZero) tMapping, -  tInt01), 0); +  tFunc(tStr tType(tMix) tOr(tMapping, tVoid), tInt01), 0);       ADD_FUNCTION("apply_attribute_constant",    f_compilation_apply_attribute_constant,    tFunc(tStr tMix tType(tMix) tType(tFunction) tMapping,    tType(tFunction)), 0);    -  +  ADD_FUNCTION("eval_type_attribute", f_compilation_eval_type_attribute, +  tFunc(tStr tType(tMix) tMapping, tOr(tType(tMix), tZero)), 0); +     ADD_FUNCTION("_sprintf", f_compilation__sprintf,    tFunc(tInt tOr(tMap(tStr, tMix), tVoid), tStr), ID_PROTECTED);       ADD_FUNCTION("suppress_deprecation_warnings",    f_compilation_suppress_deprecation_warnings,    tFunc(tVoid, tInt), 0);       start_new_program();    Pike_compiler->new_program->id =    PROG_COMPILERENVIRONMENT_PIKECOMPILER_COMPILERSTATE_ID;