responsible for freeing the memory. */
char *
diagnostic_build_prefix (diagnostic_context *context,
- diagnostic_info *diagnostic)
+ const diagnostic_info *diagnostic)
{
static const char *const diagnostic_kind_text[] = {
#define DEFINE_DIAGNOSTIC_KIND(K, T) (T),
}
void
-default_diagnostic_finalizer (diagnostic_context *context,
+default_diagnostic_finalizer (diagnostic_context *context ATTRIBUTE_UNUSED,
diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
{
- pp_destroy_prefix (context->printer);
}
/* Interface to specify diagnostic kind overrides. Returns the
pp_output_formatted_text (context->printer);
diagnostic_show_locus (context, diagnostic);
(*diagnostic_finalizer (context)) (context, diagnostic);
+ pp_destroy_prefix (context->printer);
pp_newline_and_flush (context->printer);
diagnostic_action_after_output (context, diagnostic);
diagnostic->message.format_spec = saved_format_spec;
va_end (ap);
}
+/* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
+void
+diagnostic_append_note (diagnostic_context *context,
+ location_t location,
+ const char * gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, gmsgid);
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, location, DK_NOTE);
+ if (context->inhibit_notes_p)
+ return;
+ pp_set_prefix (context->printer,
+ diagnostic_build_prefix (context, &diagnostic));
+ pp_newline (context->printer);
+ pp_format (context->printer, &diagnostic.message);
+ pp_output_formatted_text (context->printer);
+ pp_destroy_prefix (context->printer);
+ diagnostic_show_locus (context, &diagnostic);
+ va_end(ap);
+}
+
bool
emit_diagnostic (diagnostic_t kind, location_t location, int opt,
const char *gmsgid, ...)
static void
maybe_unwind_expanded_macro_loc (diagnostic_context *context,
- diagnostic_info *diagnostic,
+ const diagnostic_info *diagnostic,
source_location where)
{
const struct line_map *map;
/* Walk LOC_VEC and print the macro expansion trace, unless the
first macro which expansion triggered this trace was expanded
inside a system header. */
+ int saved_location_line =
+ expand_location_to_spelling_point (diagnostic->location).line;
+
if (!LINEMAP_SYSP (map))
FOR_EACH_VEC_ELT (loc_map_pair, loc_vec, ix, iter)
{
- source_location resolved_def_loc = 0, resolved_exp_loc = 0,
- saved_location = 0;
- int resolved_def_loc_line = 0, saved_location_line = 0;
- diagnostic_t saved_kind;
- const char *saved_prefix;
/* Sometimes, in the unwound macro expansion trace, we want to
print a part of the context that shows where, in the
definition of the relevant macro, is the token (we are
A contrario, when the first interesting diagnostic line
points into the definition of the macro, we don't need to
display any line for that macro definition in the trace
- anymore, otherwise it'd be redundant.
-
- This flag is true when we need to display the context of
- the macro definition. */
- bool print_definition_context_p = false;
+ anymore, otherwise it'd be redundant. */
/* Okay, now here is what we want. For each token resulting
from macro expansion we want to show: 1/ where in the
/* Resolve the location iter->where into the locus 1/ of the
comment above. */
- resolved_def_loc =
+ source_location resolved_def_loc =
linemap_resolve_location (line_table, iter->where,
LRK_MACRO_DEFINITION_LOCATION, NULL);
/* Don't print trace for locations that are reserved or from
within a system header. */
- {
- const struct line_map *m = NULL;
- source_location l = linemap_resolve_location (line_table, resolved_def_loc,
- LRK_SPELLING_LOCATION,
- &m);
- if (l < RESERVED_LOCATION_COUNT
- || LINEMAP_SYSP (m))
- continue;
-
- resolved_def_loc_line = SOURCE_LINE (m, l);
- }
+ const struct line_map *m = NULL;
+ source_location l =
+ linemap_resolve_location (line_table, resolved_def_loc,
+ LRK_SPELLING_LOCATION, &m);
+ if (l < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (m))
+ continue;
+
+ /* We need to print the context of the macro definition only
+ when the locus of the first displayed diagnostic (displayed
+ before this trace) was inside the definition of the
+ macro. */
+ int resolved_def_loc_line = SOURCE_LINE (m, l);
+ if (ix == 0 && saved_location_line != resolved_def_loc_line)
+ {
+ diagnostic_append_note (context, resolved_def_loc,
+ "in definition of macro %qs",
+ linemap_map_get_macro_name (iter->map));
+ /* At this step, as we've printed the context of the macro
+ definition, we don't want to print the context of its
+ expansion, otherwise, it'd be redundant. */
+ continue;
+ }
/* Resolve the location of the expansion point of the macro
which expansion gave the token represented by def_loc.
This is the locus 2/ of the earlier comment. */
- resolved_exp_loc =
+ source_location resolved_exp_loc =
linemap_resolve_location (line_table,
MACRO_MAP_EXPANSION_POINT_LOCATION (iter->map),
LRK_MACRO_DEFINITION_LOCATION, NULL);
- saved_kind = diagnostic->kind;
- saved_prefix = pp_get_prefix (context->printer);
- saved_location = diagnostic->location;
- saved_location_line =
- expand_location_to_spelling_point (saved_location).line;
-
- diagnostic->kind = DK_NOTE;
-
- /* We need to print the context of the macro definition only
- when the locus of the first displayed diagnostic (displayed
- before this trace) was inside the definition of the
- macro. */
- print_definition_context_p =
- (ix == 0 && (saved_location_line != resolved_def_loc_line));
-
- if (print_definition_context_p)
- {
- diagnostic->location = resolved_def_loc;
- pp_set_prefix (context->printer,
- diagnostic_build_prefix (context, diagnostic));
- pp_newline (context->printer);
- pp_printf (context->printer, "in definition of macro '%s'",
- linemap_map_get_macro_name (iter->map));
- pp_destroy_prefix (context->printer);
- diagnostic_show_locus (context, diagnostic);
- /* At this step, as we've printed the context of the macro
- definition, we don't want to print the context of its
- expansion, otherwise, it'd be redundant. */
- continue;
- }
-
- diagnostic->location = resolved_exp_loc;
- pp_set_prefix (context->printer,
- diagnostic_build_prefix (context, diagnostic));
- pp_newline (context->printer);
- pp_printf (context->printer, "in expansion of macro '%s'",
- linemap_map_get_macro_name (iter->map));
- pp_destroy_prefix (context->printer);
- diagnostic_show_locus (context, diagnostic);
-
- diagnostic->kind = saved_kind;
- diagnostic->location = saved_location;
- pp_set_prefix (context->printer, saved_prefix);
+ diagnostic_append_note (context, resolved_exp_loc,
+ "in expansion of macro %qs",
+ linemap_map_get_macro_name (iter->map));
}
VEC_free (loc_map_pair, heap, loc_vec);