summaryrefslogtreecommitdiff
path: root/gcc/diagnostic.c
diff options
context:
space:
mode:
authorgdr <gdr@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-13 12:40:54 +0000
committergdr <gdr@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-13 12:40:54 +0000
commit45dc76a2b98fb5988fc2aafd4a784c79943fa3b6 (patch)
tree64a8739961836d221cb8ccf2f243ac4fa21f4b00 /gcc/diagnostic.c
parent4abd34cb7c7e5edc61904bb8a43500b4a5926da7 (diff)
downloadgcc-45dc76a2b98fb5988fc2aafd4a784c79943fa3b6.tar.gz
* diagnostic.c (output_format): Recognize "%H" as a format
specifier for a location_t. (text_specifies_location): New function. (diagnostic_set_info): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54584 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/diagnostic.c')
-rw-r--r--gcc/diagnostic.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index fd4462aedf0..3132a3d6106 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -89,6 +89,7 @@ static void default_diagnostic_finalizer PARAMS ((diagnostic_context *,
diagnostic_info *));
static void error_recursion PARAMS ((diagnostic_context *)) ATTRIBUTE_NORETURN;
+static bool text_specifies_location PARAMS ((text_info *, location_t *));
extern int rtl_dump_and_exit;
extern int warnings_are_errors;
@@ -495,7 +496,8 @@ output_buffer_to_stream (buffer)
%c: character.
%s: string.
%%: `%'.
- %*.s: a substring the length of which is specified by an integer. */
+ %*.s: a substring the length of which is specified by an integer.
+ %H: location_t. */
static void
output_format (buffer, text)
output_buffer *buffer;
@@ -576,6 +578,16 @@ output_format (buffer, text)
output_add_character (buffer, '%');
break;
+ case 'H':
+ {
+ const location_t *locus = va_arg (*text->args_ptr, location_t *);
+ output_add_string (buffer, "file '");
+ output_add_string (buffer, locus->file);
+ output_add_string (buffer, "', line ");
+ output_decimal (buffer, locus->file);
+ }
+ break;
+
case '.':
{
int n;
@@ -769,6 +781,30 @@ diagnostic_initialize (context)
context->warnings_are_errors_message = warnings_are_errors;
}
+/* Returns true if the next format specifier in TEXT is a format specifier
+ for a location_t. If so, update the object pointed by LOCUS to reflect
+ the specified location in *TEXT->args_ptr. */
+static bool
+text_specifies_location (text, locus)
+ text_info *text;
+ location_t *locus;
+{
+ const char *p;
+ /* Skip any leading text. */
+ for (p = text->format_spec; *p && *p != '%'; ++p)
+ ;
+
+ /* Extract the location information if any. */
+ if (*p == '%' && *++p == 'H')
+ {
+ *locus = *va_arg (*text->args_ptr, location_t *);
+ text->format_spec = p + 1;
+ return true;
+ }
+
+ return false;
+}
+
void
diagnostic_set_info (diagnostic, msgid, args, file, line, kind)
diagnostic_info *diagnostic;
@@ -780,8 +816,13 @@ diagnostic_set_info (diagnostic, msgid, args, file, line, kind)
{
diagnostic->message.format_spec = msgid;
diagnostic->message.args_ptr = args;
- diagnostic->location.file = file;
- diagnostic->location.line = line;
+ /* If the diagnostic message doesn't specify a loccation,
+ use FILE and LINE. */
+ if (!text_specifies_location (&diagnostic->message, &diagnostic->location))
+ {
+ diagnostic->location.file = file;
+ diagnostic->location.line = line;
+ }
diagnostic->kind = kind;
}