X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcppmacro.c;h=eba8c0032a3ada313adcea21d81deb989f1b2ec5;hb=7de4f5f229944e622115372dedac95f86ab3ef2f;hp=d5179487637b1bab9b715bd52617966e5e843b16;hpb=0602564743c89e52f31a4dc5518e14a80c372d57;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index d5179487637..eba8c0032a3 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -1,6 +1,6 @@ /* Part of CPP library. (Macro and #define handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. Written by Per Bothner, 1994. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -25,6 +25,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "cpplib.h" #include "cpphash.h" @@ -54,7 +56,6 @@ static const cpp_token *padding_token static void expand_arg PARAMS ((cpp_reader *, macro_arg *)); static const cpp_token *new_string_token PARAMS ((cpp_reader *, uchar *, unsigned int)); -static const cpp_token *new_number_token PARAMS ((cpp_reader *, unsigned int)); static const cpp_token *stringify_arg PARAMS ((cpp_reader *, macro_arg *)); static void paste_all_tokens PARAMS ((cpp_reader *, const cpp_token *)); static bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **, @@ -70,11 +71,32 @@ static cpp_token *alloc_expansion_token PARAMS ((cpp_reader *, cpp_macro *)); static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *)); static bool warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *, const cpp_macro *)); -static int parse_params PARAMS ((cpp_reader *, cpp_macro *)); +static bool parse_params PARAMS ((cpp_reader *, cpp_macro *)); static void check_trad_stringification PARAMS ((cpp_reader *, const cpp_macro *, const cpp_string *)); +/* Emits a warning if NODE is a macro defined in the main file that + has not been used. */ +int +_cpp_warn_if_unused_macro (pfile, node, v) + cpp_reader *pfile; + cpp_hashnode *node; + void *v ATTRIBUTE_UNUSED; +{ + if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) + { + cpp_macro *macro = node->value.macro; + + if (!macro->used + && MAIN_FILE_P (lookup_line (&pfile->line_maps, macro->line))) + cpp_error_with_line (pfile, DL_WARNING, macro->line, 0, + "macro \"%s\" is not used", NODE_NAME (node)); + } + + return 1; +} + /* Allocates and returns a CPP_STRING token, containing TEXT of length LEN, after null-terminating it. TEXT must be in permanent storage. */ static const cpp_token * @@ -93,24 +115,6 @@ new_string_token (pfile, text, len) return token; } -/* Allocates and returns a CPP_NUMBER token evaluating to NUMBER. */ -static const cpp_token * -new_number_token (pfile, number) - cpp_reader *pfile; - unsigned int number; -{ - cpp_token *token = _cpp_temp_token (pfile); - /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers. */ - unsigned char *buf = _cpp_unaligned_alloc (pfile, 21); - - sprintf ((char *) buf, "%u", number); - token->type = CPP_NUMBER; - token->val.str.text = buf; - token->val.str.len = ustrlen (buf); - token->flags = 0; - return token; -} - static const char * const monthnames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -121,19 +125,20 @@ static const char * const monthnames[] = on the context stack. Also handles _Pragma, for which no new token is created. Returns 1 if it generates a new token context, 0 to return the token to the caller. */ -static int -builtin_macro (pfile, node) +const uchar * +_cpp_builtin_macro_text (pfile, node) cpp_reader *pfile; cpp_hashnode *node; { - const cpp_token *result; + const uchar *result = NULL; + unsigned int number = 1; switch (node->value.builtin) { default: cpp_error (pfile, DL_ICE, "invalid built-in macro \"%s\"", NODE_NAME (node)); - return 0; + break; case BT_FILE: case BT_BASE_FILE: @@ -149,10 +154,12 @@ builtin_macro (pfile, node) name = map->to_file; len = strlen (name); - buf = _cpp_unaligned_alloc (pfile, len * 4 + 1); - len = cpp_quote_string (buf, (const unsigned char *) name, len) - buf; - - result = new_string_token (pfile, buf, len); + buf = _cpp_unaligned_alloc (pfile, len * 4 + 3); + result = buf; + *buf = '"'; + buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); + *buf++ = '"'; + *buf = '\0'; } break; @@ -160,16 +167,18 @@ builtin_macro (pfile, node) /* The line map depth counts the primary source as level 1, but historically __INCLUDE_DEPTH__ has called the primary source level 0. */ - result = new_number_token (pfile, pfile->line_maps.depth - 1); + number = pfile->line_maps.depth - 1; break; case BT_SPECLINE: /* If __LINE__ is embedded in a macro, it must expand to the line of the macro's invocation, not its definition. Otherwise things like assert() will not work properly. */ - result = new_number_token (pfile, - SOURCE_LINE (pfile->map, - pfile->cur_token[-1].line)); + if (CPP_OPTION (pfile, traditional)) + number = pfile->line; + else + number = pfile->cur_token[-1].line; + number = SOURCE_LINE (pfile->map, number); break; /* __STDC__ has the value 1 under normal circumstances. @@ -179,55 +188,88 @@ builtin_macro (pfile, node) value 0. */ case BT_STDC: { - int stdc; - enum c_lang lang = CPP_OPTION (pfile, lang); if (CPP_IN_SYSTEM_HEADER (pfile) && CPP_OPTION (pfile, stdc_0_in_system_headers) - && !(lang == CLK_STDC89 || lang == CLK_STDC94 - || lang == CLK_STDC99)) /* || lang == CLK_CXX98 ? */ - stdc = 0; + && !CPP_OPTION (pfile,std)) + number = 0; else - stdc = 1; - - result = new_number_token (pfile, stdc); + number = 1; } break; case BT_DATE: case BT_TIME: - if (pfile->date.type == CPP_EOF) + if (pfile->date == NULL) { /* Allocate __DATE__ and __TIME__ strings from permanent storage. We only do this once, and don't generate them at init time, because time() and localtime() are very slow on some systems. */ - time_t tt = time (NULL); - struct tm *tb = localtime (&tt); - - pfile->date.val.str.text = - _cpp_unaligned_alloc (pfile, sizeof ("Oct 11 1347")); - pfile->date.val.str.len = sizeof ("Oct 11 1347") - 1; - pfile->date.type = CPP_STRING; - pfile->date.flags = 0; - sprintf ((char *) pfile->date.val.str.text, "%s %2d %4d", - monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900); - - pfile->time.val.str.text = - _cpp_unaligned_alloc (pfile, sizeof ("12:34:56")); - pfile->time.val.str.len = sizeof ("12:34:56") - 1; - pfile->time.type = CPP_STRING; - pfile->time.flags = 0; - sprintf ((char *) pfile->time.val.str.text, "%02d:%02d:%02d", - tb->tm_hour, tb->tm_min, tb->tm_sec); + time_t tt; + struct tm *tb = NULL; + + /* (time_t) -1 is a legitimate value for "number of seconds + since the Epoch", so we have to do a little dance to + distinguish that from a genuine error. */ + errno = 0; + tt = time(NULL); + if (tt != (time_t)-1 || errno == 0) + tb = localtime (&tt); + + if (tb) + { + pfile->date = _cpp_unaligned_alloc (pfile, + sizeof ("\"Oct 11 1347\"")); + sprintf ((char *) pfile->date, "\"%s %2d %4d\"", + monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900); + + pfile->time = _cpp_unaligned_alloc (pfile, + sizeof ("\"12:34:56\"")); + sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"", + tb->tm_hour, tb->tm_min, tb->tm_sec); + } + else + { + cpp_errno (pfile, DL_WARNING, + "could not determine date and time"); + + pfile->date = U"\"??? ?? ????\""; + pfile->time = U"\"??:??:??\""; + } } if (node->value.builtin == BT_DATE) - result = &pfile->date; + result = pfile->date; else - result = &pfile->time; + result = pfile->time; break; + } + + if (result == NULL) + { + /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers. */ + result = _cpp_unaligned_alloc (pfile, 21); + sprintf ((char *) result, "%u", number); + } - case BT_PRAGMA: + return result; +} + +/* Convert builtin macros like __FILE__ to a token and push it on the + context stack. Also handles _Pragma, for which no new token is + created. Returns 1 if it generates a new token context, 0 to + return the token to the caller. */ +static int +builtin_macro (pfile, node) + cpp_reader *pfile; + cpp_hashnode *node; +{ + const uchar *buf; + size_t len; + char *nbuf; + + if (node->value.builtin == BT_PRAGMA) + { /* Don't interpret _Pragma within directives. The standard is not clear on this, but to me this makes most sense. */ if (pfile->state.in_directive) @@ -237,7 +279,23 @@ builtin_macro (pfile, node) return 1; } - push_token_context (pfile, NULL, result, 1); + buf = _cpp_builtin_macro_text (pfile, node); + len = ustrlen (buf); + nbuf = alloca (len + 1); + memcpy (nbuf, buf, len); + nbuf[len]='\n'; + + cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true, 1); + _cpp_clean_line (pfile); + + /* Set pfile->cur_token as required by _cpp_lex_direct. */ + pfile->cur_token = _cpp_temp_token (pfile); + push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); + if (pfile->buffer->cur != pfile->buffer->rlimit) + cpp_error (pfile, DL_ICE, "invalid built-in macro \"%s\"", + NODE_NAME (node)); + _cpp_pop_buffer (pfile); + return 1; } @@ -282,11 +340,16 @@ stringify_arg (pfile, arg) cpp_reader *pfile; macro_arg *arg; { - unsigned char *dest = BUFF_FRONT (pfile->u_buff); + unsigned char *dest; unsigned int i, escape_it, backslash_count = 0; const cpp_token *source = NULL; size_t len; + if (BUFF_ROOM (pfile->u_buff) < 3) + _cpp_extend_buff (pfile, &pfile->u_buff, 3); + dest = BUFF_FRONT (pfile->u_buff); + *dest++ = '"'; + /* Loop, reading in the argument's tokens. */ for (i = 0; i < arg->count; i++) { @@ -303,11 +366,11 @@ stringify_arg (pfile, arg) || token->type == CPP_CHAR || token->type == CPP_WCHAR); /* Room for each char being written in octal, initial space and - final NUL. */ + final quote and NUL. */ len = cpp_token_len (token); if (escape_it) len *= 4; - len += 2; + len += 3; if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len) { @@ -317,7 +380,7 @@ stringify_arg (pfile, arg) } /* Leading white space? */ - if (dest != BUFF_FRONT (pfile->u_buff)) + if (dest - 1 != BUFF_FRONT (pfile->u_buff)) { if (source == NULL) source = token; @@ -337,7 +400,7 @@ stringify_arg (pfile, arg) else dest = cpp_spell_token (pfile, token, dest); - if (token->type == CPP_OTHER && token->val.c == '\\') + if (token->type == CPP_OTHER && token->val.str.text[0] == '\\') backslash_count++; else backslash_count = 0; @@ -352,12 +415,13 @@ stringify_arg (pfile, arg) } /* Commit the memory, including NUL, and return the token. */ + *dest++ = '"'; len = dest - BUFF_FRONT (pfile->u_buff); BUFF_FRONT (pfile->u_buff) = dest + 1; return new_string_token (pfile, dest - len, len); } -/* Try to paste two tokens. On success, return non-zero. In any +/* Try to paste two tokens. On success, return nonzero. In any case, PLHS is updated to point to the pasted token, which is guaranteed to not have the PASTE_LEFT flag set. */ static bool @@ -379,19 +443,13 @@ paste_tokens (pfile, plhs, rhs) It is simpler to insert a space here, rather than modifying the lexer to ignore comments in some circumstances. Simply returning false doesn't work, since we want to clear the PASTE_LEFT flag. */ - if (lhs->type == CPP_DIV - && (rhs->type == CPP_MULT || rhs->type == CPP_DIV)) + if (lhs->type == CPP_DIV && rhs->type != CPP_EQ) *end++ = ' '; end = cpp_spell_token (pfile, rhs, end); - *end = '\0'; + *end = '\n'; cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true, 1); - - /* Tweak the column number the lexer will report. */ - pfile->buffer->col_adjust = pfile->cur_token[-1].col - 1; - - /* We don't want a leading # to be interpreted as a directive. */ - pfile->buffer->saved_flags = 0; + _cpp_clean_line (pfile); /* Set pfile->cur_token as required by _cpp_lex_direct. */ pfile->cur_token = _cpp_temp_token (pfile); @@ -613,7 +671,20 @@ collect_args (pfile, node) if (argc == 1 && macro->paramc == 0 && args[0].count == 0) argc = 0; if (_cpp_arguments_ok (pfile, macro, node, argc)) - return base_buff; + { + /* GCC has special semantics for , ## b where b is a varargs + parameter: we remove the comma if b was omitted entirely. + If b was merely an empty argument, the comma is retained. + If the macro takes just one (varargs) parameter, then we + retain the comma only if we are standards conforming. + + If FIRST is NULL replace_args () swallows the comma. */ + if (macro->variadic && (argc < macro->paramc + || (argc == 1 && args[0].count == 0 + && !CPP_OPTION (pfile, std)))) + args[macro->paramc - 1].first = NULL; + return base_buff; + } } /* An error occurred. */ @@ -712,6 +783,8 @@ enter_macro_context (pfile, node) /* Disable the macro within its expansion. */ node->flags |= NODE_DISABLED; + macro->used = 1; + if (macro->paramc == 0) push_token_context (pfile, node, macro->exp.tokens, macro->count); @@ -800,15 +873,13 @@ replace_args (pfile, node, macro, args) count = arg->count, from = arg->first; if (dest != first) { - /* GCC has special semantics for , ## b where b is a - varargs parameter: the comma disappears if b was - given no actual arguments (not merely if b is an - empty argument); otherwise the paste flag is removed. */ if (dest[-1]->type == CPP_COMMA && macro->variadic && src->val.arg_no == macro->paramc) { - if (count == 0) + /* Swallow a pasted comma if from == NULL, otherwise + drop the paste flag. */ + if (from == NULL) dest--; else paste_flag = dest - 1; @@ -822,7 +893,7 @@ replace_args (pfile, node, macro, args) count = arg->expanded_count, from = arg->expanded; /* Padding on the left of an argument (unless RHS of ##). */ - if (!pfile->state.in_directive + if ((!pfile->state.in_directive || pfile->state.directive_wants_padding) && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT)) *dest++ = padding_token (pfile, src); @@ -947,6 +1018,7 @@ _cpp_push_text_context (pfile, macro, start, len) context->buff = NULL; CUR (context) = start; RLIMIT (context) = start + len; + macro->flags |= NODE_DISABLED; } /* Expand an argument ARG before replacing parameters in a @@ -961,10 +1033,15 @@ expand_arg (pfile, arg) macro_arg *arg; { unsigned int capacity; + bool saved_warn_trad; if (arg->count == 0) return; + /* Don't warn about funlike macros when pre-expanding. */ + saved_warn_trad = CPP_WTRADITIONAL (pfile); + CPP_WTRADITIONAL (pfile) = 0; + /* Loop, reading in the arguments. */ capacity = 256; arg->expanded = (const cpp_token **) @@ -991,6 +1068,8 @@ expand_arg (pfile, arg) } _cpp_pop_context (pfile); + + CPP_WTRADITIONAL (pfile) = saved_warn_trad; } /* Pop the current context off the stack, re-enabling the macro if the @@ -1119,8 +1198,12 @@ cpp_scan_nooutput (pfile) transparently continuing with the including file. */ pfile->buffer->return_at_eof = true; - while (cpp_get_token (pfile)->type != CPP_EOF) - ; + if (CPP_OPTION (pfile, traditional)) + while (_cpp_read_logical_line_trad (pfile)) + ; + else + while (cpp_get_token (pfile)->type != CPP_EOF) + ; } /* Step back one (or more) tokens. Can only step mack more than 1 if @@ -1158,7 +1241,7 @@ _cpp_backup_tokens (pfile, count) /* #define directive parsing and handling. */ -/* Returns non-zero if a macro redefinition warning is required. */ +/* Returns nonzero if a macro redefinition warning is required. */ static bool warn_of_redefinition (pfile, node, macro2) cpp_reader *pfile; @@ -1176,9 +1259,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,7 +1273,10 @@ 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); + + if (macro1->count != macro2->count) + return true; for (i = 0; i < macro1->count; i++) if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) @@ -1211,19 +1297,20 @@ _cpp_free_definition (h) } /* Save parameter NODE to the parameter list of macro MACRO. Returns - zero on success, non-zero if the parameter is a duplicate. */ + zero on success, nonzero if the parameter is a duplicate. */ bool _cpp_save_parameter (pfile, macro, node) cpp_reader *pfile; cpp_macro *macro; cpp_hashnode *node; { + unsigned int len; /* Constraint 6.10.3.6 - duplicate parameter names. */ - if (node->arg_index) + if (node->flags & NODE_MACRO_ARG) { cpp_error (pfile, DL_ERROR, "duplicate macro parameter \"%s\"", NODE_NAME (node)); - return 1; + return true; } if (BUFF_ROOM (pfile->a_buff) @@ -1231,12 +1318,23 @@ _cpp_save_parameter (pfile, macro, node) _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *)); ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node; - node->arg_index = macro->paramc; - return 0; + node->flags |= NODE_MACRO_ARG; + len = macro->paramc * sizeof (union _cpp_hashnode_value); + if (len > pfile->macro_buffer_len) + { + pfile->macro_buffer = (uchar *) xrealloc (pfile->macro_buffer, len); + pfile->macro_buffer_len = len; + } + ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1] + = node->value; + + node->value.arg_index = macro->paramc; + return false; } -/* Check the syntax of the parameters in a MACRO definition. */ -static int +/* Check the syntax of the parameters in a MACRO definition. Returns + false if an error occurs. */ +static bool parse_params (pfile, macro) cpp_reader *pfile; cpp_macro *macro; @@ -1259,31 +1357,31 @@ parse_params (pfile, macro) cpp_error (pfile, DL_ERROR, "\"%s\" may not appear in macro parameter list", cpp_token_as_text (pfile, token)); - return 0; + return false; case CPP_NAME: if (prev_ident) { cpp_error (pfile, DL_ERROR, "macro parameters must be comma-separated"); - return 0; + return false; } prev_ident = 1; if (_cpp_save_parameter (pfile, macro, token->val.node)) - return 0; + return false; continue; case CPP_CLOSE_PAREN: if (prev_ident || macro->paramc == 0) - return 1; + return true; /* Fall through to pick up the error. */ case CPP_COMMA: if (!prev_ident) { cpp_error (pfile, DL_ERROR, "parameter name missing"); - return 0; + return false; } prev_ident = 0; continue; @@ -1306,12 +1404,12 @@ parse_params (pfile, macro) /* We're at the end, and just expect a closing parenthesis. */ token = _cpp_lex_token (pfile); if (token->type == CPP_CLOSE_PAREN) - return 1; + return true; /* Fall through. */ case CPP_EOF: cpp_error (pfile, DL_ERROR, "missing ')' in macro parameter list"); - return 0; + return false; } } } @@ -1341,10 +1439,11 @@ lex_expansion_token (pfile, macro) token = _cpp_lex_direct (pfile); /* Is this a parameter? */ - if (token->type == CPP_NAME && token->val.node->arg_index) + if (token->type == CPP_NAME + && (token->val.node->flags & NODE_MACRO_ARG) != 0) { token->type = CPP_MACRO_ARG; - token->val.arg_no = token->val.node->arg_index; + token->val.arg_no = token->val.node->value.arg_index; } else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0 && (token->type == CPP_STRING || token->type == CPP_CHAR)) @@ -1450,7 +1549,7 @@ create_iso_definition (pfile, macro) return true; } -/* Parse a macro and save its expansion. Returns non-zero on success. */ +/* Parse a macro and save its expansion. Returns nonzero on success. */ bool _cpp_create_definition (pfile, node) cpp_reader *pfile; @@ -1465,6 +1564,7 @@ _cpp_create_definition (pfile, node) macro->params = 0; macro->paramc = 0; macro->variadic = 0; + macro->used = !CPP_OPTION (pfile, warn_unused_macros); macro->count = 0; macro->fun_like = 0; /* To suppress some diagnostics. */ @@ -1493,13 +1593,20 @@ _cpp_create_definition (pfile, node) /* Clear the fast argument lookup indices. */ for (i = macro->paramc; i-- > 0; ) - macro->params[i]->arg_index = 0; + { + struct cpp_hashnode *node = macro->params[i]; + node->flags &= ~ NODE_MACRO_ARG; + node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i]; + } if (!ok) return ok; - if (node->type != NT_VOID) + if (node->type == NT_MACRO) { + if (CPP_OPTION (pfile, warn_unused_macros)) + _cpp_warn_if_unused_macro (pfile, node, NULL); + if (warn_of_redefinition (pfile, node, macro)) { cpp_error_with_line (pfile, DL_PEDWARN, pfile->directive_line, 0, @@ -1510,9 +1617,11 @@ _cpp_create_definition (pfile, node) node->value.macro->line, 0, "this is the location of the previous definition"); } - _cpp_free_definition (node); } + if (node->type != NT_VOID) + _cpp_free_definition (node); + /* Enter definition in hash table. */ node->type = NT_MACRO; node->value.macro = macro; @@ -1531,10 +1640,11 @@ check_trad_stringification (pfile, macro, string) const cpp_string *string; { unsigned int i, len; - const uchar *p, *q, *limit = string->text + string->len; + const uchar *p, *q, *limit; /* Loop over the string. */ - for (p = string->text; p < limit; p = q) + limit = string->text + string->len - 1; + for (p = string->text + 1; p < limit; p = q) { /* Find the start of an identifier. */ while (p < limit && !is_idstart (*p)) @@ -1596,18 +1706,23 @@ cpp_macro_definition (pfile, node) len += NODE_LEN (macro->params[i]) + 1; /* "," */ } - for (i = 0; i < macro->count; i++) + if (CPP_OPTION (pfile, traditional)) + len += _cpp_replacement_text_len (macro); + else { - cpp_token *token = ¯o->exp.tokens[i]; + for (i = 0; i < macro->count; i++) + { + cpp_token *token = ¯o->exp.tokens[i]; - if (token->type == CPP_MACRO_ARG) - len += NODE_LEN (macro->params[token->val.arg_no - 1]); - else - len += cpp_token_len (token); /* Includes room for ' '. */ - if (token->flags & STRINGIFY_ARG) - len++; /* "#" */ - if (token->flags & PASTE_LEFT) - len += 3; /* " ##" */ + if (token->type == CPP_MACRO_ARG) + len += NODE_LEN (macro->params[token->val.arg_no - 1]); + else + len += cpp_token_len (token) + 1; /* Includes room for ' '. */ + if (token->flags & STRINGIFY_ARG) + len++; /* "#" */ + if (token->flags & PASTE_LEFT) + len += 3; /* " ##" */ + } } if (len > pfile->macro_buffer_len) @@ -1650,8 +1765,10 @@ cpp_macro_definition (pfile, node) definition is the empty string. */ *buffer++ = ' '; + if (CPP_OPTION (pfile, traditional)) + buffer = _cpp_copy_replacement_text (macro, buffer); + else if (macro->count) /* Expansion tokens. */ - if (macro->count) { for (i = 0; i < macro->count; i++) {