@@ -1,6 +1,6 @@
/* Definitions for CPP library.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2007, 2008, 2009
+ 2004, 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
@@ -512,6 +512,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
@@ -602,7 +605,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))
@@ -729,7 +734,7 @@ extern const cpp_token *cpp_get_token (c
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);
@@ -65,7 +65,7 @@ static bool create_iso_definition (cpp_r
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,
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, u
/* 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,
/* 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 *
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)
@@ -58,7 +58,9 @@ write_macdef (cpp_reader *pfile, cpp_has
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)
{
@@ -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.
#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 cha
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
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
@@ -2076,7 +2076,7 @@ c-family/c-common.o : c-family/c-common.
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)