diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/error.c | 33 | ||||
-rw-r--r-- | gcc/cp/parser.c | 5 | ||||
-rw-r--r-- | gcc/diagnostic.c | 20 | ||||
-rw-r--r-- | gcc/diagnostic.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp/string-1.C | 9 | ||||
-rw-r--r-- | libcpp/ChangeLog | 8 | ||||
-rw-r--r-- | libcpp/charset.c | 10 | ||||
-rw-r--r-- | libcpp/errors.c | 27 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 8 |
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. */ |