summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/error.c33
-rw-r--r--gcc/cp/parser.c5
-rw-r--r--gcc/diagnostic.c20
-rw-r--r--gcc/diagnostic.h4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp/string-1.C9
-rw-r--r--libcpp/ChangeLog8
-rw-r--r--libcpp/charset.c10
-rw-r--r--libcpp/errors.c27
-rw-r--r--libcpp/include/cpplib.h8
13 files changed, 130 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2935b3274a4..d6e62a6cecb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-11-03 Joseph S. Myers <joseph@codesourcery.com>
+
+ PR c++/17964
+ * diagnostic.c (diagnostic_set_info_translated): New function.
+ (diagnostic_set_info): Use it. Add comment.
+ * diagnostic.h (diagnostic_set_info_translated): Declare.
+
2005-11-03 Eric Botcazou <ebotcazou@adacore.com>
* dwarf2asm.c (dw2_force_const_mem): Add new parameter 'public'.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 625413b364f..5d281d31361 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2005-11-03 Joseph S. Myers <joseph@codesourcery.com>
+
+ PR c++/17964
+ * error.c (cp_cpp_error): New function.
+ * cp-tree.h (cp_cpp_error): Declare.
+ * parser.c (cp_lexer_new_main): Set CPP option client_diagnostic
+ and error callback after lexing.
+
2005-11-03 Mark Mitchell <mark@codesourcery.com>
PR c++/21627
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 97cc064110c..e1ca9f3bea7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4437,5 +4437,8 @@ extern void cp_genericize (tree);
#else
#define ATTRIBUTE_GCC_CXXDIAG(m, n) ATTRIBUTE_NONNULL(m)
#endif
+extern void cp_cpp_error (cpp_reader *, int,
+ const char *, va_list)
+ ATTRIBUTE_GCC_CXXDIAG(3,0);
#endif /* ! GCC_CP_TREE_H */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 8e39ccadd1e..d5144b446f7 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2327,3 +2327,36 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
#undef next_lang
#undef next_int
}
+
+/* Callback from cpp_error for PFILE to print diagnostics arising from
+ interpreting strings. The diagnostic is of type LEVEL; MSG is the
+ translated message and AP the arguments. */
+
+void
+cp_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+ const char *msg, va_list ap)
+{
+ diagnostic_info diagnostic;
+ diagnostic_t dlevel;
+ switch (level)
+ {
+ case CPP_DL_WARNING:
+ case CPP_DL_WARNING_SYSHDR:
+ dlevel = DK_WARNING;
+ break;
+ case CPP_DL_PEDWARN:
+ dlevel = pedantic_error_kind ();
+ break;
+ case CPP_DL_ERROR:
+ dlevel = DK_ERROR;
+ break;
+ case CPP_DL_ICE:
+ dlevel = DK_ICE;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ diagnostic_set_info_translated (&diagnostic, msg, &ap,
+ input_location, dlevel);
+ report_diagnostic (&diagnostic);
+}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9821981f310..bbc5c1156bd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -297,6 +297,11 @@ cp_lexer_new_main (void)
string constant concatenation. */
c_lex_return_raw_strings = false;
+ /* Subsequent preprocessor diagnostics should use compiler
+ diagnostic functions to get the compiler source location. */
+ cpp_get_options (parse_in)->client_diagnostic = true;
+ cpp_get_callbacks (parse_in)->error = cp_cpp_error;
+
gcc_assert (lexer->next_token->type != CPP_PURGED);
return lexer;
}
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index c416010b223..7f4d8147340 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -112,19 +112,31 @@ diagnostic_initialize (diagnostic_context *context)
context->lock = 0;
}
+/* Initialize DIAGNOSTIC, where the message MSG has already been
+ translated. */
void
-diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
- va_list *args, location_t location,
- diagnostic_t kind)
+diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
+ va_list *args, location_t location,
+ diagnostic_t kind)
{
diagnostic->message.err_no = errno;
diagnostic->message.args_ptr = args;
- diagnostic->message.format_spec = _(gmsgid);
+ diagnostic->message.format_spec = msg;
diagnostic->location = location;
diagnostic->kind = kind;
diagnostic->option_index = 0;
}
+/* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
+ translated. */
+void
+diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
+ va_list *args, location_t location,
+ diagnostic_t kind)
+{
+ diagnostic_set_info_translated (diagnostic, _(gmsgid), args, location, kind);
+}
+
/* Return a malloc'd string describing a location. The caller is
responsible for freeing the memory. */
char *
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index e44d68028eb..3a3204bdcc3 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -184,6 +184,10 @@ extern void diagnostic_report_diagnostic (diagnostic_context *,
#ifdef ATTRIBUTE_GCC_DIAG
extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
+extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
+ va_list *, location_t,
+ diagnostic_t)
+ ATTRIBUTE_GCC_DIAG(2,0);
#endif
extern char *diagnostic_build_prefix (diagnostic_info *);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ac49bbcd28a..49d41e153e3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2005-11-03 Joseph S. Myers <joseph@codesourcery.com>
+ PR c++/17964
+ * g++.dg/cpp/string-1.C: New test.
+
+2005-11-03 Joseph S. Myers <joseph@codesourcery.com>
+
* gcc.target/powerpc: New directory.
* gcc.target/powerpc/powerpc.exp: New file.
* gcc.dg/20020118-1.c, gcc.dg/20030218-1.c, gcc.dg/20030505.c,
diff --git a/gcc/testsuite/g++.dg/cpp/string-1.C b/gcc/testsuite/g++.dg/cpp/string-1.C
new file mode 100644
index 00000000000..da3133071d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp/string-1.C
@@ -0,0 +1,9 @@
+// Test location of diagnostics for interpreting strings. Bug 17964.
+// Origin: Joseph Myers <joseph@codesourcery.com>
+// { dg-do compile }
+
+const char *s = "\q"; // { dg-error "unknown escape sequence" }
+
+const char *t = "\ "; // { dg-error "unknown escape sequence" }
+
+const char *u = "";
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 884002b1ea0..c0364802678 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,11 @@
+2005-11-03 Joseph S. Myers <joseph@codesourcery.com>
+
+ PR c++/17964
+ * include/cpplib.h (struct cpp_options): Add client_diagnostic.
+ (struct cpp_callbacks): Add error.
+ * errors.c (cpp_error): If client_diagnostic, use error callback.
+ * charset.c (convert_escape): Don't use %03o in diagnostic.
+
2005-10-21 James E Wilson <wilson@specifix.com>
PR preprocessor/15220
diff --git a/libcpp/charset.c b/libcpp/charset.c
index 2c87fb6ac27..78c89816735 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -1277,8 +1277,14 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit,
cpp_error (pfile, CPP_DL_PEDWARN,
"unknown escape sequence '\\%c'", (int) c);
else
- cpp_error (pfile, CPP_DL_PEDWARN,
- "unknown escape sequence: '\\%03o'", (int) c);
+ {
+ /* diagnostic.c does not support "%03o". When it does, this
+ code can use %03o directly in the diagnostic again. */
+ char buf[32];
+ sprintf(buf, "%03o", (int) c);
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "unknown escape sequence: '\\%s'", buf);
+ }
}
/* Now convert what we have to the execution character set. */
diff --git a/libcpp/errors.c b/libcpp/errors.c
index 477101e3041..554d9e3c5f1 100644
--- a/libcpp/errors.c
+++ b/libcpp/errors.c
@@ -140,20 +140,25 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
va_start (ap, msgid);
- if (CPP_OPTION (pfile, traditional))
- {
- if (pfile->state.in_directive)
- src_loc = pfile->directive_line;
- else
- src_loc = pfile->line_table->highest_line;
- }
+ if (CPP_OPTION (pfile, client_diagnostic))
+ pfile->cb.error (pfile, level, _(msgid), ap);
else
{
- src_loc = pfile->cur_token[-1].src_loc;
- }
+ if (CPP_OPTION (pfile, traditional))
+ {
+ if (pfile->state.in_directive)
+ src_loc = pfile->directive_line;
+ else
+ src_loc = pfile->line_table->highest_line;
+ }
+ else
+ {
+ src_loc = pfile->cur_token[-1].src_loc;
+ }
- if (_cpp_begin_message (pfile, level, src_loc, 0))
- v_message (msgid, ap);
+ if (_cpp_begin_message (pfile, level, src_loc, 0))
+ v_message (msgid, ap);
+ }
va_end (ap);
}
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 3c4d0d6cb5b..c5d8e85391a 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -435,6 +435,9 @@ struct cpp_options
/* True means return pragmas as tokens rather than processing
them directly. */
bool defer_pragmas;
+
+ /* True means error callback should be used for diagnostics. */
+ bool client_diagnostic;
};
/* Callback for header lookup for HEADER, which is the name of a
@@ -467,6 +470,11 @@ struct cpp_callbacks
int (*valid_pch) (cpp_reader *, const char *, int);
void (*read_pch) (cpp_reader *, const char *, int, const char *);
missing_header_cb missing_header;
+
+ /* Called to emit a diagnostic if client_diagnostic option is true.
+ This callback receives the translated message. */
+ void (*error) (cpp_reader *, int, const char *, va_list)
+ ATTRIBUTE_PRINTF(3,0);
};
/* Chain of directories to look for include files in. */