mirror of git://gcc.gnu.org/git/gcc.git
Makefile.in: Update.
* Makefile.in: Update. * c-common.c: Don't include real.h or except.h. (REGISTER_PREFIX): Remove. (builtin_define_std, builtin_define_with_value, builtin_define_with_int_value, builtin_define_with_hex_fp_value, builtin_define_type_max, builtin_define_type_precision, builtin_define_float_constants): Move to c-cppbuiltin.c. (c_stddef_cpp_builtins): New. * c-common.h (builtin_define_with_value, c_stddef_cpp_builtins): New. * c-cppbuiltin.c: New, extracted from c-common.c. (define__GNUC__): New. * cppspec.c (lang_specific_driver): Remove support of -no-gcc. * gcc.c: Remove support of %v1, %v2 and %v3 specs. (cpp_unique_options): Don't support no-gcc. (do_spec_1): Remove support of version specs. * doc/invoke.texi: Remove documentation of %v1, %v2 and %v3. * doc/passes.texi: Update. * doc/tm.texi: Update. cp: * Make-lang.in (CXX_C_OBJS): Update. * lang-specs.h: Don't define __GNUG__ here. From-SVN: r64162
This commit is contained in:
parent
5858cd26b2
commit
cb60f38d5b
|
@ -1,3 +1,24 @@
|
|||
2003-03-11 Neil Booth <neil@daikokuya.co.uk>
|
||||
|
||||
* Makefile.in: Update.
|
||||
* c-common.c: Don't include real.h or except.h.
|
||||
(REGISTER_PREFIX): Remove.
|
||||
(builtin_define_std, builtin_define_with_value,
|
||||
builtin_define_with_int_value, builtin_define_with_hex_fp_value,
|
||||
builtin_define_type_max, builtin_define_type_precision,
|
||||
builtin_define_float_constants): Move to c-cppbuiltin.c.
|
||||
(c_stddef_cpp_builtins): New.
|
||||
* c-common.h (builtin_define_with_value, c_stddef_cpp_builtins): New.
|
||||
* c-cppbuiltin.c: New, extracted from c-common.c.
|
||||
(define__GNUC__): New.
|
||||
* cppspec.c (lang_specific_driver): Remove support of -no-gcc.
|
||||
* gcc.c: Remove support of %v1, %v2 and %v3 specs.
|
||||
(cpp_unique_options): Don't support no-gcc.
|
||||
(do_spec_1): Remove support of version specs.
|
||||
* doc/invoke.texi: Remove documentation of %v1, %v2 and %v3.
|
||||
* doc/passes.texi: Update.
|
||||
* doc/tm.texi: Update.
|
||||
|
||||
2003-03-10 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
* dwarf2out.c (multiple_reg_loc_descriptor): Fix thinko.
|
||||
|
|
|
@ -760,7 +760,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@
|
|||
# Language-specific object files for C and Objective C.
|
||||
C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
|
||||
c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
|
||||
c-incpath.o cppdefault.o c-ppoutput.o \
|
||||
c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o \
|
||||
c-objc-common.o c-dump.o c-pch.o libcpp.a $(C_TARGET_OBJS)
|
||||
|
||||
# Language-specific object files for C.
|
||||
|
@ -1273,9 +1273,9 @@ tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h
|
|||
# A file used by all variants of C.
|
||||
|
||||
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(OBSTACK_H) $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) \
|
||||
$(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
|
||||
diagnostic.h except.h gt-c-common.h real.h langhooks.h varray.h
|
||||
$(OBSTACK_H) $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h \
|
||||
$(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \
|
||||
diagnostic.h gt-c-common.h langhooks.h varray.h $(RTL_H) $(TARGET_H)
|
||||
c-pretty-print.o : c-pretty-print.c c-pretty-print.h pretty-print.h \
|
||||
$(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h
|
||||
|
||||
|
@ -1283,6 +1283,10 @@ c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_CO
|
|||
c-pragma.h flags.h toplev.h langhooks.h tree-inline.h diagnostic.h \
|
||||
intl.h
|
||||
|
||||
c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(C_COMMON_H) c-pragma.h flags.h toplev.h langhooks.h \
|
||||
output.h except.h real.h
|
||||
|
||||
# A file used by all variants of C and some other languages.
|
||||
|
||||
attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h \
|
||||
|
|
473
gcc/c-common.c
473
gcc/c-common.c
|
@ -1,6 +1,6 @@
|
|||
/* Subroutines shared by all languages that are variants of C.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002 Free Software Foundation, Inc.
|
||||
2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -24,7 +24,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "real.h"
|
||||
#include "flags.h"
|
||||
#include "toplev.h"
|
||||
#include "output.h"
|
||||
|
@ -40,9 +39,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "cpplib.h"
|
||||
#include "target.h"
|
||||
#include "langhooks.h"
|
||||
#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
|
||||
#include "tree-inline.h"
|
||||
|
||||
|
||||
cpp_reader *parse_in; /* Declared in c-pragma.h. */
|
||||
|
||||
/* We let tm.h override the types used here, to handle trivial differences
|
||||
|
@ -87,10 +86,6 @@ cpp_reader *parse_in; /* Declared in c-pragma.h. */
|
|||
: "long long unsigned int"))
|
||||
#endif
|
||||
|
||||
#ifndef REGISTER_PREFIX
|
||||
#define REGISTER_PREFIX ""
|
||||
#endif
|
||||
|
||||
/* The variant of the C language being processed. */
|
||||
|
||||
enum c_language_kind c_language;
|
||||
|
@ -806,18 +801,6 @@ static void check_nonnull_arg PARAMS ((void *, tree,
|
|||
static bool nonnull_check_p PARAMS ((tree, unsigned HOST_WIDE_INT));
|
||||
static bool get_nonnull_operand PARAMS ((tree,
|
||||
unsigned HOST_WIDE_INT *));
|
||||
void builtin_define_std PARAMS ((const char *));
|
||||
static void builtin_define_with_value PARAMS ((const char *, const char *,
|
||||
int));
|
||||
static void builtin_define_with_int_value PARAMS ((const char *,
|
||||
HOST_WIDE_INT));
|
||||
static void builtin_define_with_hex_fp_value PARAMS ((const char *, tree,
|
||||
int, const char *,
|
||||
const char *));
|
||||
static void builtin_define_type_max PARAMS ((const char *, tree, int));
|
||||
static void builtin_define_type_precision PARAMS ((const char *, tree));
|
||||
static void builtin_define_float_constants PARAMS ((const char *,
|
||||
const char *, tree));
|
||||
|
||||
/* Table of machine-independent attributes common to all C-like languages. */
|
||||
const struct attribute_spec c_common_attribute_table[] =
|
||||
|
@ -4761,461 +4744,15 @@ boolean_increment (code, arg)
|
|||
return val;
|
||||
}
|
||||
|
||||
/* Define NAME with value TYPE precision. */
|
||||
static void
|
||||
builtin_define_type_precision (name, type)
|
||||
const char *name;
|
||||
tree type;
|
||||
{
|
||||
builtin_define_with_int_value (name, TYPE_PRECISION (type));
|
||||
}
|
||||
|
||||
/* Define the float.h constants for TYPE using NAME_PREFIX and FP_SUFFIX. */
|
||||
static void
|
||||
builtin_define_float_constants (name_prefix, fp_suffix, type)
|
||||
const char *name_prefix;
|
||||
const char *fp_suffix;
|
||||
tree type;
|
||||
{
|
||||
/* Used to convert radix-based values to base 10 values in several cases.
|
||||
|
||||
In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at
|
||||
least 6 significant digits for correct results. Using the fraction
|
||||
formed by (log(2)*1e6)/(log(10)*1e6) overflows a 32-bit integer as an
|
||||
intermediate; perhaps someone can find a better approximation, in the
|
||||
mean time, I suspect using doubles won't harm the bootstrap here. */
|
||||
|
||||
const double log10_2 = .30102999566398119521;
|
||||
double log10_b;
|
||||
const struct real_format *fmt;
|
||||
|
||||
char name[64], buf[128];
|
||||
int dig, min_10_exp, max_10_exp;
|
||||
int decimal_dig;
|
||||
|
||||
fmt = real_format_for_mode[TYPE_MODE (type) - QFmode];
|
||||
|
||||
/* The radix of the exponent representation. */
|
||||
if (type == float_type_node)
|
||||
builtin_define_with_int_value ("__FLT_RADIX__", fmt->b);
|
||||
log10_b = log10_2 * fmt->log2_b;
|
||||
|
||||
/* The number of radix digits, p, in the floating-point significand. */
|
||||
sprintf (name, "__%s_MANT_DIG__", name_prefix);
|
||||
builtin_define_with_int_value (name, fmt->p);
|
||||
|
||||
/* The number of decimal digits, q, such that any floating-point number
|
||||
with q decimal digits can be rounded into a floating-point number with
|
||||
p radix b digits and back again without change to the q decimal digits,
|
||||
|
||||
p log10 b if b is a power of 10
|
||||
floor((p - 1) log10 b) otherwise
|
||||
*/
|
||||
dig = (fmt->p - 1) * log10_b;
|
||||
sprintf (name, "__%s_DIG__", name_prefix);
|
||||
builtin_define_with_int_value (name, dig);
|
||||
|
||||
/* The minimum negative int x such that b**(x-1) is a normalized float. */
|
||||
sprintf (name, "__%s_MIN_EXP__", name_prefix);
|
||||
sprintf (buf, "(%d)", fmt->emin);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
|
||||
/* The minimum negative int x such that 10**x is a normalized float,
|
||||
|
||||
ceil (log10 (b ** (emin - 1)))
|
||||
= ceil (log10 (b) * (emin - 1))
|
||||
|
||||
Recall that emin is negative, so the integer truncation calculates
|
||||
the ceiling, not the floor, in this case. */
|
||||
min_10_exp = (fmt->emin - 1) * log10_b;
|
||||
sprintf (name, "__%s_MIN_10_EXP__", name_prefix);
|
||||
sprintf (buf, "(%d)", min_10_exp);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
|
||||
/* The maximum int x such that b**(x-1) is a representable float. */
|
||||
sprintf (name, "__%s_MAX_EXP__", name_prefix);
|
||||
builtin_define_with_int_value (name, fmt->emax);
|
||||
|
||||
/* The maximum int x such that 10**x is in the range of representable
|
||||
finite floating-point numbers,
|
||||
|
||||
floor (log10((1 - b**-p) * b**emax))
|
||||
= floor (log10(1 - b**-p) + log10(b**emax))
|
||||
= floor (log10(1 - b**-p) + log10(b)*emax)
|
||||
|
||||
The safest thing to do here is to just compute this number. But since
|
||||
we don't link cc1 with libm, we cannot. We could implement log10 here
|
||||
a series expansion, but that seems too much effort because:
|
||||
|
||||
Note that the first term, for all extant p, is a number exceedingly close
|
||||
to zero, but slightly negative. Note that the second term is an integer
|
||||
scaling an irrational number, and that because of the floor we are only
|
||||
interested in its integral portion.
|
||||
|
||||
In order for the first term to have any effect on the integral portion
|
||||
of the second term, the second term has to be exceedingly close to an
|
||||
integer itself (e.g. 123.000000000001 or something). Getting a result
|
||||
that close to an integer requires that the irrational multiplicand have
|
||||
a long series of zeros in its expansion, which doesn't occur in the
|
||||
first 20 digits or so of log10(b).
|
||||
|
||||
Hand-waving aside, crunching all of the sets of constants above by hand
|
||||
does not yield a case for which the first term is significant, which
|
||||
in the end is all that matters. */
|
||||
max_10_exp = fmt->emax * log10_b;
|
||||
sprintf (name, "__%s_MAX_10_EXP__", name_prefix);
|
||||
builtin_define_with_int_value (name, max_10_exp);
|
||||
|
||||
/* The number of decimal digits, n, such that any floating-point number
|
||||
can be rounded to n decimal digits and back again without change to
|
||||
the value.
|
||||
|
||||
p * log10(b) if b is a power of 10
|
||||
ceil(1 + p * log10(b)) otherwise
|
||||
|
||||
The only macro we care about is this number for the widest supported
|
||||
floating type, but we want this value for rendering constants below. */
|
||||
{
|
||||
double d_decimal_dig = 1 + fmt->p * log10_b;
|
||||
decimal_dig = d_decimal_dig;
|
||||
if (decimal_dig < d_decimal_dig)
|
||||
decimal_dig++;
|
||||
}
|
||||
if (type == long_double_type_node)
|
||||
builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig);
|
||||
|
||||
/* Since, for the supported formats, B is always a power of 2, we
|
||||
construct the following numbers directly as a hexadecimal
|
||||
constants. */
|
||||
|
||||
/* The maximum representable finite floating-point number,
|
||||
(1 - b**-p) * b**emax */
|
||||
{
|
||||
int i, n;
|
||||
char *p;
|
||||
|
||||
strcpy (buf, "0x0.");
|
||||
n = fmt->p * fmt->log2_b;
|
||||
for (i = 0, p = buf + 4; i + 3 < n; i += 4)
|
||||
*p++ = 'f';
|
||||
if (i < n)
|
||||
*p++ = "08ce"[n - i];
|
||||
sprintf (p, "p%d", fmt->emax * fmt->log2_b);
|
||||
}
|
||||
sprintf (name, "__%s_MAX__", name_prefix);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
|
||||
|
||||
/* The minimum normalized positive floating-point number,
|
||||
b**(emin-1). */
|
||||
sprintf (name, "__%s_MIN__", name_prefix);
|
||||
sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
|
||||
|
||||
/* The difference between 1 and the least value greater than 1 that is
|
||||
representable in the given floating point type, b**(1-p). */
|
||||
sprintf (name, "__%s_EPSILON__", name_prefix);
|
||||
sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
|
||||
|
||||
/* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized
|
||||
positive floating-point number, b**(emin-p). Zero for formats that
|
||||
don't support denormals. */
|
||||
sprintf (name, "__%s_DENORM_MIN__", name_prefix);
|
||||
if (fmt->has_denorm)
|
||||
{
|
||||
sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig,
|
||||
buf, fp_suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (buf, "0.0%s", fp_suffix);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
}
|
||||
|
||||
/* For C++ std::numeric_limits<T>::has_infinity. */
|
||||
sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
|
||||
builtin_define_with_int_value (name,
|
||||
MODE_HAS_INFINITIES (TYPE_MODE (type)));
|
||||
/* For C++ std::numeric_limits<T>::has_quiet_NaN. We do not have a
|
||||
predicate to distinguish a target that has both quiet and
|
||||
signalling NaNs from a target that has only quiet NaNs or only
|
||||
signalling NaNs, so we assume that a target that has any kind of
|
||||
NaN has quiet NaNs. */
|
||||
sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
|
||||
builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
|
||||
}
|
||||
|
||||
/* Hook that registers front end and target-specific built-ins. */
|
||||
/* Built-in macros for stddef.h, that require macros defined in this
|
||||
file. */
|
||||
void
|
||||
cb_register_builtins (pfile)
|
||||
cpp_reader *pfile;
|
||||
c_stddef_cpp_builtins()
|
||||
{
|
||||
/* -undef turns off target-specific built-ins. */
|
||||
if (flag_undef)
|
||||
return;
|
||||
|
||||
if (c_language == clk_cplusplus)
|
||||
{
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
cpp_define (pfile, "__GXX_WEAK__=1");
|
||||
else
|
||||
cpp_define (pfile, "__GXX_WEAK__=0");
|
||||
if (flag_exceptions)
|
||||
cpp_define (pfile, "__EXCEPTIONS");
|
||||
if (warn_deprecated)
|
||||
cpp_define (pfile, "__DEPRECATED");
|
||||
}
|
||||
|
||||
/* represents the C++ ABI version, always defined so it can be used while
|
||||
preprocessing C and assembler. */
|
||||
cpp_define (pfile, "__GXX_ABI_VERSION=102");
|
||||
|
||||
/* libgcc needs to know this. */
|
||||
if (USING_SJLJ_EXCEPTIONS)
|
||||
cpp_define (pfile, "__USING_SJLJ_EXCEPTIONS__");
|
||||
|
||||
/* stddef.h needs to know these. */
|
||||
builtin_define_with_value ("__SIZE_TYPE__", SIZE_TYPE, 0);
|
||||
builtin_define_with_value ("__PTRDIFF_TYPE__", PTRDIFF_TYPE, 0);
|
||||
builtin_define_with_value ("__WCHAR_TYPE__", MODIFIED_WCHAR_TYPE, 0);
|
||||
builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0);
|
||||
|
||||
/* limits.h needs to know these. */
|
||||
builtin_define_type_max ("__SCHAR_MAX__", signed_char_type_node, 0);
|
||||
builtin_define_type_max ("__SHRT_MAX__", short_integer_type_node, 0);
|
||||
builtin_define_type_max ("__INT_MAX__", integer_type_node, 0);
|
||||
builtin_define_type_max ("__LONG_MAX__", long_integer_type_node, 1);
|
||||
builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node, 2);
|
||||
builtin_define_type_max ("__WCHAR_MAX__", wchar_type_node, 0);
|
||||
|
||||
builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
|
||||
|
||||
/* float.h needs to know these. */
|
||||
|
||||
builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
|
||||
TARGET_FLT_EVAL_METHOD);
|
||||
|
||||
builtin_define_float_constants ("FLT", "F", float_type_node);
|
||||
builtin_define_float_constants ("DBL", "", double_type_node);
|
||||
builtin_define_float_constants ("LDBL", "L", long_double_type_node);
|
||||
|
||||
/* For use in assembly language. */
|
||||
builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
|
||||
builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);
|
||||
|
||||
/* Misc. */
|
||||
builtin_define_with_value ("__VERSION__", version_string, 1);
|
||||
|
||||
/* Other target-independent built-ins determined by command-line
|
||||
options. */
|
||||
if (optimize_size)
|
||||
cpp_define (pfile, "__OPTIMIZE_SIZE__");
|
||||
if (optimize)
|
||||
cpp_define (pfile, "__OPTIMIZE__");
|
||||
|
||||
if (flag_hosted)
|
||||
cpp_define (pfile, "__STDC_HOSTED__=1");
|
||||
else
|
||||
cpp_define (pfile, "__STDC_HOSTED__=0");
|
||||
|
||||
if (fast_math_flags_set_p ())
|
||||
cpp_define (pfile, "__FAST_MATH__");
|
||||
if (flag_really_no_inline)
|
||||
cpp_define (pfile, "__NO_INLINE__");
|
||||
if (flag_signaling_nans)
|
||||
cpp_define (pfile, "__SUPPORT_SNAN__");
|
||||
if (flag_finite_math_only)
|
||||
cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
|
||||
else
|
||||
cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
|
||||
|
||||
if (flag_iso)
|
||||
cpp_define (pfile, "__STRICT_ANSI__");
|
||||
|
||||
if (!flag_signed_char)
|
||||
cpp_define (pfile, "__CHAR_UNSIGNED__");
|
||||
|
||||
if (c_language == clk_cplusplus && TREE_UNSIGNED (wchar_type_node))
|
||||
cpp_define (pfile, "__WCHAR_UNSIGNED__");
|
||||
|
||||
/* Make the choice of ObjC runtime visible to source code. */
|
||||
if (flag_objc && flag_next_runtime)
|
||||
cpp_define (pfile, "__NEXT_RUNTIME__");
|
||||
|
||||
/* A straightforward target hook doesn't work, because of problems
|
||||
linking that hook's body when part of non-C front ends. */
|
||||
# define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
|
||||
# define preprocessing_trad_p() (cpp_get_options (pfile)->traditional)
|
||||
# define builtin_define(TXT) cpp_define (pfile, TXT)
|
||||
# define builtin_assert(TXT) cpp_assert (pfile, TXT)
|
||||
TARGET_CPU_CPP_BUILTINS ();
|
||||
TARGET_OS_CPP_BUILTINS ();
|
||||
}
|
||||
|
||||
/* Pass an object-like macro. If it doesn't lie in the user's
|
||||
namespace, defines it unconditionally. Otherwise define a version
|
||||
with two leading underscores, and another version with two leading
|
||||
and trailing underscores, and define the original only if an ISO
|
||||
standard was not nominated.
|
||||
|
||||
e.g. passing "unix" defines "__unix", "__unix__" and possibly
|
||||
"unix". Passing "_mips" defines "__mips", "__mips__" and possibly
|
||||
"_mips". */
|
||||
void
|
||||
builtin_define_std (macro)
|
||||
const char *macro;
|
||||
{
|
||||
size_t len = strlen (macro);
|
||||
char *buff = alloca (len + 5);
|
||||
char *p = buff + 2;
|
||||
char *q = p + len;
|
||||
|
||||
/* prepend __ (or maybe just _) if in user's namespace. */
|
||||
memcpy (p, macro, len + 1);
|
||||
if (!( *p == '_' && (p[1] == '_' || ISUPPER (p[1]))))
|
||||
{
|
||||
if (*p != '_')
|
||||
*--p = '_';
|
||||
if (p[1] != '_')
|
||||
*--p = '_';
|
||||
}
|
||||
cpp_define (parse_in, p);
|
||||
|
||||
/* If it was in user's namespace... */
|
||||
if (p != buff + 2)
|
||||
{
|
||||
/* Define the macro with leading and following __. */
|
||||
if (q[-1] != '_')
|
||||
*q++ = '_';
|
||||
if (q[-2] != '_')
|
||||
*q++ = '_';
|
||||
*q = '\0';
|
||||
cpp_define (parse_in, p);
|
||||
|
||||
/* Finally, define the original macro if permitted. */
|
||||
if (!flag_iso)
|
||||
cpp_define (parse_in, macro);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass an object-like macro and a value to define it to. The third
|
||||
parameter says whether or not to turn the value into a string
|
||||
constant. */
|
||||
static void
|
||||
builtin_define_with_value (macro, expansion, is_str)
|
||||
const char *macro;
|
||||
const char *expansion;
|
||||
int is_str;
|
||||
{
|
||||
char *buf;
|
||||
size_t mlen = strlen (macro);
|
||||
size_t elen = strlen (expansion);
|
||||
size_t extra = 2; /* space for an = and a NUL */
|
||||
|
||||
if (is_str)
|
||||
extra += 2; /* space for two quote marks */
|
||||
|
||||
buf = alloca (mlen + elen + extra);
|
||||
if (is_str)
|
||||
sprintf (buf, "%s=\"%s\"", macro, expansion);
|
||||
else
|
||||
sprintf (buf, "%s=%s", macro, expansion);
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
/* Pass an object-like macro and an integer value to define it to. */
|
||||
static void
|
||||
builtin_define_with_int_value (macro, value)
|
||||
const char *macro;
|
||||
HOST_WIDE_INT value;
|
||||
{
|
||||
char *buf;
|
||||
size_t mlen = strlen (macro);
|
||||
size_t vlen = 18;
|
||||
size_t extra = 2; /* space for = and NUL. */
|
||||
|
||||
buf = alloca (mlen + vlen + extra);
|
||||
memcpy (buf, macro, mlen);
|
||||
buf[mlen] = '=';
|
||||
sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value);
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
/* Pass an object-like macro a hexadecimal floating-point value. */
|
||||
static void
|
||||
builtin_define_with_hex_fp_value (macro, type, digits, hex_str, fp_suffix)
|
||||
const char *macro;
|
||||
tree type ATTRIBUTE_UNUSED;
|
||||
int digits;
|
||||
const char *hex_str;
|
||||
const char *fp_suffix;
|
||||
{
|
||||
REAL_VALUE_TYPE real;
|
||||
char dec_str[64], buf[256];
|
||||
|
||||
/* 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
|
||||
pedwarn from the preprocessor, which has no context, so we can't
|
||||
suppress the warning with __extension__.
|
||||
|
||||
So instead what we do is construct the number in hex (because
|
||||
it's easy to get the exact correct value), parse it as a real,
|
||||
then print it back out as decimal. */
|
||||
|
||||
real_from_string (&real, hex_str);
|
||||
real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
|
||||
|
||||
sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
/* Define MAX for TYPE based on the precision of the type. IS_LONG is
|
||||
1 for type "long" and 2 for "long long". We have to handle
|
||||
unsigned types, since wchar_t might be unsigned. */
|
||||
|
||||
static void
|
||||
builtin_define_type_max (macro, type, is_long)
|
||||
const char *macro;
|
||||
tree type;
|
||||
int is_long;
|
||||
{
|
||||
static const char *const values[]
|
||||
= { "127", "255",
|
||||
"32767", "65535",
|
||||
"2147483647", "4294967295",
|
||||
"9223372036854775807", "18446744073709551615",
|
||||
"170141183460469231731687303715884105727",
|
||||
"340282366920938463463374607431768211455" };
|
||||
static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
|
||||
|
||||
const char *value, *suffix;
|
||||
char *buf;
|
||||
size_t idx;
|
||||
|
||||
/* Pre-rendering the values mean we don't have to futz with printing a
|
||||
multi-word decimal value. There are also a very limited number of
|
||||
precisions that we support, so it's really a waste of time. */
|
||||
switch (TYPE_PRECISION (type))
|
||||
{
|
||||
case 8: idx = 0; break;
|
||||
case 16: idx = 2; break;
|
||||
case 32: idx = 4; break;
|
||||
case 64: idx = 6; break;
|
||||
case 128: idx = 8; break;
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
value = values[idx + TREE_UNSIGNED (type)];
|
||||
suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
|
||||
|
||||
buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
|
||||
sprintf (buf, "%s=%s%s", macro, value, suffix);
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1292,6 +1292,9 @@ extern void c_common_read_pch PARAMS ((cpp_reader *pfile,
|
|||
int fd,
|
||||
const char *orig));
|
||||
extern void c_common_write_pch PARAMS ((void));
|
||||
extern void builtin_define_with_value PARAMS ((const char *,
|
||||
const char *, int));
|
||||
extern void c_stddef_cpp_builtins PARAMS ((void));
|
||||
|
||||
/* In c-ppoutput.c */
|
||||
extern void init_pp_output PARAMS ((FILE *));
|
||||
|
|
|
@ -0,0 +1,570 @@
|
|||
/* Define builtin-in macros for the C family front ends.
|
||||
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "flags.h"
|
||||
#include "real.h"
|
||||
#include "c-common.h"
|
||||
#include "c-pragma.h"
|
||||
#include "output.h"
|
||||
#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
|
||||
#include "toplev.h"
|
||||
|
||||
#ifndef REGISTER_PREFIX
|
||||
#define REGISTER_PREFIX ""
|
||||
#endif
|
||||
|
||||
static void builtin_define_std PARAMS ((const char *));
|
||||
static void builtin_define_with_value_n PARAMS ((const char *, const char *,
|
||||
size_t));
|
||||
static void builtin_define_with_int_value PARAMS ((const char *,
|
||||
HOST_WIDE_INT));
|
||||
static void builtin_define_with_hex_fp_value PARAMS ((const char *, tree,
|
||||
int, const char *,
|
||||
const char *));
|
||||
static void builtin_define_type_max PARAMS ((const char *, tree, int));
|
||||
static void builtin_define_type_precision PARAMS ((const char *, tree));
|
||||
static void builtin_define_float_constants PARAMS ((const char *,
|
||||
const char *, tree));
|
||||
static void define__GNUC__ PARAMS ((void));
|
||||
|
||||
/* Define NAME with value TYPE precision. */
|
||||
static void
|
||||
builtin_define_type_precision (name, type)
|
||||
const char *name;
|
||||
tree type;
|
||||
{
|
||||
builtin_define_with_int_value (name, TYPE_PRECISION (type));
|
||||
}
|
||||
|
||||
/* Define the float.h constants for TYPE using NAME_PREFIX and FP_SUFFIX. */
|
||||
static void
|
||||
builtin_define_float_constants (name_prefix, fp_suffix, type)
|
||||
const char *name_prefix;
|
||||
const char *fp_suffix;
|
||||
tree type;
|
||||
{
|
||||
/* Used to convert radix-based values to base 10 values in several cases.
|
||||
|
||||
In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at
|
||||
least 6 significant digits for correct results. Using the fraction
|
||||
formed by (log(2)*1e6)/(log(10)*1e6) overflows a 32-bit integer as an
|
||||
intermediate; perhaps someone can find a better approximation, in the
|
||||
mean time, I suspect using doubles won't harm the bootstrap here. */
|
||||
|
||||
const double log10_2 = .30102999566398119521;
|
||||
double log10_b;
|
||||
const struct real_format *fmt;
|
||||
|
||||
char name[64], buf[128];
|
||||
int dig, min_10_exp, max_10_exp;
|
||||
int decimal_dig;
|
||||
|
||||
fmt = real_format_for_mode[TYPE_MODE (type) - QFmode];
|
||||
|
||||
/* The radix of the exponent representation. */
|
||||
if (type == float_type_node)
|
||||
builtin_define_with_int_value ("__FLT_RADIX__", fmt->b);
|
||||
log10_b = log10_2 * fmt->log2_b;
|
||||
|
||||
/* The number of radix digits, p, in the floating-point significand. */
|
||||
sprintf (name, "__%s_MANT_DIG__", name_prefix);
|
||||
builtin_define_with_int_value (name, fmt->p);
|
||||
|
||||
/* The number of decimal digits, q, such that any floating-point number
|
||||
with q decimal digits can be rounded into a floating-point number with
|
||||
p radix b digits and back again without change to the q decimal digits,
|
||||
|
||||
p log10 b if b is a power of 10
|
||||
floor((p - 1) log10 b) otherwise
|
||||
*/
|
||||
dig = (fmt->p - 1) * log10_b;
|
||||
sprintf (name, "__%s_DIG__", name_prefix);
|
||||
builtin_define_with_int_value (name, dig);
|
||||
|
||||
/* The minimum negative int x such that b**(x-1) is a normalized float. */
|
||||
sprintf (name, "__%s_MIN_EXP__", name_prefix);
|
||||
sprintf (buf, "(%d)", fmt->emin);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
|
||||
/* The minimum negative int x such that 10**x is a normalized float,
|
||||
|
||||
ceil (log10 (b ** (emin - 1)))
|
||||
= ceil (log10 (b) * (emin - 1))
|
||||
|
||||
Recall that emin is negative, so the integer truncation calculates
|
||||
the ceiling, not the floor, in this case. */
|
||||
min_10_exp = (fmt->emin - 1) * log10_b;
|
||||
sprintf (name, "__%s_MIN_10_EXP__", name_prefix);
|
||||
sprintf (buf, "(%d)", min_10_exp);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
|
||||
/* The maximum int x such that b**(x-1) is a representable float. */
|
||||
sprintf (name, "__%s_MAX_EXP__", name_prefix);
|
||||
builtin_define_with_int_value (name, fmt->emax);
|
||||
|
||||
/* The maximum int x such that 10**x is in the range of representable
|
||||
finite floating-point numbers,
|
||||
|
||||
floor (log10((1 - b**-p) * b**emax))
|
||||
= floor (log10(1 - b**-p) + log10(b**emax))
|
||||
= floor (log10(1 - b**-p) + log10(b)*emax)
|
||||
|
||||
The safest thing to do here is to just compute this number. But since
|
||||
we don't link cc1 with libm, we cannot. We could implement log10 here
|
||||
a series expansion, but that seems too much effort because:
|
||||
|
||||
Note that the first term, for all extant p, is a number exceedingly close
|
||||
to zero, but slightly negative. Note that the second term is an integer
|
||||
scaling an irrational number, and that because of the floor we are only
|
||||
interested in its integral portion.
|
||||
|
||||
In order for the first term to have any effect on the integral portion
|
||||
of the second term, the second term has to be exceedingly close to an
|
||||
integer itself (e.g. 123.000000000001 or something). Getting a result
|
||||
that close to an integer requires that the irrational multiplicand have
|
||||
a long series of zeros in its expansion, which doesn't occur in the
|
||||
first 20 digits or so of log10(b).
|
||||
|
||||
Hand-waving aside, crunching all of the sets of constants above by hand
|
||||
does not yield a case for which the first term is significant, which
|
||||
in the end is all that matters. */
|
||||
max_10_exp = fmt->emax * log10_b;
|
||||
sprintf (name, "__%s_MAX_10_EXP__", name_prefix);
|
||||
builtin_define_with_int_value (name, max_10_exp);
|
||||
|
||||
/* The number of decimal digits, n, such that any floating-point number
|
||||
can be rounded to n decimal digits and back again without change to
|
||||
the value.
|
||||
|
||||
p * log10(b) if b is a power of 10
|
||||
ceil(1 + p * log10(b)) otherwise
|
||||
|
||||
The only macro we care about is this number for the widest supported
|
||||
floating type, but we want this value for rendering constants below. */
|
||||
{
|
||||
double d_decimal_dig = 1 + fmt->p * log10_b;
|
||||
decimal_dig = d_decimal_dig;
|
||||
if (decimal_dig < d_decimal_dig)
|
||||
decimal_dig++;
|
||||
}
|
||||
if (type == long_double_type_node)
|
||||
builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig);
|
||||
|
||||
/* Since, for the supported formats, B is always a power of 2, we
|
||||
construct the following numbers directly as a hexadecimal
|
||||
constants. */
|
||||
|
||||
/* The maximum representable finite floating-point number,
|
||||
(1 - b**-p) * b**emax */
|
||||
{
|
||||
int i, n;
|
||||
char *p;
|
||||
|
||||
strcpy (buf, "0x0.");
|
||||
n = fmt->p * fmt->log2_b;
|
||||
for (i = 0, p = buf + 4; i + 3 < n; i += 4)
|
||||
*p++ = 'f';
|
||||
if (i < n)
|
||||
*p++ = "08ce"[n - i];
|
||||
sprintf (p, "p%d", fmt->emax * fmt->log2_b);
|
||||
}
|
||||
sprintf (name, "__%s_MAX__", name_prefix);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
|
||||
|
||||
/* The minimum normalized positive floating-point number,
|
||||
b**(emin-1). */
|
||||
sprintf (name, "__%s_MIN__", name_prefix);
|
||||
sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
|
||||
|
||||
/* The difference between 1 and the least value greater than 1 that is
|
||||
representable in the given floating point type, b**(1-p). */
|
||||
sprintf (name, "__%s_EPSILON__", name_prefix);
|
||||
sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
|
||||
|
||||
/* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized
|
||||
positive floating-point number, b**(emin-p). Zero for formats that
|
||||
don't support denormals. */
|
||||
sprintf (name, "__%s_DENORM_MIN__", name_prefix);
|
||||
if (fmt->has_denorm)
|
||||
{
|
||||
sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig,
|
||||
buf, fp_suffix);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (buf, "0.0%s", fp_suffix);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
}
|
||||
|
||||
/* For C++ std::numeric_limits<T>::has_infinity. */
|
||||
sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
|
||||
builtin_define_with_int_value (name,
|
||||
MODE_HAS_INFINITIES (TYPE_MODE (type)));
|
||||
/* For C++ std::numeric_limits<T>::has_quiet_NaN. We do not have a
|
||||
predicate to distinguish a target that has both quiet and
|
||||
signalling NaNs from a target that has only quiet NaNs or only
|
||||
signalling NaNs, so we assume that a target that has any kind of
|
||||
NaN has quiet NaNs. */
|
||||
sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
|
||||
builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
|
||||
}
|
||||
|
||||
/* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. */
|
||||
static void
|
||||
define__GNUC__ ()
|
||||
{
|
||||
/* The format of the version string, enforced below, is
|
||||
([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
|
||||
const char *q, *v = version_string;
|
||||
|
||||
while (*v && ! ISDIGIT (*v))
|
||||
v++;
|
||||
if (!*v || (v > version_string && v[-1] != '-'))
|
||||
abort ();
|
||||
|
||||
q = v;
|
||||
while (ISDIGIT (*v))
|
||||
v++;
|
||||
builtin_define_with_value_n ("__GNUC__", q, v - q);
|
||||
if (c_language == clk_cplusplus)
|
||||
builtin_define_with_value_n ("__GNUG__", q, v - q);
|
||||
|
||||
if (*v != '.' || !ISDIGIT (v[1]))
|
||||
abort ();
|
||||
q = ++v;
|
||||
while (ISDIGIT (*v))
|
||||
v++;
|
||||
builtin_define_with_value_n ("__GNUC_MINOR__", q, v - q);
|
||||
|
||||
if (*v == '.')
|
||||
{
|
||||
if (!ISDIGIT (v[1]))
|
||||
abort ();
|
||||
q = ++v;
|
||||
while (ISDIGIT (*v))
|
||||
v++;
|
||||
builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", q, v - q);
|
||||
}
|
||||
else
|
||||
builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", "0", 1);
|
||||
|
||||
if (*v && *v != ' ' && *v != '-')
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Hook that registers front end and target-specific built-ins. */
|
||||
void
|
||||
cb_register_builtins (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
/* -undef turns off target-specific built-ins. */
|
||||
if (flag_undef)
|
||||
return;
|
||||
|
||||
define__GNUC__ ();
|
||||
|
||||
/* For stddef.h. They require macros defined in c-common.c. */
|
||||
c_stddef_cpp_builtins ();
|
||||
|
||||
if (c_language == clk_cplusplus)
|
||||
{
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
cpp_define (pfile, "__GXX_WEAK__=1");
|
||||
else
|
||||
cpp_define (pfile, "__GXX_WEAK__=0");
|
||||
if (flag_exceptions)
|
||||
cpp_define (pfile, "__EXCEPTIONS");
|
||||
if (warn_deprecated)
|
||||
cpp_define (pfile, "__DEPRECATED");
|
||||
}
|
||||
|
||||
/* represents the C++ ABI version, always defined so it can be used while
|
||||
preprocessing C and assembler. */
|
||||
cpp_define (pfile, "__GXX_ABI_VERSION=102");
|
||||
|
||||
/* libgcc needs to know this. */
|
||||
if (USING_SJLJ_EXCEPTIONS)
|
||||
cpp_define (pfile, "__USING_SJLJ_EXCEPTIONS__");
|
||||
|
||||
/* limits.h needs to know these. */
|
||||
builtin_define_type_max ("__SCHAR_MAX__", signed_char_type_node, 0);
|
||||
builtin_define_type_max ("__SHRT_MAX__", short_integer_type_node, 0);
|
||||
builtin_define_type_max ("__INT_MAX__", integer_type_node, 0);
|
||||
builtin_define_type_max ("__LONG_MAX__", long_integer_type_node, 1);
|
||||
builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node, 2);
|
||||
builtin_define_type_max ("__WCHAR_MAX__", wchar_type_node, 0);
|
||||
|
||||
builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
|
||||
|
||||
/* float.h needs to know these. */
|
||||
|
||||
builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
|
||||
TARGET_FLT_EVAL_METHOD);
|
||||
|
||||
builtin_define_float_constants ("FLT", "F", float_type_node);
|
||||
builtin_define_float_constants ("DBL", "", double_type_node);
|
||||
builtin_define_float_constants ("LDBL", "L", long_double_type_node);
|
||||
|
||||
/* For use in assembly language. */
|
||||
builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
|
||||
builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);
|
||||
|
||||
/* Misc. */
|
||||
builtin_define_with_value ("__VERSION__", version_string, 1);
|
||||
|
||||
/* Other target-independent built-ins determined by command-line
|
||||
options. */
|
||||
if (optimize_size)
|
||||
cpp_define (pfile, "__OPTIMIZE_SIZE__");
|
||||
if (optimize)
|
||||
cpp_define (pfile, "__OPTIMIZE__");
|
||||
|
||||
if (flag_hosted)
|
||||
cpp_define (pfile, "__STDC_HOSTED__=1");
|
||||
else
|
||||
cpp_define (pfile, "__STDC_HOSTED__=0");
|
||||
|
||||
if (fast_math_flags_set_p ())
|
||||
cpp_define (pfile, "__FAST_MATH__");
|
||||
if (flag_really_no_inline)
|
||||
cpp_define (pfile, "__NO_INLINE__");
|
||||
if (flag_signaling_nans)
|
||||
cpp_define (pfile, "__SUPPORT_SNAN__");
|
||||
if (flag_finite_math_only)
|
||||
cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
|
||||
else
|
||||
cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
|
||||
|
||||
if (flag_iso)
|
||||
cpp_define (pfile, "__STRICT_ANSI__");
|
||||
|
||||
if (!flag_signed_char)
|
||||
cpp_define (pfile, "__CHAR_UNSIGNED__");
|
||||
|
||||
if (c_language == clk_cplusplus && TREE_UNSIGNED (wchar_type_node))
|
||||
cpp_define (pfile, "__WCHAR_UNSIGNED__");
|
||||
|
||||
/* Make the choice of ObjC runtime visible to source code. */
|
||||
if (flag_objc && flag_next_runtime)
|
||||
cpp_define (pfile, "__NEXT_RUNTIME__");
|
||||
|
||||
/* A straightforward target hook doesn't work, because of problems
|
||||
linking that hook's body when part of non-C front ends. */
|
||||
# define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
|
||||
# define preprocessing_trad_p() (cpp_get_options (pfile)->traditional)
|
||||
# define builtin_define(TXT) cpp_define (pfile, TXT)
|
||||
# define builtin_assert(TXT) cpp_assert (pfile, TXT)
|
||||
TARGET_CPU_CPP_BUILTINS ();
|
||||
TARGET_OS_CPP_BUILTINS ();
|
||||
}
|
||||
|
||||
/* Pass an object-like macro. If it doesn't lie in the user's
|
||||
namespace, defines it unconditionally. Otherwise define a version
|
||||
with two leading underscores, and another version with two leading
|
||||
and trailing underscores, and define the original only if an ISO
|
||||
standard was not nominated.
|
||||
|
||||
e.g. passing "unix" defines "__unix", "__unix__" and possibly
|
||||
"unix". Passing "_mips" defines "__mips", "__mips__" and possibly
|
||||
"_mips". */
|
||||
static void
|
||||
builtin_define_std (macro)
|
||||
const char *macro;
|
||||
{
|
||||
size_t len = strlen (macro);
|
||||
char *buff = alloca (len + 5);
|
||||
char *p = buff + 2;
|
||||
char *q = p + len;
|
||||
|
||||
/* prepend __ (or maybe just _) if in user's namespace. */
|
||||
memcpy (p, macro, len + 1);
|
||||
if (!( *p == '_' && (p[1] == '_' || ISUPPER (p[1]))))
|
||||
{
|
||||
if (*p != '_')
|
||||
*--p = '_';
|
||||
if (p[1] != '_')
|
||||
*--p = '_';
|
||||
}
|
||||
cpp_define (parse_in, p);
|
||||
|
||||
/* If it was in user's namespace... */
|
||||
if (p != buff + 2)
|
||||
{
|
||||
/* Define the macro with leading and following __. */
|
||||
if (q[-1] != '_')
|
||||
*q++ = '_';
|
||||
if (q[-2] != '_')
|
||||
*q++ = '_';
|
||||
*q = '\0';
|
||||
cpp_define (parse_in, p);
|
||||
|
||||
/* Finally, define the original macro if permitted. */
|
||||
if (!flag_iso)
|
||||
cpp_define (parse_in, macro);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pass an object-like macro and a value to define it to. The third
|
||||
parameter says whether or not to turn the value into a string
|
||||
constant. */
|
||||
void
|
||||
builtin_define_with_value (macro, expansion, is_str)
|
||||
const char *macro;
|
||||
const char *expansion;
|
||||
int is_str;
|
||||
{
|
||||
char *buf;
|
||||
size_t mlen = strlen (macro);
|
||||
size_t elen = strlen (expansion);
|
||||
size_t extra = 2; /* space for an = and a NUL */
|
||||
|
||||
if (is_str)
|
||||
extra += 2; /* space for two quote marks */
|
||||
|
||||
buf = alloca (mlen + elen + extra);
|
||||
if (is_str)
|
||||
sprintf (buf, "%s=\"%s\"", macro, expansion);
|
||||
else
|
||||
sprintf (buf, "%s=%s", macro, expansion);
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
/* Pass an object-like macro and a value to define it to. The third
|
||||
parameter is the length of the expansion. */
|
||||
static void
|
||||
builtin_define_with_value_n (macro, expansion, elen)
|
||||
const char *macro;
|
||||
const char *expansion;
|
||||
size_t elen;
|
||||
{
|
||||
char *buf;
|
||||
size_t mlen = strlen (macro);
|
||||
|
||||
/* Space for an = and a NUL. */
|
||||
buf = alloca (mlen + elen + 2);
|
||||
memcpy (buf, macro, mlen);
|
||||
buf[mlen]= '=';
|
||||
memcpy (buf + mlen + 1, expansion, elen);
|
||||
buf[mlen + elen + 1] = '\0';
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
/* Pass an object-like macro and an integer value to define it to. */
|
||||
static void
|
||||
builtin_define_with_int_value (macro, value)
|
||||
const char *macro;
|
||||
HOST_WIDE_INT value;
|
||||
{
|
||||
char *buf;
|
||||
size_t mlen = strlen (macro);
|
||||
size_t vlen = 18;
|
||||
size_t extra = 2; /* space for = and NUL. */
|
||||
|
||||
buf = alloca (mlen + vlen + extra);
|
||||
memcpy (buf, macro, mlen);
|
||||
buf[mlen] = '=';
|
||||
sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value);
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
/* Pass an object-like macro a hexadecimal floating-point value. */
|
||||
static void
|
||||
builtin_define_with_hex_fp_value (macro, type, digits, hex_str, fp_suffix)
|
||||
const char *macro;
|
||||
tree type ATTRIBUTE_UNUSED;
|
||||
int digits;
|
||||
const char *hex_str;
|
||||
const char *fp_suffix;
|
||||
{
|
||||
REAL_VALUE_TYPE real;
|
||||
char dec_str[64], buf[256];
|
||||
|
||||
/* 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
|
||||
pedwarn from the preprocessor, which has no context, so we can't
|
||||
suppress the warning with __extension__.
|
||||
|
||||
So instead what we do is construct the number in hex (because
|
||||
it's easy to get the exact correct value), parse it as a real,
|
||||
then print it back out as decimal. */
|
||||
|
||||
real_from_string (&real, hex_str);
|
||||
real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
|
||||
|
||||
sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
||||
|
||||
/* Define MAX for TYPE based on the precision of the type. IS_LONG is
|
||||
1 for type "long" and 2 for "long long". We have to handle
|
||||
unsigned types, since wchar_t might be unsigned. */
|
||||
|
||||
static void
|
||||
builtin_define_type_max (macro, type, is_long)
|
||||
const char *macro;
|
||||
tree type;
|
||||
int is_long;
|
||||
{
|
||||
static const char *const values[]
|
||||
= { "127", "255",
|
||||
"32767", "65535",
|
||||
"2147483647", "4294967295",
|
||||
"9223372036854775807", "18446744073709551615",
|
||||
"170141183460469231731687303715884105727",
|
||||
"340282366920938463463374607431768211455" };
|
||||
static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
|
||||
|
||||
const char *value, *suffix;
|
||||
char *buf;
|
||||
size_t idx;
|
||||
|
||||
/* Pre-rendering the values mean we don't have to futz with printing a
|
||||
multi-word decimal value. There are also a very limited number of
|
||||
precisions that we support, so it's really a waste of time. */
|
||||
switch (TYPE_PRECISION (type))
|
||||
{
|
||||
case 8: idx = 0; break;
|
||||
case 16: idx = 2; break;
|
||||
case 32: idx = 4; break;
|
||||
case 64: idx = 6; break;
|
||||
case 128: idx = 8; break;
|
||||
default: abort ();
|
||||
}
|
||||
|
||||
value = values[idx + TREE_UNSIGNED (type)];
|
||||
suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
|
||||
|
||||
buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
|
||||
sprintf (buf, "%s=%s%s", macro, value, suffix);
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
}
|
|
@ -1,3 +1,8 @@
|
|||
2003-03-11 Neil Booth <neil@daikokuya.co.uk>
|
||||
|
||||
* Make-lang.in (CXX_C_OBJS): Update.
|
||||
* lang-specs.h: Don't define __GNUG__ here.
|
||||
|
||||
2003-03-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* call.c (perform_overload_resolution): New function.
|
||||
|
|
|
@ -80,7 +80,7 @@ g++-cross$(exeext): g++$(exeext)
|
|||
# Shared with C front end:
|
||||
CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
|
||||
c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
|
||||
c-incpath.o cppdefault.o c-ppoutput.o
|
||||
c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o
|
||||
|
||||
# Language-specific object files.
|
||||
CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
|
||||
|
|
|
@ -36,24 +36,22 @@ Boston, MA 02111-1307, USA. */
|
|||
{".H", "@c++-header", 0},
|
||||
{".hh", "@c++-header", 0},
|
||||
{"@c++-header",
|
||||
"%{E|M|MM:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%(cpp_options) %2 %(cpp_debug_options)}\
|
||||
"%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\
|
||||
%{!E:%{!M:%{!MM:\
|
||||
%{save-temps:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%{save-temps:cc1plus -E\
|
||||
%(cpp_options) %2 %b.ii \n}\
|
||||
cc1plus %{save-temps:-fpreprocessed %b.ii}\
|
||||
%{!save-temps:%(cpp_unique_options) %{!no-gcc:-D__GNUG__=%v1}}\
|
||||
%{!save-temps:%(cpp_unique_options)}\
|
||||
%(cc1_options) %2 %{+e1*}\
|
||||
-o %g.s %{!o*:--output-pch=%i.gch} %W{o*:--output-pch=%*}%V}}}",
|
||||
CPLUSPLUS_CPP_SPEC},
|
||||
{"@c++",
|
||||
"%{E|M|MM:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%(cpp_options) %2 %(cpp_debug_options)}\
|
||||
"%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\
|
||||
%{!E:%{!M:%{!MM:\
|
||||
%{save-temps|no-integrated-cpp:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%{save-temps|no-integrated-cpp:cc1plus -E\
|
||||
%(cpp_options) %2 %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
|
||||
cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\
|
||||
%{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options) %{!no-gcc:-D__GNUG__=%v1}}}\
|
||||
%{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\
|
||||
%(cc1_options) %2 %{+e1*}\
|
||||
%{!fsyntax-only:%(invoke_as)}}}}",
|
||||
CPLUSPLUS_CPP_SPEC},
|
||||
|
|
|
@ -65,9 +65,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
/* Do we need to insert -E? */
|
||||
int need_E = 1;
|
||||
|
||||
/* Do we need to insert -no-gcc? */
|
||||
int need_no_gcc = 1;
|
||||
|
||||
/* Have we seen an input file? */
|
||||
int seen_input = 0;
|
||||
|
||||
|
@ -122,8 +119,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
}
|
||||
else if (argv[i][1] == 'x')
|
||||
need_fixups = 0;
|
||||
else if (argv[i][1] == 'g' && !strcmp(&argv[i][2], "cc"))
|
||||
need_no_gcc = 0;
|
||||
else if (WORD_SWITCH_TAKES_ARG (&argv[i][1]))
|
||||
quote = 1;
|
||||
}
|
||||
|
@ -172,7 +167,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
|
||||
/* If we don't need to edit the command line, we can bail early. */
|
||||
|
||||
new_argc = argc + need_E + need_no_gcc + read_stdin
|
||||
new_argc = argc + need_E + read_stdin
|
||||
+ !!o_here + !!lang_c_here + !!lang_S_here;
|
||||
|
||||
if (new_argc == argc)
|
||||
|
@ -187,9 +182,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
if (need_E)
|
||||
new_argv[j++] = "-E";
|
||||
|
||||
if (need_no_gcc)
|
||||
new_argv[j++] = "-no-gcc";
|
||||
|
||||
for (i = 1; i < argc; i++, j++)
|
||||
{
|
||||
if (i == lang_c_here)
|
||||
|
|
|
@ -5306,18 +5306,6 @@ Output the accumulated assembler options specified by @option{-Wa}.
|
|||
@item %Z
|
||||
Output the accumulated preprocessor options specified by @option{-Wp}.
|
||||
|
||||
@item %v1
|
||||
Substitute the major version number of GCC@.
|
||||
(For version 2.9.5, this is 2.)
|
||||
|
||||
@item %v2
|
||||
Substitute the minor version number of GCC@.
|
||||
(For version 2.9.5, this is 9.)
|
||||
|
||||
@item %v3
|
||||
Substitute the patch level number of GCC@.
|
||||
(For version 2.9.5, this is 5.)
|
||||
|
||||
@item %a
|
||||
Process the @code{asm} spec. This is used to compute the
|
||||
switches to be passed to the assembler.
|
||||
|
|
|
@ -84,6 +84,7 @@ the other C-like languages: @file{c-common.c},
|
|||
@file{c-lex.c},
|
||||
@file{c-incpath.c},
|
||||
@file{c-ppoutput.c},
|
||||
@file{c-cppbuiltin.c},
|
||||
@file{c-common.h},
|
||||
@file{c-dump.h},
|
||||
@file{c-incpath.h}
|
||||
|
|
|
@ -619,7 +619,7 @@ Here are run-time target specifications.
|
|||
This function-like macro expands to a block of code that defines
|
||||
built-in preprocessor macros and assertions for the target cpu, using
|
||||
the functions @code{builtin_define}, @code{builtin_define_std} and
|
||||
@code{builtin_assert} defined in @file{c-common.c}. When the front end
|
||||
@code{builtin_assert}. When the front end
|
||||
calls this macro it provides a trailing semicolon, and since it has
|
||||
finished command line option processing your code can use those
|
||||
results freely.
|
||||
|
|
67
gcc/gcc.c
67
gcc/gcc.c
|
@ -466,12 +466,6 @@ or with constant text in a single argument.
|
|||
%X Output the accumulated linker options specified by compilations.
|
||||
%Y Output the accumulated assembler options specified by compilations.
|
||||
%Z Output the accumulated preprocessor options specified by compilations.
|
||||
%v1 Substitute the major version number of GCC.
|
||||
(For version 2.5.3, this is 2.)
|
||||
%v2 Substitute the minor version number of GCC.
|
||||
(For version 2.5.3, this is 5.)
|
||||
%v3 Substitute the patch level number of GCC.
|
||||
(For version 2.5.3, this is 3.)
|
||||
%a process ASM_SPEC as a spec.
|
||||
This allows config.h to specify part of the spec for running as.
|
||||
%A process ASM_FINAL_SPEC as a spec. A capital A is actually
|
||||
|
@ -740,14 +734,12 @@ static const char *trad_capable_cpp =
|
|||
therefore no dependency entry, confuses make into thinking a .o
|
||||
file that happens to exist is up-to-date. */
|
||||
static const char *cpp_unique_options =
|
||||
"%{C:%{!E:%eGNU C does not support -C without using -E}}\
|
||||
%{CC:%{!E:%eGNU C does not support -CC without using -E}}\
|
||||
"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
|
||||
%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
|
||||
%{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
|
||||
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
|
||||
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
|
||||
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
|
||||
%{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
|
||||
%{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
|
||||
%{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
|
||||
%{E|M|MM:%W{o*}}";
|
||||
|
@ -5305,63 +5297,6 @@ do_spec_1 (spec, inswitch, soft_matched_part)
|
|||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
{
|
||||
int c1 = *p++; /* Select first or second version number. */
|
||||
const char *v = compiler_version;
|
||||
const char *q;
|
||||
static const char zeroc = '0';
|
||||
|
||||
/* The format of the version string is
|
||||
([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
|
||||
|
||||
/* Ignore leading non-digits. i.e. "foo-" in "foo-2.7.2". */
|
||||
while (! ISDIGIT (*v))
|
||||
v++;
|
||||
if (v > compiler_version && v[-1] != '-')
|
||||
abort ();
|
||||
|
||||
/* If desired, advance to second version number. */
|
||||
if (c1 >= '2')
|
||||
{
|
||||
/* Set V after the first period. */
|
||||
while (ISDIGIT (*v))
|
||||
v++;
|
||||
if (*v != '.')
|
||||
abort ();
|
||||
v++;
|
||||
}
|
||||
|
||||
/* If desired, advance to third version number.
|
||||
But don't complain if it's not present */
|
||||
if (c1 == '3')
|
||||
{
|
||||
/* Set V after the second period. */
|
||||
while (ISDIGIT (*v))
|
||||
v++;
|
||||
if ((*v != 0) && (*v != ' ') && (*v != '.') && (*v != '-'))
|
||||
abort ();
|
||||
if (*v != 0)
|
||||
v++;
|
||||
}
|
||||
|
||||
/* Set Q at the next period or at the end. */
|
||||
q = v;
|
||||
while (ISDIGIT (*q))
|
||||
q++;
|
||||
if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
|
||||
abort ();
|
||||
|
||||
if (q > v)
|
||||
/* Put that part into the command. */
|
||||
obstack_grow (&obstack, v, q - v);
|
||||
else
|
||||
/* Default to "0" */
|
||||
obstack_grow (&obstack, &zeroc, 1);
|
||||
arg_going = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
error ("spec failure: unrecognized spec option '%c'", c);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue