From 8e680db5b64c74ef131f7eb6a50902cf2134f845 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 11 Jun 2010 20:37:34 +0200 Subject: [PATCH] cpplib.h (struct cpp_callbacks): Add user_builtin_macro callback. * include/cpplib.h (struct cpp_callbacks): Add user_builtin_macro callback. (enum cpp_builtin_type): Add BT_FIRST_USER and BT_LAST_USER. (cpp_macro_definition): Remove const qual from second argument. * macro.c (enter_macro_context): Call user_builtin_macro callback for NODE_BUILTIN !NODE_USED macros. (warn_of_redefinition): Likewise. Remove const qual from second argument. (cpp_macro_definition): Likewise. * pch.c (write_macdef, save_macros): Call user_builtin_macro callback for NODE_BUILTIN !NODE_USED macros. * c-family/c-cppbuiltin.c: Include cpp-id-data.h. (lazy_hex_fp_values, lazy_hex_fp_value_count): New variables. (lazy_hex_fp_value): New function. (builtin_define_with_hex_fp_value): Provide definitions lazily. * Makefile.in (c-family/c-cppbuiltin.o): Depend on $(CPP_ID_DATA_H). From-SVN: r160626 --- gcc/ChangeLog | 8 +++++ gcc/Makefile.in | 2 +- gcc/c-family/c-cppbuiltin.c | 70 ++++++++++++++++++++++++++++++++++++- libcpp/ChangeLog | 14 ++++++++ libcpp/include/cpplib.h | 9 +++-- libcpp/macro.c | 31 +++++++++++----- libcpp/pch.c | 10 +++++- 7 files changed, 130 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d32047ee21..c52a81bbc22 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-06-10 Jakub Jelinek + + * c-family/c-cppbuiltin.c: Include cpp-id-data.h. + (lazy_hex_fp_values, lazy_hex_fp_value_count): New variables. + (lazy_hex_fp_value): New function. + (builtin_define_with_hex_fp_value): Provide definitions lazily. + * Makefile.in (c-family/c-cppbuiltin.o): Depend on $(CPP_ID_DATA_H). + 2010-06-11 Sebastian Pop PR middle-end/44483 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index c47ee954d2b..0d4f746a95a 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2081,7 +2081,7 @@ c-family/c-common.o : c-family/c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ c-family/c-cppbuiltin.o : c-family/c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) version.h $(C_COMMON_H) $(C_PRAGMA_H) \ $(FLAGS_H) $(TOPLEV_H) output.h $(EXCEPT_H) $(TREE_H) $(TARGET_H) \ - $(TM_P_H) $(BASEVER) debug.h + $(TM_P_H) $(BASEVER) debug.h $(CPP_ID_DATA_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ -DBASEVER=$(BASEVER_s) $< $(OUTPUT_OPTION) diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 6bbdb460e7a..4ed6975e45b 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -1,5 +1,5 @@ /* Define builtin-in macros for the C family front ends. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" #include "tm_p.h" /* For TARGET_CPU_CPP_BUILTINS & friends. */ #include "target.h" +#include "cpp-id-data.h" #ifndef TARGET_OS_CPP_BUILTINS # define TARGET_OS_CPP_BUILTINS() @@ -946,6 +947,50 @@ builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value) cpp_define (parse_in, buf); } +/* builtin_define_with_hex_fp_value is very expensive, so the following + array and function allows it to be done lazily when __DBL_MAX__ + etc. is first used. */ + +static struct +{ + const char *hex_str; + cpp_macro *macro; + enum machine_mode mode; + int digits; + const char *fp_suffix; +} lazy_hex_fp_values[12]; +static int lazy_hex_fp_value_count; + +static bool +lazy_hex_fp_value (cpp_reader *pfile ATTRIBUTE_UNUSED, + cpp_hashnode *node) +{ + REAL_VALUE_TYPE real; + char dec_str[64], buf1[256]; + unsigned int idx; + if (node->value.builtin < BT_FIRST_USER + || (int) node->value.builtin >= BT_FIRST_USER + lazy_hex_fp_value_count) + return false; + + idx = node->value.builtin - BT_FIRST_USER; + real_from_string (&real, lazy_hex_fp_values[idx].hex_str); + real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str), + lazy_hex_fp_values[idx].digits, 0, + lazy_hex_fp_values[idx].mode); + + sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[idx].fp_suffix); + node->flags &= ~(NODE_BUILTIN | NODE_USED); + node->value.macro = lazy_hex_fp_values[idx].macro; + for (idx = 0; idx < node->value.macro->count; idx++) + if (node->value.macro->exp.tokens[idx].type == CPP_NUMBER) + break; + gcc_assert (idx < node->value.macro->count); + node->value.macro->exp.tokens[idx].val.str.len = strlen (buf1); + node->value.macro->exp.tokens[idx].val.str.text + = (const unsigned char *) xstrdup (buf1); + return true; +} + /* Pass an object-like macro a hexadecimal floating-point value. */ static void builtin_define_with_hex_fp_value (const char *macro, @@ -957,6 +1002,29 @@ builtin_define_with_hex_fp_value (const char *macro, REAL_VALUE_TYPE real; char dec_str[64], buf1[256], buf2[256]; + /* This is very expensive, so if possible expand them lazily. */ + if (lazy_hex_fp_value_count < 12 + && flag_dump_macros == 0 + && !cpp_get_options (parse_in)->traditional) + { + struct cpp_hashnode *node; + if (lazy_hex_fp_value_count == 0) + cpp_get_callbacks (parse_in)->user_builtin_macro = lazy_hex_fp_value; + sprintf (buf2, fp_cast, "1.1"); + sprintf (buf1, "%s=%s", macro, buf2); + cpp_define (parse_in, buf1); + node = C_CPP_HASHNODE (get_identifier (macro)); + lazy_hex_fp_values[lazy_hex_fp_value_count].hex_str = xstrdup (hex_str); + lazy_hex_fp_values[lazy_hex_fp_value_count].mode = TYPE_MODE (type); + lazy_hex_fp_values[lazy_hex_fp_value_count].digits = digits; + lazy_hex_fp_values[lazy_hex_fp_value_count].fp_suffix = fp_suffix; + lazy_hex_fp_values[lazy_hex_fp_value_count].macro = node->value.macro; + node->flags |= NODE_BUILTIN; + node->value.builtin = BT_FIRST_USER + lazy_hex_fp_value_count; + lazy_hex_fp_value_count++; + return; + } + /* Hex values are really cool and convenient, except that they're not supported in strict ISO C90 mode. First, the "p-" sequence is not valid as part of a preprocessor number. Second, we get a diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index d52da05f937..2b3d224913f 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,17 @@ +2010-06-11 Jakub Jelinek + + * include/cpplib.h (struct cpp_callbacks): Add user_builtin_macro + callback. + (enum cpp_builtin_type): Add BT_FIRST_USER and BT_LAST_USER. + (cpp_macro_definition): Remove const qual from second argument. + * macro.c (enter_macro_context): Call user_builtin_macro callback for + NODE_BUILTIN !NODE_USED macros. + (warn_of_redefinition): Likewise. Remove const qual from second + argument. + (cpp_macro_definition): Likewise. + * pch.c (write_macdef, save_macros): Call user_builtin_macro callback + for NODE_BUILTIN !NODE_USED macros. + 2010-06-10 Joseph Myers * include/cpplib.h (struct cpp_options): Remove show_column. diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index ba79262f6cd..87d368e2925 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -509,6 +509,9 @@ struct cpp_callbacks /* Called whenever a macro is expanded or tested. Second argument is the location of the start of the current expansion. */ void (*used) (cpp_reader *, source_location, cpp_hashnode *); + + /* Callback that can change a user builtin into normal macro. */ + bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *); }; #ifdef VMS @@ -599,7 +602,9 @@ enum cpp_builtin_type BT_STDC, /* `__STDC__' */ BT_PRAGMA, /* `_Pragma' operator */ BT_TIMESTAMP, /* `__TIMESTAMP__' */ - BT_COUNTER /* `__COUNTER__' */ + BT_COUNTER, /* `__COUNTER__' */ + BT_FIRST_USER, /* User defined builtin macros. */ + BT_LAST_USER = BT_FIRST_USER + 31 }; #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) @@ -726,7 +731,7 @@ extern const cpp_token *cpp_get_token (cpp_reader *); extern const cpp_token *cpp_get_token_with_location (cpp_reader *, source_location *); extern const unsigned char *cpp_macro_definition (cpp_reader *, - const cpp_hashnode *); + cpp_hashnode *); extern void _cpp_backup_tokens (cpp_reader *, unsigned int); extern const cpp_token *cpp_peek_token (cpp_reader *, int); diff --git a/libcpp/macro.c b/libcpp/macro.c index cbb0b0e7159..31de4156c64 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -65,7 +65,7 @@ static bool create_iso_definition (cpp_reader *, cpp_macro *); static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *); static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *); -static bool warn_of_redefinition (cpp_reader *, const cpp_hashnode *, +static bool warn_of_redefinition (cpp_reader *, cpp_hashnode *, const cpp_macro *); static bool parse_params (cpp_reader *, cpp_macro *); static void check_trad_stringification (cpp_reader *, const cpp_macro *, @@ -835,7 +835,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, if ((node->flags & NODE_BUILTIN) && !(node->flags & NODE_USED)) { node->flags |= NODE_USED; - if (pfile->cb.used_define) + if ((!pfile->cb.user_builtin_macro + || !pfile->cb.user_builtin_macro (pfile, node)) + && pfile->cb.used_define) pfile->cb.used_define (pfile, pfile->directive_line, node); } @@ -1430,7 +1432,7 @@ _cpp_backup_tokens (cpp_reader *pfile, unsigned int count) /* Returns nonzero if a macro redefinition warning is required. */ static bool -warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node, +warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node, const cpp_macro *macro2) { const cpp_macro *macro1; @@ -1442,7 +1444,11 @@ warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node, /* Suppress warnings for builtins that lack the NODE_WARN flag. */ if (node->flags & NODE_BUILTIN) - return false; + { + if (!pfile->cb.user_builtin_macro + || !pfile->cb.user_builtin_macro (pfile, node)) + return false; + } /* Redefinitions of conditional (context-sensitive) macros, on the other hand, must be allowed silently. */ @@ -1982,19 +1988,26 @@ check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, Caller is expected to generate the "#define" bit if needed. The returned text is temporary, and automatically freed later. */ const unsigned char * -cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node) +cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node) { unsigned int i, len; - const cpp_macro *macro = node->value.macro; + const cpp_macro *macro; unsigned char *buffer; if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN)) { - cpp_error (pfile, CPP_DL_ICE, - "invalid hash type %d in cpp_macro_definition", node->type); - return 0; + if (node->type != NT_MACRO + || !pfile->cb.user_builtin_macro + || !pfile->cb.user_builtin_macro (pfile, node)) + { + cpp_error (pfile, CPP_DL_ICE, + "invalid hash type %d in cpp_macro_definition", + node->type); + return 0; + } } + macro = node->value.macro; /* Calculate length. */ len = NODE_LEN (node) + 2; /* ' ' and NUL. */ if (macro->fun_like) diff --git a/libcpp/pch.c b/libcpp/pch.c index 2fb7ba543e7..a6d8cea38d3 100644 --- a/libcpp/pch.c +++ b/libcpp/pch.c @@ -58,7 +58,9 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) return 1; case NT_MACRO: - if ((hn->flags & NODE_BUILTIN)) + if ((hn->flags & NODE_BUILTIN) + && (!pfile->cb.user_builtin_macro + || !pfile->cb.user_builtin_macro (pfile, hn))) return 1; { @@ -759,6 +761,12 @@ static int save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) { struct save_macro_data *data = (struct save_macro_data *)data_p; + + if ((h->flags & NODE_BUILTIN) + && h->type == NT_MACRO + && r->cb.user_builtin_macro) + r->cb.user_builtin_macro (r, h); + if (h->type != NT_VOID && (h->flags & NODE_BUILTIN) == 0) {