Branch: Tag:

2017-02-09

2017-02-09 17:34:20 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Compiler: Moved yyreport() et al to pike_compiler.cmod.

More code cleanup.

2176:    POP_PIKE_FRAME();   }    + /** +  * Main entry point for compiler messages originating from C-code. +  * +  * Sends the message along to PikeCompiler()->report(). +  * +  * NOTE: The format string fmt (and vargs) is only formatted with +  * string_builder_vsprintf() if the number of extra +  * Pike stack arguments (args) is zero. +  * +  * NOTE: This function may be called from functions that sometimes +  * execute outside of the compilation context, eg by +  * __handle_sprintf_format(), which can be called directly +  * by Pike-code, in which case it is a NO-OP. +  */ + PMOD_EXPORT void va_yyreport(int severity_level, +  struct pike_string *file, INT_TYPE line, +  struct pike_string *system, INT32 args, +  const char *fmt, va_list vargs) + { +  struct compilation *c = MAYBE_THIS_COMPILATION; +  struct string_builder s; +  +  if (!c) { +  /* No compiler context. */ +  pop_n_elems(args); +  return; +  } +  +  STACK_LEVEL_START(args); +  + #ifdef PIKE_DEBUG +  if(Pike_interpreter.recoveries && Pike_sp-Pike_interpreter.evaluator_stack < Pike_interpreter.recoveries->stack_pointer) +  Pike_fatal("Stack error (underflow)\n"); + #endif +  +  /* Convert type errors to warnings in non-strict compat mode. */ +  if ((system == type_check_system_string) && +  (severity_level == REPORT_ERROR) && +  (Pike_compiler->compat_major != -1) && +  !(c->lex.pragmas & ID_STRICT_TYPES) && +  ((Pike_compiler->compat_major < PIKE_MAJOR_VERSION) || +  ((Pike_compiler->compat_major == PIKE_MAJOR_VERSION) && +  (Pike_compiler->compat_minor < PIKE_MINOR_VERSION)))) { +  severity_level = REPORT_WARNING; +  } +  +  /* 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 ((severity_level <= REPORT_WARNING) && +  Pike_compiler->num_parse_error) { +  pop_n_elems(args); +  return; +  } +  +  if (severity_level >= REPORT_ERROR) { +  if (Pike_compiler->num_parse_error > 20) { +  pop_n_elems(args); +  return; +  } +  Pike_compiler->num_parse_error++; +  cumulative_parse_error++; +  } +  +  push_int(severity_level); +  ref_push_string(file?file:c->lex.current_file); +  push_int(line?line:c->lex.current_line); +  ref_push_string(system); +  if (args) { +  int i = args; +  push_text(fmt); +  /* Copy the arguments. */ +  while (i--) { +  push_svalue(Pike_sp-(args+5)); +  } +  } else { +  init_string_builder(&s, 0); +  string_builder_vsprintf(&s, fmt, vargs); +  push_string(finish_string_builder(&s)); +  } +  +  safe_apply_current(PC_REPORT_FUN_NUM, args + 5); +  pop_stack(); +  if (args) pop_n_elems(args); +  STACK_LEVEL_DONE(0); + } +  + PMOD_EXPORT void low_yyreport(int severity_level, +  struct pike_string *file, INT_TYPE line, +  struct pike_string *system, +  INT32 args, const char *fmt, ...) + { +  va_list vargs; +  +  va_start(vargs,fmt); +  va_yyreport(severity_level, file, line, system, args, fmt, vargs); +  va_end(vargs); + } +  + PMOD_EXPORT void yyreport(int severity_level, struct pike_string *system, +  INT32 args, const char *fmt, ...) + { +  va_list vargs; +  +  va_start(vargs,fmt); +  va_yyreport(severity_level, NULL, 0, system, args, fmt, vargs); +  va_end(vargs); + } +  + PMOD_EXPORT void yywarning(char *fmt, ...) + { +  va_list vargs; +  +  va_start(vargs,fmt); +  va_yyreport(REPORT_WARNING, NULL, 0, parser_system_string, 0, fmt, vargs); +  va_end(vargs); + } +  + PMOD_EXPORT void my_yyerror(const char *fmt,...) + { +  va_list vargs; +  va_start(vargs,fmt); +  va_yyreport(REPORT_ERROR, NULL, 0, parser_system_string, 0, fmt, vargs); +  va_end(vargs); + } +  + PMOD_EXPORT void yyerror(const char *str) + { +  my_yyerror("%s", str); + } +  + /** +  * Main entry point for errors from the type-checking subsystems. +  * +  * The message (if any) will be formatted for the same source +  * position as the got_t. +  * +  * The expect_t will be formatted for the same position as the got_t +  * if there's no expected_file/expected_line. +  * +  * The got_t will be formatted for the current lex position if there's +  * no got_file/got_line. +  */ + void yytype_report(int severity_level, +  struct pike_string *expected_file, INT_TYPE expected_line, +  struct pike_type *expected_t, +  struct pike_string *got_file, INT_TYPE got_line, +  struct pike_type *got_t, +  INT32 args, const char *fmt, ...) + { +  if (fmt) +  { +  va_list vargs; +  va_start(vargs, fmt); +  va_yyreport(severity_level, got_file, got_line, type_check_system_string, +  args, fmt, vargs); +  va_end(vargs); +  } +  +  if (expected_t && got_t) { +  yyexplain_nonmatching_types(severity_level, +  expected_file?expected_file:got_file, +  expected_line?expected_line:got_line, +  expected_t, +  got_file, got_line, got_t); +  } else if (expected_t) { +  ref_push_type_value(expected_t); +  low_yyreport(severity_level, +  expected_file?expected_file:got_file, +  expected_line?expected_line:got_line, +  type_check_system_string, +  1, "Expected: %O."); +  } else if (got_t) { +  ref_push_type_value(got_t); +  low_yyreport(severity_level, got_file, got_line, type_check_system_string, +  1, "Got : %O."); +  } + } +  + void yytype_error(const char *msg, struct pike_type *expected_t, +  struct pike_type *got_t, unsigned int flags) + { +  yytype_report((flags & YYTE_IS_WARNING)?REPORT_WARNING:REPORT_ERROR, +  NULL, 0, expected_t, NULL, 0, got_t, 0, "%s", msg); + } +  + struct pike_string *format_exception_for_error_msg (struct svalue *thrown) + { +  struct pike_string *s = NULL; +  +  push_svalue (thrown); +  SAFE_APPLY_MASTER ("describe_error", 1); +  +  if (TYPEOF(Pike_sp[-1]) == T_STRING) { +  f_string_trim(1); +  push_constant_text("\n"); +  push_constant_text(" "); +  f_replace(3); +  return (--Pike_sp)->u.string; +  } +  else { +  pop_stack(); +  return NULL; +  } + } +  + void handle_compile_exception (const char *yyerror_fmt, ...) + { +  struct svalue thrown; +  struct compilation *c = THIS_COMPILATION; +  +  CHECK_COMPILER(); +  +  move_svalue (&thrown, &throw_value); +  mark_free_svalue (&throw_value); +  +  if (yyerror_fmt) { +  va_list args; +  va_start (args, yyerror_fmt); +  va_yyreport(REPORT_ERROR, NULL, 0, parser_system_string, 0, +  yyerror_fmt, args); +  va_end (args); +  } +  +  push_svalue(&thrown); +  /* safe_apply_current(PC_FILTER_EXCEPTION_FUN_NUM, 1); */ +  low_safe_apply_handler("compile_exception", c->handler, c->compat_handler, 1); +  +  if (SAFE_IS_ZERO(Pike_sp-1)) { +  struct pike_string *s = format_exception_for_error_msg (&thrown); +  if (s) { +  push_string(s); +  yyreport(REPORT_ERROR, parser_system_string, 1, "%s"); +  } +  } +  +  pop_stack(); +  free_svalue(&thrown); + } +    /*! @class CompilerState    *!    *! Keeps the state of a single program/class during compilation.