diff options
author | neil <neil@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-10 06:03:13 +0000 |
---|---|---|
committer | neil <neil@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-10 06:03:13 +0000 |
commit | 3396dc8065ec59cb307362fa820c58cb5cde9bff (patch) | |
tree | adbb48f5611c4e938179b3f12970a0c7bef07ce1 /gcc | |
parent | 08cb25b34934ce594d9f56eb9c56ef96ad6fedb4 (diff) | |
download | gcc-3396dc8065ec59cb307362fa820c58cb5cde9bff.tar.gz |
* cpphash.h (struct cpp_macro): Put comments on their own lines.
(_cpp_expansions_different_trad): New.
* cppmacro.c (warn_of_redefinition): Fix for traditional case.
* cpptrad.c (canonicalize_text): New.
(scan_out_logical_line): Handle no arguments correctly.
(save_replacement_text): Commit memory when finished.
(_cpp_expansions_different_trad): New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54432 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cpphash.h | 36 | ||||
-rw-r--r-- | gcc/cppmacro.c | 15 | ||||
-rw-r--r-- | gcc/cpptrad.c | 114 |
4 files changed, 145 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94b77eb8c66..0f6cf2e50c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2002-06-10 Neil Booth <neil@daikokuya.demon.co.uk> + + * cpphash.h (struct cpp_macro): Put comments on their own lines. + (_cpp_expansions_different_trad): New. + * cppmacro.c (warn_of_redefinition): Fix for traditional case. + * cpptrad.c (canonicalize_text): New. + (scan_out_logical_line): Handle no arguments correctly. + (save_replacement_text): Commit memory when finished. + (_cpp_expansions_different_trad): New. + 2002-06-10 Tim Josling <tej@melbpc.org.au> * gengtype.c (unnamed enum containing BASE_FILE_*): Add languages diff --git a/gcc/cpphash.h b/gcc/cpphash.h index 6baf211958d..6d41ead6237 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -69,18 +69,35 @@ struct dummy Variadic macros cannot occur with traditional cpp. */ struct cpp_macro { - cpp_hashnode **params; /* Parameters, if any. */ + /* Parameters, if any. */ + cpp_hashnode **params; + + /* Replacement tokens (ISO) or replacement text (traditional). See + comment at top of cpptrad.c for how traditional function-like + macros are encoded. */ union { - cpp_token *tokens; /* Tokens of replacement list (ISO). */ - const uchar *text; /* Expansion text (traditional). */ + cpp_token *tokens; + const uchar *text; } exp; - unsigned int line; /* Starting line number. */ - unsigned int count; /* Number of tokens / bytes in expansion. */ - unsigned short paramc; /* Number of parameters. */ - unsigned int fun_like : 1; /* If a function-like macro. */ - unsigned int variadic : 1; /* If a variadic macro. */ - unsigned int syshdr : 1; /* If macro defined in system header. */ + + /* Definition line number. */ + unsigned int line; + + /* Number of tokens in expansion, or bytes for traditional macros. */ + unsigned int count; + + /* Number of parameters. */ + unsigned short paramc; + + /* If a function-like macro. */ + unsigned int fun_like : 1; + + /* If a variadic macro. */ + unsigned int variadic : 1; + + /* If macro defined in system header. */ + unsigned int syshdr : 1; }; /* A generic memory buffer, and operations on it. */ @@ -499,6 +516,7 @@ extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *, extern cpp_hashnode *_cpp_lex_identifier_trad PARAMS ((cpp_reader *)); extern void _cpp_set_trad_context PARAMS ((cpp_reader *)); extern bool _cpp_create_trad_definition PARAMS ((cpp_reader *, cpp_macro *)); +extern bool _cpp_expansions_different_trad PARAMS ((cpp_macro *, cpp_macro *)); /* Utility routines and macros. */ #define DSC(str) (const uchar *)str, sizeof str - 1 diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index d5179487637..a9ca6cf2dbf 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -1176,9 +1176,9 @@ warn_of_redefinition (pfile, node, macro2) definitions are the same. (6.10.3 paragraph 2). */ macro1 = node->value.macro; - /* The quick failures. */ - if (macro1->count != macro2->count - || macro1->paramc != macro2->paramc + /* Don't check count here as it can be different in valid + traditional redefinitions with just whitespace differences. */ + if (macro1->paramc != macro2->paramc || macro1->fun_like != macro2->fun_like || macro1->variadic != macro2->variadic) return true; @@ -1190,11 +1190,12 @@ warn_of_redefinition (pfile, node, macro2) /* Check the replacement text or tokens. */ if (CPP_OPTION (pfile, traditional)) - return memcmp (macro1->exp.text, macro2->exp.text, macro1->count); + return _cpp_expansions_different_trad (macro1, macro2); - for (i = 0; i < macro1->count; i++) - if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) - return true; + if (macro1->count == macro2->count) + for (i = 0; i < macro1->count; i++) + if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) + return true; return false; } diff --git a/gcc/cpptrad.c b/gcc/cpptrad.c index 7ba9d924ef0..4a76f96f0f2 100644 --- a/gcc/cpptrad.c +++ b/gcc/cpptrad.c @@ -89,6 +89,8 @@ static void maybe_start_funlike PARAMS ((cpp_reader *, cpp_hashnode *, const uchar *, struct fun_macro *)); static void save_argument PARAMS ((struct fun_macro *, size_t)); static void replace_args_and_push PARAMS ((cpp_reader *, struct fun_macro *)); +static size_t canonicalize_text PARAMS ((uchar *, const uchar *, size_t, + uchar *)); /* Ensures we have N bytes' space in the output buffer, and reallocates it if not. */ @@ -557,16 +559,11 @@ scan_out_logical_line (pfile, macro) pfile->state.parsing_args = 0; save_argument (&fmacro, out - pfile->trad_out_base); - /* A single whitespace argument is no argument. */ - if (fmacro.argc == 1 && m->paramc == 0) - { - const uchar *p = pfile->trad_out_base; - p += fmacro.args[0]; - while (is_space (*p)) - p++; - if (p == pfile->trad_out_base + fmacro.args[1]) - fmacro.argc = 0; - } + /* A single zero-length argument is no argument. */ + if (fmacro.argc == 1 + && m->paramc == 0 + && out == pfile->trad_out_base + 1) + fmacro.argc = 0; if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc)) { @@ -758,11 +755,11 @@ save_replacement_text (pfile, macro, arg_index) /* Lex the rest into the start of the output buffer. */ pfile->trad_out_cur = pfile->trad_out_base; - /* If this is the end of the macro, count up the bytes of text - in the replacement list, excluding the parameter names, and - save this in macro->count, else store the total bytes in the - replacement text so far (including block headers). */ macro->count += blen; + + /* If we've finished, commit the memory. */ + if (arg_index == 0) + BUFF_FRONT (pfile->a_buff) += macro->count; } } @@ -814,6 +811,95 @@ _cpp_create_trad_definition (pfile, macro) return true; } +/* Copy SRC of length LEN to DEST, but convert all contiguous + whitespace to a single space, provided it is not in quotes. The + quote currently in effect is pointed to by PQUOTE, and is updated + by the function. Returns the number of bytes copied. */ +static size_t +canonicalize_text (dest, src, len, pquote) + uchar *dest; + const uchar *src; + size_t len; + uchar *pquote; +{ + uchar *orig_dest = dest; + uchar quote = *pquote; + + while (len) + { + if (is_space (*src) && !quote) + { + do + src++, len--; + while (len && is_space (*src)); + *dest++ = ' '; + } + else + { + if (*src == '\'' || *src == '"') + { + if (!quote) + quote = *src; + else if (quote == *src) + quote = 0; + } + *dest++ = *src++, len--; + } + } + + *pquote = quote; + return dest - orig_dest; +} + +/* Returns true if MACRO1 and MACRO2 have expansions different other + than in the form of their whitespace. */ +bool +_cpp_expansions_different_trad (macro1, macro2) + cpp_macro *macro1, *macro2; +{ + uchar *p1 = xmalloc (macro1->count + macro2->count); + uchar *p2 = p1 + macro1->count; + uchar quote1 = 0, quote2; + bool mismatch; + size_t len1, len2; + + if (macro1->paramc > 0) + { + const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text; + + mismatch = true; + for (;;) + { + struct block *b1 = (struct block *) exp1; + struct block *b2 = (struct block *) exp2; + + if (b1->arg_index != b2->arg_index) + break; + + len1 = canonicalize_text (p1, b1->text, b1->text_len, "e1); + len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2); + if (len1 != len2 || memcmp (p1, p2, len1)) + break; + if (b1->arg_index == 0) + { + mismatch = false; + break; + } + exp1 += BLOCK_LEN (b1->text_len); + exp2 += BLOCK_LEN (b2->text_len); + } + } + else + { + len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, "e1); + len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, "e2); + mismatch = (len1 != len2 || memcmp (p1, p2, len1)); + } + + free (p1); + return mismatch; +} + /* Prepare to be able to scan the current buffer. */ void _cpp_set_trad_context (pfile) |