summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorsimonb <simonb@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-07 17:18:10 +0000
committersimonb <simonb@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-07 17:18:10 +0000
commit3a79f5dae958f51cced5663ae831955d01f53959 (patch)
tree579586014184f45d4119737d83f6440cab3847ac /libcpp
parent1ecc1105cbfe526cf44c6f393e588ba0d7418cd7 (diff)
downloadgcc-3a79f5dae958f51cced5663ae831955d01f53959.tar.gz
* diagnostic.h (diagnostic_override_option_index): New macro to
set a diagnostic's option_index. * c-tree.h (c_cpp_error): Add warning reason argument. * opts.c (_warning_as_error_callback): New. (register_warning_as_error_callback): Store callback for warnings enabled via enable_warning_as_error. (enable_warning_as_error): Call callback, minor code tidy. * opts.h (register_warning_as_error_callback): Declare. * c-opts.c (warning_as_error_callback): New, set cpp_opts flag in response to -Werror=. (c_common_init_options): Register warning_as_error_callback in opts.c. * common.opt: Add -Wno-cpp option. * c-common.c (struct reason_option_codes_t): Map cpp warning reason codes to gcc option indexes. * (c_option_controlling_cpp_error): New function, lookup the gcc option index for a cpp warning reason code. * (c_cpp_error): Add warning reason argument, call c_option_controlling_cpp_error for diagnostic_override_option_index. * doc/invoke.texi: Document -Wno-cpp. * cpp.c (cb_cpp_error): Add warning reason argument, set a value for diagnostic_override_option_index if CPP_W_WARNING_DIRECTIVE. * directives.c (do_diagnostic): Add warning reason argument, call appropriate error reporting function for code. (directive_diagnostics): Call specific warning functions with warning reason where appropriate. (do_error, do_warning, do_pragma_dependency): Add warning reason argument to do_diagnostic calls. * macro.c (_cpp_warn_if_unused_macro, enter_macro_context, _cpp_create_definition): Call specific warning functions with warning reason where appropriate. * Makefile.in: Add new diagnostic functions to gettext translations. * include/cpplib.h (struct cpp_callbacks): Add warning reason code to error callback. (CPP_DL_WARNING, CPP_DL_WARNING_SYSHDR, CPP_DL_PEDWARN, CPP_DL_ERROR, CPP_DL_ICE, CPP_DL_NOTE, CPP_DL_FATAL): Replace macros with enums. (CPP_W_NONE, CPP_W_DEPRECATED, CPP_W_COMMENTS, CPP_W_MISSING_INCLUDE_DIRS, CPP_W_TRIGRAPHS, CPP_W_MULTICHAR, CPP_W_TRADITIONAL, CPP_W_LONG_LONG, CPP_W_ENDIF_LABELS, CPP_W_NUM_SIGN_CHANGE, CPP_W_VARIADIC_MACROS, CPP_W_BUILTIN_MACRO_REDEFINED, CPP_W_DOLLARS, CPP_W_UNDEF, CPP_W_UNUSED_MACROS, CPP_W_CXX_OPERATOR_NAMES, CPP_W_NORMALIZE, CPP_W_INVALID_PCH, CPP_W_WARNING_DIRECTIVE): New enums for cpp warning reason codes. (cpp_warning, cpp_pedwarning, cpp_warning_syshdr, cpp_warning_with_line, cpp_pedwarning_with_line, cpp_warning_with_line_syshdr): New specific error reporting functions. * pch.c (cpp_valid_state): Call specific warning functions with warning reason where appropriate. * errors.c (cpp_diagnostic, cpp_diagnostic_with_line): New central diagnostic handlers. (cpp_warning, cpp_pedwarning, cpp_warning_syshdr, cpp_warning_with_line, cpp_pedwarning_with_line, cpp_warning_with_line_syshdr): New specific error reporting functions. * expr.c (cpp_classify_number, eval_token, num_unary_op): Call specific warning functions with warning reason where appropriate. * lex.c (_cpp_process_line_notes, _cpp_skip_block_comment, warn_about_normalization, lex_identifier_intern, lex_identifier, _cpp_lex_direct): Ditto. * charset.c (_cpp_valid_ucn, convert_hex, convert_escape, narrow_str_to_charconst): Ditto. * gcc.dg/cpp/warn-undef-2.c: New. * gcc.dg/cpp/warn-traditional-2.c: New. * gcc.dg/cpp/warn-comments-2.c: New. * gcc.dg/cpp/warning-directive-1.c: New. * gcc.dg/cpp/warn-long-long.c: New. * gcc.dg/cpp/warn-traditional.c: New. * gcc.dg/cpp/warn-variadic-2.c: New. * gcc.dg/cpp/warn-undef.c: New. * gcc.dg/cpp/warn-normalized-1.c: New. * gcc.dg/cpp/warning-directive-2.c: New. * gcc.dg/cpp/warn-long-long-2.c: New. * gcc.dg/cpp/warn-variadic.c: New. * gcc.dg/cpp/warn-normalized-2.c: New. * gcc.dg/cpp/warning-directive-3.c: New. * gcc.dg/cpp/warn-deprecated-2.c: New. * gcc.dg/cpp/warn-trigraphs-1.c: New. * gcc.dg/cpp/warn-multichar-2.c: New. * gcc.dg/cpp/warn-normalized-3.c: New. * gcc.dg/cpp/warning-directive-4.c: New. * gcc.dg/cpp/warn-unused-macros.c: New. * gcc.dg/cpp/warn-trigraphs-2.c: New. * gcc.dg/cpp/warn-cxx-compat-2.c: New. * gcc.dg/cpp/warn-cxx-compat.c: New. * gcc.dg/cpp/warn-redefined.c: New. * gcc.dg/cpp/warn-trigraphs-3.c: New. * gcc.dg/cpp/warn-unused-macros-2.c: New. * gcc.dg/cpp/warn-deprecated.c: New. * gcc.dg/cpp/warn-trigraphs-4.c: New. * gcc.dg/cpp/warn-redefined-2.c: New. * gcc.dg/cpp/warn-comments.c: New. * gcc.dg/cpp/warn-multichar.c: New. * g++.dg/cpp/warning-directive-1.C: New. * g++.dg/cpp/warning-directive-2.C: New. * g++.dg/cpp/warning-directive-3.C: New. * g++.dg/cpp/warning-directive-4.C: New. * gfortran.dg/warning-directive-1.F90: New. * gfortran.dg/warning-directive-3.F90: New. * gfortran.dg/warning-directive-2.F90: New. * gfortran.dg/warning-directive-4.F90: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158079 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog42
-rw-r--r--libcpp/Makefile.in9
-rw-r--r--libcpp/charset.c16
-rw-r--r--libcpp/directives.c37
-rw-r--r--libcpp/errors.c166
-rw-r--r--libcpp/expr.c44
-rw-r--r--libcpp/include/cpplib.h80
-rw-r--r--libcpp/lex.c43
-rw-r--r--libcpp/macro.c27
-rw-r--r--libcpp/pch.c26
10 files changed, 371 insertions, 119 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index b55d25576e7..7762099dd12 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,45 @@
+2010-04-07 Simon Baldwin <simonb@google.com>
+
+ * directives.c (do_diagnostic): Add warning reason argument,
+ call appropriate error reporting function for code.
+ (directive_diagnostics): Call specific warning functions with
+ warning reason where appropriate.
+ (do_error, do_warning, do_pragma_dependency): Add warning reason
+ argument to do_diagnostic calls.
+ * macro.c (_cpp_warn_if_unused_macro, enter_macro_context,
+ _cpp_create_definition): Call specific warning functions with
+ warning reason where appropriate.
+ * Makefile.in: Add new diagnostic functions to gettext translations.
+ * include/cpplib.h (struct cpp_callbacks): Add warning reason code
+ to error callback.
+ (CPP_DL_WARNING, CPP_DL_WARNING_SYSHDR, CPP_DL_PEDWARN, CPP_DL_ERROR,
+ CPP_DL_ICE, CPP_DL_NOTE, CPP_DL_FATAL): Replace macros with enums.
+ (CPP_W_NONE, CPP_W_DEPRECATED, CPP_W_COMMENTS,
+ CPP_W_MISSING_INCLUDE_DIRS, CPP_W_TRIGRAPHS, CPP_W_MULTICHAR,
+ CPP_W_TRADITIONAL, CPP_W_LONG_LONG, CPP_W_ENDIF_LABELS,
+ CPP_W_NUM_SIGN_CHANGE, CPP_W_VARIADIC_MACROS,
+ CPP_W_BUILTIN_MACRO_REDEFINED, CPP_W_DOLLARS, CPP_W_UNDEF,
+ CPP_W_UNUSED_MACROS, CPP_W_CXX_OPERATOR_NAMES, CPP_W_NORMALIZE,
+ CPP_W_INVALID_PCH, CPP_W_WARNING_DIRECTIVE): New enums for cpp
+ warning reason codes.
+ (cpp_warning, cpp_pedwarning, cpp_warning_syshdr,
+ cpp_warning_with_line, cpp_pedwarning_with_line,
+ cpp_warning_with_line_syshdr): New specific error reporting functions.
+ * pch.c (cpp_valid_state): Call specific warning functions with
+ warning reason where appropriate.
+ * errors.c (cpp_diagnostic, cpp_diagnostic_with_line): New central
+ diagnostic handlers.
+ (cpp_warning, cpp_pedwarning, cpp_warning_syshdr,
+ cpp_warning_with_line, cpp_pedwarning_with_line,
+ cpp_warning_with_line_syshdr): New specific error reporting functions.
+ * expr.c (cpp_classify_number, eval_token, num_unary_op): Call
+ specific warning functions with warning reason where appropriate.
+ * lex.c (_cpp_process_line_notes, _cpp_skip_block_comment,
+ warn_about_normalization, lex_identifier_intern, lex_identifier,
+ _cpp_lex_direct): Ditto.
+ * charset.c (_cpp_valid_ucn, convert_hex, convert_escape,
+ narrow_str_to_charconst): Ditto.
+
2010-04-06 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/43642
diff --git a/libcpp/Makefile.in b/libcpp/Makefile.in
index 268d1baaca2..8d19d8dbf14 100644
--- a/libcpp/Makefile.in
+++ b/libcpp/Makefile.in
@@ -249,8 +249,15 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES)
$(mkinstalldirs) $(srcdir)/po
$(XGETTEXT) --default-domain=$(PACKAGE) \
--keyword=_ --keyword=N_ \
- --keyword=cpp_error:3 --keyword=cpp_errno:3 \
+ --keyword=cpp_error:3 \
+ --keyword=cpp_warning:3 \
+ --keyword=cpp_pedwarning:3 \
+ --keyword=cpp_warning_syshdr:3 \
--keyword=cpp_error_with_line:5 \
+ --keyword=cpp_warning_with_line:5 \
+ --keyword=cpp_pedwarning_with_line:5 \
+ --keyword=cpp_warning_with_line_syshdr:5 \
+ --keyword=cpp_errno:3 \
--keyword=SYNTAX_ERROR --keyword=SYNTAX_ERROR2 \
--copyright-holder="Free Software Foundation, Inc." \
--msgid-bugs-address="http://gcc.gnu.org/bugs.html" \
diff --git a/libcpp/charset.c b/libcpp/charset.c
index 304efc8de0d..7bc3db3b44f 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -993,9 +993,9 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr,
cpp_error (pfile, CPP_DL_WARNING,
"universal character names are only valid in C++ and C99");
else if (CPP_WTRADITIONAL (pfile) && identifier_pos == 0)
- cpp_error (pfile, CPP_DL_WARNING,
- "the meaning of '\\%c' is different in traditional C",
- (int) str[-1]);
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "the meaning of '\\%c' is different in traditional C",
+ (int) str[-1]);
if (str[-1] == 'u')
length = 4;
@@ -1174,8 +1174,8 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
size_t mask = width_to_mask (width);
if (CPP_WTRADITIONAL (pfile))
- cpp_error (pfile, CPP_DL_WARNING,
- "the meaning of '\\x' is different in traditional C");
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "the meaning of '\\x' is different in traditional C");
from++; /* Skip 'x'. */
while (from < limit)
@@ -1302,8 +1302,8 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit,
case 'a':
if (CPP_WTRADITIONAL (pfile))
- cpp_error (pfile, CPP_DL_WARNING,
- "the meaning of '\\a' is different in traditional C");
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "the meaning of '\\a' is different in traditional C");
c = charconsts[0];
break;
@@ -1509,7 +1509,7 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str,
"character constant too long for its type");
}
else if (i > 1 && CPP_OPTION (pfile, warn_multichar))
- cpp_error (pfile, CPP_DL_WARNING, "multi-character character constant");
+ cpp_warning (pfile, CPP_W_MULTICHAR, "multi-character character constant");
/* Multichar constants are of type int and therefore signed. */
if (i > 1)
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 409d908b4e8..77da485cda1 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -104,7 +104,7 @@ static const char *parse_include (cpp_reader *, int *, const cpp_token ***,
static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
static unsigned int read_flag (cpp_reader *, unsigned int);
static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
-static void do_diagnostic (cpp_reader *, int, int);
+static void do_diagnostic (cpp_reader *, int, int, int);
static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
static void do_include_common (cpp_reader *, enum include_type);
@@ -355,8 +355,8 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented)
else if (((dir->flags & DEPRECATED) != 0
|| (dir == &dtable[T_IMPORT] && !CPP_OPTION (pfile, objc)))
&& CPP_OPTION (pfile, warn_deprecated))
- cpp_error (pfile, CPP_DL_WARNING, "#%s is a deprecated GCC extension",
- dir->name);
+ cpp_warning (pfile, CPP_W_DEPRECATED,
+ "#%s is a deprecated GCC extension", dir->name);
}
/* Traditionally, a directive is ignored unless its # is in
@@ -368,16 +368,16 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented)
if (CPP_WTRADITIONAL (pfile))
{
if (dir == &dtable[T_ELIF])
- cpp_error (pfile, CPP_DL_WARNING,
- "suggest not using #elif in traditional C");
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "suggest not using #elif in traditional C");
else if (indented && dir->origin == KANDR)
- cpp_error (pfile, CPP_DL_WARNING,
- "traditional C ignores #%s with the # indented",
- dir->name);
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "traditional C ignores #%s with the # indented",
+ dir->name);
else if (!indented && dir->origin != KANDR)
- cpp_error (pfile, CPP_DL_WARNING,
- "suggest hiding #%s from traditional C with an indented #",
- dir->name);
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "suggest hiding #%s from traditional C with an indented #",
+ dir->name);
}
}
@@ -1045,7 +1045,7 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
/* Report a warning or error detected by the program we are
processing. Use the directive's tokens in the error message. */
static void
-do_diagnostic (cpp_reader *pfile, int code, int print_dir)
+do_diagnostic (cpp_reader *pfile, int code, int reason, int print_dir)
{
const unsigned char *dir_name;
unsigned char *line;
@@ -1059,21 +1059,26 @@ do_diagnostic (cpp_reader *pfile, int code, int print_dir)
line = cpp_output_line_to_string (pfile, dir_name);
pfile->state.prevent_expansion--;
- cpp_error_with_line (pfile, code, src_loc, 0, "%s", line);
+ if (code == CPP_DL_WARNING_SYSHDR && reason)
+ cpp_warning_with_line_syshdr (pfile, reason, src_loc, 0, "%s", line);
+ else if (code == CPP_DL_WARNING && reason)
+ cpp_warning_with_line (pfile, reason, src_loc, 0, "%s", line);
+ else
+ cpp_error_with_line (pfile, code, src_loc, 0, "%s", line);
free (line);
}
static void
do_error (cpp_reader *pfile)
{
- do_diagnostic (pfile, CPP_DL_ERROR, 1);
+ do_diagnostic (pfile, CPP_DL_ERROR, 0, 1);
}
static void
do_warning (cpp_reader *pfile)
{
/* We want #warning diagnostics to be emitted in system headers too. */
- do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, 1);
+ do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, CPP_W_WARNING_DIRECTIVE, 1);
}
/* Report program identification. */
@@ -1595,7 +1600,7 @@ do_pragma_dependency (cpp_reader *pfile)
if (cpp_get_token (pfile)->type != CPP_EOF)
{
_cpp_backup_tokens (pfile, 1);
- do_diagnostic (pfile, CPP_DL_WARNING, 0);
+ do_diagnostic (pfile, CPP_DL_WARNING, 0, 0);
}
}
diff --git a/libcpp/errors.c b/libcpp/errors.c
index bc852894993..b7783f54d31 100644
--- a/libcpp/errors.c
+++ b/libcpp/errors.c
@@ -28,16 +28,16 @@ along with this program; see the file COPYING3. If not see
#include "cpplib.h"
#include "internal.h"
-/* Print an error at the location of the previously lexed token. */
-bool
-cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
+/* Print a diagnostic at the location of the previously lexed token. */
+
+ATTRIBUTE_FPTR_PRINTF(4,0)
+static bool
+cpp_diagnostic (cpp_reader * pfile, int level, int reason,
+ const char *msgid, va_list *ap)
{
source_location src_loc;
- va_list ap;
bool ret;
- va_start (ap, msgid);
-
if (CPP_OPTION (pfile, traditional))
{
if (pfile->state.in_directive)
@@ -61,13 +61,95 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
if (!pfile->cb.error)
abort ();
- ret = pfile->cb.error (pfile, level, src_loc, 0, _(msgid), &ap);
+ ret = pfile->cb.error (pfile, level, reason, src_loc, 0, _(msgid), ap);
+
+ return ret;
+}
+
+/* Print a warning or error, depending on the value of LEVEL. */
+
+bool
+cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
+{
+ va_list ap;
+ bool ret;
+
+ va_start (ap, msgid);
+
+ ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap);
va_end (ap);
return ret;
}
-/* Print an error at a specific location. */
+/* Print a warning. The warning reason may be given in REASON. */
+
+bool
+cpp_warning (cpp_reader * pfile, int reason, const char *msgid, ...)
+{
+ va_list ap;
+ bool ret;
+
+ va_start (ap, msgid);
+
+ ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap);
+
+ va_end (ap);
+ return ret;
+}
+
+/* Print a pedantic warning. The warning reason may be given in REASON. */
+
+bool
+cpp_pedwarning (cpp_reader * pfile, int reason, const char *msgid, ...)
+{
+ va_list ap;
+ bool ret;
+
+ va_start (ap, msgid);
+
+ ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap);
+
+ va_end (ap);
+ return ret;
+}
+
+/* Print a warning, including system headers. The warning reason may be
+ given in REASON. */
+
+bool
+cpp_warning_syshdr (cpp_reader * pfile, int reason, const char *msgid, ...)
+{
+ va_list ap;
+ bool ret;
+
+ va_start (ap, msgid);
+
+ ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap);
+
+ va_end (ap);
+ return ret;
+}
+
+/* Print a diagnostic at a specific location. */
+
+ATTRIBUTE_FPTR_PRINTF(6,0)
+static bool
+cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason,
+ source_location src_loc, unsigned int column,
+ const char *msgid, va_list *ap)
+{
+ bool ret;
+
+ if (!pfile->cb.error)
+ abort ();
+ ret = pfile->cb.error (pfile, level, reason, src_loc, column, _(msgid), ap);
+
+ return ret;
+}
+
+/* Print a warning or error, depending on the value of LEVEL. */
+
bool
cpp_error_with_line (cpp_reader *pfile, int level,
source_location src_loc, unsigned int column,
@@ -75,17 +157,77 @@ cpp_error_with_line (cpp_reader *pfile, int level,
{
va_list ap;
bool ret;
-
+
va_start (ap, msgid);
- if (!pfile->cb.error)
- abort ();
- ret = pfile->cb.error (pfile, level, src_loc, column, _(msgid), &ap);
+ ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc,
+ column, msgid, &ap);
+
+ va_end (ap);
+ return ret;
+}
+
+/* Print a warning. The warning reason may be given in REASON. */
+
+bool
+cpp_warning_with_line (cpp_reader *pfile, int reason,
+ source_location src_loc, unsigned int column,
+ const char *msgid, ...)
+{
+ va_list ap;
+ bool ret;
+
+ va_start (ap, msgid);
+
+ ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc,
+ column, msgid, &ap);
+
+ va_end (ap);
+ return ret;
+}
+
+/* Print a pedantic warning. The warning reason may be given in REASON. */
+
+bool
+cpp_pedwarning_with_line (cpp_reader *pfile, int reason,
+ source_location src_loc, unsigned int column,
+ const char *msgid, ...)
+{
+ va_list ap;
+ bool ret;
+
+ va_start (ap, msgid);
+
+ ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc,
+ column, msgid, &ap);
va_end (ap);
return ret;
}
+/* Print a warning, including system headers. The warning reason may be
+ given in REASON. */
+
+bool
+cpp_warning_with_line_syshdr (cpp_reader *pfile, int reason,
+ source_location src_loc, unsigned int column,
+ const char *msgid, ...)
+{
+ va_list ap;
+ bool ret;
+
+ va_start (ap, msgid);
+
+ ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc,
+ column, msgid, &ap);
+
+ va_end (ap);
+ return ret;
+}
+
+/* Print a warning or error, depending on the value of LEVEL. Include
+ information from errno. */
+
bool
cpp_errno (cpp_reader *pfile, int level, const char *msgid)
{
diff --git a/libcpp/expr.c b/libcpp/expr.c
index 60cb2816a7a..4dbc98974af 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -371,9 +371,9 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
if (limit != str
&& CPP_WTRADITIONAL (pfile)
&& ! cpp_sys_macro_p (pfile))
- cpp_error (pfile, CPP_DL_WARNING,
- "traditional C rejects the \"%.*s\" suffix",
- (int) (limit - str), str);
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "traditional C rejects the \"%.*s\" suffix",
+ (int) (limit - str), str);
/* A suffix for double is a GCC extension via decimal float support.
If the suffix also specifies an imaginary value we'll catch that
@@ -417,21 +417,27 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile))
{
int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY));
- int large = (result & CPP_N_WIDTH) == CPP_N_LARGE;
+ int large = (result & CPP_N_WIDTH) == CPP_N_LARGE
+ && CPP_OPTION (pfile, warn_long_long);
- if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long)))
- cpp_error (pfile, CPP_DL_WARNING,
- "traditional C rejects the \"%.*s\" suffix",
- (int) (limit - str), str);
+ if (u_or_i || large)
+ cpp_warning (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL,
+ "traditional C rejects the \"%.*s\" suffix",
+ (int) (limit - str), str);
}
if ((result & CPP_N_WIDTH) == CPP_N_LARGE
&& CPP_OPTION (pfile, warn_long_long))
- cpp_error (pfile,
- CPP_OPTION (pfile, c99) ? CPP_DL_WARNING : CPP_DL_PEDWARN,
- CPP_OPTION (pfile, cplusplus)
- ? "use of C++0x long long integer constant"
- : "use of C99 long long integer constant");
+ {
+ const char *message = CPP_OPTION (pfile, cplusplus)
+ ? N_("use of C++0x long long integer constant")
+ : N_("use of C99 long long integer constant");
+
+ if (CPP_OPTION (pfile, c99))
+ cpp_warning (pfile, CPP_W_LONG_LONG, message);
+ else
+ cpp_pedwarning (pfile, CPP_W_LONG_LONG, message);
+ }
result |= CPP_N_INTEGER;
}
@@ -792,8 +798,8 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
result.high = 0;
result.low = 0;
if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
- cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined",
- NODE_NAME (token->val.node.node));
+ cpp_warning (pfile, CPP_W_UNDEF, "\"%s\" is not defined",
+ NODE_NAME (token->val.node.node));
}
break;
@@ -806,8 +812,8 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
cpp_error (pfile, CPP_DL_PEDWARN,
"assertions are a GCC extension");
else if (CPP_OPTION (pfile, warn_deprecated))
- cpp_error (pfile, CPP_DL_WARNING,
- "assertions are a deprecated extension");
+ cpp_warning (pfile, CPP_W_DEPRECATED,
+ "assertions are a deprecated extension");
}
_cpp_test_assertion (pfile, &temp);
result.high = 0;
@@ -1502,8 +1508,8 @@ num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op)
{
case CPP_UPLUS:
if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval)
- cpp_error (pfile, CPP_DL_WARNING,
- "traditional C rejects the unary plus operator");
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
+ "traditional C rejects the unary plus operator");
num.overflow = false;
break;
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 6175bbcb092..9f29e6e63ae 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -497,9 +497,9 @@ struct cpp_callbacks
/* Called to emit a diagnostic. This callback receives the
translated message. */
- bool (*error) (cpp_reader *, int, source_location, unsigned int,
+ bool (*error) (cpp_reader *, int, int, source_location, unsigned int,
const char *, va_list *)
- ATTRIBUTE_FPTR_PRINTF(5,0);
+ ATTRIBUTE_FPTR_PRINTF(6,0);
/* Callbacks for when a macro is expanded, or tested (whether
defined or not at the time) in #ifdef, #ifndef or "defined". */
@@ -829,25 +829,57 @@ cpp_num cpp_num_sign_extend (cpp_num, size_t);
position in the translation unit with it, use cpp_error_with_line
with a line number of zero. */
-/* Warning, an error with -Werror. */
-#define CPP_DL_WARNING 0x00
-/* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */
-#define CPP_DL_WARNING_SYSHDR 0x01
-/* Warning, an error with -pedantic-errors or -Werror. */
-#define CPP_DL_PEDWARN 0x02
-/* An error. */
-#define CPP_DL_ERROR 0x03
-/* An internal consistency check failed. Prints "internal error: ",
- otherwise the same as CPP_DL_ERROR. */
-#define CPP_DL_ICE 0x04
-/* An informative note following a warning. */
-#define CPP_DL_NOTE 0x05
-/* A fatal error. */
-#define CPP_DL_FATAL 0x06
+enum {
+ /* Warning, an error with -Werror. */
+ CPP_DL_WARNING = 0,
+ /* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */
+ CPP_DL_WARNING_SYSHDR,
+ /* Warning, an error with -pedantic-errors or -Werror. */
+ CPP_DL_PEDWARN,
+ /* An error. */
+ CPP_DL_ERROR,
+ /* An internal consistency check failed. Prints "internal error: ",
+ otherwise the same as CPP_DL_ERROR. */
+ CPP_DL_ICE,
+ /* An informative note following a warning. */
+ CPP_DL_NOTE,
+ /* A fatal error. */
+ CPP_DL_FATAL
+};
+
+/* Warning reason codes. Use a reason code of zero for unclassified warnings
+ and errors that are not warnings. */
+enum {
+ CPP_W_NONE = 0,
+ CPP_W_DEPRECATED,
+ CPP_W_COMMENTS,
+ CPP_W_MISSING_INCLUDE_DIRS,
+ CPP_W_TRIGRAPHS,
+ CPP_W_MULTICHAR,
+ CPP_W_TRADITIONAL,
+ CPP_W_LONG_LONG,
+ CPP_W_ENDIF_LABELS,
+ CPP_W_NUM_SIGN_CHANGE,
+ CPP_W_VARIADIC_MACROS,
+ CPP_W_BUILTIN_MACRO_REDEFINED,
+ CPP_W_DOLLARS,
+ CPP_W_UNDEF,
+ CPP_W_UNUSED_MACROS,
+ CPP_W_CXX_OPERATOR_NAMES,
+ CPP_W_NORMALIZE,
+ CPP_W_INVALID_PCH,
+ CPP_W_WARNING_DIRECTIVE
+};
/* Output a diagnostic of some kind. */
extern bool cpp_error (cpp_reader *, int, const char *msgid, ...)
ATTRIBUTE_PRINTF_3;
+extern bool cpp_warning (cpp_reader *, int, const char *msgid, ...)
+ ATTRIBUTE_PRINTF_3;
+extern bool cpp_pedwarning (cpp_reader *, int, const char *msgid, ...)
+ ATTRIBUTE_PRINTF_3;
+extern bool cpp_warning_syshdr (cpp_reader *, int, const char *msgid, ...)
+ ATTRIBUTE_PRINTF_3;
/* Output a diagnostic with "MSGID: " preceding the
error string of errno. No location is printed. */
@@ -856,8 +888,18 @@ extern bool cpp_errno (cpp_reader *, int, const char *msgid);
/* Same as cpp_error, except additionally specifies a position as a
(translation unit) physical line and physical column. If the line is
zero, then no location is printed. */
-extern bool cpp_error_with_line (cpp_reader *, int, source_location, unsigned,
- const char *msgid, ...) ATTRIBUTE_PRINTF_5;
+extern bool cpp_error_with_line (cpp_reader *, int, source_location,
+ unsigned, const char *msgid, ...)
+ ATTRIBUTE_PRINTF_5;
+extern bool cpp_warning_with_line (cpp_reader *, int, source_location,
+ unsigned, const char *msgid, ...)
+ ATTRIBUTE_PRINTF_5;
+extern bool cpp_pedwarning_with_line (cpp_reader *, int, source_location,
+ unsigned, const char *msgid, ...)
+ ATTRIBUTE_PRINTF_5;
+extern bool cpp_warning_with_line_syshdr (cpp_reader *, int, source_location,
+ unsigned, const char *msgid, ...)
+ ATTRIBUTE_PRINTF_5;
/* In lex.c */
extern int cpp_ideq (const cpp_token *, const char *);
diff --git a/libcpp/lex.c b/libcpp/lex.c
index f2999822534..f6282729946 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -301,14 +301,16 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
&& (!in_comment || warn_in_comment (pfile, note)))
{
if (CPP_OPTION (pfile, trigraphs))
- cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
- "trigraph ??%c converted to %c",
- note->type,
- (int) _cpp_trigraph_map[note->type]);
+ cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS,
+ pfile->line_table->highest_line, col,
+ "trigraph ??%c converted to %c",
+ note->type,
+ (int) _cpp_trigraph_map[note->type]);
else
{
- cpp_error_with_line
- (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
+ cpp_warning_with_line
+ (pfile, CPP_W_TRIGRAPHS,
+ pfile->line_table->highest_line, col,
"trigraph ??%c ignored, use -trigraphs to enable",
note->type);
}
@@ -355,9 +357,10 @@ _cpp_skip_block_comment (cpp_reader *pfile)
&& cur[0] == '*' && cur[1] != '/')
{
buffer->cur = cur;
- cpp_error_with_line (pfile, CPP_DL_WARNING,
- pfile->line_table->highest_line, CPP_BUF_COL (buffer),
- "\"/*\" within comment");
+ cpp_warning_with_line (pfile, CPP_W_COMMENTS,
+ pfile->line_table->highest_line,
+ CPP_BUF_COL (buffer),
+ "\"/*\" within comment");
}
}
else if (c == '\n')
@@ -460,11 +463,11 @@ warn_about_normalization (cpp_reader *pfile,
sz = cpp_spell_token (pfile, token, buf, false) - buf;
if (NORMALIZE_STATE_RESULT (s) == normalized_C)
- cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0,
- "`%.*s' is not in NFKC", (int) sz, buf);
+ cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0,
+ "`%.*s' is not in NFKC", (int) sz, buf);
else
- cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0,
- "`%.*s' is not in NFC", (int) sz, buf);
+ cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0,
+ "`%.*s' is not in NFC", (int) sz, buf);
}
}
@@ -545,9 +548,9 @@ lex_identifier_intern (cpp_reader *pfile, const uchar *base)
/* For -Wc++-compat, warn about use of C++ named operators. */
if (result->flags & NODE_WARN_OPERATOR)
- cpp_error (pfile, CPP_DL_WARNING,
- "identifier \"%s\" is a special operator name in C++",
- NODE_NAME (result));
+ cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES,
+ "identifier \"%s\" is a special operator name in C++",
+ NODE_NAME (result));
}
return result;
@@ -622,9 +625,9 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
/* For -Wc++-compat, warn about use of C++ named operators. */
if (result->flags & NODE_WARN_OPERATOR)
- cpp_error (pfile, CPP_DL_WARNING,
- "identifier \"%s\" is a special operator name in C++",
- NODE_NAME (result));
+ cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES,
+ "identifier \"%s\" is a special operator name in C++",
+ NODE_NAME (result));
}
return result;
@@ -1531,7 +1534,7 @@ _cpp_lex_direct (cpp_reader *pfile)
}
if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
- cpp_error (pfile, CPP_DL_WARNING, "multi-line comment");
+ cpp_warning (pfile, CPP_W_COMMENTS, "multi-line comment");
}
else if (c == '=')
{
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 6647db56714..cbb0b0e7159 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -83,8 +83,8 @@ _cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
if (!macro->used
&& MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line)))
- cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0,
- "macro \"%s\" is not used", NODE_NAME (node));
+ cpp_warning_with_line (pfile, CPP_W_UNUSED_MACROS, macro->line, 0,
+ "macro \"%s\" is not used", NODE_NAME (node));
}
return 1;
@@ -860,9 +860,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
if (buff == NULL)
{
if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
- cpp_error (pfile, CPP_DL_WARNING,
+ cpp_warning (pfile, CPP_W_TRADITIONAL,
"function-like macro \"%s\" must be used with arguments in traditional C",
- NODE_NAME (node));
+ NODE_NAME (node));
if (pragma_buff)
_cpp_release_buff (pfile, pragma_buff);
@@ -1585,13 +1585,14 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
if (! CPP_OPTION (pfile, c99)
&& CPP_OPTION (pfile, pedantic)
&& CPP_OPTION (pfile, warn_variadic_macros))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "anonymous variadic macros were introduced in C99");
+ cpp_pedwarning
+ (pfile, CPP_W_VARIADIC_MACROS,
+ "anonymous variadic macros were introduced in C99");
}
else if (CPP_OPTION (pfile, pedantic)
&& CPP_OPTION (pfile, warn_variadic_macros))
- cpp_error (pfile, CPP_DL_PEDWARN,
- "ISO C does not permit named variadic macros");
+ cpp_pedwarning (pfile, CPP_W_VARIADIC_MACROS,
+ "ISO C does not permit named variadic macros");
/* We're at the end, and just expect a closing parenthesis. */
token = _cpp_lex_token (pfile);
@@ -1894,10 +1895,14 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
if (warn_of_redefinition (pfile, node, macro))
{
+ const int reason = (node->flags & NODE_BUILTIN)
+ ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;
bool warned;
- warned = cpp_error_with_line (pfile, CPP_DL_PEDWARN,
- pfile->directive_line, 0,
- "\"%s\" redefined", NODE_NAME (node));
+
+ warned = cpp_pedwarning_with_line (pfile, reason,
+ pfile->directive_line, 0,
+ "\"%s\" redefined",
+ NODE_NAME (node));
if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
cpp_error_with_line (pfile, CPP_DL_NOTE,
diff --git a/libcpp/pch.c b/libcpp/pch.c
index c70759a996d..2fb7ba543e7 100644
--- a/libcpp/pch.c
+++ b/libcpp/pch.c
@@ -613,9 +613,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
|| h->flags & NODE_POISONED)
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `%.*s' is poisoned",
- name, m.name_length, namebuf);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `%.*s' is poisoned",
+ name, m.name_length, namebuf);
goto fail;
}
@@ -635,9 +635,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
continue;
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `%.*s' not defined",
- name, m.name_length, namebuf);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `%.*s' not defined",
+ name, m.name_length, namebuf);
goto fail;
}
@@ -647,7 +647,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
|| memcmp (namebuf, newdefn, m.definition_length) != 0)
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
"%s: not used because `%.*s' defined as `%s' not `%.*s'",
name, m.name_length, namebuf, newdefn + m.name_length,
m.definition_length - m.name_length,
@@ -688,9 +688,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
else
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `%s' is defined",
- name, first);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `%s' is defined",
+ name, first);
goto fail;
}
}
@@ -708,9 +708,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
if (counter && r->counter)
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `__COUNTER__' is invalid",
- name);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `__COUNTER__' is invalid",
+ name);
goto fail;
}