cpplib.h (struct cpp_callbacks): Add user_builtin_macro callback.
authorJakub Jelinek <jakub@redhat.com>
Fri, 11 Jun 2010 18:37:34 +0000 (20:37 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 11 Jun 2010 18:37:34 +0000 (20:37 +0200)
* 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
gcc/Makefile.in
gcc/c-family/c-cppbuiltin.c
libcpp/ChangeLog
libcpp/include/cpplib.h
libcpp/macro.c
libcpp/pch.c

index 5d32047ee212d9d7da1e46e7a0185638cf845345..c52a81bbc22651ee1a1d12ecbb4922ad1b453b79 100644 (file)
@@ -1,3 +1,11 @@
+2010-06-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * 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  <sebastian.pop@amd.com>
 
        PR middle-end/44483
index c47ee954d2b799a828c0e41ecb448c4c2858a3f1..0d4f746a95ad8525c34c98a2f2fd1eec199e2695 100644 (file)
@@ -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)
 
index 6bbdb460e7ad5b7e0945ed86009c3e38bdc9175d..4ed6975e45b00bd2ed618543a5255e18f3aa3f9b 100644 (file)
@@ -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
index d52da05f937cf721d733a381c564b4bf0cd10c85..2b3d224913f37c22d078aa9f08bbaa86680286ed 100644 (file)
@@ -1,3 +1,17 @@
+2010-06-11  Jakub Jelinek  <jakub@redhat.com>
+
+       * 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  <joseph@codesourcery.com>
 
        * include/cpplib.h (struct cpp_options): Remove show_column.
index ba79262f6cd1de0860f9dcf462f40032f9d1e46f..87d368e292541d4242f2c2b43d9b60b84d2ca7de 100644 (file)
@@ -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);
 
index cbb0b0e715937db6745a99df6ba81c8b75914c7c..31de4156c6420fa04399f4921ada0b297a836b6f 100644 (file)
@@ -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)
index 2fb7ba543e787e52f87d928fe0d04938ddfece8b..a6d8cea38d3c5df56b96f0d8e434bce52095cf52 100644 (file)
@@ -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)
     {