From 5ba3700755947a6416e1a609455171e0b8de7767 Mon Sep 17 00:00:00 2001 From: zack Date: Fri, 29 Oct 1999 04:31:14 +0000 Subject: [PATCH] 1999-10-28 21:27 -0700 Zack Weinberg * cpplib.h (struct cpp_buffer: fname, nominal_fname, last_nominal_fname): Mark const. (struct include_hash: name, nshort, control_macro): Mark const. (struct macrodef: symnam): Mark const. (struct if_stack: fname): Mark const. (is_idchar, is_idstart, is_hor_space, trigraph_table): Delete. (IStable): New character-syntax array which encompasses all the old is_foo arrays. (is_idchar, is_numchar, is_idstart, is_numstart, is_hspace, is_space): New macros for interrogating IStable. (check_macro_name): Kill last argument. All callers changed. * cppinit.c (initialize_char_syntax): Delete. (is_idchar, is_idstart, is_hor_space, is_space, trigraph_table): Delete. (IStable): New. Initialize with clever macros to avoid information duplication. (builtin_array): Table of builtins to get rid of explicit list in initialize_builtins. (initialize_builtins): Use builtins_array. (cpp_start_read): Call init_IStable, and set IStable['$'] if opts->dollars_in_ident. * cppexp.c: Change all refs to is_xyz[] arrays to use new is_xyz() macros. (cpp_parse_expr): Avoid 'format string is not constant' warning. Use ISGRAPH to identify printable chars. * cppfiles.c: Change all refs to is_xyz[] arrays to use new is_xyz() macros. (read_and_prescan): Map trigraphs to chars with open-coded if-else-if-... sequence, not a lookup table. * cpphash.c: Change all refs to is_xyz[] arrays to use new is_xyz() macros. * cpplib.c: Change all refs to is_xyz[] arrays to use new is_xyz() macros. Kill SKIP_ALL_WHITE_SPACE (unused). (check_macro_name): Remove ability to report an invalid assertion name, which is never used. (do_line): Constify a couple of char *'s. * cppmain.c (main): Call cpp_cleanup before returning. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30252 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 43 ++++++++ gcc/cppexp.c | 14 +-- gcc/cppfiles.c | 33 ++++-- gcc/cpphash.c | 58 +++++----- gcc/cppinit.c | 327 +++++++++++++++++++++------------------------------------ gcc/cpplib.c | 52 ++++----- gcc/cpplib.h | 51 +++++---- gcc/cppmain.c | 2 + 8 files changed, 281 insertions(+), 299 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aeb66bf3761..4435b727460 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,46 @@ +1999-10-28 21:27 -0700 Zack Weinberg + + * cpplib.h (struct cpp_buffer: fname, nominal_fname, + last_nominal_fname): Mark const. + (struct include_hash: name, nshort, control_macro): Mark + const. + (struct macrodef: symnam): Mark const. + (struct if_stack: fname): Mark const. + (is_idchar, is_idstart, is_hor_space, trigraph_table): Delete. + (IStable): New character-syntax array which encompasses all + the old is_foo arrays. + (is_idchar, is_numchar, is_idstart, is_numstart, is_hspace, + is_space): New macros for interrogating IStable. + (check_macro_name): Kill last argument. All callers changed. + + * cppinit.c (initialize_char_syntax): Delete. + (is_idchar, is_idstart, is_hor_space, is_space, + trigraph_table): Delete. + (IStable): New. Initialize with clever macros to avoid + information duplication. + (builtin_array): Table of builtins to get rid of explicit list + in initialize_builtins. + (initialize_builtins): Use builtins_array. + (cpp_start_read): Call init_IStable, and set IStable['$'] if + opts->dollars_in_ident. + + * cppexp.c: Change all refs to is_xyz[] arrays to use new + is_xyz() macros. + (cpp_parse_expr): Avoid 'format string is not constant' + warning. Use ISGRAPH to identify printable chars. + * cppfiles.c: Change all refs to is_xyz[] arrays to use new + is_xyz() macros. + (read_and_prescan): Map trigraphs to chars with open-coded + if-else-if-... sequence, not a lookup table. + * cpphash.c: Change all refs to is_xyz[] arrays to use new + is_xyz() macros. + * cpplib.c: Change all refs to is_xyz[] arrays to use new + is_xyz() macros. Kill SKIP_ALL_WHITE_SPACE (unused). + (check_macro_name): Remove ability to report an invalid + assertion name, which is never used. + (do_line): Constify a couple of char *'s. + * cppmain.c (main): Call cpp_cleanup before returning. + Thu Oct 28 21:16:35 1999 Mark Mitchell * ggc.h (struct ggc_statistics): New type. diff --git a/gcc/cppexp.c b/gcc/cppexp.c index 5d50c75af69..dafbe92e74e 100644 --- a/gcc/cppexp.c +++ b/gcc/cppexp.c @@ -457,12 +457,12 @@ cpp_lex (pfile, skip_evaluation) cpp_skip_hspace (pfile); } - if (!is_idstart[*ip->cur]) + if (!is_idstart(*ip->cur)) goto oops; if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"')) goto oops; tok = ip->cur; - while (is_idchar[*ip->cur]) + while (is_idchar(*ip->cur)) ++ip->cur; len = ip->cur - tok; cpp_skip_hspace (pfile); @@ -1010,11 +1010,11 @@ cpp_parse_expr (pfile) } break; default: - cpp_error (pfile, - (top[1].op >= ' ' && top[1].op <= '~' - ? "unimplemented operator '%c'\n" - : "unimplemented operator '\\%03o'\n"), - top[1].op); + if (ISGRAPH (top[1].op)) + cpp_error (pfile, "unimplemented operator '%c'\n", top[1].op); + else + cpp_error (pfile, "unimplemented operator '\\%03o'\n", + top[1].op); } } if (op.op == 0) diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c index 2aa2eebdeb0..dfeddcc8ca2 100644 --- a/gcc/cppfiles.c +++ b/gcc/cppfiles.c @@ -437,10 +437,10 @@ read_filename_string (ch, f) len = 20; set = alloc = xmalloc (len + 1); - if (! is_space[ch]) + if (! is_space(ch)) { *set++ = ch; - while ((ch = getc (f)) != EOF && ! is_space[ch]) + while ((ch = getc (f)) != EOF && ! is_space(ch)) { if (set - alloc == len) { @@ -503,10 +503,10 @@ read_name_map (pfile, dirname) char *from, *to; struct file_name_map *ptr; - if (is_space[ch]) + if (is_space(ch)) continue; from = read_filename_string (ch, f); - while ((ch = getc (f)) != EOF && is_hor_space[ch]) + while ((ch = getc (f)) != EOF && is_hspace(ch)) ; to = read_filename_string (ch, f); @@ -976,7 +976,7 @@ read_and_prescan (pfile, fp, desc, len) case SPECCASE_QUESTION: /* ? */ { - unsigned int d; + unsigned int d, t; /* If we're at the end of the intermediate buffer, we have to shift the ?'s down to the start and come back next pass. */ @@ -998,12 +998,27 @@ read_and_prescan (pfile, fp, desc, len) *--ibase = '?'; goto read_next; } - if (!trigraph_table[d]) + + /* Trigraph map: + * from to from to from to + * ?? = # ?? ) ] ?? ! | + * ?? ( [ ?? ' ^ ?? > } + * ?? / \ ?? < { ?? - ~ + */ + if (d == '=') t = '#'; + else if (d == ')') t = ']'; + else if (d == '!') t = '|'; + else if (d == '(') t = '['; + else if (d == '\'') t = '^'; + else if (d == '>') t = '}'; + else if (d == '/') t = '\\'; + else if (d == '<') t = '{'; + else if (d == '-') t = '~'; + else { *op++ = '?'; break; } - if (CPP_OPTIONS (pfile)->warn_trigraphs) { unsigned long col; @@ -1014,10 +1029,10 @@ read_and_prescan (pfile, fp, desc, len) } if (CPP_OPTIONS (pfile)->trigraphs) { - if (trigraph_table[d] == '\\') + if (t == '\\') goto backslash; else - *op++ = trigraph_table[d]; + *op++ = t; } else { diff --git a/gcc/cpphash.c b/gcc/cpphash.c index c7da2b3116d..8c268f455a3 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -40,7 +40,7 @@ static struct tm *timestamp PARAMS ((cpp_reader *)); static void special_symbol PARAMS ((HASHNODE *, cpp_reader *)); -#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0) +#define SKIP_WHITE_SPACE(p) do { while (is_hspace(*p)) p++; } while (0) #define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL) #define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) @@ -131,7 +131,7 @@ cpp_lookup (pfile, name, len, hash) if (len < 0) { - for (bp = name; is_idchar[*bp]; bp++); + for (bp = name; is_idchar(*bp); bp++); len = bp - name; } @@ -224,7 +224,7 @@ cpp_install (pfile, name, len, type, value, hash) if (len < 0) { p = name; - while (is_idchar[*p]) + while (is_idchar(*p)) p++; len = p - name; } @@ -306,7 +306,7 @@ collect_expansion (pfile, buf, limit, nargs, arglist) /* Find the beginning of the trailing whitespace. */ p = buf; - while (p < limit && is_space[limit[-1]]) + while (p < limit && is_space(limit[-1])) limit--; /* Allocate space for the text in the macro definition. @@ -376,7 +376,7 @@ collect_expansion (pfile, buf, limit, nargs, arglist) /* ##: concatenate preceding and following tokens. */ /* Take out the first #, discard preceding whitespace. */ exp_p--; - while (exp_p > lastp && is_hor_space[exp_p[-1]]) + while (exp_p > lastp && is_hspace(exp_p[-1])) --exp_p; /* Skip the second #. */ p++; @@ -392,7 +392,7 @@ collect_expansion (pfile, buf, limit, nargs, arglist) Don't leave the # in the expansion. */ exp_p--; SKIP_WHITE_SPACE (p); - if (p == limit || !is_idstart[*p] + if (p == limit || !is_idstart(*p) || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '"'))) cpp_error (pfile, @@ -457,17 +457,17 @@ collect_expansion (pfile, buf, limit, nargs, arglist) } /* Handle the start of a symbol. */ - if (is_idchar[c] && nargs > 0) + if (is_idchar(c) && nargs > 0) { U_CHAR *id_beg = p - 1; int id_len; --exp_p; - while (p != limit && is_idchar[*p]) + while (p != limit && is_idchar(*p)) p++; id_len = p - id_beg; - if (is_idstart[c] + if (is_idstart(c) && !(id_len == 1 && c == 'L' && (*p == '\'' || *p == '"'))) { register struct arglist *arg; @@ -612,12 +612,12 @@ create_definition (buf, limit, pfile, predefinition) bp = buf; - while (is_hor_space[*bp]) + while (is_hspace(*bp)) bp++; symname = bp; /* remember where it starts */ - sym_length = check_macro_name (pfile, bp, 0); + sym_length = check_macro_name (pfile, bp); bp += sym_length; /* Lossage will occur if identifiers or control keywords are broken @@ -648,11 +648,11 @@ create_definition (buf, limit, pfile, predefinition) cpp_pedwarn (pfile, "another parameter follows `%s'", rest_extension); - if (!is_idstart[*bp]) + if (!is_idstart(*bp)) cpp_pedwarn (pfile, "invalid character in macro parameter name"); /* Find the end of the arg name. */ - while (is_idchar[*bp]) + while (is_idchar(*bp)) { bp++; /* do we have a "special" rest-args extension here? */ @@ -737,7 +737,7 @@ create_definition (buf, limit, pfile, predefinition) if (bp < limit) { - if (is_hor_space[*bp]) + if (is_hspace(*bp)) { bp++; SKIP_WHITE_SPACE (bp); @@ -1141,7 +1141,7 @@ macroexpand (pfile, hp) /* cpp.texi says for foo ( ) we provide one argument. However, if foo wants just 0 arguments, treat this as 0. */ if (nargs == 0) - while (bp != lim && is_space[*bp]) + while (bp != lim && is_space(*bp)) bp++; if (bp == lim) i = 0; @@ -1227,7 +1227,7 @@ macroexpand (pfile, hp) /* Internal sequences of whitespace are replaced by one space except within a string or char token. */ - if (is_space[c]) + if (is_space(c)) { if (CPP_WRITTEN (pfile) > (unsigned) arg->stringified && (CPP_PWRITTEN (pfile))[-1] == '\r') @@ -1333,11 +1333,11 @@ macroexpand (pfile, hp) && last_ap->raw_after))) { /* Delete final whitespace. */ - while (totlen > count_before && is_space[xbuf[totlen - 1]]) + while (totlen > count_before && is_space(xbuf[totlen - 1])) totlen--; /* Delete the nonwhites before them. */ - while (totlen > count_before && !is_space[xbuf[totlen - 1]]) + while (totlen > count_before && !is_space(xbuf[totlen - 1])) totlen--; } @@ -1357,7 +1357,7 @@ macroexpand (pfile, hp) whitespace markers, and no-reexpansion markers. */ while (p1 != l1) { - if (is_space[p1[0]]) + if (is_space(p1[0])) p1++; else if (p1[0] == '\r') p1 += 2; @@ -1371,7 +1371,7 @@ macroexpand (pfile, hp) whitespace markers, and no-reexpansion markers. */ while (p1 != l1) { - if (is_space[l1[-1]]) + if (is_space(l1[-1])) l1--; else if (l1[-1] == '\r') l1--; @@ -1510,7 +1510,7 @@ unsafe_chars (c1, c2) case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': letter: /* We're in the middle of either a name or a pre-processing number. */ - return (is_idchar[c2] || c2 == '.'); + return (is_idchar(c2) || c2 == '.'); case '<': case '>': case '!': case '%': case '#': case ':': case '^': case '&': case '|': case '*': case '/': case '=': @@ -1551,7 +1551,7 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp) or some other (less common) characters. */ if (xbuf[0] == '\r' && xbuf[1] == ' ' - && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\'' + && (is_idchar(xbuf[2]) || xbuf[2] == '(' || xbuf[2] == '\'' || xbuf[2] == '\"')) mbuf->cur += 2; @@ -1627,25 +1627,25 @@ comp_def_part (first, beg1, len1, beg2, len2, last) register U_CHAR *end2 = beg2 + len2; if (first) { - while (beg1 != end1 && is_space[*beg1]) + while (beg1 != end1 && is_space(*beg1)) beg1++; - while (beg2 != end2 && is_space[*beg2]) + while (beg2 != end2 && is_space(*beg2)) beg2++; } if (last) { - while (beg1 != end1 && is_space[end1[-1]]) + while (beg1 != end1 && is_space(end1[-1])) end1--; - while (beg2 != end2 && is_space[end2[-1]]) + while (beg2 != end2 && is_space(end2[-1])) end2--; } while (beg1 != end1 && beg2 != end2) { - if (is_space[*beg1] && is_space[*beg2]) + if (is_space(*beg1) && is_space(*beg2)) { - while (beg1 != end1 && is_space[*beg1]) + while (beg1 != end1 && is_space(*beg1)) beg1++; - while (beg2 != end2 && is_space[*beg2]) + while (beg2 != end2 && is_space(*beg2)) beg2++; } else if (*beg1 == *beg2) diff --git a/gcc/cppinit.c b/gcc/cppinit.c index ec59a76995e..fa41c3ca74b 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -194,7 +194,6 @@ struct pending_option } while (0) #endif -static void initialize_char_syntax PARAMS ((int)); static void print_help PARAMS ((void)); static void path_include PARAMS ((cpp_reader *, struct cpp_pending *, @@ -210,174 +209,57 @@ static void initialize_dependency_output PARAMS ((cpp_reader *)); /* Last argument to append_include_chain: chain to use */ enum { QUOTE = 0, BRACKET, SYSTEM, AFTER }; -/* If gcc is in use (stage2/stage3) we can make these tables initialized - data. */ +/* If gcc is in use (stage2/stage3) we can make this table initialized data. */ +#ifdef __STDC__ +#define CAT(a, b) a##b +#else +#define CAT(a, b) a/**/b +#endif + #if HAVE_GCC_VERSION(2,7) -/* Table to tell if a character is legal as the second or later character - of a C identifier. */ -U_CHAR is_idchar[256] = -{ - ['a'] = 1, ['b'] = 1, ['c'] = 1, ['d'] = 1, ['e'] = 1, ['f'] = 1, - ['g'] = 1, ['h'] = 1, ['i'] = 1, ['j'] = 1, ['k'] = 1, ['l'] = 1, - ['m'] = 1, ['n'] = 1, ['o'] = 1, ['p'] = 1, ['q'] = 1, ['r'] = 1, - ['s'] = 1, ['t'] = 1, ['u'] = 1, ['v'] = 1, ['w'] = 1, ['x'] = 1, - ['y'] = 1, ['z'] = 1, - - ['A'] = 1, ['B'] = 1, ['C'] = 1, ['D'] = 1, ['E'] = 1, ['F'] = 1, - ['G'] = 1, ['H'] = 1, ['I'] = 1, ['J'] = 1, ['K'] = 1, ['L'] = 1, - ['M'] = 1, ['N'] = 1, ['O'] = 1, ['P'] = 1, ['Q'] = 1, ['R'] = 1, - ['S'] = 1, ['T'] = 1, ['U'] = 1, ['V'] = 1, ['W'] = 1, ['X'] = 1, - ['Y'] = 1, ['Z'] = 1, - - ['1'] = 1, ['2'] = 1, ['3'] = 1, ['4'] = 1, ['5'] = 1, ['6'] = 1, - ['7'] = 1, ['8'] = 1, ['9'] = 1, ['0'] = 1, - - ['_'] = 1, -}; +#define TABLE(id) static inline void CAT(init_, id) PARAMS ((void)) {} \ +unsigned char id[256] = { +#define s(p, v) [p] = v, +#define END }; +#else +#define TABLE(id) unsigned char id[256] = { 0 }; \ +static void CAT(init_, id) PARAMS ((void)) { \ +unsigned char *x = id; +#define s(p, v) x[p] = v; +#define END } +#endif -/* Table to tell if a character is legal as the first character of - a C identifier. */ -U_CHAR is_idstart[256] = -{ - ['a'] = 1, ['b'] = 1, ['c'] = 1, ['d'] = 1, ['e'] = 1, ['f'] = 1, - ['g'] = 1, ['h'] = 1, ['i'] = 1, ['j'] = 1, ['k'] = 1, ['l'] = 1, - ['m'] = 1, ['n'] = 1, ['o'] = 1, ['p'] = 1, ['q'] = 1, ['r'] = 1, - ['s'] = 1, ['t'] = 1, ['u'] = 1, ['v'] = 1, ['w'] = 1, ['x'] = 1, - ['y'] = 1, ['z'] = 1, - - ['A'] = 1, ['B'] = 1, ['C'] = 1, ['D'] = 1, ['E'] = 1, ['F'] = 1, - ['G'] = 1, ['H'] = 1, ['I'] = 1, ['J'] = 1, ['K'] = 1, ['L'] = 1, - ['M'] = 1, ['N'] = 1, ['O'] = 1, ['P'] = 1, ['Q'] = 1, ['R'] = 1, - ['S'] = 1, ['T'] = 1, ['U'] = 1, ['V'] = 1, ['W'] = 1, ['X'] = 1, - ['Y'] = 1, ['Z'] = 1, - - ['_'] = 1, -}; +#define A(x) s(x, ISidnum|ISidstart) +#define N(x) s(x, ISidnum|ISnumstart) +#define H(x) s(x, IShspace|ISspace) +#define S(x) s(x, ISspace) -/* Table to tell if a character is horizontal space. - \r is magical, so it is not in here. */ -U_CHAR is_hor_space[256] = -{ - [' '] = 1, ['\t'] = 1, ['\v'] = 1, ['\f'] = 1, -}; -/* table to tell if a character is horizontal or vertical space. */ -U_CHAR is_space[256] = -{ - [' '] = 1, ['\t'] = 1, ['\v'] = 1, ['\f'] = 1, ['\n'] = 1, -}; -/* Table to handle trigraph conversion, which occurs before all other - processing, everywhere in the file. (This is necessary since one - of the trigraphs encodes backslash.) Note it's off by default. - - from to from to from to - ?? = # ?? ) ] ?? ! | - ?? ( [ ?? ' ^ ?? > } - ?? / \ ?? < { ?? - ~ - - There is not a space between the ?? and the third char. I put spaces - there to avoid warnings when compiling this file. */ -U_CHAR trigraph_table[256] = -{ - ['='] = '#', [')'] = ']', ['!'] = '|', - ['('] = '[', ['\''] = '^', ['>'] = '}', - ['/'] = '\\', ['<'] = '{', ['-'] = '~', -}; +TABLE (IStable) + A('_') -/* This function will be entirely removed soon. */ -static inline void -initialize_char_syntax (dollar_in_ident) - int dollar_in_ident; -{ - is_idchar['$'] = dollar_in_ident; - is_idstart['$'] = dollar_in_ident; -} + A('a') A('b') A('c') A('d') A('e') A('f') A('g') A('h') A('i') + A('j') A('k') A('l') A('m') A('n') A('o') A('p') A('q') A('r') + A('s') A('t') A('u') A('v') A('w') A('x') A('y') A('z') -#else /* Not GCC. */ + A('A') A('B') A('C') A('D') A('E') A('F') A('G') A('H') A('I') + A('J') A('K') A('L') A('M') A('N') A('O') A('P') A('Q') A('R') + A('S') A('T') A('U') A('V') A('W') A('X') A('Y') A('Z') -U_CHAR is_idchar[256] = { 0 }; -U_CHAR is_idstart[256] = { 0 }; -U_CHAR is_hor_space[256] = { 0 }; -U_CHAR is_space[256] = { 0 }; -U_CHAR trigraph_table[256] = { 0 }; + N('1') N('2') N('3') N('4') N('5') N('6') N('7') N('8') N('9') N('0') -/* Initialize syntactic classifications of characters. */ -static void -initialize_char_syntax (dollar_in_ident) - int dollar_in_ident; -{ - is_idstart['a'] = 1; is_idstart['b'] = 1; is_idstart['c'] = 1; - is_idstart['d'] = 1; is_idstart['e'] = 1; is_idstart['f'] = 1; - is_idstart['g'] = 1; is_idstart['h'] = 1; is_idstart['i'] = 1; - is_idstart['j'] = 1; is_idstart['k'] = 1; is_idstart['l'] = 1; - is_idstart['m'] = 1; is_idstart['n'] = 1; is_idstart['o'] = 1; - is_idstart['p'] = 1; is_idstart['q'] = 1; is_idstart['r'] = 1; - is_idstart['s'] = 1; is_idstart['t'] = 1; is_idstart['u'] = 1; - is_idstart['v'] = 1; is_idstart['w'] = 1; is_idstart['x'] = 1; - is_idstart['y'] = 1; is_idstart['z'] = 1; - - is_idstart['A'] = 1; is_idstart['B'] = 1; is_idstart['C'] = 1; - is_idstart['D'] = 1; is_idstart['E'] = 1; is_idstart['F'] = 1; - is_idstart['G'] = 1; is_idstart['H'] = 1; is_idstart['I'] = 1; - is_idstart['J'] = 1; is_idstart['K'] = 1; is_idstart['L'] = 1; - is_idstart['M'] = 1; is_idstart['N'] = 1; is_idstart['O'] = 1; - is_idstart['P'] = 1; is_idstart['Q'] = 1; is_idstart['R'] = 1; - is_idstart['S'] = 1; is_idstart['T'] = 1; is_idstart['U'] = 1; - is_idstart['V'] = 1; is_idstart['W'] = 1; is_idstart['X'] = 1; - is_idstart['Y'] = 1; is_idstart['Z'] = 1; - - is_idstart['_'] = 1; - - is_idchar['a'] = 1; is_idchar['b'] = 1; is_idchar['c'] = 1; - is_idchar['d'] = 1; is_idchar['e'] = 1; is_idchar['f'] = 1; - is_idchar['g'] = 1; is_idchar['h'] = 1; is_idchar['i'] = 1; - is_idchar['j'] = 1; is_idchar['k'] = 1; is_idchar['l'] = 1; - is_idchar['m'] = 1; is_idchar['n'] = 1; is_idchar['o'] = 1; - is_idchar['p'] = 1; is_idchar['q'] = 1; is_idchar['r'] = 1; - is_idchar['s'] = 1; is_idchar['t'] = 1; is_idchar['u'] = 1; - is_idchar['v'] = 1; is_idchar['w'] = 1; is_idchar['x'] = 1; - is_idchar['y'] = 1; is_idchar['z'] = 1; - - is_idchar['A'] = 1; is_idchar['B'] = 1; is_idchar['C'] = 1; - is_idchar['D'] = 1; is_idchar['E'] = 1; is_idchar['F'] = 1; - is_idchar['G'] = 1; is_idchar['H'] = 1; is_idchar['I'] = 1; - is_idchar['J'] = 1; is_idchar['K'] = 1; is_idchar['L'] = 1; - is_idchar['M'] = 1; is_idchar['N'] = 1; is_idchar['O'] = 1; - is_idchar['P'] = 1; is_idchar['Q'] = 1; is_idchar['R'] = 1; - is_idchar['S'] = 1; is_idchar['T'] = 1; is_idchar['U'] = 1; - is_idchar['V'] = 1; is_idchar['W'] = 1; is_idchar['X'] = 1; - is_idchar['Y'] = 1; is_idchar['Z'] = 1; - - is_idchar['1'] = 1; is_idchar['2'] = 1; is_idchar['3'] = 1; - is_idchar['4'] = 1; is_idchar['5'] = 1; is_idchar['6'] = 1; - is_idchar['7'] = 1; is_idchar['8'] = 1; is_idchar['9'] = 1; - is_idchar['0'] = 1; - - is_idchar['_'] = 1; - - is_idchar['$'] = dollar_in_ident; - is_idstart['$'] = dollar_in_ident; - - /* white space tables */ - is_hor_space[' '] = 1; - is_hor_space['\t'] = 1; - is_hor_space['\v'] = 1; - is_hor_space['\f'] = 1; - - is_space[' '] = 1; - is_space['\t'] = 1; - is_space['\v'] = 1; - is_space['\f'] = 1; - is_space['\n'] = 1; - - /* trigraph conversion */ - trigraph_table['='] = '#'; trigraph_table[')'] = ']'; - trigraph_table['!'] = '|'; trigraph_table['('] = '['; - trigraph_table['\''] = '^'; trigraph_table['>'] = '}'; - trigraph_table['/'] = '\\'; trigraph_table['<'] = '{'; - trigraph_table['-'] = '~'; -} + H(' ') H('\t') H('\v') H('\f') -#endif /* Not GCC. */ + S('\n') +END + +#undef A +#undef N +#undef H +#undef S +#undef TABLE +#undef END +#undef s +#undef CAT /* Given a colon-separated list of file names PATH, add all the names to the search path for include files. */ @@ -614,58 +496,89 @@ cpp_cleanup (pfile) } -/* Initialize the built-in macros. */ -static void -initialize_builtins (pfile) - cpp_reader *pfile; +/* This structure defines one built-in macro. A node of type TYPE will + be entered in the macro hash table under the name NAME, with value + VALUE (if any). FLAGS tweaks the behavior a little: + DUMP write debug info for this macro + STDC define only if not -traditional + C89 define only if -lang-c89 + C9X define only if -lang-c9x + ULP value is the global user_label_prefix (which can't be + put directly into the table). + */ + +struct builtin +{ + const char *name; + const char *value; + unsigned short type; + unsigned short flags; +}; +#define DUMP 0x01 +#define STDC 0x02 +#define C89 0x04 +#define C9X 0x08 +#define ULP 0x10 + +static const struct builtin builtin_array[] = { -#define NAME(str) (const U_CHAR *)str, sizeof str - 1 - cpp_install (pfile, NAME("__TIME__"), T_TIME, 0, -1); - cpp_install (pfile, NAME("__DATE__"), T_DATE, 0, -1); - cpp_install (pfile, NAME("__FILE__"), T_FILE, 0, -1); - cpp_install (pfile, NAME("__BASE_FILE__"), T_BASE_FILE, 0, -1); - cpp_install (pfile, NAME("__LINE__"), T_SPECLINE, 0, -1); - cpp_install (pfile, NAME("__INCLUDE_LEVEL__"), T_INCLUDE_LEVEL, 0, -1); - cpp_install (pfile, NAME("__VERSION__"), T_VERSION, 0, -1); + { "__TIME__", 0, T_TIME, DUMP }, + { "__DATE__", 0, T_DATE, DUMP }, + { "__FILE__", 0, T_FILE, 0 }, + { "__BASE_FILE__", 0, T_BASE_FILE, DUMP }, + { "__LINE__", 0, T_SPECLINE, 0 }, + { "__INCLUDE_LEVEL__", 0, T_INCLUDE_LEVEL, 0 }, + { "__VERSION__", 0, T_VERSION, DUMP }, + { "__STDC__", 0, T_STDC, DUMP|STDC }, + + { "__USER_LABEL_PREFIX__", 0, T_CONST, ULP }, + { "__REGISTER_PREFIX__", REGISTER_PREFIX, T_CONST, 0 }, + { "__HAVE_BUILTIN_SETJMP__", "1", T_CONST, 0 }, #ifndef NO_BUILTIN_SIZE_TYPE - cpp_install (pfile, NAME("__SIZE_TYPE__"), T_CONST, SIZE_TYPE, -1); + { "__SIZE_TYPE__", SIZE_TYPE, T_CONST, DUMP }, #endif #ifndef NO_BUILTIN_PTRDIFF_TYPE - cpp_install (pfile, NAME("__PTRDIFF_TYPE__ "), T_CONST, PTRDIFF_TYPE, -1); -#endif - cpp_install (pfile, NAME("__WCHAR_TYPE__"), T_CONST, WCHAR_TYPE, -1); - cpp_install (pfile, NAME("__USER_LABEL_PREFIX__"), T_CONST, user_label_prefix, -1); - cpp_install (pfile, NAME("__REGISTER_PREFIX__"), T_CONST, REGISTER_PREFIX, -1); - cpp_install (pfile, NAME("__HAVE_BUILTIN_SETJMP__"), T_CONST, "1", -1); - if (!CPP_TRADITIONAL (pfile)) - { - cpp_install (pfile, NAME("__STDC__"), T_STDC, 0, -1); -#if 0 - if (CPP_OPTIONS (pfile)->c9x) - cpp_install (pfile, NAME("__STDC_VERSION__"),T_CONST, "199909L", -1); - else + { "__PTRDIFF_TYPE__", PTRDIFF_TYPE, T_CONST, DUMP }, #endif - cpp_install (pfile, NAME("__STDC_VERSION__"),T_CONST, "199409L", -1); - } -#undef NAME + { "__WCHAR_TYPE__", WCHAR_TYPE, T_CONST, DUMP }, + { "__STDC_VERSION__", "199409L", T_CONST, DUMP|STDC|C89 }, + { "__STDC_VERSION__", "199909L", T_CONST, DUMP|STDC|C9X }, + { 0, 0, 0, 0 } +}; + +/* Subroutine of cpp_start_read; reads the builtins table above and + enters the macros into the hash table. */ - if (CPP_OPTIONS (pfile)->debug_output) +static void +initialize_builtins (pfile) + cpp_reader *pfile; +{ + int len; + const struct builtin *b; + const char *val; + for(b = builtin_array; b->name; b++) { - dump_special_to_buffer (pfile, "__BASE_FILE__"); - dump_special_to_buffer (pfile, "__VERSION__"); -#ifndef NO_BUILTIN_SIZE_TYPE - dump_special_to_buffer (pfile, "__SIZE_TYPE__"); -#endif -#ifndef NO_BUILTIN_PTRDIFF_TYPE - dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__"); -#endif - dump_special_to_buffer (pfile, "__WCHAR_TYPE__"); - dump_special_to_buffer (pfile, "__DATE__"); - dump_special_to_buffer (pfile, "__TIME__"); - if (!CPP_TRADITIONAL (pfile)) - dump_special_to_buffer (pfile, "__STDC__"); + if ((b->flags & STDC) && CPP_TRADITIONAL (pfile)) + continue; + if ((b->flags & C89) && CPP_OPTIONS (pfile)->c9x) + continue; + if ((b->flags & C9X) && !CPP_OPTIONS (pfile)->c9x) + continue; + + val = (b->flags & ULP) ? user_label_prefix : b->value; + len = strlen (b->name); + + cpp_install (pfile, b->name, len, b->type, val, -1); + if ((b->flags & DUMP) && CPP_OPTIONS (pfile)->debug_output) + dump_special_to_buffer (pfile, b->name); } + } +#undef DUMP +#undef STDC +#undef C89 +#undef C9X +#undef ULP /* Another subroutine of cpp_start_read. This one sets up to do dependency-file output. */ @@ -802,7 +715,11 @@ cpp_start_read (pfile, fname) /* Now that we know dollars_in_ident, we can initialize the syntax tables. */ - initialize_char_syntax (opts->dollars_in_ident); + init_IStable (); + /* XXX Get rid of code that depends on this, then IStable can + be truly const. */ + if (opts->dollars_in_ident) + IStable['$'] = ISidstart|ISidnum; /* Do partial setup of input buffer for the sake of generating early #line directives (when -g is in effect). */ diff --git a/gcc/cpplib.c b/gcc/cpplib.c index 7e41d1b4228..c3e3960c66f 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -25,8 +25,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "cpphash.h" #include "intl.h" -#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0) -#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0) +#define SKIP_WHITE_SPACE(p) do { while (is_hspace(*p)) p++; } while (0) #define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) ? CPP_BUFFER (pfile)->cur[N] : EOF) #define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) @@ -411,7 +410,7 @@ cpp_skip_hspace (pfile) c = GETC(); if (c == EOF) return; - else if (is_hor_space[c]) + else if (is_hspace(c)) { if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile)) cpp_pedwarn (pfile, "%s in preprocessing directive", @@ -596,36 +595,29 @@ pass_thru_directive (buf, len, pfile, keyword) CPP_PUTS_Q (pfile, buf, len); } -/* Check a purported macro name SYMNAME, and yield its length. - ASSERTION is nonzero if this is really for an assertion name. */ +/* Check a purported macro name SYMNAME, and yield its length. */ int -check_macro_name (pfile, symname, assertion) +check_macro_name (pfile, symname) cpp_reader *pfile; const U_CHAR *symname; - int assertion; { const U_CHAR *p; int sym_length; - for (p = symname; is_idchar[*p]; p++) + for (p = symname; is_idchar(*p); p++) ; sym_length = p - symname; if (sym_length == 0 || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"'))) - cpp_error (pfile, - assertion ? "invalid assertion name" : "invalid macro name"); - else if (!is_idstart[*symname] + cpp_error (pfile, "invalid macro name"); + else if (!is_idstart(*symname) || (! strncmp (symname, "defined", 7) && sym_length == 7)) { U_CHAR *msg; /* what pain... */ msg = (U_CHAR *) alloca (sym_length + 1); bcopy (symname, msg, sym_length); msg[sym_length] = 0; - cpp_error (pfile, - (assertion - ? "invalid assertion name `%s'" - : "invalid macro name `%s'"), - msg); + cpp_error (pfile, "invalid macro name `%s'", msg); } return sym_length; } @@ -1354,7 +1346,7 @@ do_line (pfile, keyword) if (strcmp (fname, ip->nominal_fname)) { - char *newname, *oldname; + const char *newname, *oldname; if (!strcmp (fname, ip->fname)) newname = ip->fname; else if (ip->last_nominal_fname @@ -1370,7 +1362,7 @@ do_line (pfile, keyword) && ip->last_nominal_fname != oldname && ip->last_nominal_fname != newname && ip->last_nominal_fname != ip->fname) - free (ip->last_nominal_fname); + free ((void *) ip->last_nominal_fname); if (newname == ip->fname) ip->last_nominal_fname = NULL; @@ -1415,7 +1407,7 @@ do_undef (pfile, keyword) cpp_skip_hspace (pfile); c = GETC(); - if (! is_idstart[c]) + if (! is_idstart(c)) { cpp_error (pfile, "token after #undef is not an identifier"); skip_rest_of_line (pfile); @@ -1440,7 +1432,7 @@ do_undef (pfile, keyword) CPP_SET_WRITTEN (pfile, here); - sym_length = check_macro_name (pfile, buf, 0); + sym_length = check_macro_name (pfile, buf); while ((hp = cpp_lookup (pfile, name, sym_length, -1)) != NULL) { @@ -1643,10 +1635,10 @@ do_pragma (pfile, keyword) { U_CHAR *end = syms; - while (is_idchar[*end]) + while (is_idchar(*end)) end++; - if (!is_hor_space[*end] && *end != '\0') + if (!is_hspace(*end) && *end != '\0') { cpp_error (pfile, "invalid #pragma poison directive"); return 1; @@ -1924,7 +1916,7 @@ do_xifdef (pfile, keyword) else { U_CHAR *cp = buf; fprintf (pcp_outfile, "#undef "); - while (is_idchar[*cp]) /* Ick! */ + while (is_idchar(*cp)) /* Ick! */ fputc (*cp++, pcp_outfile); putc ('\n', pcp_outfile); } @@ -2573,7 +2565,7 @@ cpp_get_token (pfile) c = PEEKC (); if (c == EOF) break; - if (!is_idchar[c] && c != '.' + if (!is_idchar(c) && c != '.' && ((c2 != 'e' && c2 != 'E' && ((c2 != 'p' && c2 != 'P') || CPP_C89 (pfile))) || (c != '+' && c != '-'))) @@ -2598,7 +2590,7 @@ cpp_get_token (pfile) c = GETC(); if (c == EOF) goto chill_number_eof; - if (!is_idchar[c]) + if (!is_idchar(c)) break; CPP_PUTC (pfile, c); } @@ -2720,7 +2712,7 @@ cpp_get_token (pfile) { CPP_PUTC (pfile, c); c = PEEKC (); - if (c == EOF || !is_hor_space[c]) + if (c == EOF || !is_hspace(c)) break; FORWARD(1); } @@ -2816,7 +2808,7 @@ parse_name (pfile, c) { for (;;) { - if (! is_idchar[c]) + if (! is_idchar(c)) { FORWARD (-1); break; @@ -2939,7 +2931,7 @@ parse_assertion (pfile) int c, dropwhite; cpp_skip_hspace (pfile); c = PEEKC(); - if (! is_idstart[c]) + if (! is_idstart(c)) { cpp_error (pfile, "assertion predicate is not an identifier"); return 0; @@ -2951,7 +2943,7 @@ parse_assertion (pfile) c = PEEKC(); if (c != '(') { - if (is_hor_space[c] || c == '\r') + if (is_hspace(c) || c == '\r') cpp_skip_hspace (pfile); c = PEEKC(); } @@ -2963,7 +2955,7 @@ parse_assertion (pfile) dropwhite = 1; while ((c = GETC()) != ')') { - if (is_hor_space[c]) + if (is_space(c)) { if (! dropwhite) { diff --git a/gcc/cpplib.h b/gcc/cpplib.h index 3880f2c34d3..f18a61d8ca4 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -96,11 +96,11 @@ struct cpp_buffer struct cpp_buffer *prev; /* Real filename. (Alias to ->ihash->fname, obsolete). */ - char *fname; + const char *fname; /* Filename specified with #line command. */ - char *nominal_fname; + const char *nominal_fname; /* Last filename specified with #line command. */ - char *last_nominal_fname; + const char *last_nominal_fname; /* Actual directory of this file, used only for "" includes */ struct file_name_list *actual_dir; @@ -550,11 +550,12 @@ struct include_hash /* Location of the file in the include search path. Used for include_next */ struct file_name_list *foundhere; - char *name; /* (partial) pathname of file */ - char *nshort; /* name of file as referenced in #include */ - const char *control_macro; /* macro, if any, preventing reinclusion - see - redundant_include_p */ - char *buf, *limit; /* for file content cache, not yet implemented */ + const char *name; /* (partial) pathname of file */ + const char *nshort; /* name of file as referenced in #include */ + const char *control_macro; /* macro, if any, preventing reinclusion - + see redundant_include_p */ + char *buf, *limit; /* for file content cache, + not yet implemented */ }; /* Name under which this program was invoked. */ @@ -610,7 +611,7 @@ typedef struct macrodef MACRODEF; struct macrodef { struct definition *defn; - unsigned char *symnam; + const U_CHAR *symnam; int symlen; }; @@ -665,18 +666,30 @@ struct definition { } args; }; -/* These tables are not really `const', but they are only modified at +/* Character classes. + If the definition of `numchar' looks odd to you, please look up the + definition of a pp-number in the C standard [section 6.4.8 of C99] */ +#define ISidnum 0x01 /* a-zA-Z0-9_ */ +#define ISidstart 0x02 /* _a-zA-Z */ +#define ISnumstart 0x04 /* 0-9 */ +#define IShspace 0x08 /* ' ' \t \f \v */ +#define ISspace 0x10 /* ' ' \t \f \v \n */ + +#define is_idchar(x) (IStable[x] & ISidnum) +#define is_numchar(x) (IStable[x] & ISidnum) +#define is_idstart(x) (IStable[x] & ISidstart) +#define is_numstart(x) (IStable[x] & ISnumstart) +#define is_hspace(x) (IStable[x] & IShspace) +#define is_space(x) (IStable[x] & ISspace) + +/* This table is not really `const', but it is only modified at initialization time, in a separate translation unit from the rest - of the library. We let the rest of the library think they are `const' - to get better code and some additional sanity checks. */ + of the library. We let the rest of the library think it is `const' + to get better code and some additional compile-time checks. */ #ifndef FAKE_CONST #define FAKE_CONST const #endif -extern FAKE_CONST unsigned char is_idstart[256]; -extern FAKE_CONST unsigned char is_idchar[256]; -extern FAKE_CONST unsigned char is_hor_space[256]; -extern FAKE_CONST unsigned char is_space[256]; -extern FAKE_CONST unsigned char trigraph_table[256]; +extern FAKE_CONST unsigned char IStable[256]; #undef FAKE_CONST /* Stack of conditionals currently in progress @@ -684,7 +697,7 @@ extern FAKE_CONST unsigned char trigraph_table[256]; struct if_stack { struct if_stack *next; /* for chaining to the next stack frame */ - char *fname; /* copied from input when frame is made */ + const char *fname; /* copied from input when frame is made */ int lineno; /* similarly */ int if_succeeded; /* true if a leg of this if-group has been passed through rescan */ @@ -739,7 +752,7 @@ extern void quote_string PARAMS ((cpp_reader *, const char *)); extern void cpp_expand_to_buffer PARAMS ((cpp_reader *, const U_CHAR *, int)); extern void cpp_scan_buffer PARAMS ((cpp_reader *)); -extern int check_macro_name PARAMS ((cpp_reader *, const U_CHAR *, int)); +extern int check_macro_name PARAMS ((cpp_reader *, const U_CHAR *)); /* Last arg to output_line_command. */ enum file_change_code {same_file, enter_file, leave_file}; diff --git a/gcc/cppmain.c b/gcc/cppmain.c index c0dec16d2c7..2e31faebfa5 100644 --- a/gcc/cppmain.c +++ b/gcc/cppmain.c @@ -117,6 +117,8 @@ main (argc, argv) < CPP_WRITTEN (&parse_in)) cpp_pfatal_with_name (&parse_in, opts->out_fname); + cpp_cleanup (&parse_in); + if (parse_in.errors) return (FATAL_EXIT_CODE); return (SUCCESS_EXIT_CODE); -- 2.11.0