diff --git a/src/pike_compiler.h b/src/pike_compiler.h index 001c8571dc064573ccec4c547cc35919024aea37..63226076619f6535d188e9e5b485bbc3d9b735e1 100644 --- a/src/pike_compiler.h +++ b/src/pike_compiler.h @@ -2,7 +2,7 @@ || 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_compiler.h,v 1.11 2008/05/03 20:06:06 grubba Exp $ +|| $Id: pike_compiler.h,v 1.12 2008/05/04 14:04:10 grubba Exp $ */ #ifndef PIKE_COMPILER_H @@ -82,5 +82,6 @@ struct compilation #define PC_HANDLE_INHERIT_FUN_NUM 7 #define PC_POP_TYPE_ATTRIBUTE_FUN_NUM 8 #define PC_PUSH_TYPE_ATTRIBUTE_FUN_NUM 9 +#define PC_APPLY_TYPE_ATTRIBUTE_FUN_NUM 10 #endif /* !PIKE_COMPILER_H */ diff --git a/src/pike_types.c b/src/pike_types.c index 1059b8ebb2f98fdd8a44fc0f7961cc79ee25c9cc..91822162f88b763184e2c7df2bf407db668b9f78 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -2,7 +2,7 @@ || 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.324 2008/05/03 20:06:07 grubba Exp $ +|| $Id: pike_types.c,v 1.325 2008/05/04 14:04:11 grubba Exp $ */ #include "global.h" @@ -5717,6 +5717,7 @@ static struct pike_type *lower_new_check_call(struct pike_type *fun_type, #endif /* PIKE_TYPE_DEBUG */ ) { + struct compilation *c = MAYBE_THIS_COMPILATION; struct pike_type *res = NULL; struct pike_type *tmp; struct pike_type *tmp2; @@ -5749,6 +5750,22 @@ static struct pike_type *lower_new_check_call(struct pike_type *fun_type, case PIKE_T_ATTRIBUTE: res = lower_new_check_call(fun_type->cdr, arg_type, flags, sval CHECK_CALL_ARGS); + if (!res) return NULL; + if (c) { + ref_push_string((struct pike_string *)fun_type->car); + ref_push_type_value(fun_type->cdr); + ref_push_type_value(arg_type); + safe_apply_current2(PC_APPLY_TYPE_ATTRIBUTE_FUN_NUM, 3, + "apply_type_attribute"); + if ((Pike_sp[-1].type == T_INT) && + (Pike_sp[-1].subtype == NUMBER_NUMBER) && + (!Pike_sp[-1].u.integer)) { + pop_stack(); + free_type(res); + return NULL; + } + pop_stack(); + } type_stack_mark(); push_finished_type(res); push_type_attribute((struct pike_string *)fun_type->car); @@ -5965,6 +5982,7 @@ static struct pike_type *lower_new_check_call(struct pike_type *fun_type, struct compilation *c = MAYBE_THIS_COMPILATION; /* Perform extra argument checking based on the attribute. */ /* FIXME: Support multiple attributes. */ + /* FIXME: Ought to use PikeCompiler! */ ref_push_string((struct pike_string *)tmp2->car); push_svalue(sval); ref_push_type_value(tmp2->cdr); @@ -6074,6 +6092,9 @@ struct pike_type *low_new_check_call(struct pike_type *fun_type, arg_type = arg_type->cdr; goto loop; + /* FIXME: PIKE_T_ATTRIBUTE's ought to propagate out to the basic types. + */ + case T_OR: if (!(tmp = low_new_check_call(fun_type, arg_type->car, flags, sval))) { if (flags & CALL_STRICT) { diff --git a/src/program.c b/src/program.c index 4299516b90bda8c85e9e341b058e5dc44c834c4e..706cddee6296c68c4a4ebc6157c10a91168d14fb 100644 --- a/src/program.c +++ b/src/program.c @@ -2,7 +2,7 @@ || 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.686 2008/05/03 20:06:06 grubba Exp $ +|| $Id: program.c,v 1.687 2008/05/04 14:04:10 grubba Exp $ */ #include "global.h" @@ -8487,6 +8487,52 @@ static void f_compilation_push_type_attribute(INT32 args) push_int(1); } +/*! @decl int(0..1) apply_type_attribute(string attribute, @ + *! type a, type b) + *! + *! Type attribute handler. + *! + *! 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. + *! + *! @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; + struct compilation *c = THIS_COMPILATION; + struct pike_string *deprecated_string; + + get_all_args("apply_type_attribute", args, "%W%*%*", &attr, &a, &b); + + if (Pike_compiler->compiler_pass == 2) { + MAKE_CONST_STRING(deprecated_string, "deprecated"); + if (attr == deprecated_string) { + push_int(REPORT_WARNING); + ref_push_string(c->lex.current_file); + push_int(c->lex.current_line); + push_constant_text("type_check"); + push_constant_text("Calling a deprecated value."); + apply_current(PC_REPORT_FUN_NUM, 5); + args++; + } + } + pop_n_elems(args); + push_int(1); +} + static void f_compilation__sprintf(INT32 args) { struct compilation *c = THIS_COMPILATION; @@ -8764,6 +8810,9 @@ static void compile_compiler(void) ADD_FUNCTION("push_type_attribute", f_compilation_push_type_attribute, tFunc(tStr tType(tMix) tType(tMix), tInt01), 0); + ADD_FUNCTION("apply_type_attribute", f_compilation_apply_type_attribute, + tFunc(tStr tType(tMix) tType(tMix), tInt01), 0); + ADD_FUNCTION("_sprintf", f_compilation__sprintf, tFunc(tInt tOr(tMap(tStr, tMix), tVoid), tStr), ID_STATIC);