aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-diagnostic.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-diagnostic.c')
-rw-r--r--gcc/tree-diagnostic.c83
1 files changed, 71 insertions, 12 deletions
diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c
index 95b8ef3..705da94 100644
--- a/gcc/tree-diagnostic.c
+++ b/gcc/tree-diagnostic.c
@@ -36,9 +36,9 @@ void
diagnostic_report_current_function (diagnostic_context *context,
diagnostic_info *diagnostic)
{
- diagnostic_report_current_module (context, diagnostic_location (diagnostic));
- lang_hooks.print_error_function (context, LOCATION_FILE (input_location),
- diagnostic);
+ location_t loc = diagnostic_location (diagnostic);
+ diagnostic_report_current_module (context, loc);
+ lang_hooks.print_error_function (context, LOCATION_FILE (loc), diagnostic);
}
static void
@@ -276,15 +276,6 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
t = va_arg (*text->args_ptr, tree);
break;
- case 'G':
- percent_G_format (text);
- return true;
-
- case 'K':
- t = va_arg (*text->args_ptr, tree);
- percent_K_format (text, EXPR_LOCATION (t), TREE_BLOCK (t));
- return true;
-
default:
return false;
}
@@ -305,6 +296,73 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
return true;
}
+/* Set the locations of call sites along the inlining stack corresponding
+ to the DIAGNOSTIC location. */
+
+static void
+set_inlining_locations (diagnostic_context *,
+ diagnostic_info *diagnostic)
+{
+ location_t loc = diagnostic_location (diagnostic);
+ tree block = LOCATION_BLOCK (loc);
+
+ /* Count the number of locations in system headers. When all are,
+ warnings are suppressed by -Wno-system-headers. Otherwise, they
+ involve some user code, possibly inlined into a function in a system
+ header, and are not treated as coming from system headers. */
+ unsigned nsyslocs = 0;
+
+ /* Use a reference to the vector of locations for convenience. */
+ auto &ilocs = diagnostic->m_iinfo.m_ilocs;
+
+ while (block && TREE_CODE (block) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (block))
+ {
+ tree ao = BLOCK_ABSTRACT_ORIGIN (block);
+ if (TREE_CODE (ao) == FUNCTION_DECL)
+ {
+ if (!diagnostic->m_iinfo.m_ao)
+ diagnostic->m_iinfo.m_ao = block;
+
+ location_t bsloc = BLOCK_SOURCE_LOCATION (block);
+ ilocs.safe_push (bsloc);
+ if (in_system_header_at (bsloc))
+ ++nsyslocs;
+ }
+ else if (TREE_CODE (ao) != BLOCK)
+ break;
+
+ block = BLOCK_SUPERCONTEXT (block);
+ }
+
+ if (ilocs.length ())
+ {
+ /* When there is an inlining context use the macro expansion
+ location for the original location and bump up NSYSLOCS if
+ it's in a system header since it's not counted above. */
+ location_t sysloc = expansion_point_location_if_in_system_header (loc);
+ if (sysloc != loc)
+ {
+ loc = sysloc;
+ ++nsyslocs;
+ }
+ }
+ else
+ {
+ /* When there's no inlining context use the original location
+ and set NSYSLOCS accordingly. */
+ nsyslocs = in_system_header_at (loc) != 0;
+ }
+
+ ilocs.safe_push (loc);
+
+ /* Set if all locations are in a system header. */
+ diagnostic->m_iinfo.m_allsyslocs = nsyslocs == ilocs.length ();
+
+ if (tree *ao = pp_ti_abstract_origin (&diagnostic->message))
+ *ao = (tree)diagnostic->m_iinfo.m_ao;
+}
+
/* Sets CONTEXT to use language independent diagnostics. */
void
tree_diagnostics_defaults (diagnostic_context *context)
@@ -314,4 +372,5 @@ tree_diagnostics_defaults (diagnostic_context *context)
diagnostic_format_decoder (context) = default_tree_printer;
context->print_path = default_tree_diagnostic_path_printer;
context->make_json_for_path = default_tree_make_json_for_path;
+ context->set_locations_cb = set_inlining_locations;
}