From: Zack Weinberg Date: Sat, 1 Apr 2000 22:55:25 +0000 (+0000) Subject: cpplib.c: Include symcat.h. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=07aa0b04f2ef60131900c2ea350d0d78e028acad;p=platform%2Fupstream%2Fgcc.git cpplib.c: Include symcat.h. * cpplib.c: Include symcat.h. Add 'origin' field to struct directive. Add origin values to DIRECTIVE_TABLE. Generate the strings and function names on the fly. Take the #sccs entry out of the table if SCCS_DIRECTIVE is not defined. (_cpp_handle_directive): Decide if the # was at the beginning of the line here. Issue -pedantic warnings for extended directives here. Warn about K+R directives with the # indented, and C89/extended directives with the # not indented, here. (do_import, do_include_next, do_warning, do_ident, do_sccs, do_assert, do_unassert): Don't issue pedantic warning here. * cpphash.h: Add CPP_WTRADITIONAL macro. * cpplib.h (struct cpp_options): Rename warn_stringify to warn_traditional; update comments. * cppinit.c (handle_option): Set warn_traditional not warn_stringify. * cpphash.c: Replace CPP_OPTION (pfile, warn_stringify) with CPP_WTRADITIONAL (pfile). * cpplex.c (_cpp_lex_token): Don't decide if directives should be ignored in -traditional mode here. * cpplex.c: Copy ISTABLE macros from cppinit.c, and adapt them to initialize speccase[] and trigraph_map[]. Delete all references to pfile->input_speccase. Always treat '?' as a special character. Remove table-initialization code from _cpp_init_input_buffer. * cpplib.h (struct cpp_reader): Remove input_speccase field. * cppinit.c (cpp_cleanup): Don't free input_speccase. From-SVN: r32860 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8b6746a..3fb581d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,27 @@ 2000-04-01 Zack Weinberg + * cpplib.c: Include symcat.h. Add 'origin' field to struct + directive. Add origin values to DIRECTIVE_TABLE. Generate + the strings and function names on the fly. Take the #sccs + entry out of the table if SCCS_DIRECTIVE is not defined. + (_cpp_handle_directive): Decide if the # was at the beginning + of the line here. Issue -pedantic warnings for extended + directives here. Warn about K+R directives with the # + indented, and C89/extended directives with the # not indented, + here. + (do_import, do_include_next, do_warning, do_ident, do_sccs, + do_assert, do_unassert): Don't issue pedantic warning here. + + * cpphash.h: Add CPP_WTRADITIONAL macro. + * cpplib.h (struct cpp_options): Rename warn_stringify to + warn_traditional; update comments. + * cppinit.c (handle_option): Set warn_traditional not + warn_stringify. + * cpphash.c: Replace CPP_OPTION (pfile, warn_stringify) with + CPP_WTRADITIONAL (pfile). + * cpplex.c (_cpp_lex_token): Don't decide if directives should + be ignored in -traditional mode here. + * cpplex.c: Copy ISTABLE macros from cppinit.c, and adapt them to initialize speccase[] and trigraph_map[]. Delete all references to pfile->input_speccase. Always treat '?' as a diff --git a/gcc/cpphash.c b/gcc/cpphash.c index 998ebe6..0eadc9a 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -406,7 +406,7 @@ collect_expansion (pfile, arglist) if (last_token == STRIZE) cpp_error (pfile, "`#' is not followed by a macro argument name"); - if (CPP_TRADITIONAL (pfile) || CPP_OPTION (pfile, warn_stringify)) + if (CPP_TRADITIONAL (pfile) || CPP_WTRADITIONAL (pfile)) goto maybe_trad_stringify; else goto norm; @@ -480,7 +480,7 @@ collect_expansion (pfile, arglist) (int) argv[i].len, argv[i].name); continue; } - if (CPP_OPTION (pfile, warn_stringify)) + if (CPP_WTRADITIONAL (pfile)) cpp_warning (pfile, "macro argument `%.*s' is stringified", (int) argv[i].len, argv[i].name); diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 33aa0d1..3d0a147 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -226,7 +226,9 @@ extern unsigned char _cpp_IStable[256]; #define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps) #define CPP_TRADITIONAL(PFILE) CPP_OPTION (PFILE, traditional) #define CPP_PEDANTIC(PFILE) \ - (CPP_OPTION (PFILE, pedantic) && !CPP_BUFFER (pfile)->system_header_p) + (CPP_OPTION (PFILE, pedantic) && !CPP_BUFFER (PFILE)->system_header_p) +#define CPP_WTRADITIONAL(PF) \ + (CPP_OPTION (PF, warn_traditional) && !CPP_BUFFER (PF)->system_header_p) /* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion. (Note that it is false while we're expanding macro *arguments*.) */ diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 63f5ea8..93298ef 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -1647,7 +1647,7 @@ handle_option (pfile, argc, argv) CPP_OPTION (pfile, warn_comments) = 1; } else if (!strcmp (argv[i], "-Wtraditional")) - CPP_OPTION (pfile, warn_stringify) = 1; + CPP_OPTION (pfile, warn_traditional) = 1; else if (!strcmp (argv[i], "-Wtrigraphs")) CPP_OPTION (pfile, warn_trigraphs) = 1; else if (!strcmp (argv[i], "-Wcomment")) @@ -1661,7 +1661,7 @@ handle_option (pfile, argc, argv) else if (!strcmp (argv[i], "-Werror")) CPP_OPTION (pfile, warnings_are_errors) = 1; else if (!strcmp (argv[i], "-Wno-traditional")) - CPP_OPTION (pfile, warn_stringify) = 0; + CPP_OPTION (pfile, warn_traditional) = 0; else if (!strcmp (argv[i], "-Wno-trigraphs")) CPP_OPTION (pfile, warn_trigraphs) = 0; else if (!strcmp (argv[i], "-Wno-comment")) diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 68f034c..b0d3f5f 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -729,12 +729,6 @@ _cpp_lex_token (pfile) if (!pfile->only_seen_white) goto randomchar; - /* -traditional directives are recognized only with the # in - column 1. - XXX Layering violation. */ - if (CPP_TRADITIONAL (pfile) - && CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base != 1) - goto randomchar; return CPP_DIRECTIVE; case '\"': diff --git a/gcc/cpplib.c b/gcc/cpplib.c index a64c8bc..747f6f5 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -26,6 +26,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "cpphash.h" #include "hashtab.h" #include "intl.h" +#include "symcat.h" #define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) \ ? CPP_BUFFER (pfile)->cur[N] : EOF) @@ -37,10 +38,11 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ struct directive { - unsigned int length; /* Length of name */ - const char *name; /* Name of directive */ int (*func) /* Function to handle directive */ PARAMS ((cpp_reader *)); + const char *name; /* Name of directive */ + unsigned short length; /* Length of name */ + unsigned short origin; /* Origin of this directive */ }; /* Stack of conditionals currently in progress @@ -72,6 +74,9 @@ static int consider_directive_while_skipping PARAMS ((cpp_reader *, IF_STACK *)); static int get_macro_name PARAMS ((cpp_reader *)); +/* Values for the "origin" field of the table below. */ +enum { KANDR = 0, STDC89, EXTENSION }; + /* This is the table of directive handlers. It is ordered by frequency of occurrence; the numbers at the end are directive counts from all the source code I have lying around (egcs and libc @@ -82,26 +87,33 @@ static int get_macro_name PARAMS ((cpp_reader *)); of which all but #warning and #include_next are deprecated. The name is where the extension appears to have come from. */ +/* #sccs is not always recognized. */ +#ifdef SCCS_DIRECTIVE +# define SCCS_ENTRY D(sccs, T_SCCS, EXTENSION) /* 0 - SVR2? */ +#else +# define SCCS_ENTRY /* nothing */ +#endif + #define DIRECTIVE_TABLE \ -D("define", do_define, T_DEFINE) /* 270554 */ \ -D("include", do_include, T_INCLUDE) /* 52262 */ \ -D("endif", do_endif, T_ENDIF) /* 45855 */ \ -D("ifdef", do_ifdef, T_IFDEF) /* 22000 */ \ -D("if", do_if, T_IF) /* 18162 */ \ -D("else", do_else, T_ELSE) /* 9863 */ \ -D("ifndef", do_ifndef, T_IFNDEF) /* 9675 */ \ -D("undef", do_undef, T_UNDEF) /* 4837 */ \ -D("line", do_line, T_LINE) /* 2465 */ \ -D("elif", do_elif, T_ELIF) /* 610 */ \ -D("error", do_error, T_ERROR) /* 475 */ \ -D("pragma", do_pragma, T_PRAGMA) /* 195 */ \ -D("warning", do_warning, T_WARNING) /* 22 - GNU */ \ -D("include_next", do_include_next, T_INCLUDE_NEXT) /* 19 - GNU */ \ -D("ident", do_ident, T_IDENT) /* 11 - SVR4 */ \ -D("import", do_import, T_IMPORT) /* 0 - ObjC */ \ -D("assert", do_assert, T_ASSERT) /* 0 - SVR4 */ \ -D("unassert", do_unassert, T_UNASSERT) /* 0 - SVR4 */ \ -D("sccs", do_sccs, T_SCCS) /* 0 - SVR2? */ +D(define, T_DEFINE, KANDR) /* 270554 */ \ +D(include, T_INCLUDE, KANDR) /* 52262 */ \ +D(endif, T_ENDIF, KANDR) /* 45855 */ \ +D(ifdef, T_IFDEF, KANDR) /* 22000 */ \ +D(if, T_IF, KANDR) /* 18162 */ \ +D(else, T_ELSE, KANDR) /* 9863 */ \ +D(ifndef, T_IFNDEF, KANDR) /* 9675 */ \ +D(undef, T_UNDEF, KANDR) /* 4837 */ \ +D(line, T_LINE, KANDR) /* 2465 */ \ +D(elif, T_ELIF, KANDR) /* 610 */ \ +D(error, T_ERROR, STDC89) /* 475 */ \ +D(pragma, T_PRAGMA, STDC89) /* 195 */ \ +D(warning, T_WARNING, EXTENSION) /* 22 - GNU */ \ +D(include_next, T_INCLUDE_NEXT, EXTENSION) /* 19 - GNU */ \ +D(ident, T_IDENT, EXTENSION) /* 11 - SVR4 */ \ +D(import, T_IMPORT, EXTENSION) /* 0 - ObjC */ \ +D(assert, T_ASSERT, EXTENSION) /* 0 - SVR4 */ \ +D(unassert, T_UNASSERT, EXTENSION) /* 0 - SVR4 */ \ +SCCS_ENTRY /* Use the table to generate a series of prototypes, an enum for the directive names, and an array of directive handlers. */ @@ -110,11 +122,11 @@ D("sccs", do_sccs, T_SCCS) /* 0 - SVR2? */ instead of void, because some old compilers have trouble with pointers to functions returning void. */ -#define D(name, fun, tag) static int fun PARAMS ((cpp_reader *)); +#define D(name, t, o) static int CONCAT2(do_, name) PARAMS ((cpp_reader *)); DIRECTIVE_TABLE #undef D -#define D(name, fun, tag) tag, +#define D(n, tag, o) tag, enum { DIRECTIVE_TABLE @@ -122,7 +134,8 @@ enum }; #undef D -#define D(name, fun, tag) { sizeof name - 1, name, fun }, +#define D(name, t, origin) \ +{ CONCAT2(do_, name), STRINGX(name), sizeof STRINGX(name) - 1, origin }, static const struct directive dtable[] = { DIRECTIVE_TABLE @@ -138,6 +151,7 @@ _cpp_handle_directive (pfile) cpp_reader *pfile; { int c, i; + int hash_at_bol; unsigned int len; U_CHAR *ident; long old_written = CPP_WRITTEN (pfile); @@ -148,6 +162,10 @@ _cpp_handle_directive (pfile) return 0; } + /* -traditional directives are recognized only with the # in column 1. + XXX Layering violation. */ + hash_at_bol = (CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base == 1); + _cpp_skip_hspace (pfile); c = PEEKC (); @@ -163,7 +181,7 @@ _cpp_handle_directive (pfile) if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed) && ! CPP_BUFFER (pfile)->manual_pop) - cpp_pedwarn (pfile, "`#' followed by integer"); + cpp_pedwarn (pfile, "# followed by integer"); do_line (pfile); return 1; } @@ -180,7 +198,7 @@ _cpp_handle_directive (pfile) len = CPP_PWRITTEN (pfile) - ident; if (len == 0) { - /* A line of just `#' becomes blank. A line with something + /* A line of just # becomes blank. A line with something other than an identifier after the # is reparsed as a non- directive line. */ CPP_SET_WRITTEN (pfile, old_written); @@ -206,10 +224,26 @@ _cpp_handle_directive (pfile) cpp_error (pfile, "`#%s' may not be used inside a macro argument", dtable[i].name); _cpp_skip_rest_of_line (pfile); + return 1; } - else - (*dtable[i].func) (pfile); + if (CPP_PEDANTIC (pfile) && dtable[i].origin == EXTENSION) + cpp_pedwarn (pfile, "ISO C does not allow #%s", dtable[i].name); + if (CPP_WTRADITIONAL (pfile)) + { + if (!hash_at_bol && dtable[i].origin == KANDR) + cpp_warning (pfile, "the # in #%s should be at the left margin", + dtable[i].name); + else if (hash_at_bol && dtable[i].origin != KANDR) + cpp_warning (pfile, + "the # in #%s should not be at the left margin", + dtable[i].name); + } + + if (CPP_TRADITIONAL (pfile) && !hash_at_bol) + return 0; + + (*dtable[i].func) (pfile); return 1; } @@ -527,9 +561,6 @@ do_import (pfile) unsigned int len; char *token; - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "ANSI C does not allow `#import'"); - if (CPP_OPTION (pfile, warn_import) && !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning) { @@ -559,9 +590,6 @@ do_include_next (pfile) char *token; struct file_name_list *search_start = 0; - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "ANSI C does not allow `#include_next'"); - len = parse_include (pfile, dtable[T_INCLUDE_NEXT].name); if (len == 0) return 0; @@ -835,9 +863,6 @@ do_warning (pfile) _cpp_skip_rest_of_line (pfile); limit = CPP_BUFFER (pfile)->cur; - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "ANSI C does not allow `#warning'"); - cpp_warning (pfile, "#warning %.*s", (int)(limit - text), text); return 0; } @@ -850,10 +875,6 @@ do_ident (pfile) { long old_written = CPP_WRITTEN (pfile); - /* Allow #ident in system headers, since that's not user's fault. */ - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "ANSI C does not allow `#ident'"); - CPP_PUTS (pfile, "#ident ", 7); /* Next token should be a string constant. */ @@ -1066,20 +1087,15 @@ do_pragma_poison (pfile) } /* Just ignore #sccs, on systems where we define it at all. */ +#ifdef SCCS_DIRECTIVE static int do_sccs (pfile) cpp_reader *pfile; { -#ifdef SCCS_DIRECTIVE - if (CPP_PEDANTIC (pfile)) - cpp_pedwarn (pfile, "ANSI C does not allow `#sccs'"); -#else - cpp_error (pfile, "undefined or invalid # directive `sccs'"); -#endif _cpp_skip_rest_of_line (pfile); return 0; } - +#endif /* We've found an `#if' directive. If the only thing before it in this file is white space, and if it is of the form @@ -1612,9 +1628,6 @@ do_assert (pfile) size_t blen, tlen; unsigned long bhash, thash; - if (CPP_PEDANTIC (pfile) && pfile->done_initializing) - cpp_pedwarn (pfile, "ANSI C does not allow `#assert'"); - _cpp_skip_hspace (pfile); sym = CPP_PWRITTEN (pfile); /* remember where it starts */ ret = _cpp_parse_assertion (pfile); @@ -1678,9 +1691,6 @@ do_unassert (pfile) long baselen, thislen; HASHNODE *base, *this, *next; - if (CPP_PEDANTIC (pfile) && pfile->done_initializing) - cpp_pedwarn (pfile, "ANSI C does not allow `#unassert'"); - _cpp_skip_hspace (pfile); sym = CPP_PWRITTEN (pfile); /* remember where it starts */ diff --git a/gcc/cpplib.h b/gcc/cpplib.h index b16206b..a8faf33 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -236,8 +236,9 @@ struct cpp_options unsigned char warn_import; /* Nonzero means warn if a macro argument is (or would be) - stringified with -traditional. */ - unsigned char warn_stringify; + stringified with -traditional, and warn about directives + with the # indented from the beginning of the line. */ + unsigned char warn_traditional; /* Nonzero means turn warnings into errors. */ unsigned char warnings_are_errors; diff --git a/gcc/testsuite/gcc.dg/cpp-tradwarn1.c b/gcc/testsuite/gcc.dg/cpp-tradwarn1.c new file mode 100644 index 0000000..8395c80 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp-tradwarn1.c @@ -0,0 +1,30 @@ +/* Test for warnings about nontraditional directives. */ +/* { dg-do preprocess } */ +/* { dg-options "-pedantic -Wtraditional" } */ + +/* Block 1: K+R directives should have the # at the left margin. */ + +#define foo bar /* { dg-bogus "left margin" "^#kandr" } */ +# define foo bar /* { dg-bogus "left margin" "^# kandr" } */ + #define foo bar /* { dg-warning "left margin" "^ #kandr" } */ + # define foo bar /* { dg-warning "left margin" "^ # kandr" } */ + +/* Block 2: C89 directives should not have the # at the left margin. */ + +#pragma whatever /* { dg-warning "left margin" "^#c89" } */ +# pragma whatever /* { dg-warning "left margin" "^# c89" } */ + #pragma whatever /* { dg-bogus "left margin" "^ #c89" } */ + # pragma whatever /* { dg-bogus "left margin" "^ # c89" } */ + +/* Block 3: Extensions should not have the # at the left margin, + _and_ they should get a -pedantic warning. */ + +#assert foo(bar) /* { dg-warning "left margin" "^#ext" } */ +# assert bar(baz) /* { dg-warning "left margin" "^# ext" } */ + #assert baz(quux) /* { dg-bogus "left margin" "^ #ext" } */ + # assert quux(weeble) /* { dg-bogus "left margin" "^ # ext" } */ + +/* { dg-warning "ISO C does not" "extension warning" { target native } 22 } */ +/* { dg-warning "ISO C does not" "extension warning" { target native } 23 } */ +/* { dg-warning "ISO C does not" "extension warning" { target native } 24 } */ +/* { dg-warning "ISO C does not" "extension warning" { target native } 25 } */