summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-10 06:03:13 +0000
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-10 06:03:13 +0000
commit3396dc8065ec59cb307362fa820c58cb5cde9bff (patch)
treeadbb48f5611c4e938179b3f12970a0c7bef07ce1 /gcc
parent08cb25b34934ce594d9f56eb9c56ef96ad6fedb4 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cpphash.h36
-rw-r--r--gcc/cppmacro.c15
-rw-r--r--gcc/cpptrad.c114
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 (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
- return true;
+ if (macro1->count == macro2->count)
+ for (i = 0; i < macro1->count; i++)
+ if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->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, &quote1);
+ len2 = canonicalize_text (p2, b2->text, b2->text_len, &quote2);
+ 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, &quote1);
+ len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, &quote2);
+ 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)