mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
GCC 4.2.0 release.
This commit is contained in:
parent
9ba78bf6b1
commit
6b834ef156
1230 changed files with 891980 additions and 225100 deletions
1
contrib/gcc/BASE-VER
Normal file
1
contrib/gcc/BASE-VER
Normal file
|
|
@ -0,0 +1 @@
|
|||
4.2.0
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
|
@ -485,7 +485,7 @@ convey the exclusion of warranty; and each file should have at least the
|
|||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
|
|
|
|||
10115
contrib/gcc/ChangeLog
10115
contrib/gcc/ChangeLog
File diff suppressed because it is too large
Load diff
3969
contrib/gcc/ChangeLog-1997
Normal file
3969
contrib/gcc/ChangeLog-1997
Normal file
File diff suppressed because it is too large
Load diff
17616
contrib/gcc/ChangeLog-1998
Normal file
17616
contrib/gcc/ChangeLog-1998
Normal file
File diff suppressed because it is too large
Load diff
21786
contrib/gcc/ChangeLog-1999
Normal file
21786
contrib/gcc/ChangeLog-1999
Normal file
File diff suppressed because it is too large
Load diff
32124
contrib/gcc/ChangeLog-2000
Normal file
32124
contrib/gcc/ChangeLog-2000
Normal file
File diff suppressed because it is too large
Load diff
33645
contrib/gcc/ChangeLog-2001
Normal file
33645
contrib/gcc/ChangeLog-2001
Normal file
File diff suppressed because it is too large
Load diff
35988
contrib/gcc/ChangeLog-2002
Normal file
35988
contrib/gcc/ChangeLog-2002
Normal file
File diff suppressed because it is too large
Load diff
37862
contrib/gcc/ChangeLog-2003
Normal file
37862
contrib/gcc/ChangeLog-2003
Normal file
File diff suppressed because it is too large
Load diff
47880
contrib/gcc/ChangeLog-2004
Normal file
47880
contrib/gcc/ChangeLog-2004
Normal file
File diff suppressed because it is too large
Load diff
35909
contrib/gcc/ChangeLog-2005
Normal file
35909
contrib/gcc/ChangeLog-2005
Normal file
File diff suppressed because it is too large
Load diff
16726
contrib/gcc/ChangeLog-2006
Normal file
16726
contrib/gcc/ChangeLog-2006
Normal file
File diff suppressed because it is too large
Load diff
19338
contrib/gcc/ChangeLog.tree-ssa
Normal file
19338
contrib/gcc/ChangeLog.tree-ssa
Normal file
File diff suppressed because it is too large
Load diff
1
contrib/gcc/DATESTAMP
Normal file
1
contrib/gcc/DATESTAMP
Normal file
|
|
@ -0,0 +1 @@
|
|||
20070514
|
||||
0
contrib/gcc/DEV-PHASE
Normal file
0
contrib/gcc/DEV-PHASE
Normal file
|
|
@ -6,60 +6,24 @@ time as we can formally start documenting the interface this file will
|
|||
serve as a repository for information on these interface and any incompatable
|
||||
changes we've made.
|
||||
|
||||
2004-09-09:
|
||||
In an effort to decrease execution time, single char tree code
|
||||
classes were changed to enumerated values.
|
||||
|
||||
Old way:
|
||||
|
||||
DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", 'd', 0)
|
||||
|
||||
New way:
|
||||
|
||||
DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", tcc_declaration, 0)
|
||||
|
||||
2001-02-26:
|
||||
A DECL_INITIAL of NULL_TREE or error_mark_node in a VAR_DECL is no longer
|
||||
taken to signify a tentative definition which should not be emitted until
|
||||
end-of-file. Frontends which want that behavior should set
|
||||
DECL_DEFER_OUTPUT before calling rest_of_decl_compilation.
|
||||
|
||||
Aug 31, 1998:
|
||||
The interface to HANDLE_PRAGMA has changed. It now takes three arguments.
|
||||
The first two are pointers to functions that should be used to read characters
|
||||
from the input stream, and to push them back into the input stream respectively.
|
||||
The third argument is a pointer to a null terminate string which is the first
|
||||
word after #pragma. The expression supplied by HANDLE_PRAGMA should return
|
||||
nonzero if it parsed and implemented the pragma. Otherwise it should return
|
||||
zero, and leave the input stream as it was before the expression was evaluated.
|
||||
|
||||
A new back-end definable macro has been added: INSERT_ATTRIBUTES. This macro
|
||||
allows backend to add attributes to decls as they are created.
|
||||
|
||||
Jun 10, 1998:
|
||||
The interface to lang_decode_option has changed. It now uses and argc/argv
|
||||
interface to allow for options that use more than one input string. The new
|
||||
declaration is: int lang_decode_option (int argc, char** argv). It now
|
||||
returns the number of input strings processed, or 0 if the option is
|
||||
unknown.
|
||||
|
||||
Jun 7, 1998:
|
||||
Front-ends must now define lang_init_options. It is safe for this
|
||||
function to do nothing. See c-lang.c.
|
||||
|
||||
Apr 21, 1998:
|
||||
Front ends which link with c-common or other files from the C/C++
|
||||
front-ends may need to handle TI types. Look for references to
|
||||
[unsigned]int_DI_type_node in your front end. If you have references
|
||||
to these variables, you'll need up update the front end.
|
||||
|
||||
To update the front end you must mirror all the code which currently
|
||||
deals with intDI_type_node to also handle intTI_type_node.
|
||||
|
||||
|
||||
Apr 7, 1998:
|
||||
The interface between toplev.c and the language front ends for opening the
|
||||
source file has changed:
|
||||
|
||||
o init_lex() has been renamed to init_parse (char *filename) where filename
|
||||
is the name of the source file.
|
||||
o The code in toplev.c which opened the source file should be moved to
|
||||
the new init_parse function.
|
||||
o toplev.c now calls finish_parse() instead of closing the source file
|
||||
using fclose(). This should now be done in finish_parse, if necessary.
|
||||
|
||||
Apr 1, 1998:
|
||||
Front-ends must now define lang_print_xnode. It is safe for this
|
||||
function to do nothing. See c-lang.c.
|
||||
|
||||
Feb 1, 1998:
|
||||
|
||||
GCC used to store structure sizes & offsets to elements as bitsize
|
||||
|
|
@ -78,10 +42,6 @@ Feb 1, 1998:
|
|||
When a size in bits is converted into a size in bytes, which is expressed
|
||||
in trees, care should be taken to change the tree's type again to sizetype.
|
||||
|
||||
We've updated C, C++, Fortran & Objective-C to work with the new
|
||||
scheme. Other languages will need to be updated accordingly.
|
||||
Contact amylaar@cygnus.com for additional information.
|
||||
|
||||
?? 1997:
|
||||
|
||||
In an effort to decrease cache thrashing and useless loads we've changed the
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
512
contrib/gcc/acinclude.m4
Normal file
512
contrib/gcc/acinclude.m4
Normal file
|
|
@ -0,0 +1,512 @@
|
|||
dnl See whether we need a declaration for a function.
|
||||
dnl The result is highly dependent on the INCLUDES passed in, so make sure
|
||||
dnl to use a different cache variable name in this macro if it is invoked
|
||||
dnl in a different context somewhere else.
|
||||
dnl gcc_AC_CHECK_DECL(SYMBOL,
|
||||
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
|
||||
AC_DEFUN([gcc_AC_CHECK_DECL],
|
||||
[AC_MSG_CHECKING([whether $1 is declared])
|
||||
AC_CACHE_VAL(gcc_cv_have_decl_$1,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$4],
|
||||
[#ifndef $1
|
||||
char *(*pfn) = (char *(*)) $1 ;
|
||||
#endif])], eval "gcc_cv_have_decl_$1=yes", eval "gcc_cv_have_decl_$1=no")])
|
||||
if eval "test \"`echo '$gcc_cv_have_decl_'$1`\" = yes"; then
|
||||
AC_MSG_RESULT(yes) ; ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no) ; ifelse([$3], , :, [$3])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
dnl Check multiple functions to see whether each needs a declaration.
|
||||
dnl Arrange to define HAVE_DECL_<FUNCTION> to 0 or 1 as appropriate.
|
||||
dnl gcc_AC_CHECK_DECLS(SYMBOLS,
|
||||
dnl [ACTION-IF-NEEDED [, ACTION-IF-NOT-NEEDED [, INCLUDES]]])
|
||||
AC_DEFUN([gcc_AC_CHECK_DECLS],
|
||||
[AC_FOREACH([gcc_AC_Func], [$1],
|
||||
[AH_TEMPLATE(AS_TR_CPP(HAVE_DECL_[]gcc_AC_Func),
|
||||
[Define to 1 if we found a declaration for ']gcc_AC_Func[', otherwise
|
||||
define to 0.])])dnl
|
||||
for ac_func in $1
|
||||
do
|
||||
ac_tr_decl=AS_TR_CPP([HAVE_DECL_$ac_func])
|
||||
gcc_AC_CHECK_DECL($ac_func,
|
||||
[AC_DEFINE_UNQUOTED($ac_tr_decl, 1) $2],
|
||||
[AC_DEFINE_UNQUOTED($ac_tr_decl, 0) $3],
|
||||
dnl It is possible that the include files passed in here are local headers
|
||||
dnl which supply a backup declaration for the relevant prototype based on
|
||||
dnl the definition of (or lack of) the HAVE_DECL_ macro. If so, this test
|
||||
dnl will always return success. E.g. see libiberty.h's handling of
|
||||
dnl `basename'. To avoid this, we define the relevant HAVE_DECL_ macro to
|
||||
dnl 1 so that any local headers used do not provide their own prototype
|
||||
dnl during this test.
|
||||
#undef $ac_tr_decl
|
||||
#define $ac_tr_decl 1
|
||||
$4
|
||||
)
|
||||
done
|
||||
])
|
||||
|
||||
dnl 'make compare' can be significantly faster, if cmp itself can
|
||||
dnl skip bytes instead of using tail. The test being performed is
|
||||
dnl "if cmp --ignore-initial=2 t1 t2 && ! cmp --ignore-initial=1 t1 t2"
|
||||
dnl but we need to sink errors and handle broken shells. We also test
|
||||
dnl for the parameter format "cmp file1 file2 skip1 skip2" which is
|
||||
dnl accepted by cmp on some systems.
|
||||
AC_DEFUN([gcc_AC_PROG_CMP_IGNORE_INITIAL],
|
||||
[AC_CACHE_CHECK([for cmp's capabilities], gcc_cv_prog_cmp_skip,
|
||||
[ echo abfoo >t1
|
||||
echo cdfoo >t2
|
||||
gcc_cv_prog_cmp_skip=slowcompare
|
||||
if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then
|
||||
if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
gcc_cv_prog_cmp_skip=gnucompare
|
||||
fi
|
||||
fi
|
||||
if test $gcc_cv_prog_cmp_skip = slowcompare ; then
|
||||
if cmp t1 t2 2 2 > /dev/null 2>&1; then
|
||||
if cmp t1 t2 1 1 > /dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
gcc_cv_prog_cmp_skip=fastcompare
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
rm t1 t2
|
||||
])
|
||||
make_compare_target=$gcc_cv_prog_cmp_skip
|
||||
AC_SUBST(make_compare_target)
|
||||
])
|
||||
|
||||
dnl See if symbolic links work and if not, try to substitute either hard links or simple copy.
|
||||
AC_DEFUN([gcc_AC_PROG_LN_S],
|
||||
[AC_MSG_CHECKING(whether ln -s works)
|
||||
AC_CACHE_VAL(gcc_cv_prog_LN_S,
|
||||
[rm -f conftestdata_t
|
||||
echo >conftestdata_f
|
||||
if ln -s conftestdata_f conftestdata_t 2>/dev/null
|
||||
then
|
||||
gcc_cv_prog_LN_S="ln -s"
|
||||
else
|
||||
if ln conftestdata_f conftestdata_t 2>/dev/null
|
||||
then
|
||||
gcc_cv_prog_LN_S=ln
|
||||
else
|
||||
if cp -p conftestdata_f conftestdata_t 2>/dev/null
|
||||
then
|
||||
gcc_cv_prog_LN_S="cp -p"
|
||||
else
|
||||
gcc_cv_prog_LN_S=cp
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
rm -f conftestdata_f conftestdata_t
|
||||
])dnl
|
||||
LN_S="$gcc_cv_prog_LN_S"
|
||||
if test "$gcc_cv_prog_LN_S" = "ln -s"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
if test "$gcc_cv_prog_LN_S" = "ln"; then
|
||||
AC_MSG_RESULT([no, using ln])
|
||||
else
|
||||
AC_MSG_RESULT([no, and neither does ln, so using $gcc_cv_prog_LN_S])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(LN_S)dnl
|
||||
])
|
||||
|
||||
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
|
||||
dnl of the usual 2.
|
||||
AC_DEFUN([gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG],
|
||||
[AC_CACHE_CHECK([if mkdir takes one argument], gcc_cv_mkdir_takes_one_arg,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_DIRECT_H
|
||||
# include <direct.h>
|
||||
#endif], [mkdir ("foo", 0);])],
|
||||
gcc_cv_mkdir_takes_one_arg=no, gcc_cv_mkdir_takes_one_arg=yes)])
|
||||
if test $gcc_cv_mkdir_takes_one_arg = yes ; then
|
||||
AC_DEFINE(MKDIR_TAKES_ONE_ARG, 1, [Define if host mkdir takes a single argument.])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([gcc_AC_PROG_INSTALL],
|
||||
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
|
||||
# Find a good install program. We prefer a C program (faster),
|
||||
# so one script is as good as another. But avoid the broken or
|
||||
# incompatible versions:
|
||||
# SysV /etc/install, /usr/sbin/install
|
||||
# SunOS /usr/etc/install
|
||||
# IRIX /sbin/install
|
||||
# AIX /bin/install
|
||||
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
|
||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||
# ./install, which can be erroneously created by make from ./install.sh.
|
||||
AC_MSG_CHECKING(for a BSD compatible install)
|
||||
if test -z "$INSTALL"; then
|
||||
AC_CACHE_VAL(ac_cv_path_install,
|
||||
[ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
|
||||
for ac_dir in $PATH; do
|
||||
# Account for people who put trailing slashes in PATH elements.
|
||||
case "$ac_dir/" in
|
||||
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
|
||||
*)
|
||||
# OSF1 and SCO ODT 3.0 have their own names for install.
|
||||
for ac_prog in ginstall scoinst install; do
|
||||
if test -f $ac_dir/$ac_prog; then
|
||||
if test $ac_prog = install &&
|
||||
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
|
||||
# AIX install. It has an incompatible calling convention.
|
||||
# OSF/1 installbsd also uses dspmsg, but is usable.
|
||||
:
|
||||
else
|
||||
ac_cv_path_install="$ac_dir/$ac_prog -c"
|
||||
break 2
|
||||
fi
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
done
|
||||
IFS="$ac_save_IFS"
|
||||
])dnl
|
||||
if test "${ac_cv_path_install+set}" = set; then
|
||||
INSTALL="$ac_cv_path_install"
|
||||
else
|
||||
# As a last resort, use the slow shell script. We don't cache a
|
||||
# path for INSTALL within a source directory, because that will
|
||||
# break other packages using the cache if that directory is
|
||||
# removed, or if the path is relative.
|
||||
INSTALL="$ac_install_sh"
|
||||
fi
|
||||
fi
|
||||
dnl We do special magic for INSTALL instead of AC_SUBST, to get
|
||||
dnl relative paths right.
|
||||
AC_MSG_RESULT($INSTALL)
|
||||
AC_SUBST(INSTALL)dnl
|
||||
|
||||
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
|
||||
# It thinks the first close brace ends the variable substitution.
|
||||
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
|
||||
AC_SUBST(INSTALL_PROGRAM)dnl
|
||||
|
||||
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
||||
AC_SUBST(INSTALL_DATA)dnl
|
||||
])
|
||||
|
||||
# mmap(2) blacklisting. Some platforms provide the mmap library routine
|
||||
# but don't support all of the features we need from it.
|
||||
AC_DEFUN([gcc_AC_FUNC_MMAP_BLACKLIST],
|
||||
[
|
||||
AC_CHECK_HEADER([sys/mman.h],
|
||||
[gcc_header_sys_mman_h=yes], [gcc_header_sys_mman_h=no])
|
||||
AC_CHECK_FUNC([mmap], [gcc_func_mmap=yes], [gcc_func_mmap=no])
|
||||
if test "$gcc_header_sys_mman_h" != yes \
|
||||
|| test "$gcc_func_mmap" != yes; then
|
||||
gcc_cv_func_mmap_file=no
|
||||
gcc_cv_func_mmap_dev_zero=no
|
||||
gcc_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether read-only mmap of a plain file works],
|
||||
gcc_cv_func_mmap_file,
|
||||
[# Add a system to this blacklist if
|
||||
# mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
|
||||
# memory area containing the same data that you'd get if you applied
|
||||
# read() to the same fd. The only system known to have a problem here
|
||||
# is VMS, where text files have record structure.
|
||||
case "$host_os" in
|
||||
vms* | ultrix*)
|
||||
gcc_cv_func_mmap_file=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_file=yes;;
|
||||
esac])
|
||||
AC_CACHE_CHECK([whether mmap from /dev/zero works],
|
||||
gcc_cv_func_mmap_dev_zero,
|
||||
[# Add a system to this blacklist if it has mmap() but /dev/zero
|
||||
# does not exist, or if mmapping /dev/zero does not give anonymous
|
||||
# zeroed pages with both the following properties:
|
||||
# 1. If you map N consecutive pages in with one call, and then
|
||||
# unmap any subset of those pages, the pages that were not
|
||||
# explicitly unmapped remain accessible.
|
||||
# 2. If you map two adjacent blocks of memory and then unmap them
|
||||
# both at once, they must both go away.
|
||||
# Systems known to be in this category are Windows (all variants),
|
||||
# VMS, and Darwin.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
|
||||
gcc_cv_func_mmap_dev_zero=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_dev_zero=yes;;
|
||||
esac])
|
||||
|
||||
# Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
|
||||
AC_CACHE_CHECK([for MAP_ANON(YMOUS)], gcc_cv_decl_map_anon,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
[#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
],
|
||||
[int n = MAP_ANONYMOUS;])],
|
||||
gcc_cv_decl_map_anon=yes,
|
||||
gcc_cv_decl_map_anon=no)])
|
||||
|
||||
if test $gcc_cv_decl_map_anon = no; then
|
||||
gcc_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
|
||||
gcc_cv_func_mmap_anon,
|
||||
[# Add a system to this blacklist if it has mmap() and MAP_ANON or
|
||||
# MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
||||
# doesn't give anonymous zeroed pages with the same properties listed
|
||||
# above for use of /dev/zero.
|
||||
# Systems known to be in this category are Windows, VMS, and SCO Unix.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | sco* | udk* )
|
||||
gcc_cv_func_mmap_anon=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_anon=yes;;
|
||||
esac])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $gcc_cv_func_mmap_file = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_FILE, 1,
|
||||
[Define if read-only mmap of a plain file works.])
|
||||
fi
|
||||
if test $gcc_cv_func_mmap_dev_zero = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
|
||||
[Define if mmap of /dev/zero works.])
|
||||
fi
|
||||
if test $gcc_cv_func_mmap_anon = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_ANON, 1,
|
||||
[Define if mmap with MAP_ANON(YMOUS) works.])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Locate a program and check that its version is acceptable.
|
||||
dnl AC_PROG_CHECK_VER(var, name, version-switch,
|
||||
dnl version-extract-regexp, version-glob)
|
||||
AC_DEFUN([gcc_AC_CHECK_PROG_VER],
|
||||
[AC_REQUIRE([gcc_AC_BUILD_EXEEXT])
|
||||
AC_CHECK_PROG([$1], [$2], [$2])
|
||||
if test -n "[$]$1"; then
|
||||
# Found it, now check the version.
|
||||
AC_CACHE_CHECK(for modern $2, gcc_cv_prog_$2_modern,
|
||||
[changequote(<<,>>)dnl
|
||||
ac_prog_version=`<<$>>$1 $3 2>&1 |
|
||||
sed -n 's/^.*patsubst(<<$4>>,/,\/).*$/\1/p'`
|
||||
changequote([,])dnl
|
||||
echo "configure:__oline__: version of $2 is $ac_prog_version" >&AS_MESSAGE_LOG_FD
|
||||
changequote(<<,>>)dnl
|
||||
case $ac_prog_version in
|
||||
'') gcc_cv_prog_$2_modern=no;;
|
||||
<<$5>>)
|
||||
gcc_cv_prog_$2_modern=yes;;
|
||||
*) gcc_cv_prog_$2_modern=no;;
|
||||
esac
|
||||
changequote([,])dnl
|
||||
])
|
||||
else
|
||||
gcc_cv_prog_$2_modern=no
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Determine if enumerated bitfields are unsigned. ISO C says they can
|
||||
dnl be either signed or unsigned.
|
||||
dnl
|
||||
AC_DEFUN([gcc_AC_C_ENUM_BF_UNSIGNED],
|
||||
[AC_CACHE_CHECK(for unsigned enumerated bitfields, gcc_cv_enum_bf_unsigned,
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([#include <stdlib.h>
|
||||
enum t { BLAH = 128 } ;
|
||||
struct s_t { enum t member : 8; } s ;
|
||||
int main(void)
|
||||
{
|
||||
s.member = BLAH;
|
||||
if (s.member < 0) exit(1);
|
||||
exit(0);
|
||||
|
||||
}])], gcc_cv_enum_bf_unsigned=yes, gcc_cv_enum_bf_unsigned=no, gcc_cv_enum_bf_unsigned=yes)])
|
||||
if test $gcc_cv_enum_bf_unsigned = yes; then
|
||||
AC_DEFINE(ENUM_BITFIELDS_ARE_UNSIGNED, 1,
|
||||
[Define if enumerated bitfields are treated as unsigned values.])
|
||||
fi])
|
||||
|
||||
dnl Probe number of bits in a byte.
|
||||
dnl Note C89 requires CHAR_BIT >= 8.
|
||||
dnl
|
||||
AC_DEFUN([gcc_AC_C_CHAR_BIT],
|
||||
[AC_CACHE_CHECK(for CHAR_BIT, gcc_cv_decl_char_bit,
|
||||
[AC_EGREP_CPP(found,
|
||||
[#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef CHAR_BIT
|
||||
found
|
||||
#endif], gcc_cv_decl_char_bit=yes, gcc_cv_decl_char_bit=no)
|
||||
])
|
||||
if test $gcc_cv_decl_char_bit = no; then
|
||||
AC_CACHE_CHECK(number of bits in a byte, gcc_cv_c_nbby,
|
||||
[i=8
|
||||
gcc_cv_c_nbby=
|
||||
while test $i -lt 65; do
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,
|
||||
[switch(0) {
|
||||
case (unsigned char)((unsigned long)1 << $i) == ((unsigned long)1 << $i):
|
||||
case (unsigned char)((unsigned long)1<<($i-1)) == ((unsigned long)1<<($i-1)):
|
||||
; }])],
|
||||
[gcc_cv_c_nbby=$i; break])
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
test -z "$gcc_cv_c_nbby" && gcc_cv_c_nbby=failed
|
||||
])
|
||||
if test $gcc_cv_c_nbby = failed; then
|
||||
AC_MSG_ERROR(cannot determine number of bits in a byte)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(CHAR_BIT, $gcc_cv_c_nbby,
|
||||
[Define as the number of bits in a byte, if \`limits.h' doesn't.])
|
||||
fi
|
||||
fi])
|
||||
|
||||
AC_DEFUN([gcc_AC_INITFINI_ARRAY],
|
||||
[AC_ARG_ENABLE(initfini-array,
|
||||
[ --enable-initfini-array use .init_array/.fini_array sections],
|
||||
[], [
|
||||
AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
|
||||
gcc_cv_initfini_array, [dnl
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
static int x = -1;
|
||||
int main (void) { return x; }
|
||||
int foo (void) { x = 0; }
|
||||
int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;])],
|
||||
[gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
|
||||
[gcc_cv_initfini_array=no])])
|
||||
enable_initfini_array=$gcc_cv_initfini_array
|
||||
])
|
||||
if test $enable_initfini_array = yes; then
|
||||
AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
|
||||
[Define .init_array/.fini_array sections are available and working.])
|
||||
fi])
|
||||
|
||||
dnl # _gcc_COMPUTE_GAS_VERSION
|
||||
dnl # Used by gcc_GAS_VERSION_GTE_IFELSE
|
||||
dnl #
|
||||
dnl # WARNING:
|
||||
dnl # gcc_cv_as_gas_srcdir must be defined before this.
|
||||
dnl # This gross requirement will go away eventually.
|
||||
AC_DEFUN([_gcc_COMPUTE_GAS_VERSION],
|
||||
[gcc_cv_as_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
|
||||
for f in $gcc_cv_as_bfd_srcdir/configure \
|
||||
$gcc_cv_as_gas_srcdir/configure \
|
||||
$gcc_cv_as_gas_srcdir/configure.in \
|
||||
$gcc_cv_as_gas_srcdir/Makefile.in ; do
|
||||
gcc_cv_gas_version=`sed -n -e 's/^[[ ]]*\(VERSION=[[0-9]]*\.[[0-9]]*.*\)/\1/p' < $f`
|
||||
if test x$gcc_cv_gas_version != x; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([[0-9]]*\)"`
|
||||
gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.\([[0-9]]*\)"`
|
||||
gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)"`
|
||||
case $gcc_cv_gas_patch_version in
|
||||
"") gcc_cv_gas_patch_version="0" ;;
|
||||
esac
|
||||
gcc_cv_gas_vers=`expr \( \( $gcc_cv_gas_major_version \* 1000 \) \
|
||||
+ $gcc_cv_gas_minor_version \) \* 1000 \
|
||||
+ $gcc_cv_gas_patch_version`
|
||||
]) []dnl # _gcc_COMPUTE_GAS_VERSION
|
||||
|
||||
dnl # gcc_GAS_VERSION_GTE_IFELSE([elf,] major, minor, patchlevel,
|
||||
dnl # [command_if_true = :], [command_if_false = :])
|
||||
dnl # Check to see if the version of GAS is greater than or
|
||||
dnl # equal to the specified version.
|
||||
dnl #
|
||||
dnl # The first ifelse() shortens the shell code if the patchlevel
|
||||
dnl # is unimportant (the usual case). The others handle missing
|
||||
dnl # commands. Note that the tests are structured so that the most
|
||||
dnl # common version number cases are tested first.
|
||||
AC_DEFUN([_gcc_GAS_VERSION_GTE_IFELSE],
|
||||
[ifelse([$1], elf,
|
||||
[if test $in_tree_gas_is_elf = yes \
|
||||
&&],
|
||||
[if]) test $gcc_cv_gas_vers -ge `expr \( \( $2 \* 1000 \) + $3 \) \* 1000 + $4`
|
||||
then dnl
|
||||
ifelse([$5],,:,[$5])[]dnl
|
||||
ifelse([$6],,,[
|
||||
else $6])
|
||||
fi])
|
||||
|
||||
AC_DEFUN([gcc_GAS_VERSION_GTE_IFELSE],
|
||||
[AC_REQUIRE([_gcc_COMPUTE_GAS_VERSION])dnl
|
||||
ifelse([$1], elf, [_gcc_GAS_VERSION_GTE_IFELSE($@)],
|
||||
[_gcc_GAS_VERSION_GTE_IFELSE(,$@)])])
|
||||
|
||||
dnl gcc_GAS_CHECK_FEATURE(description, cv, [[elf,]major,minor,patchlevel],
|
||||
dnl [extra switches to as], [assembler input],
|
||||
dnl [extra testing logic], [command if feature available])
|
||||
dnl
|
||||
dnl Checks for an assembler feature. If we are building an in-tree
|
||||
dnl gas, the feature is available if the associated assembler version
|
||||
dnl is greater than or equal to major.minor.patchlevel. If not, then
|
||||
dnl ASSEMBLER INPUT is fed to the assembler and the feature is available
|
||||
dnl if assembly succeeds. If EXTRA TESTING LOGIC is not the empty string,
|
||||
dnl then it is run instead of simply setting CV to "yes" - it is responsible
|
||||
dnl for doing so, if appropriate.
|
||||
AC_DEFUN([gcc_GAS_CHECK_FEATURE],
|
||||
[AC_CACHE_CHECK([assembler for $1], [$2],
|
||||
[[$2]=no
|
||||
ifelse([$3],,,[dnl
|
||||
if test $in_tree_gas = yes; then
|
||||
gcc_GAS_VERSION_GTE_IFELSE($3, [[$2]=yes])
|
||||
el])if test x$gcc_cv_as != x; then
|
||||
echo ifelse(m4_substr([$5],0,1),[$], "[$5]", '[$5]') > conftest.s
|
||||
if AC_TRY_COMMAND([$gcc_cv_as $4 -o conftest.o conftest.s >&AS_MESSAGE_LOG_FD])
|
||||
then
|
||||
ifelse([$6],, [$2]=yes, [$6])
|
||||
else
|
||||
echo "configure: failed program was" >&AS_MESSAGE_LOG_FD
|
||||
cat conftest.s >&AS_MESSAGE_LOG_FD
|
||||
fi
|
||||
rm -f conftest.o conftest.s
|
||||
fi])
|
||||
ifelse([$7],,,[dnl
|
||||
if test $[$2] = yes; then
|
||||
$7
|
||||
fi])])
|
||||
|
||||
dnl GCC_TARGET_TEMPLATE(KEY)
|
||||
dnl ------------------------
|
||||
dnl Define KEY as a valid configure key on the target machine.
|
||||
|
||||
m4_define([GCC_TARGET_TEMPLATE],
|
||||
[m4_define([GCC_TARGET_TEMPLATE($1)],[])])
|
||||
|
||||
dnl AH_TEMPLATE(KEY, DESCRIPTION)
|
||||
dnl -----------------------------
|
||||
dnl Issue an autoheader template for KEY, i.e., a comment composed of
|
||||
dnl DESCRIPTION (properly wrapped), and then #undef KEY. Redefinition
|
||||
dnl of the macro in autoheader.m4, to support definition of only a few
|
||||
dnl keys while compiling target libraries.
|
||||
|
||||
m4_define([AH_TEMPLATE],
|
||||
[AH_VERBATIM([$1],m4_text_wrap([$2 */], [ ], [/* ])
|
||||
m4_ifdef([GCC_TARGET_TEMPLATE($1)],[],[#ifndef USED_FOR_TARGET
|
||||
])[#undef $1]m4_ifdef([GCC_TARGET_TEMPLATE($1)],[],[
|
||||
#endif
|
||||
]))])
|
||||
|
||||
dnl Make sure that build_exeext is looked for
|
||||
AC_DEFUN([gcc_AC_BUILD_EXEEXT], [
|
||||
ac_executable_extensions="$build_exeext"])
|
||||
|
||||
880
contrib/gcc/aclocal.m4
vendored
880
contrib/gcc/aclocal.m4
vendored
|
|
@ -1,784 +1,104 @@
|
|||
sinclude(../config/acx.m4)
|
||||
sinclude(../config/accross.m4)
|
||||
sinclude(../config/gettext.m4)
|
||||
sinclude(../config/progtest.m4)
|
||||
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
|
||||
|
||||
dnl See if stdbool.h properly defines bool and true/false.
|
||||
AC_DEFUN([gcc_AC_HEADER_STDBOOL],
|
||||
[AC_CACHE_CHECK([for working stdbool.h],
|
||||
ac_cv_header_stdbool_h,
|
||||
[AC_TRY_COMPILE([#include <stdbool.h>],
|
||||
[bool foo = false;],
|
||||
ac_cv_header_stdbool_h=yes, ac_cv_header_stdbool_h=no)])
|
||||
if test $ac_cv_header_stdbool_h = yes; then
|
||||
AC_DEFINE(HAVE_STDBOOL_H, 1,
|
||||
[Define if you have a working <stdbool.h> header file.])
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is `.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[dnl Rely on autoconf to set up CDPATH properly.
|
||||
AC_PREREQ([2.50])dnl
|
||||
# expand $ac_aux_dir to an absolute path
|
||||
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||
])
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 3
|
||||
|
||||
# AM_PROG_CC_C_O
|
||||
# --------------
|
||||
# Like AC_PROG_CC_C_O, but changed for automake.
|
||||
AC_DEFUN([AM_PROG_CC_C_O],
|
||||
[AC_REQUIRE([AC_PROG_CC_C_O])dnl
|
||||
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
# FIXME: we rely on the cache variable name because
|
||||
# there is no other way.
|
||||
set dummy $CC
|
||||
ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
|
||||
if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
|
||||
# Losing compiler, so override with the script.
|
||||
# FIXME: It is wrong to rewrite CC.
|
||||
# But if we don't then we get into trouble of one sort or another.
|
||||
# A longer-term fix would be to have automake use am__CC in this case,
|
||||
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||
CC="$am_aux_dir/compile $CC"
|
||||
fi
|
||||
])
|
||||
|
||||
dnl See whether we can include both string.h and strings.h.
|
||||
AC_DEFUN([gcc_AC_HEADER_STRING],
|
||||
[AC_CACHE_CHECK([whether string.h and strings.h may both be included],
|
||||
gcc_cv_header_string,
|
||||
[AC_TRY_COMPILE([#include <string.h>
|
||||
#include <strings.h>], , gcc_cv_header_string=yes, gcc_cv_header_string=no)])
|
||||
if test $gcc_cv_header_string = yes; then
|
||||
AC_DEFINE(STRING_WITH_STRINGS, 1, [Define if you can safely include both <string.h> and <strings.h>.])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl See whether we need a declaration for a function.
|
||||
dnl The result is highly dependent on the INCLUDES passed in, so make sure
|
||||
dnl to use a different cache variable name in this macro if it is invoked
|
||||
dnl in a different context somewhere else.
|
||||
dnl gcc_AC_CHECK_DECL(SYMBOL,
|
||||
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
|
||||
AC_DEFUN([gcc_AC_CHECK_DECL],
|
||||
[AC_MSG_CHECKING([whether $1 is declared])
|
||||
AC_CACHE_VAL(gcc_cv_have_decl_$1,
|
||||
[AC_TRY_COMPILE([$4],
|
||||
[#ifndef $1
|
||||
char *(*pfn) = (char *(*)) $1 ;
|
||||
#endif], eval "gcc_cv_have_decl_$1=yes", eval "gcc_cv_have_decl_$1=no")])
|
||||
if eval "test \"`echo '$gcc_cv_have_decl_'$1`\" = yes"; then
|
||||
AC_MSG_RESULT(yes) ; ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no) ; ifelse([$3], , :, [$3])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
dnl Check multiple functions to see whether each needs a declaration.
|
||||
dnl Arrange to define HAVE_DECL_<FUNCTION> to 0 or 1 as appropriate.
|
||||
dnl gcc_AC_CHECK_DECLS(SYMBOLS,
|
||||
dnl [ACTION-IF-NEEDED [, ACTION-IF-NOT-NEEDED [, INCLUDES]]])
|
||||
AC_DEFUN([gcc_AC_CHECK_DECLS],
|
||||
[for ac_func in $1
|
||||
do
|
||||
changequote(, )dnl
|
||||
ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
|
||||
changequote([, ])dnl
|
||||
gcc_AC_CHECK_DECL($ac_func,
|
||||
[AC_DEFINE_UNQUOTED($ac_tr_decl, 1) $2],
|
||||
[AC_DEFINE_UNQUOTED($ac_tr_decl, 0) $3],
|
||||
dnl It is possible that the include files passed in here are local headers
|
||||
dnl which supply a backup declaration for the relevant prototype based on
|
||||
dnl the definition of (or lack of) the HAVE_DECL_ macro. If so, this test
|
||||
dnl will always return success. E.g. see libiberty.h's handling of
|
||||
dnl `basename'. To avoid this, we define the relevant HAVE_DECL_ macro to
|
||||
dnl 1 so that any local headers used do not provide their own prototype
|
||||
dnl during this test.
|
||||
#undef $ac_tr_decl
|
||||
#define $ac_tr_decl 1
|
||||
$4
|
||||
)
|
||||
done
|
||||
dnl Automatically generate config.h entries via autoheader.
|
||||
if test x = y ; then
|
||||
patsubst(translit([$1], [a-z], [A-Z]), [\w+],
|
||||
[AC_DEFINE([HAVE_DECL_\&], 1,
|
||||
[Define to 1 if we found this declaration otherwise define to 0.])])dnl
|
||||
fi
|
||||
])
|
||||
|
||||
dnl 'make compare' can be significantly faster, if cmp itself can
|
||||
dnl skip bytes instead of using tail. The test being performed is
|
||||
dnl "if cmp --ignore-initial=2 t1 t2 && ! cmp --ignore-initial=1 t1 t2"
|
||||
dnl but we need to sink errors and handle broken shells. We also test
|
||||
dnl for the parameter format "cmp file1 file2 skip1 skip2" which is
|
||||
dnl accepted by cmp on some systems.
|
||||
AC_DEFUN([gcc_AC_PROG_CMP_IGNORE_INITIAL],
|
||||
[AC_CACHE_CHECK([for cmp's capabilities], gcc_cv_prog_cmp_skip,
|
||||
[ echo abfoo >t1
|
||||
echo cdfoo >t2
|
||||
gcc_cv_prog_cmp_skip=slowcompare
|
||||
if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then
|
||||
if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
gcc_cv_prog_cmp_skip=gnucompare
|
||||
fi
|
||||
fi
|
||||
if test $gcc_cv_prog_cmp_skip = slowcompare ; then
|
||||
if cmp t1 t2 2 2 > /dev/null 2>&1; then
|
||||
if cmp t1 t2 1 1 > /dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
gcc_cv_prog_cmp_skip=fastcompare
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
rm t1 t2
|
||||
])
|
||||
make_compare_target=$gcc_cv_prog_cmp_skip
|
||||
AC_SUBST(make_compare_target)
|
||||
])
|
||||
|
||||
dnl See if the printf functions in libc support %p in format strings.
|
||||
AC_DEFUN([gcc_AC_FUNC_PRINTF_PTR],
|
||||
[AC_CACHE_CHECK(whether the printf functions support %p,
|
||||
gcc_cv_func_printf_ptr,
|
||||
[AC_TRY_RUN([#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char buf[64];
|
||||
char *p = buf, *q = NULL;
|
||||
sprintf(buf, "%p", p);
|
||||
sscanf(buf, "%p", &q);
|
||||
return (p != q);
|
||||
}], gcc_cv_func_printf_ptr=yes, gcc_cv_func_printf_ptr=no,
|
||||
gcc_cv_func_printf_ptr=no)
|
||||
rm -f core core.* *.core])
|
||||
if test $gcc_cv_func_printf_ptr = yes ; then
|
||||
AC_DEFINE(HAVE_PRINTF_PTR, 1, [Define if printf supports "%p".])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl See if symbolic links work and if not, try to substitute either hard links or simple copy.
|
||||
AC_DEFUN([gcc_AC_PROG_LN_S],
|
||||
[AC_MSG_CHECKING(whether ln -s works)
|
||||
AC_CACHE_VAL(gcc_cv_prog_LN_S,
|
||||
[rm -f conftestdata_t
|
||||
echo >conftestdata_f
|
||||
if ln -s conftestdata_f conftestdata_t 2>/dev/null
|
||||
then
|
||||
gcc_cv_prog_LN_S="ln -s"
|
||||
else
|
||||
if ln conftestdata_f conftestdata_t 2>/dev/null
|
||||
then
|
||||
gcc_cv_prog_LN_S=ln
|
||||
else
|
||||
gcc_cv_prog_LN_S=cp
|
||||
fi
|
||||
fi
|
||||
rm -f conftestdata_f conftestdata_t
|
||||
])dnl
|
||||
LN_S="$gcc_cv_prog_LN_S"
|
||||
if test "$gcc_cv_prog_LN_S" = "ln -s"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
if test "$gcc_cv_prog_LN_S" = "ln"; then
|
||||
AC_MSG_RESULT([no, using ln])
|
||||
else
|
||||
AC_MSG_RESULT([no, and neither does ln, so using cp])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(LN_S)dnl
|
||||
])
|
||||
|
||||
dnl See if hard links work and if not, try to substitute either symbolic links or simple copy.
|
||||
AC_DEFUN([gcc_AC_PROG_LN],
|
||||
[AC_MSG_CHECKING(whether ln works)
|
||||
AC_CACHE_VAL(gcc_cv_prog_LN,
|
||||
[rm -f conftestdata_t
|
||||
echo >conftestdata_f
|
||||
if ln conftestdata_f conftestdata_t 2>/dev/null
|
||||
then
|
||||
gcc_cv_prog_LN="ln"
|
||||
else
|
||||
if ln -s conftestdata_f conftestdata_t 2>/dev/null
|
||||
then
|
||||
gcc_cv_prog_LN="ln -s"
|
||||
else
|
||||
gcc_cv_prog_LN=cp
|
||||
fi
|
||||
fi
|
||||
rm -f conftestdata_f conftestdata_t
|
||||
])dnl
|
||||
LN="$gcc_cv_prog_LN"
|
||||
if test "$gcc_cv_prog_LN" = "ln"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
if test "$gcc_cv_prog_LN" = "ln -s"; then
|
||||
AC_MSG_RESULT([no, using ln -s])
|
||||
else
|
||||
AC_MSG_RESULT([no, and neither does ln -s, so using cp])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(LN)dnl
|
||||
])
|
||||
|
||||
dnl Check whether _Bool is built-in.
|
||||
AC_DEFUN([gcc_AC_C__BOOL],
|
||||
[AC_CACHE_CHECK(for built-in _Bool, gcc_cv_c__bool,
|
||||
[AC_TRY_COMPILE(,
|
||||
[_Bool foo;],
|
||||
gcc_cv_c__bool=yes, gcc_cv_c__bool=no)
|
||||
])
|
||||
if test $gcc_cv_c__bool = yes; then
|
||||
AC_DEFINE(HAVE__BOOL, 1, [Define if the \`_Bool' type is built-in.])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
|
||||
dnl of the usual 2.
|
||||
AC_DEFUN([gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG],
|
||||
[AC_CACHE_CHECK([if mkdir takes one argument], gcc_cv_mkdir_takes_one_arg,
|
||||
[AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_DIRECT_H
|
||||
# include <direct.h>
|
||||
#endif], [mkdir ("foo", 0);],
|
||||
gcc_cv_mkdir_takes_one_arg=no, gcc_cv_mkdir_takes_one_arg=yes)])
|
||||
if test $gcc_cv_mkdir_takes_one_arg = yes ; then
|
||||
AC_DEFINE(MKDIR_TAKES_ONE_ARG, 1, [Define if host mkdir takes a single argument.])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([gcc_AC_PROG_INSTALL],
|
||||
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
|
||||
# Find a good install program. We prefer a C program (faster),
|
||||
# so one script is as good as another. But avoid the broken or
|
||||
# incompatible versions:
|
||||
# SysV /etc/install, /usr/sbin/install
|
||||
# SunOS /usr/etc/install
|
||||
# IRIX /sbin/install
|
||||
# AIX /bin/install
|
||||
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
|
||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||
# ./install, which can be erroneously created by make from ./install.sh.
|
||||
AC_MSG_CHECKING(for a BSD compatible install)
|
||||
if test -z "$INSTALL"; then
|
||||
AC_CACHE_VAL(ac_cv_path_install,
|
||||
[ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
|
||||
for ac_dir in $PATH; do
|
||||
# Account for people who put trailing slashes in PATH elements.
|
||||
case "$ac_dir/" in
|
||||
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
|
||||
*)
|
||||
# OSF1 and SCO ODT 3.0 have their own names for install.
|
||||
for ac_prog in ginstall scoinst install; do
|
||||
if test -f $ac_dir/$ac_prog; then
|
||||
if test $ac_prog = install &&
|
||||
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
|
||||
# AIX install. It has an incompatible calling convention.
|
||||
# OSF/1 installbsd also uses dspmsg, but is usable.
|
||||
:
|
||||
else
|
||||
ac_cv_path_install="$ac_dir/$ac_prog -c"
|
||||
break 2
|
||||
fi
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
done
|
||||
IFS="$ac_save_IFS"
|
||||
])dnl
|
||||
if test "${ac_cv_path_install+set}" = set; then
|
||||
INSTALL="$ac_cv_path_install"
|
||||
else
|
||||
# As a last resort, use the slow shell script. We don't cache a
|
||||
# path for INSTALL within a source directory, because that will
|
||||
# break other packages using the cache if that directory is
|
||||
# removed, or if the path is relative.
|
||||
INSTALL="$ac_install_sh"
|
||||
fi
|
||||
fi
|
||||
dnl We do special magic for INSTALL instead of AC_SUBST, to get
|
||||
dnl relative paths right.
|
||||
AC_MSG_RESULT($INSTALL)
|
||||
AC_SUBST(INSTALL)dnl
|
||||
|
||||
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
|
||||
# It thinks the first close brace ends the variable substitution.
|
||||
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
|
||||
AC_SUBST(INSTALL_PROGRAM)dnl
|
||||
|
||||
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
|
||||
AC_SUBST(INSTALL_DATA)dnl
|
||||
])
|
||||
|
||||
dnl Test for GNAT.
|
||||
dnl We require the gnatbind program, and a compiler driver that
|
||||
dnl understands Ada. We use the user's CC setting, already found.
|
||||
dnl
|
||||
dnl Sets the shell variable have_gnat to yes or no as appropriate, and
|
||||
dnl substitutes GNATBIND.
|
||||
AC_DEFUN([gcc_AC_PROG_GNAT],
|
||||
[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_CHECK_TOOL(GNATBIND, gnatbind, no)
|
||||
AC_CACHE_CHECK([whether compiler driver understands Ada],
|
||||
gcc_cv_cc_supports_ada,
|
||||
[cat >conftest.adb <<EOF
|
||||
procedure conftest is begin null; end conftest;
|
||||
EOF
|
||||
gcc_cv_cc_supports_ada=no
|
||||
# There is a bug in old released versions of GCC which causes the
|
||||
# driver to exit successfully when the appropriate language module
|
||||
# has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
|
||||
# Therefore we must check for the error message as well as an
|
||||
# unsuccessful exit.
|
||||
# Other compilers, like HP Tru64 UNIX cc, exit successfully when
|
||||
# given a .adb file, but produce no object file. So we must check
|
||||
# if an object file was really produced to guard against this.
|
||||
errors=`(${CC} -c conftest.adb) 2>&1 || echo failure`
|
||||
if test x"$errors" = x && test -f conftest.$ac_objext; then
|
||||
gcc_cv_cc_supports_ada=yes
|
||||
break
|
||||
fi
|
||||
rm -f conftest.*])
|
||||
|
||||
if test x$GNATBIND != xno && test x$gcc_cv_cc_supports_ada != xno; then
|
||||
have_gnat=yes
|
||||
else
|
||||
have_gnat=no
|
||||
fi
|
||||
])
|
||||
|
||||
dnl GCC_PATH_PROG(VARIABLE, PROG-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND [, PATH]])
|
||||
dnl like AC_PATH_PROG but use other cache variables
|
||||
AC_DEFUN([GCC_PATH_PROG],
|
||||
[# Extract the first word of "$2", so it can be a program name with args.
|
||||
set dummy $2; ac_word=[$]2
|
||||
AC_MSG_CHECKING([for $ac_word])
|
||||
AC_CACHE_VAL(gcc_cv_path_$1,
|
||||
[case "[$]$1" in
|
||||
/*)
|
||||
gcc_cv_path_$1="[$]$1" # Let the user override the test with a path.
|
||||
;;
|
||||
?:/*)
|
||||
gcc_cv_path_$1="[$]$1" # Let the user override the test with a dos path.
|
||||
;;
|
||||
*)
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
|
||||
dnl $ac_dummy forces splitting on constant user-supplied paths.
|
||||
dnl POSIX.2 word splitting is done only on the output of word expansions,
|
||||
dnl not every word. This closes a longstanding sh security hole.
|
||||
ac_dummy="ifelse([$4], , $PATH, [$4])"
|
||||
for ac_dir in $ac_dummy; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f $ac_dir/$ac_word; then
|
||||
gcc_cv_path_$1="$ac_dir/$ac_word"
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
dnl If no 3rd arg is given, leave the cache variable unset,
|
||||
dnl so GCC_PATH_PROGS will keep looking.
|
||||
ifelse([$3], , , [ test -z "[$]gcc_cv_path_$1" && gcc_cv_path_$1="$3"
|
||||
])dnl
|
||||
;;
|
||||
esac])dnl
|
||||
$1="$gcc_cv_path_$1"
|
||||
if test -n "[$]$1"; then
|
||||
AC_MSG_RESULT([$]$1)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
AC_SUBST($1)dnl
|
||||
])
|
||||
|
||||
# mmap(2) blacklisting. Some platforms provide the mmap library routine
|
||||
# but don't support all of the features we need from it.
|
||||
AC_DEFUN([gcc_AC_FUNC_MMAP_BLACKLIST],
|
||||
[if test $ac_cv_header_sys_mman_h != yes \
|
||||
|| test $ac_cv_func_mmap != yes; then
|
||||
gcc_cv_func_mmap_file=no
|
||||
gcc_cv_func_mmap_dev_zero=no
|
||||
gcc_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether read-only mmap of a plain file works],
|
||||
gcc_cv_func_mmap_file,
|
||||
[# Add a system to this blacklist if
|
||||
# mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
|
||||
# memory area containing the same data that you'd get if you applied
|
||||
# read() to the same fd. The only system known to have a problem here
|
||||
# is VMS, where text files have record structure.
|
||||
case "$host_os" in
|
||||
vms* | ultrix*)
|
||||
gcc_cv_func_mmap_file=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_file=yes;;
|
||||
esac])
|
||||
AC_CACHE_CHECK([whether mmap from /dev/zero works],
|
||||
gcc_cv_func_mmap_dev_zero,
|
||||
[# Add a system to this blacklist if it has mmap() but /dev/zero
|
||||
# does not exist, or if mmapping /dev/zero does not give anonymous
|
||||
# zeroed pages with both the following properties:
|
||||
# 1. If you map N consecutive pages in with one call, and then
|
||||
# unmap any subset of those pages, the pages that were not
|
||||
# explicitly unmapped remain accessible.
|
||||
# 2. If you map two adjacent blocks of memory and then unmap them
|
||||
# both at once, they must both go away.
|
||||
# Systems known to be in this category are Windows (all variants),
|
||||
# VMS, and Darwin.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | darwin* | ultrix* | hpux10* | hpux11.00)
|
||||
gcc_cv_func_mmap_dev_zero=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_dev_zero=yes;;
|
||||
esac])
|
||||
|
||||
# Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
|
||||
AC_CACHE_CHECK([for MAP_ANON(YMOUS)], gcc_cv_decl_map_anon,
|
||||
[AC_TRY_COMPILE(
|
||||
[#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
],
|
||||
[int n = MAP_ANONYMOUS;],
|
||||
gcc_cv_decl_map_anon=yes,
|
||||
gcc_cv_decl_map_anon=no)])
|
||||
|
||||
if test $gcc_cv_decl_map_anon = no; then
|
||||
gcc_cv_func_mmap_anon=no
|
||||
else
|
||||
AC_CACHE_CHECK([whether mmap with MAP_ANON(YMOUS) works],
|
||||
gcc_cv_func_mmap_anon,
|
||||
[# Add a system to this blacklist if it has mmap() and MAP_ANON or
|
||||
# MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
||||
# doesn't give anonymous zeroed pages with the same properties listed
|
||||
# above for use of /dev/zero.
|
||||
# Systems known to be in this category are Windows, VMS, and SCO Unix.
|
||||
case "$host_os" in
|
||||
vms* | cygwin* | pe | mingw* | sco* | udk* )
|
||||
gcc_cv_func_mmap_anon=no ;;
|
||||
*)
|
||||
gcc_cv_func_mmap_anon=yes;;
|
||||
esac])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $gcc_cv_func_mmap_file = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_FILE, 1,
|
||||
[Define if read-only mmap of a plain file works.])
|
||||
fi
|
||||
if test $gcc_cv_func_mmap_dev_zero = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_DEV_ZERO, 1,
|
||||
[Define if mmap of /dev/zero works.])
|
||||
fi
|
||||
if test $gcc_cv_func_mmap_anon = yes; then
|
||||
AC_DEFINE(HAVE_MMAP_ANON, 1,
|
||||
[Define if mmap with MAP_ANON(YMOUS) works.])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Locate a program and check that its version is acceptable.
|
||||
dnl AC_PROG_CHECK_VER(var, name, version-switch,
|
||||
dnl version-extract-regexp, version-glob)
|
||||
AC_DEFUN([gcc_AC_CHECK_PROG_VER],
|
||||
[AC_CHECK_PROG([$1], [$2], [$2])
|
||||
if test -n "[$]$1"; then
|
||||
# Found it, now check the version.
|
||||
AC_CACHE_CHECK(for modern $2, gcc_cv_prog_$2_modern,
|
||||
[changequote(<<,>>)dnl
|
||||
ac_prog_version=`<<$>>$1 $3 2>&1 |
|
||||
sed -n 's/^.*patsubst(<<$4>>,/,\/).*$/\1/p'`
|
||||
changequote([,])dnl
|
||||
echo "configure:__oline__: version of $2 is $ac_prog_version" >&AC_FD_CC
|
||||
changequote(<<,>>)dnl
|
||||
case $ac_prog_version in
|
||||
'') gcc_cv_prog_$2_modern=no;;
|
||||
<<$5>>)
|
||||
gcc_cv_prog_$2_modern=yes;;
|
||||
*) gcc_cv_prog_$2_modern=no;;
|
||||
esac
|
||||
changequote([,])dnl
|
||||
])
|
||||
else
|
||||
gcc_cv_prog_$2_modern=no
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Determine if enumerated bitfields are unsigned. ISO C says they can
|
||||
dnl be either signed or unsigned.
|
||||
dnl
|
||||
AC_DEFUN([gcc_AC_C_ENUM_BF_UNSIGNED],
|
||||
[AC_CACHE_CHECK(for unsigned enumerated bitfields, gcc_cv_enum_bf_unsigned,
|
||||
[AC_TRY_RUN(#include <stdlib.h>
|
||||
enum t { BLAH = 128 } ;
|
||||
struct s_t { enum t member : 8; } s ;
|
||||
int main(void)
|
||||
{
|
||||
s.member = BLAH;
|
||||
if (s.member < 0) exit(1);
|
||||
exit(0);
|
||||
|
||||
}, gcc_cv_enum_bf_unsigned=yes, gcc_cv_enum_bf_unsigned=no, gcc_cv_enum_bf_unsigned=yes)])
|
||||
if test $gcc_cv_enum_bf_unsigned = yes; then
|
||||
AC_DEFINE(ENUM_BITFIELDS_ARE_UNSIGNED, 1,
|
||||
[Define if enumerated bitfields are treated as unsigned values.])
|
||||
fi])
|
||||
|
||||
dnl Probe number of bits in a byte.
|
||||
dnl Note C89 requires CHAR_BIT >= 8.
|
||||
dnl
|
||||
AC_DEFUN([gcc_AC_C_CHAR_BIT],
|
||||
[AC_CACHE_CHECK(for CHAR_BIT, gcc_cv_decl_char_bit,
|
||||
[AC_EGREP_CPP(found,
|
||||
[#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef CHAR_BIT
|
||||
found
|
||||
#endif], gcc_cv_decl_char_bit=yes, gcc_cv_decl_char_bit=no)
|
||||
])
|
||||
if test $gcc_cv_decl_char_bit = no; then
|
||||
AC_CACHE_CHECK(number of bits in a byte, gcc_cv_c_nbby,
|
||||
[i=8
|
||||
gcc_cv_c_nbby=
|
||||
while test $i -lt 65; do
|
||||
AC_TRY_COMPILE(,
|
||||
[switch(0) {
|
||||
case (unsigned char)((unsigned long)1 << $i) == ((unsigned long)1 << $i):
|
||||
case (unsigned char)((unsigned long)1<<($i-1)) == ((unsigned long)1<<($i-1)):
|
||||
; }],
|
||||
[gcc_cv_c_nbby=$i; break])
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
test -z "$gcc_cv_c_nbby" && gcc_cv_c_nbby=failed
|
||||
])
|
||||
if test $gcc_cv_c_nbby = failed; then
|
||||
AC_MSG_ERROR(cannot determine number of bits in a byte)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(CHAR_BIT, $gcc_cv_c_nbby,
|
||||
[Define as the number of bits in a byte, if \`limits.h' doesn't.])
|
||||
fi
|
||||
fi])
|
||||
|
||||
dnl Checking for long long.
|
||||
dnl By Caolan McNamara <caolan@skynet.ie>
|
||||
dnl Added check for __int64, Zack Weinberg <zackw@stanford.edu>
|
||||
dnl
|
||||
AC_DEFUN([gcc_AC_C_LONG_LONG],
|
||||
[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long,
|
||||
[AC_TRY_COMPILE(,[long long int i;],
|
||||
ac_cv_c_long_long=yes,
|
||||
ac_cv_c_long_long=no)])
|
||||
if test $ac_cv_c_long_long = yes; then
|
||||
AC_DEFINE(HAVE_LONG_LONG, 1,
|
||||
[Define if your compiler supports the \`long long' type.])
|
||||
fi
|
||||
AC_CACHE_CHECK(for __int64, ac_cv_c___int64,
|
||||
[AC_TRY_COMPILE(,[__int64 i;],
|
||||
ac_cv_c___int64=yes,
|
||||
ac_cv_c___int64=no)])
|
||||
if test $ac_cv_c___int64 = yes; then
|
||||
AC_DEFINE(HAVE___INT64, 1,
|
||||
[Define if your compiler supports the \`__int64' type.])
|
||||
fi
|
||||
])
|
||||
|
||||
#serial AM2
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
AC_DEFUN([AM_ICONV],
|
||||
[
|
||||
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
|
||||
dnl those with the standalone portable GNU libiconv installed).
|
||||
|
||||
am_cv_lib_iconv_ldpath=
|
||||
AC_ARG_WITH([libiconv-prefix],
|
||||
[ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib], [
|
||||
for dir in `echo "$withval" | tr : ' '`; do
|
||||
if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
|
||||
if test -d $dir/lib; then am_cv_lib_iconv_ldpath="-L$dir/lib"; fi
|
||||
done
|
||||
])
|
||||
|
||||
AC_CHECK_HEADERS([iconv.h])
|
||||
|
||||
AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
|
||||
am_cv_func_iconv="no, consider installing GNU libiconv"
|
||||
am_cv_lib_iconv=no
|
||||
AC_TRY_LINK([#include <stdlib.h>
|
||||
#include <iconv.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);],
|
||||
am_cv_func_iconv=yes)
|
||||
if test "$am_cv_func_iconv" != yes; then
|
||||
am_save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $am_cv_libiconv_ldpath -liconv"
|
||||
AC_TRY_LINK([#include <stdlib.h>
|
||||
#include <iconv.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);],
|
||||
am_cv_lib_iconv=yes
|
||||
am_cv_func_iconv=yes)
|
||||
LIBS="$am_save_LIBS"
|
||||
fi
|
||||
])
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
|
||||
AC_MSG_CHECKING([for iconv declaration])
|
||||
AC_CACHE_VAL(am_cv_proto_iconv, [
|
||||
AC_TRY_COMPILE([
|
||||
#include <stdlib.h>
|
||||
#include <iconv.h>
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
|
||||
#else
|
||||
size_t iconv();
|
||||
#endif
|
||||
], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
|
||||
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
|
||||
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
|
||||
AC_MSG_RESULT([$]{ac_t:-
|
||||
}[$]am_cv_proto_iconv)
|
||||
AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
|
||||
[Define as const if the declaration of iconv() needs const.])
|
||||
fi
|
||||
LIBICONV=
|
||||
if test "$am_cv_lib_iconv" = yes; then
|
||||
LIBICONV="$am_cv_lib_iconv_ldpath -liconv"
|
||||
fi
|
||||
AC_SUBST(LIBICONV)
|
||||
])
|
||||
|
||||
AC_DEFUN([gcc_AC_INITFINI_ARRAY],
|
||||
[AC_ARG_ENABLE(initfini-array,
|
||||
[ --enable-initfini-array use .init_array/.fini_array sections],
|
||||
[], [
|
||||
AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
|
||||
gcc_cv_initfini_array, [dnl
|
||||
AC_TRY_RUN([
|
||||
static int x = -1;
|
||||
int main (void) { return x; }
|
||||
int foo (void) { x = 0; }
|
||||
int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;],
|
||||
[gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
|
||||
[gcc_cv_initfini_array=no])])
|
||||
enable_initfini_array=$gcc_cv_initfini_array
|
||||
])
|
||||
if test $enable_initfini_array = yes; then
|
||||
AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
|
||||
[Define .init_array/.fini_array sections are available and working.])
|
||||
fi])
|
||||
|
||||
dnl # _gcc_COMPUTE_GAS_VERSION
|
||||
dnl # Used by gcc_GAS_VERSION_GTE_IFELSE
|
||||
dnl #
|
||||
dnl # WARNING:
|
||||
dnl # gcc_cv_as_gas_srcdir must be defined before this.
|
||||
dnl # This gross requirement will go away eventually.
|
||||
AC_DEFUN([_gcc_COMPUTE_GAS_VERSION],
|
||||
[gcc_cv_as_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
|
||||
for f in $gcc_cv_as_bfd_srcdir/configure \
|
||||
$gcc_cv_as_gas_srcdir/configure \
|
||||
$gcc_cv_as_gas_srcdir/configure.in \
|
||||
$gcc_cv_as_gas_srcdir/Makefile.in ; do
|
||||
gcc_cv_gas_version=`grep '^VERSION=[[0-9]]*\.[[0-9]]*' $f`
|
||||
if test x$gcc_cv_gas_version != x; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([[0-9]]*\)"`
|
||||
gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.\([[0-9]]*\)"`
|
||||
gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)"`
|
||||
case $gcc_cv_gas_patch_version in
|
||||
"") gcc_cv_gas_patch_version="0" ;;
|
||||
esac
|
||||
gcc_cv_gas_vers=`expr \( \( $gcc_cv_gas_major_version \* 1000 \) \
|
||||
+ $gcc_cv_gas_minor_version \) \* 1000 \
|
||||
+ $gcc_cv_gas_patch_version`
|
||||
]) []dnl # _gcc_COMPUTE_GAS_VERSION
|
||||
|
||||
dnl # gcc_GAS_VERSION_GTE_IFELSE([elf,] major, minor, patchlevel,
|
||||
dnl # [command_if_true = :], [command_if_false = :])
|
||||
dnl # Check to see if the version of GAS is greater than or
|
||||
dnl # equal to the specified version.
|
||||
dnl #
|
||||
dnl # The first ifelse() shortens the shell code if the patchlevel
|
||||
dnl # is unimportant (the usual case). The others handle missing
|
||||
dnl # commands. Note that the tests are structured so that the most
|
||||
dnl # common version number cases are tested first.
|
||||
AC_DEFUN([_gcc_GAS_VERSION_GTE_IFELSE],
|
||||
[ifelse([$1], elf,
|
||||
[if test $in_tree_gas_is_elf = yes \
|
||||
&&],
|
||||
[if]) test $gcc_cv_gas_vers -ge `expr \( \( $2 \* 1000 \) + $3 \) \* 1000 + $4`
|
||||
then dnl
|
||||
ifelse([$5],,:,[$5])[]dnl
|
||||
ifelse([$6],,,[
|
||||
else $6])
|
||||
fi])
|
||||
|
||||
AC_DEFUN([gcc_GAS_VERSION_GTE_IFELSE],
|
||||
[AC_REQUIRE([_gcc_COMPUTE_GAS_VERSION])dnl
|
||||
ifelse([$1], elf, [_gcc_GAS_VERSION_GTE_IFELSE($@)],
|
||||
[_gcc_GAS_VERSION_GTE_IFELSE(,$@)])])
|
||||
|
||||
dnl gcc_GAS_CHECK_FEATURE(description, cv, [[elf,]major,minor,patchlevel],
|
||||
dnl [extra switches to as], [assembler input],
|
||||
dnl [extra testing logic], [command if feature available])
|
||||
dnl
|
||||
dnl Checks for an assembler feature. If we are building an in-tree
|
||||
dnl gas, the feature is available if the associated assembler version
|
||||
dnl is greater than or equal to major.minor.patchlevel. If not, then
|
||||
dnl ASSEMBLER INPUT is fed to the assembler and the feature is available
|
||||
dnl if assembly succeeds. If EXTRA TESTING LOGIC is not the empty string,
|
||||
dnl then it is run instead of simply setting CV to "yes" - it is responsible
|
||||
dnl for doing so, if appropriate.
|
||||
AC_DEFUN([gcc_GAS_CHECK_FEATURE],
|
||||
[AC_CACHE_CHECK([assembler for $1], [$2],
|
||||
[[$2]=no
|
||||
ifelse([$3],,,[dnl
|
||||
if test $in_tree_gas = yes; then
|
||||
gcc_GAS_VERSION_GTE_IFELSE($3, [[$2]=yes])
|
||||
el])if test x$gcc_cv_as != x; then
|
||||
echo ifelse(m4_substr([$5],0,1),[$], "[$5]", '[$5]') > conftest.s
|
||||
if AC_TRY_COMMAND([$gcc_cv_as $4 -o conftest.o conftest.s >&AC_FD_CC])
|
||||
then
|
||||
ifelse([$6],, [$2]=yes, [$6])
|
||||
else
|
||||
echo "configure: failed program was" >&AC_FD_CC
|
||||
cat conftest.s >&AC_FD_CC
|
||||
fi
|
||||
rm -f conftest.o conftest.s
|
||||
fi])
|
||||
ifelse([$7],,,[dnl
|
||||
if test $[$2] = yes; then
|
||||
$7
|
||||
fi])])
|
||||
|
||||
# lcmessage.m4 serial 3 (gettext-0.11.3)
|
||||
dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
|
||||
dnl This file is free software, distributed under the terms of the GNU
|
||||
dnl General Public License. As a special exception to the GNU General
|
||||
dnl Public License, this file may be distributed as part of a program
|
||||
dnl that contains a configuration script generated by Autoconf, under
|
||||
dnl the same distribution terms as the rest of that program.
|
||||
dnl
|
||||
dnl This file can can be used in projects which are not available under
|
||||
dnl the GNU General Public License or the GNU Library General Public
|
||||
dnl License but which still want to provide support for the GNU gettext
|
||||
dnl functionality.
|
||||
dnl Please note that the actual code of the GNU gettext library is covered
|
||||
dnl by the GNU Library General Public License, and the rest of the GNU
|
||||
dnl gettext package package is covered by the GNU General Public License.
|
||||
dnl They are *not* in the public domain.
|
||||
|
||||
dnl Authors:
|
||||
dnl Ulrich Drepper <drepper@cygnus.com>, 1995.
|
||||
|
||||
# Check whether LC_MESSAGES is available in <locale.h>.
|
||||
|
||||
AC_DEFUN([AM_LC_MESSAGES],
|
||||
[
|
||||
AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
|
||||
[AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
|
||||
am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
|
||||
if test $am_cv_val_LC_MESSAGES = yes; then
|
||||
AC_DEFINE(HAVE_LC_MESSAGES, 1,
|
||||
[Define if your <locale.h> file defines LC_MESSAGES.])
|
||||
fi
|
||||
])
|
||||
m4_include([../config/acx.m4])
|
||||
m4_include([../config/codeset.m4])
|
||||
m4_include([../config/gettext-sister.m4])
|
||||
m4_include([../config/iconv.m4])
|
||||
m4_include([../config/lcmessage.m4])
|
||||
m4_include([../config/lib-ld.m4])
|
||||
m4_include([../config/lib-link.m4])
|
||||
m4_include([../config/lib-prefix.m4])
|
||||
m4_include([../config/progtest.m4])
|
||||
m4_include([acinclude.m4])
|
||||
|
|
|
|||
81
contrib/gcc/addresses.h
Normal file
81
contrib/gcc/addresses.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/* Inline functions to test validity of reg classes for addressing modes.
|
||||
Copyright (C) 2006 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, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* Wrapper function to unify target macros MODE_CODE_BASE_REG_CLASS,
|
||||
MODE_BASE_REG_REG_CLASS, MODE_BASE_REG_CLASS and BASE_REG_CLASS.
|
||||
Arguments as for the MODE_CODE_BASE_REG_CLASS macro. */
|
||||
|
||||
static inline enum reg_class
|
||||
base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
enum rtx_code outer_code ATTRIBUTE_UNUSED,
|
||||
enum rtx_code index_code ATTRIBUTE_UNUSED)
|
||||
{
|
||||
#ifdef MODE_CODE_BASE_REG_CLASS
|
||||
return MODE_CODE_BASE_REG_CLASS (mode, outer_code, index_code);
|
||||
#else
|
||||
#ifdef MODE_BASE_REG_REG_CLASS
|
||||
if (index_code == REG)
|
||||
return MODE_BASE_REG_REG_CLASS (mode);
|
||||
#endif
|
||||
#ifdef MODE_BASE_REG_CLASS
|
||||
return MODE_BASE_REG_CLASS (mode);
|
||||
#else
|
||||
return BASE_REG_CLASS;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Wrapper function to unify target macros REGNO_MODE_CODE_OK_FOR_BASE_P,
|
||||
REGNO_MODE_OK_FOR_REG_BASE_P, REGNO_MODE_OK_FOR_BASE_P and
|
||||
REGNO_OK_FOR_BASE_P.
|
||||
Arguments as for the REGNO_MODE_CODE_OK_FOR_BASE_P macro. */
|
||||
|
||||
static inline bool
|
||||
ok_for_base_p_1 (unsigned regno, enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
enum rtx_code outer_code ATTRIBUTE_UNUSED,
|
||||
enum rtx_code index_code ATTRIBUTE_UNUSED)
|
||||
{
|
||||
#ifdef REGNO_MODE_CODE_OK_FOR_BASE_P
|
||||
return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, outer_code, index_code);
|
||||
#else
|
||||
#ifdef REGNO_MODE_OK_FOR_REG_BASE_P
|
||||
if (index_code == REG)
|
||||
return REGNO_MODE_OK_FOR_REG_BASE_P (regno, mode);
|
||||
#endif
|
||||
#ifdef REGNO_MODE_OK_FOR_BASE_P
|
||||
return REGNO_MODE_OK_FOR_BASE_P (regno, mode);
|
||||
#else
|
||||
return REGNO_OK_FOR_BASE_P (regno);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Wrapper around ok_for_base_p_1, for use after register allocation is
|
||||
complete. Arguments as for the called function. */
|
||||
|
||||
static inline bool
|
||||
regno_ok_for_base_p (unsigned regno, enum machine_mode mode,
|
||||
enum rtx_code outer_code, enum rtx_code index_code)
|
||||
{
|
||||
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
|
||||
regno = reg_renumber[regno];
|
||||
|
||||
return ok_for_base_p_1 (regno, mode, outer_code, index_code);
|
||||
}
|
||||
1005
contrib/gcc/alias.c
1005
contrib/gcc/alias.c
File diff suppressed because it is too large
Load diff
35
contrib/gcc/alias.h
Normal file
35
contrib/gcc/alias.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* Exported functions from alias.c
|
||||
Copyright (C) 2004 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, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_ALIAS_H
|
||||
#define GCC_ALIAS_H
|
||||
|
||||
extern HOST_WIDE_INT new_alias_set (void);
|
||||
extern HOST_WIDE_INT get_varargs_alias_set (void);
|
||||
extern HOST_WIDE_INT get_frame_alias_set (void);
|
||||
extern bool component_uses_parent_alias_set (tree);
|
||||
|
||||
/* This alias set can be used to force a memory to conflict with all
|
||||
other memories, creating a barrier across which no memory reference
|
||||
can move. Note that there are other legacy ways to create such
|
||||
memory barriers, including an address of SCRATCH. */
|
||||
#define ALIAS_SET_MEMORY_BARRIER ((HOST_WIDE_INT) -1)
|
||||
|
||||
#endif /* GCC_ALIAS_H */
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/* Functions to support a pool of allocatable objects.
|
||||
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2003, 2004
|
||||
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Daniel Berlin <dan@cgsoftware.com>
|
||||
|
||||
|
|
@ -17,24 +17,14 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "alloc-pool.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
/* Redefine abort to report an internal error w/o coredump, and
|
||||
reporting the location of the error in the source file. This logic
|
||||
is duplicated in rtl.h and tree.h because every file that needs the
|
||||
special abort includes one or both. toplev.h gets too few files,
|
||||
system.h gets too many. */
|
||||
|
||||
extern void fancy_abort (const char *, int, const char *)
|
||||
ATTRIBUTE_NORETURN;
|
||||
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
|
||||
|
||||
#define align_eight(x) (((x+7) >> 3) << 3)
|
||||
|
||||
/* The internal allocation object. */
|
||||
|
|
@ -75,7 +65,7 @@ static ALLOC_POOL_ID_TYPE last_id;
|
|||
|
||||
#ifdef GATHER_STATISTICS
|
||||
|
||||
/* Store infromation about each particular alloc_pool. */
|
||||
/* Store information about each particular alloc_pool. */
|
||||
struct alloc_pool_descriptor
|
||||
{
|
||||
const char *name;
|
||||
|
|
@ -113,7 +103,7 @@ alloc_pool_descriptor (const char *name)
|
|||
|
||||
slot = (struct alloc_pool_descriptor **)
|
||||
htab_find_slot_with_hash (alloc_pool_hash, name,
|
||||
htab_hash_pointer (name),
|
||||
htab_hash_pointer (name),
|
||||
1);
|
||||
if (*slot)
|
||||
return *slot;
|
||||
|
|
@ -135,8 +125,7 @@ create_alloc_pool (const char *name, size_t size, size_t num)
|
|||
struct alloc_pool_descriptor *desc;
|
||||
#endif
|
||||
|
||||
if (!name)
|
||||
abort ();
|
||||
gcc_assert (name);
|
||||
|
||||
/* Make size large enough to store the list header. */
|
||||
if (size < sizeof (alloc_pool_list))
|
||||
|
|
@ -151,8 +140,7 @@ create_alloc_pool (const char *name, size_t size, size_t num)
|
|||
#endif
|
||||
|
||||
/* Um, we can't really allocate 0 elements per block. */
|
||||
if (num == 0)
|
||||
abort ();
|
||||
gcc_assert (num);
|
||||
|
||||
/* Find the size of the pool structure, and the name. */
|
||||
pool_size = sizeof (struct alloc_pool_def);
|
||||
|
|
@ -201,10 +189,7 @@ free_alloc_pool (alloc_pool pool)
|
|||
struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (!pool)
|
||||
abort ();
|
||||
#endif
|
||||
gcc_assert (pool);
|
||||
|
||||
/* Free each block allocated to the pool. */
|
||||
for (block = pool->block_list; block != NULL; block = next_block)
|
||||
|
|
@ -215,13 +200,24 @@ free_alloc_pool (alloc_pool pool)
|
|||
desc->current -= pool->block_size;
|
||||
#endif
|
||||
}
|
||||
/* Lastly, free the pool. */
|
||||
#ifdef ENABLE_CHECKING
|
||||
memset (pool, 0xaf, sizeof (*pool));
|
||||
#endif
|
||||
/* Lastly, free the pool. */
|
||||
free (pool);
|
||||
}
|
||||
|
||||
/* Frees the alloc_pool, if it is empty and zero *POOL in this case. */
|
||||
void
|
||||
free_alloc_pool_if_empty (alloc_pool *pool)
|
||||
{
|
||||
if ((*pool)->elts_free == (*pool)->elts_allocated)
|
||||
{
|
||||
free_alloc_pool (*pool);
|
||||
*pool = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocates one element from the pool specified. */
|
||||
void *
|
||||
pool_alloc (alloc_pool pool)
|
||||
|
|
@ -234,10 +230,7 @@ pool_alloc (alloc_pool pool)
|
|||
desc->allocated+=pool->elt_size;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (!pool)
|
||||
abort ();
|
||||
#endif
|
||||
gcc_assert (pool);
|
||||
|
||||
/* If there are no more free elements, make some more!. */
|
||||
if (!pool->free_list)
|
||||
|
|
@ -246,7 +239,7 @@ pool_alloc (alloc_pool pool)
|
|||
alloc_pool_list block_header;
|
||||
|
||||
/* Make the block. */
|
||||
block = xmalloc (pool->block_size);
|
||||
block = XNEWVEC (char, pool->block_size);
|
||||
block_header = (alloc_pool_list) block;
|
||||
block += align_eight (sizeof (struct alloc_pool_list_def));
|
||||
#ifdef GATHER_STATISTICS
|
||||
|
|
@ -266,12 +259,12 @@ pool_alloc (alloc_pool pool)
|
|||
/* Mark the element to be free. */
|
||||
((allocation_object *) block)->id = 0;
|
||||
#endif
|
||||
header = (alloc_pool_list) USER_PTR_FROM_ALLOCATION_OBJECT_PTR (block);
|
||||
header->next = pool->free_list;
|
||||
pool->free_list = header;
|
||||
header = (alloc_pool_list) USER_PTR_FROM_ALLOCATION_OBJECT_PTR (block);
|
||||
header->next = pool->free_list;
|
||||
pool->free_list = header;
|
||||
}
|
||||
/* Also update the number of elements we have free/allocated, and
|
||||
increment the allocated block count. */
|
||||
increment the allocated block count. */
|
||||
pool->elts_allocated += pool->elts_per_block;
|
||||
pool->elts_free += pool->elts_per_block;
|
||||
pool->blocks_allocated += 1;
|
||||
|
|
@ -296,22 +289,19 @@ pool_free (alloc_pool pool, void *ptr)
|
|||
{
|
||||
alloc_pool_list header;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (!ptr)
|
||||
abort ();
|
||||
gcc_assert (ptr);
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
memset (ptr, 0xaf, pool->elt_size - offsetof (allocation_object, u.data));
|
||||
|
||||
/* Check whether the PTR was allocated from POOL. */
|
||||
if (pool->id != ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id)
|
||||
abort ();
|
||||
gcc_assert (pool->id == ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id);
|
||||
|
||||
/* Mark the element to be free. */
|
||||
ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id = 0;
|
||||
#else
|
||||
/* Check if we free more than we allocated, which is Bad (TM). */
|
||||
if (pool->elts_free + 1 > pool->elts_allocated)
|
||||
abort ();
|
||||
gcc_assert (pool->elts_free < pool->elts_allocated);
|
||||
#endif
|
||||
|
||||
header = (alloc_pool_list) ptr;
|
||||
|
|
@ -349,11 +339,15 @@ print_statistics (void **slot, void *b)
|
|||
#endif
|
||||
|
||||
/* Output per-alloc_pool memory usage statistics. */
|
||||
void dump_alloc_pool_statistics (void)
|
||||
void
|
||||
dump_alloc_pool_statistics (void)
|
||||
{
|
||||
#ifdef GATHER_STATISTICS
|
||||
struct output_info info;
|
||||
|
||||
if (!alloc_pool_hash)
|
||||
return;
|
||||
|
||||
fprintf (stderr, "\nAlloc-pool Kind Pools Allocated Peak Leak\n");
|
||||
fprintf (stderr, "-------------------------------------------------------------\n");
|
||||
info.count = 0;
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ 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. */
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
#ifndef ALLOC_POOL_H
|
||||
#define ALLOC_POOL_H
|
||||
|
||||
|
|
@ -49,6 +49,7 @@ typedef struct alloc_pool_def
|
|||
|
||||
extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
|
||||
extern void free_alloc_pool (alloc_pool);
|
||||
extern void free_alloc_pool_if_empty (alloc_pool *);
|
||||
extern void *pool_alloc (alloc_pool);
|
||||
extern void pool_free (alloc_pool, void *);
|
||||
extern void dump_alloc_pool_statistics (void);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* Functions dealing with attribute handling, used by most front ends.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -29,7 +29,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "output.h"
|
||||
#include "rtl.h"
|
||||
#include "ggc.h"
|
||||
#include "expr.h"
|
||||
#include "tm_p.h"
|
||||
#include "cpplib.h"
|
||||
#include "target.h"
|
||||
|
|
@ -78,25 +77,25 @@ init_attributes (void)
|
|||
/* The name must not begin and end with __. */
|
||||
const char *name = attribute_tables[i][j].name;
|
||||
int len = strlen (name);
|
||||
if (name[0] == '_' && name[1] == '_'
|
||||
&& name[len - 1] == '_' && name[len - 2] == '_')
|
||||
abort ();
|
||||
|
||||
gcc_assert (!(name[0] == '_' && name[1] == '_'
|
||||
&& name[len - 1] == '_' && name[len - 2] == '_'));
|
||||
|
||||
/* The minimum and maximum lengths must be consistent. */
|
||||
if (attribute_tables[i][j].min_length < 0)
|
||||
abort ();
|
||||
if (attribute_tables[i][j].max_length != -1
|
||||
&& (attribute_tables[i][j].max_length
|
||||
< attribute_tables[i][j].min_length))
|
||||
abort ();
|
||||
gcc_assert (attribute_tables[i][j].min_length >= 0);
|
||||
|
||||
gcc_assert (attribute_tables[i][j].max_length == -1
|
||||
|| (attribute_tables[i][j].max_length
|
||||
>= attribute_tables[i][j].min_length));
|
||||
|
||||
/* An attribute cannot require both a DECL and a TYPE. */
|
||||
if (attribute_tables[i][j].decl_required
|
||||
&& attribute_tables[i][j].type_required)
|
||||
abort ();
|
||||
gcc_assert (!attribute_tables[i][j].decl_required
|
||||
|| !attribute_tables[i][j].type_required);
|
||||
|
||||
/* If an attribute requires a function type, in particular
|
||||
it requires a type. */
|
||||
if (attribute_tables[i][j].function_type_required
|
||||
&& !attribute_tables[i][j].type_required)
|
||||
abort ();
|
||||
gcc_assert (!attribute_tables[i][j].function_type_required
|
||||
|| attribute_tables[i][j].type_required);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,9 +105,8 @@ init_attributes (void)
|
|||
int j, k;
|
||||
for (j = 0; attribute_tables[i][j].name != NULL; j++)
|
||||
for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
|
||||
if (!strcmp (attribute_tables[i][j].name,
|
||||
attribute_tables[i][k].name))
|
||||
abort ();
|
||||
gcc_assert (strcmp (attribute_tables[i][j].name,
|
||||
attribute_tables[i][k].name));
|
||||
}
|
||||
/* Check that no name occurs in more than one table. */
|
||||
for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
|
||||
|
|
@ -118,9 +116,8 @@ init_attributes (void)
|
|||
for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
|
||||
for (k = 0; attribute_tables[i][k].name != NULL; k++)
|
||||
for (l = 0; attribute_tables[j][l].name != NULL; l++)
|
||||
if (!strcmp (attribute_tables[i][k].name,
|
||||
attribute_tables[j][l].name))
|
||||
abort ();
|
||||
gcc_assert (strcmp (attribute_tables[i][k].name,
|
||||
attribute_tables[j][l].name));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -145,7 +142,7 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
if (!attributes_initialized)
|
||||
init_attributes ();
|
||||
|
||||
(*targetm.insert_attributes) (*node, &attributes);
|
||||
targetm.insert_attributes (*node, &attributes);
|
||||
|
||||
for (a = attributes; a; a = TREE_CHAIN (a))
|
||||
{
|
||||
|
|
@ -175,7 +172,7 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
|
||||
if (spec == NULL)
|
||||
{
|
||||
warning ("`%s' attribute directive ignored",
|
||||
warning (OPT_Wattributes, "%qs attribute directive ignored",
|
||||
IDENTIFIER_POINTER (name));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -183,7 +180,7 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
|| (spec->max_length >= 0
|
||||
&& list_length (args) > spec->max_length))
|
||||
{
|
||||
error ("wrong number of arguments specified for `%s' attribute",
|
||||
error ("wrong number of arguments specified for %qs attribute",
|
||||
IDENTIFIER_POINTER (name));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -200,7 +197,7 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
}
|
||||
else
|
||||
{
|
||||
warning ("`%s' attribute does not apply to types",
|
||||
warning (OPT_Wattributes, "%qs attribute does not apply to types",
|
||||
IDENTIFIER_POINTER (name));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -230,8 +227,8 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
pull out the target type now, frob it as appropriate, and
|
||||
rebuild the pointer type later.
|
||||
|
||||
This would all be simpler if attributes were part of the
|
||||
declarator, grumble grumble. */
|
||||
This would all be simpler if attributes were part of the
|
||||
declarator, grumble grumble. */
|
||||
fn_ptr_tmp = TREE_TYPE (*anode);
|
||||
anode = &fn_ptr_tmp;
|
||||
flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
|
||||
|
|
@ -246,12 +243,21 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
if (TREE_CODE (*anode) != FUNCTION_TYPE
|
||||
&& TREE_CODE (*anode) != METHOD_TYPE)
|
||||
{
|
||||
warning ("`%s' attribute only applies to function types",
|
||||
warning (OPT_Wattributes,
|
||||
"%qs attribute only applies to function types",
|
||||
IDENTIFIER_POINTER (name));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (TYPE_P (*anode)
|
||||
&& (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
|
||||
&& TYPE_SIZE (*anode) != NULL_TREE)
|
||||
{
|
||||
warning (OPT_Wattributes, "type attributes ignored after type is already defined");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spec->handler != NULL)
|
||||
returned_attrs = chainon ((*spec->handler) (anode, name, args,
|
||||
flags, &no_add_attrs),
|
||||
|
|
@ -262,15 +268,7 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
&& (TREE_CODE (*node) == VAR_DECL
|
||||
|| TREE_CODE (*node) == PARM_DECL
|
||||
|| TREE_CODE (*node) == RESULT_DECL))
|
||||
{
|
||||
/* Force a recalculation of mode and size. */
|
||||
DECL_MODE (*node) = VOIDmode;
|
||||
DECL_SIZE (*node) = 0;
|
||||
if (!DECL_USER_ALIGN (*node))
|
||||
DECL_ALIGN (*node) = 0;
|
||||
|
||||
layout_decl (*node, 0);
|
||||
}
|
||||
relayout_decl (*node);
|
||||
|
||||
if (!no_add_attrs)
|
||||
{
|
||||
|
|
@ -296,7 +294,26 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
if (DECL_P (*anode))
|
||||
DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
|
||||
else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
|
||||
TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
|
||||
{
|
||||
TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
|
||||
/* If this is the main variant, also push the attributes
|
||||
out to the other variants. */
|
||||
if (*anode == TYPE_MAIN_VARIANT (*anode))
|
||||
{
|
||||
tree variant;
|
||||
for (variant = *anode; variant;
|
||||
variant = TYPE_NEXT_VARIANT (variant))
|
||||
{
|
||||
if (TYPE_ATTRIBUTES (variant) == old_attrs)
|
||||
TYPE_ATTRIBUTES (variant)
|
||||
= TYPE_ATTRIBUTES (*anode);
|
||||
else if (!lookup_attribute
|
||||
(spec->name, TYPE_ATTRIBUTES (variant)))
|
||||
TYPE_ATTRIBUTES (variant) = tree_cons
|
||||
(name, args, TYPE_ATTRIBUTES (variant));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*anode = build_type_attribute_variant (*anode,
|
||||
tree_cons (name, args,
|
||||
|
|
@ -311,114 +328,13 @@ decl_attributes (tree *node, tree attributes, int flags)
|
|||
fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
|
||||
if (DECL_P (*node))
|
||||
TREE_TYPE (*node) = fn_ptr_tmp;
|
||||
else if (TREE_CODE (*node) == POINTER_TYPE)
|
||||
*node = fn_ptr_tmp;
|
||||
else
|
||||
abort ();
|
||||
{
|
||||
gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
|
||||
*node = fn_ptr_tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returned_attrs;
|
||||
}
|
||||
|
||||
/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
|
||||
lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
|
||||
|
||||
The head of the declspec list is stored in DECLSPECS.
|
||||
The head of the attribute list is stored in PREFIX_ATTRIBUTES.
|
||||
|
||||
Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
|
||||
the list elements. We drop the containing TREE_LIST nodes and link the
|
||||
resulting attributes together the way decl_attributes expects them. */
|
||||
|
||||
void
|
||||
split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
|
||||
{
|
||||
tree t, s, a, next, specs, attrs;
|
||||
|
||||
/* This can happen after an __extension__ in pedantic mode. */
|
||||
if (specs_attrs != NULL_TREE
|
||||
&& TREE_CODE (specs_attrs) == INTEGER_CST)
|
||||
{
|
||||
*declspecs = NULL_TREE;
|
||||
*prefix_attributes = NULL_TREE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* This can happen in c++ (eg: decl: typespec initdecls ';'). */
|
||||
if (specs_attrs != NULL_TREE
|
||||
&& TREE_CODE (specs_attrs) != TREE_LIST)
|
||||
{
|
||||
*declspecs = specs_attrs;
|
||||
*prefix_attributes = NULL_TREE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remember to keep the lists in the same order, element-wise. */
|
||||
|
||||
specs = s = NULL_TREE;
|
||||
attrs = a = NULL_TREE;
|
||||
for (t = specs_attrs; t; t = next)
|
||||
{
|
||||
next = TREE_CHAIN (t);
|
||||
/* Declspecs have a non-NULL TREE_VALUE. */
|
||||
if (TREE_VALUE (t) != NULL_TREE)
|
||||
{
|
||||
if (specs == NULL_TREE)
|
||||
specs = s = t;
|
||||
else
|
||||
{
|
||||
TREE_CHAIN (s) = t;
|
||||
s = t;
|
||||
}
|
||||
}
|
||||
/* The TREE_PURPOSE may also be empty in the case of
|
||||
__attribute__(()). */
|
||||
else if (TREE_PURPOSE (t) != NULL_TREE)
|
||||
{
|
||||
if (attrs == NULL_TREE)
|
||||
attrs = a = TREE_PURPOSE (t);
|
||||
else
|
||||
{
|
||||
TREE_CHAIN (a) = TREE_PURPOSE (t);
|
||||
a = TREE_PURPOSE (t);
|
||||
}
|
||||
/* More attrs can be linked here, move A to the end. */
|
||||
while (TREE_CHAIN (a) != NULL_TREE)
|
||||
a = TREE_CHAIN (a);
|
||||
}
|
||||
}
|
||||
|
||||
/* Terminate the lists. */
|
||||
if (s != NULL_TREE)
|
||||
TREE_CHAIN (s) = NULL_TREE;
|
||||
if (a != NULL_TREE)
|
||||
TREE_CHAIN (a) = NULL_TREE;
|
||||
|
||||
/* All done. */
|
||||
*declspecs = specs;
|
||||
*prefix_attributes = attrs;
|
||||
}
|
||||
|
||||
/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
|
||||
This function is used by the parser when a rule will accept attributes
|
||||
in a particular position, but we don't want to support that just yet.
|
||||
|
||||
A warning is issued for every ignored attribute. */
|
||||
|
||||
tree
|
||||
strip_attrs (tree specs_attrs)
|
||||
{
|
||||
tree specs, attrs;
|
||||
|
||||
split_specs_attrs (specs_attrs, &specs, &attrs);
|
||||
|
||||
while (attrs)
|
||||
{
|
||||
warning ("`%s' attribute ignored",
|
||||
IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
|
||||
attrs = TREE_CHAIN (attrs);
|
||||
}
|
||||
|
||||
return specs;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1556
contrib/gcc/bitmap.c
1556
contrib/gcc/bitmap.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Functions to support general ended bitmaps.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,37 +16,49 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_BITMAP_H
|
||||
#define GCC_BITMAP_H
|
||||
#include "hashtab.h"
|
||||
|
||||
/* Fundamental storage type for bitmap. */
|
||||
|
||||
/* typedef unsigned HOST_WIDE_INT BITMAP_WORD; */
|
||||
/* #define nBITMAP_WORD_BITS HOST_BITS_PER_WIDE_INT */
|
||||
typedef unsigned long BITMAP_WORD;
|
||||
#define nBITMAP_WORD_BITS (CHAR_BIT * SIZEOF_LONG)
|
||||
#define BITMAP_WORD_BITS (unsigned) nBITMAP_WORD_BITS
|
||||
/* BITMAP_WORD_BITS needs to be unsigned, but cannot contain casts as
|
||||
it is used in preprocessor directives -- hence the 1u. */
|
||||
#define BITMAP_WORD_BITS (CHAR_BIT * SIZEOF_LONG * 1u)
|
||||
|
||||
/* Number of words to use for each element in the linked list. */
|
||||
|
||||
#ifndef BITMAP_ELEMENT_WORDS
|
||||
#define BITMAP_ELEMENT_WORDS ((128 + nBITMAP_WORD_BITS - 1) / nBITMAP_WORD_BITS)
|
||||
#define BITMAP_ELEMENT_WORDS ((128 + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS)
|
||||
#endif
|
||||
|
||||
/* Number of bits in each actual element of a bitmap. We get slightly better
|
||||
code for bit % BITMAP_ELEMENT_ALL_BITS and bit / BITMAP_ELEMENT_ALL_BITS if
|
||||
bits is unsigned, assuming it is a power of 2. */
|
||||
/* Number of bits in each actual element of a bitmap. */
|
||||
|
||||
#define BITMAP_ELEMENT_ALL_BITS \
|
||||
((unsigned) (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS))
|
||||
#define BITMAP_ELEMENT_ALL_BITS (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS)
|
||||
|
||||
/* Obstack for allocating bitmaps and elements from. */
|
||||
typedef struct bitmap_obstack GTY (())
|
||||
{
|
||||
struct bitmap_element_def *elements;
|
||||
struct bitmap_head_def *heads;
|
||||
struct obstack GTY ((skip)) obstack;
|
||||
} bitmap_obstack;
|
||||
|
||||
/* Bitmap set element. We use a linked list to hold only the bits that
|
||||
are set. This allows for use to grow the bitset dynamically without
|
||||
having to realloc and copy a giant bit array. The `prev' field is
|
||||
undefined for an element on the free list. */
|
||||
having to realloc and copy a giant bit array.
|
||||
|
||||
The free list is implemented as a list of lists. There is one
|
||||
outer list connected together by prev fields. Each element of that
|
||||
outer is an inner list (that may consist only of the outer list
|
||||
element) that are connected by the next fields. The prev pointer
|
||||
is undefined for interior elements. This allows
|
||||
bitmap_elt_clear_from to be implemented in unit time rather than
|
||||
linear in the number of elements to be freed. */
|
||||
|
||||
typedef struct bitmap_element_def GTY(())
|
||||
{
|
||||
|
|
@ -61,22 +73,14 @@ typedef struct bitmap_head_def GTY(()) {
|
|||
bitmap_element *first; /* First element in linked list. */
|
||||
bitmap_element *current; /* Last element looked at. */
|
||||
unsigned int indx; /* Index of last element looked at. */
|
||||
int using_obstack; /* Are we using an obstack or ggc for
|
||||
allocation? */
|
||||
bitmap_obstack *obstack; /* Obstack to allocate elements from.
|
||||
If NULL, then use ggc_alloc. */
|
||||
} bitmap_head;
|
||||
typedef struct bitmap_head_def *bitmap;
|
||||
|
||||
/* Enumeration giving the various operations we support. */
|
||||
enum bitmap_bits {
|
||||
BITMAP_AND, /* TO = FROM1 & FROM2 */
|
||||
BITMAP_AND_COMPL, /* TO = FROM1 & ~ FROM2 */
|
||||
BITMAP_IOR, /* TO = FROM1 | FROM2 */
|
||||
BITMAP_XOR, /* TO = FROM1 ^ FROM2 */
|
||||
BITMAP_IOR_COMPL /* TO = FROM1 | ~FROM2 */
|
||||
};
|
||||
|
||||
/* Global data */
|
||||
extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */
|
||||
extern bitmap_obstack bitmap_default_obstack; /* Default bitmap obstack */
|
||||
|
||||
/* Clear a bitmap by freeing up the linked list. */
|
||||
extern void bitmap_clear (bitmap);
|
||||
|
|
@ -85,14 +89,41 @@ extern void bitmap_clear (bitmap);
|
|||
extern void bitmap_copy (bitmap, bitmap);
|
||||
|
||||
/* True if two bitmaps are identical. */
|
||||
extern int bitmap_equal_p (bitmap, bitmap);
|
||||
extern bool bitmap_equal_p (bitmap, bitmap);
|
||||
|
||||
/* Perform an operation on two bitmaps, yielding a third. */
|
||||
extern int bitmap_operation (bitmap, bitmap, bitmap, enum bitmap_bits);
|
||||
/* True if the bitmaps intersect (their AND is non-empty). */
|
||||
extern bool bitmap_intersect_p (bitmap, bitmap);
|
||||
|
||||
/* `or' into one bitmap the `and' of a second bitmap witih the complement
|
||||
of a third. */
|
||||
extern void bitmap_ior_and_compl (bitmap, bitmap, bitmap);
|
||||
/* True if the complement of the second intersects the first (their
|
||||
AND_COMPL is non-empty). */
|
||||
extern bool bitmap_intersect_compl_p (bitmap, bitmap);
|
||||
|
||||
/* True if MAP is an empty bitmap. */
|
||||
#define bitmap_empty_p(MAP) (!(MAP)->first)
|
||||
|
||||
/* Count the number of bits set in the bitmap. */
|
||||
extern unsigned long bitmap_count_bits (bitmap);
|
||||
|
||||
/* Boolean operations on bitmaps. The _into variants are two operand
|
||||
versions that modify the first source operand. The other variants
|
||||
are three operand versions that to not destroy the source bitmaps.
|
||||
The operations supported are &, & ~, |, ^. */
|
||||
extern void bitmap_and (bitmap, bitmap, bitmap);
|
||||
extern void bitmap_and_into (bitmap, bitmap);
|
||||
extern void bitmap_and_compl (bitmap, bitmap, bitmap);
|
||||
extern bool bitmap_and_compl_into (bitmap, bitmap);
|
||||
#define bitmap_compl_and(DST, A, B) bitmap_and_compl (DST, B, A)
|
||||
extern void bitmap_compl_and_into (bitmap, bitmap);
|
||||
extern void bitmap_clear_range (bitmap, unsigned int, unsigned int);
|
||||
extern bool bitmap_ior (bitmap, bitmap, bitmap);
|
||||
extern bool bitmap_ior_into (bitmap, bitmap);
|
||||
extern void bitmap_xor (bitmap, bitmap, bitmap);
|
||||
extern void bitmap_xor_into (bitmap, bitmap);
|
||||
|
||||
/* DST = A | (B & ~C). Return true if DST changes. */
|
||||
extern bool bitmap_ior_and_compl (bitmap DST, bitmap A, bitmap B, bitmap C);
|
||||
/* A |= (B & ~C). Return true if A changes. */
|
||||
extern bool bitmap_ior_and_compl_into (bitmap DST, bitmap B, bitmap C);
|
||||
|
||||
/* Clear a single register in a register set. */
|
||||
extern void bitmap_clear_bit (bitmap, int);
|
||||
|
|
@ -110,246 +141,428 @@ extern void debug_bitmap_file (FILE *, bitmap);
|
|||
/* Print a bitmap. */
|
||||
extern void bitmap_print (FILE *, bitmap, const char *, const char *);
|
||||
|
||||
/* Initialize a bitmap header. If HEAD is NULL, a new header will be
|
||||
allocated. USING_OBSTACK indicates how elements should be allocated. */
|
||||
extern bitmap bitmap_initialize (bitmap head, int using_obstack);
|
||||
/* Initialize and release a bitmap obstack. */
|
||||
extern void bitmap_obstack_initialize (bitmap_obstack *);
|
||||
extern void bitmap_obstack_release (bitmap_obstack *);
|
||||
|
||||
/* Release all memory used by the bitmap obstack. */
|
||||
extern void bitmap_release_memory (void);
|
||||
/* Initialize a bitmap header. OBSTACK indicates the bitmap obstack
|
||||
to allocate from, NULL for GC'd bitmap. */
|
||||
|
||||
static inline void
|
||||
bitmap_initialize (bitmap head, bitmap_obstack *obstack)
|
||||
{
|
||||
head->first = head->current = NULL;
|
||||
head->obstack = obstack;
|
||||
}
|
||||
|
||||
/* Allocate and free bitmaps from obstack, malloc and gc'd memory. */
|
||||
extern bitmap bitmap_obstack_alloc (bitmap_obstack *obstack);
|
||||
extern bitmap bitmap_gc_alloc (void);
|
||||
extern void bitmap_obstack_free (bitmap);
|
||||
|
||||
/* A few compatibility/functions macros for compatibility with sbitmaps */
|
||||
#define dump_bitmap(file, bitmap) bitmap_print (file, bitmap, "", "\n")
|
||||
#define bitmap_zero(a) bitmap_clear (a)
|
||||
#define bitmap_a_or_b(a,b,c) bitmap_operation (a, b, c, BITMAP_IOR)
|
||||
#define bitmap_a_and_b(a,b,c) bitmap_operation (a, b, c, BITMAP_AND)
|
||||
extern int bitmap_union_of_diff (bitmap, bitmap, bitmap, bitmap);
|
||||
extern int bitmap_first_set_bit (bitmap);
|
||||
extern int bitmap_last_set_bit (bitmap);
|
||||
extern unsigned bitmap_first_set_bit (bitmap);
|
||||
|
||||
/* Allocate a bitmap with oballoc. */
|
||||
#define BITMAP_OBSTACK_ALLOC(OBSTACK) \
|
||||
bitmap_initialize (obstack_alloc (OBSTACK, sizeof (bitmap_head)), 1)
|
||||
/* Compute bitmap hash (for purposes of hashing etc.) */
|
||||
extern hashval_t bitmap_hash(bitmap);
|
||||
|
||||
/* Allocate a bitmap with ggc_alloc. */
|
||||
#define BITMAP_GGC_ALLOC() \
|
||||
bitmap_initialize (NULL, 0)
|
||||
/* Allocate a bitmap from a bit obstack. */
|
||||
#define BITMAP_ALLOC(OBSTACK) bitmap_obstack_alloc (OBSTACK)
|
||||
|
||||
/* Allocate a bitmap with xmalloc. */
|
||||
#define BITMAP_XMALLOC() \
|
||||
bitmap_initialize (xmalloc (sizeof (bitmap_head)), 1)
|
||||
/* Allocate a gc'd bitmap. */
|
||||
#define BITMAP_GGC_ALLOC() bitmap_gc_alloc ()
|
||||
|
||||
/* Do any cleanup needed on a bitmap when it is no longer used. */
|
||||
#define BITMAP_FREE(BITMAP) \
|
||||
do { \
|
||||
if (BITMAP) \
|
||||
{ \
|
||||
bitmap_clear (BITMAP); \
|
||||
(BITMAP) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
((void)(bitmap_obstack_free (BITMAP), (BITMAP) = NULL))
|
||||
|
||||
/* Do any cleanup needed on an xmalloced bitmap when it is no longer used. */
|
||||
#define BITMAP_XFREE(BITMAP) \
|
||||
do { \
|
||||
if (BITMAP) \
|
||||
{ \
|
||||
bitmap_clear (BITMAP); \
|
||||
free (BITMAP); \
|
||||
(BITMAP) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
/* Iterator for bitmaps. */
|
||||
|
||||
/* Do any one-time initializations needed for bitmaps. */
|
||||
#define BITMAP_INIT_ONCE()
|
||||
typedef struct
|
||||
{
|
||||
/* Pointer to the current bitmap element. */
|
||||
bitmap_element *elt1;
|
||||
|
||||
/* Loop over all bits in BITMAP, starting with MIN, setting BITNUM to the
|
||||
bit number and executing CODE for all bits that are set. */
|
||||
/* Pointer to 2nd bitmap element when two are involved. */
|
||||
bitmap_element *elt2;
|
||||
|
||||
#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, CODE) \
|
||||
do { \
|
||||
bitmap_element *ptr_ = (BITMAP)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % BITMAP_WORD_BITS; \
|
||||
unsigned word_num_ = (MIN) / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; \
|
||||
\
|
||||
\
|
||||
/* Find the block the minimum bit is in. */ \
|
||||
while (ptr_ != 0 && ptr_->indx < indx_) \
|
||||
ptr_ = ptr_->next; \
|
||||
\
|
||||
if (ptr_ != 0 && ptr_->indx != indx_) \
|
||||
{ \
|
||||
bit_num_ = 0; \
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
for (; ptr_ != 0; ptr_ = ptr_->next) \
|
||||
{ \
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
BITMAP_WORD word_ = ptr_->bits[word_num_]; \
|
||||
\
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < BITMAP_WORD_BITS; bit_num_++) \
|
||||
{ \
|
||||
BITMAP_WORD mask_ = ((BITMAP_WORD) 1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * BITMAP_WORD_BITS \
|
||||
+ bit_num_); \
|
||||
CODE; \
|
||||
\
|
||||
if (word_ == 0) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bit_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
/* Word within the current element. */
|
||||
unsigned word_no;
|
||||
|
||||
/* Loop over all bits in BITMAP1 and BITMAP2, starting with MIN, setting
|
||||
BITNUM to the bit number and executing CODE for all bits that are set in
|
||||
the first bitmap and not set in the second. */
|
||||
/* Contents of the actually processed word. When finding next bit
|
||||
it is shifted right, so that the actual bit is always the least
|
||||
significant bit of ACTUAL. */
|
||||
BITMAP_WORD bits;
|
||||
} bitmap_iterator;
|
||||
|
||||
#define EXECUTE_IF_AND_COMPL_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, CODE) \
|
||||
do { \
|
||||
bitmap_element *ptr1_ = (BITMAP1)->first; \
|
||||
bitmap_element *ptr2_ = (BITMAP2)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % BITMAP_WORD_BITS; \
|
||||
unsigned word_num_ = (MIN) / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; \
|
||||
\
|
||||
/* Find the block the minimum bit is in in the first bitmap. */ \
|
||||
while (ptr1_ != 0 && ptr1_->indx < indx_) \
|
||||
ptr1_ = ptr1_->next; \
|
||||
\
|
||||
if (ptr1_ != 0 && ptr1_->indx != indx_) \
|
||||
{ \
|
||||
bit_num_ = 0; \
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
for (; ptr1_ != 0 ; ptr1_ = ptr1_->next) \
|
||||
{ \
|
||||
/* Advance BITMAP2 to the equivalent link, using an all \
|
||||
zero element if an equivalent link doesn't exist. */ \
|
||||
bitmap_element *tmp2_; \
|
||||
\
|
||||
while (ptr2_ != 0 && ptr2_->indx < ptr1_->indx) \
|
||||
ptr2_ = ptr2_->next; \
|
||||
\
|
||||
tmp2_ = ((ptr2_ != 0 && ptr2_->indx == ptr1_->indx) \
|
||||
? ptr2_ : &bitmap_zero_bits); \
|
||||
\
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
BITMAP_WORD word_ = (ptr1_->bits[word_num_] \
|
||||
& ~ tmp2_->bits[word_num_]); \
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < BITMAP_WORD_BITS; bit_num_++) \
|
||||
{ \
|
||||
BITMAP_WORD mask_ = ((BITMAP_WORD) 1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr1_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * BITMAP_WORD_BITS \
|
||||
+ bit_num_); \
|
||||
\
|
||||
CODE; \
|
||||
if (word_ == 0) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bit_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
/* Initialize a single bitmap iterator. START_BIT is the first bit to
|
||||
iterate from. */
|
||||
|
||||
/* Loop over all bits in BITMAP1 and BITMAP2, starting with MIN, setting
|
||||
BITNUM to the bit number and executing CODE for all bits that are set in
|
||||
the both bitmaps. */
|
||||
static inline void
|
||||
bmp_iter_set_init (bitmap_iterator *bi, bitmap map,
|
||||
unsigned start_bit, unsigned *bit_no)
|
||||
{
|
||||
bi->elt1 = map->first;
|
||||
bi->elt2 = NULL;
|
||||
|
||||
#define EXECUTE_IF_AND_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, CODE) \
|
||||
do { \
|
||||
bitmap_element *ptr1_ = (BITMAP1)->first; \
|
||||
bitmap_element *ptr2_ = (BITMAP2)->first; \
|
||||
unsigned int indx_ = (MIN) / BITMAP_ELEMENT_ALL_BITS; \
|
||||
unsigned bit_num_ = (MIN) % BITMAP_WORD_BITS; \
|
||||
unsigned word_num_ = (MIN) / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; \
|
||||
\
|
||||
/* Find the block the minimum bit is in in the first bitmap. */ \
|
||||
while (ptr1_ != 0 && ptr1_->indx < indx_) \
|
||||
ptr1_ = ptr1_->next; \
|
||||
\
|
||||
if (ptr1_ != 0 && ptr1_->indx != indx_) \
|
||||
{ \
|
||||
bit_num_ = 0; \
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
for (; ptr1_ != 0 ; ptr1_ = ptr1_->next) \
|
||||
{ \
|
||||
/* Advance BITMAP2 to the equivalent link. */ \
|
||||
while (ptr2_ != 0 && ptr2_->indx < ptr1_->indx) \
|
||||
ptr2_ = ptr2_->next; \
|
||||
\
|
||||
if (ptr2_ == 0) \
|
||||
{ \
|
||||
/* If there are no more elements in BITMAP2, exit loop now. */ \
|
||||
ptr1_ = (bitmap_element *)0; \
|
||||
break; \
|
||||
} \
|
||||
else if (ptr2_->indx > ptr1_->indx) \
|
||||
{ \
|
||||
bit_num_ = word_num_ = 0; \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
|
||||
{ \
|
||||
BITMAP_WORD word_ = (ptr1_->bits[word_num_] \
|
||||
& ptr2_->bits[word_num_]); \
|
||||
if (word_ != 0) \
|
||||
{ \
|
||||
for (; bit_num_ < BITMAP_WORD_BITS; bit_num_++) \
|
||||
{ \
|
||||
BITMAP_WORD mask_ = ((BITMAP_WORD) 1) << bit_num_; \
|
||||
\
|
||||
if ((word_ & mask_) != 0) \
|
||||
{ \
|
||||
word_ &= ~ mask_; \
|
||||
(BITNUM) = (ptr1_->indx * BITMAP_ELEMENT_ALL_BITS \
|
||||
+ word_num_ * BITMAP_WORD_BITS \
|
||||
+ bit_num_); \
|
||||
\
|
||||
CODE; \
|
||||
if (word_ == 0) \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bit_num_ = 0; \
|
||||
} \
|
||||
\
|
||||
word_num_ = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
/* Advance elt1 until it is not before the block containing start_bit. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt1)
|
||||
{
|
||||
bi->elt1 = &bitmap_zero_bits;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
break;
|
||||
bi->elt1 = bi->elt1->next;
|
||||
}
|
||||
|
||||
/* We might have gone past the start bit, so reinitialize it. */
|
||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
/* Initialize for what is now start_bit. */
|
||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||
|
||||
/* If this word is zero, we must make sure we're not pointing at the
|
||||
first bit, otherwise our incrementing to the next word boundary
|
||||
will fail. It won't matter if this increment moves us into the
|
||||
next word. */
|
||||
start_bit += !bi->bits;
|
||||
|
||||
*bit_no = start_bit;
|
||||
}
|
||||
|
||||
/* Initialize an iterator to iterate over the intersection of two
|
||||
bitmaps. START_BIT is the bit to commence from. */
|
||||
|
||||
static inline void
|
||||
bmp_iter_and_init (bitmap_iterator *bi, bitmap map1, bitmap map2,
|
||||
unsigned start_bit, unsigned *bit_no)
|
||||
{
|
||||
bi->elt1 = map1->first;
|
||||
bi->elt2 = map2->first;
|
||||
|
||||
/* Advance elt1 until it is not before the block containing
|
||||
start_bit. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt1)
|
||||
{
|
||||
bi->elt2 = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
break;
|
||||
bi->elt1 = bi->elt1->next;
|
||||
}
|
||||
|
||||
/* Advance elt2 until it is not before elt1. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt2)
|
||||
{
|
||||
bi->elt1 = bi->elt2 = &bitmap_zero_bits;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt2->indx >= bi->elt1->indx)
|
||||
break;
|
||||
bi->elt2 = bi->elt2->next;
|
||||
}
|
||||
|
||||
/* If we're at the same index, then we have some intersecting bits. */
|
||||
if (bi->elt1->indx == bi->elt2->indx)
|
||||
{
|
||||
/* We might have advanced beyond the start_bit, so reinitialize
|
||||
for that. */
|
||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we must immediately advance elt1, so initialize for
|
||||
that. */
|
||||
bi->word_no = BITMAP_ELEMENT_WORDS - 1;
|
||||
bi->bits = 0;
|
||||
}
|
||||
|
||||
/* If this word is zero, we must make sure we're not pointing at the
|
||||
first bit, otherwise our incrementing to the next word boundary
|
||||
will fail. It won't matter if this increment moves us into the
|
||||
next word. */
|
||||
start_bit += !bi->bits;
|
||||
|
||||
*bit_no = start_bit;
|
||||
}
|
||||
|
||||
/* Initialize an iterator to iterate over the bits in MAP1 & ~MAP2.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
bmp_iter_and_compl_init (bitmap_iterator *bi, bitmap map1, bitmap map2,
|
||||
unsigned start_bit, unsigned *bit_no)
|
||||
{
|
||||
bi->elt1 = map1->first;
|
||||
bi->elt2 = map2->first;
|
||||
|
||||
/* Advance elt1 until it is not before the block containing start_bit. */
|
||||
while (1)
|
||||
{
|
||||
if (!bi->elt1)
|
||||
{
|
||||
bi->elt1 = &bitmap_zero_bits;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
break;
|
||||
bi->elt1 = bi->elt1->next;
|
||||
}
|
||||
|
||||
/* Advance elt2 until it is not before elt1. */
|
||||
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
||||
bi->elt2 = bi->elt2->next;
|
||||
|
||||
/* We might have advanced beyond the start_bit, so reinitialize for
|
||||
that. */
|
||||
if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS)
|
||||
start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
if (bi->elt2 && bi->elt1->indx == bi->elt2->indx)
|
||||
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
||||
bi->bits >>= start_bit % BITMAP_WORD_BITS;
|
||||
|
||||
/* If this word is zero, we must make sure we're not pointing at the
|
||||
first bit, otherwise our incrementing to the next word boundary
|
||||
will fail. It won't matter if this increment moves us into the
|
||||
next word. */
|
||||
start_bit += !bi->bits;
|
||||
|
||||
*bit_no = start_bit;
|
||||
}
|
||||
|
||||
/* Advance to the next bit in BI. We don't advance to the next
|
||||
nonzero bit yet. */
|
||||
|
||||
static inline void
|
||||
bmp_iter_next (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
bi->bits >>= 1;
|
||||
*bit_no += 1;
|
||||
}
|
||||
|
||||
/* Advance to the next nonzero bit of a single bitmap, we will have
|
||||
already advanced past the just iterated bit. Return true if there
|
||||
is a bit to iterate. */
|
||||
|
||||
static inline bool
|
||||
bmp_iter_set (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
/* If our current word is nonzero, it contains the bit we want. */
|
||||
if (bi->bits)
|
||||
{
|
||||
next_bit:
|
||||
while (!(bi->bits & 1))
|
||||
{
|
||||
bi->bits >>= 1;
|
||||
*bit_no += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Round up to the word boundary. We might have just iterated past
|
||||
the end of the last word, hence the -1. It is not possible for
|
||||
bit_no to point at the beginning of the now last word. */
|
||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||
bi->word_no++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Find the next nonzero word in this elt. */
|
||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||
{
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
if (bi->bits)
|
||||
goto next_bit;
|
||||
*bit_no += BITMAP_WORD_BITS;
|
||||
bi->word_no++;
|
||||
}
|
||||
|
||||
/* Advance to the next element. */
|
||||
bi->elt1 = bi->elt1->next;
|
||||
if (!bi->elt1)
|
||||
return false;
|
||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
bi->word_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance to the next nonzero bit of an intersecting pair of
|
||||
bitmaps. We will have already advanced past the just iterated bit.
|
||||
Return true if there is a bit to iterate. */
|
||||
|
||||
static inline bool
|
||||
bmp_iter_and (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
/* If our current word is nonzero, it contains the bit we want. */
|
||||
if (bi->bits)
|
||||
{
|
||||
next_bit:
|
||||
while (!(bi->bits & 1))
|
||||
{
|
||||
bi->bits >>= 1;
|
||||
*bit_no += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Round up to the word boundary. We might have just iterated past
|
||||
the end of the last word, hence the -1. It is not possible for
|
||||
bit_no to point at the beginning of the now last word. */
|
||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||
bi->word_no++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Find the next nonzero word in this elt. */
|
||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||
{
|
||||
bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no];
|
||||
if (bi->bits)
|
||||
goto next_bit;
|
||||
*bit_no += BITMAP_WORD_BITS;
|
||||
bi->word_no++;
|
||||
}
|
||||
|
||||
/* Advance to the next identical element. */
|
||||
do
|
||||
{
|
||||
/* Advance elt1 while it is less than elt2. We always want
|
||||
to advance one elt. */
|
||||
do
|
||||
{
|
||||
bi->elt1 = bi->elt1->next;
|
||||
if (!bi->elt1)
|
||||
return false;
|
||||
}
|
||||
while (bi->elt1->indx < bi->elt2->indx);
|
||||
|
||||
/* Advance elt2 to be no less than elt1. This might not
|
||||
advance. */
|
||||
while (bi->elt2->indx < bi->elt1->indx)
|
||||
{
|
||||
bi->elt2 = bi->elt2->next;
|
||||
if (!bi->elt2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while (bi->elt1->indx != bi->elt2->indx);
|
||||
|
||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
bi->word_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance to the next nonzero bit in the intersection of
|
||||
complemented bitmaps. We will have already advanced past the just
|
||||
iterated bit. */
|
||||
|
||||
static inline bool
|
||||
bmp_iter_and_compl (bitmap_iterator *bi, unsigned *bit_no)
|
||||
{
|
||||
/* If our current word is nonzero, it contains the bit we want. */
|
||||
if (bi->bits)
|
||||
{
|
||||
next_bit:
|
||||
while (!(bi->bits & 1))
|
||||
{
|
||||
bi->bits >>= 1;
|
||||
*bit_no += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Round up to the word boundary. We might have just iterated past
|
||||
the end of the last word, hence the -1. It is not possible for
|
||||
bit_no to point at the beginning of the now last word. */
|
||||
*bit_no = ((*bit_no + BITMAP_WORD_BITS - 1)
|
||||
/ BITMAP_WORD_BITS * BITMAP_WORD_BITS);
|
||||
bi->word_no++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Find the next nonzero word in this elt. */
|
||||
while (bi->word_no != BITMAP_ELEMENT_WORDS)
|
||||
{
|
||||
bi->bits = bi->elt1->bits[bi->word_no];
|
||||
if (bi->elt2 && bi->elt2->indx == bi->elt1->indx)
|
||||
bi->bits &= ~bi->elt2->bits[bi->word_no];
|
||||
if (bi->bits)
|
||||
goto next_bit;
|
||||
*bit_no += BITMAP_WORD_BITS;
|
||||
bi->word_no++;
|
||||
}
|
||||
|
||||
/* Advance to the next element of elt1. */
|
||||
bi->elt1 = bi->elt1->next;
|
||||
if (!bi->elt1)
|
||||
return false;
|
||||
|
||||
/* Advance elt2 until it is no less than elt1. */
|
||||
while (bi->elt2 && bi->elt2->indx < bi->elt1->indx)
|
||||
bi->elt2 = bi->elt2->next;
|
||||
|
||||
*bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS;
|
||||
bi->word_no = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop over all bits set in BITMAP, starting with MIN and setting
|
||||
BITNUM to the bit number. ITER is a bitmap iterator. BITNUM
|
||||
should be treated as a read-only variable as it contains loop
|
||||
state. */
|
||||
|
||||
#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, ITER) \
|
||||
for (bmp_iter_set_init (&(ITER), (BITMAP), (MIN), &(BITNUM)); \
|
||||
bmp_iter_set (&(ITER), &(BITNUM)); \
|
||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||
|
||||
/* Loop over all the bits set in BITMAP1 & BITMAP2, starting with MIN
|
||||
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
||||
BITNUM should be treated as a read-only variable as it contains
|
||||
loop state. */
|
||||
|
||||
#define EXECUTE_IF_AND_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
||||
for (bmp_iter_and_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
||||
&(BITNUM)); \
|
||||
bmp_iter_and (&(ITER), &(BITNUM)); \
|
||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||
|
||||
/* Loop over all the bits set in BITMAP1 & ~BITMAP2, starting with MIN
|
||||
and setting BITNUM to the bit number. ITER is a bitmap iterator.
|
||||
BITNUM should be treated as a read-only variable as it contains
|
||||
loop state. */
|
||||
|
||||
#define EXECUTE_IF_AND_COMPL_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \
|
||||
for (bmp_iter_and_compl_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \
|
||||
&(BITNUM)); \
|
||||
bmp_iter_and_compl (&(ITER), &(BITNUM)); \
|
||||
bmp_iter_next (&(ITER), &(BITNUM)))
|
||||
|
||||
#endif /* GCC_BITMAP_H */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/* Perform branch target register load optimizations.
|
||||
Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -15,20 +16,16 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "bitmap.h"
|
||||
#include "sbitmap.h"
|
||||
#include "rtl.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
#include "regs.h"
|
||||
#include "obstack.h"
|
||||
#include "fibheap.h"
|
||||
#include "output.h"
|
||||
#include "target.h"
|
||||
|
|
@ -36,7 +33,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "flags.h"
|
||||
#include "insn-attr.h"
|
||||
#include "function.h"
|
||||
#include "except.h"
|
||||
#include "tm_p.h"
|
||||
#include "toplev.h"
|
||||
#include "tree-pass.h"
|
||||
|
||||
/* Target register optimizations - these are performed after reload. */
|
||||
|
||||
|
|
@ -101,6 +101,10 @@ typedef struct btr_def_s
|
|||
as appropriate. */
|
||||
char other_btr_uses_before_def;
|
||||
char other_btr_uses_after_use;
|
||||
/* We set own_end when we have moved a definition into a dominator.
|
||||
Thus, when a later combination removes this definition again, we know
|
||||
to clear out trs_live_at_end again. */
|
||||
char own_end;
|
||||
bitmap live_range;
|
||||
} *btr_def;
|
||||
|
||||
|
|
@ -126,9 +130,9 @@ static void link_btr_uses (btr_def *, btr_user *, sbitmap *, sbitmap *, int);
|
|||
static void build_btr_def_use_webs (fibheap_t);
|
||||
static int block_at_edge_of_live_range_p (int, btr_def);
|
||||
static void clear_btr_from_live_range (btr_def def);
|
||||
static void add_btr_to_live_range (btr_def);
|
||||
static void add_btr_to_live_range (btr_def, int);
|
||||
static void augment_live_range (bitmap, HARD_REG_SET *, basic_block,
|
||||
basic_block);
|
||||
basic_block, int);
|
||||
static int choose_btr (HARD_REG_SET);
|
||||
static void combine_btr_defs (btr_def, HARD_REG_SET *);
|
||||
static void btr_def_live_range (btr_def, HARD_REG_SET *);
|
||||
|
|
@ -159,6 +163,10 @@ static struct obstack migrate_btrl_obstack;
|
|||
live in that block. */
|
||||
static HARD_REG_SET *btrs_live;
|
||||
|
||||
/* Array indexed by basic block number, giving the set of registers live at
|
||||
the end of that block, including any uses by a final jump insn, if any. */
|
||||
static HARD_REG_SET *btrs_live_at_end;
|
||||
|
||||
/* Set of all target registers that we are willing to allocate. */
|
||||
static HARD_REG_SET all_btrs;
|
||||
|
||||
|
|
@ -168,8 +176,7 @@ static int first_btr, last_btr;
|
|||
|
||||
|
||||
|
||||
/* Return an estimate of the frequency of execution of block bb.
|
||||
If we have a profiling count available, we could use it here. */
|
||||
/* Return an estimate of the frequency of execution of block bb. */
|
||||
static int
|
||||
basic_block_freq (basic_block bb)
|
||||
{
|
||||
|
|
@ -191,10 +198,10 @@ find_btr_reference (rtx *px, void *preg)
|
|||
if (px == preg)
|
||||
return -1;
|
||||
x = *px;
|
||||
if (GET_CODE (x) != REG)
|
||||
if (!REG_P (x))
|
||||
return 0;
|
||||
regno = REGNO (x);
|
||||
for (i = HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1; i >= 0; i--)
|
||||
for (i = hard_regno_nregs[regno][GET_MODE (x)] - 1; i >= 0; i--)
|
||||
if (TEST_HARD_REG_BIT (all_btrs, regno+i))
|
||||
{
|
||||
btr_reference_found = px;
|
||||
|
|
@ -221,7 +228,7 @@ insn_sets_btr_p (rtx insn, int check_const, int *regno)
|
|||
{
|
||||
rtx set;
|
||||
|
||||
if (GET_CODE (insn) == INSN
|
||||
if (NONJUMP_INSN_P (insn)
|
||||
&& (set = single_set (insn)))
|
||||
{
|
||||
rtx dest = SET_DEST (set);
|
||||
|
|
@ -230,11 +237,11 @@ insn_sets_btr_p (rtx insn, int check_const, int *regno)
|
|||
if (GET_CODE (dest) == SUBREG)
|
||||
dest = XEXP (dest, 0);
|
||||
|
||||
if (GET_CODE (dest) == REG
|
||||
if (REG_P (dest)
|
||||
&& TEST_HARD_REG_BIT (all_btrs, REGNO (dest)))
|
||||
{
|
||||
if (btr_referenced_p (src, NULL))
|
||||
abort();
|
||||
gcc_assert (!btr_referenced_p (src, NULL));
|
||||
|
||||
if (!check_const || CONSTANT_P (src))
|
||||
{
|
||||
if (regno)
|
||||
|
|
@ -315,8 +322,8 @@ add_btr_def (fibheap_t all_btr_defs, basic_block bb, int insn_luid, rtx insn,
|
|||
|
||||
fibheap_insert (all_btr_defs, -this->cost, this);
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Found target reg definition: sets %u { bb %d, insn %d }%s priority %d\n",
|
||||
dest_reg, bb->index, INSN_UID (insn), (this->group ? "" : ":not const"),
|
||||
this->cost);
|
||||
|
|
@ -359,13 +366,13 @@ new_btr_user (basic_block bb, int insn_luid, rtx insn)
|
|||
user->n_reaching_defs = 0;
|
||||
user->first_reaching_def = -1;
|
||||
|
||||
if (rtl_dump_file)
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (rtl_dump_file, "Uses target reg: { bb %d, insn %d }",
|
||||
fprintf (dump_file, "Uses target reg: { bb %d, insn %d }",
|
||||
bb->index, INSN_UID (insn));
|
||||
|
||||
if (user->use)
|
||||
fprintf (rtl_dump_file, ": unambiguous use of reg %d\n",
|
||||
fprintf (dump_file, ": unambiguous use of reg %d\n",
|
||||
REGNO (user->use));
|
||||
}
|
||||
|
||||
|
|
@ -379,16 +386,16 @@ dump_hard_reg_set (HARD_REG_SET s)
|
|||
int reg;
|
||||
for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
|
||||
if (TEST_HARD_REG_BIT (s, reg))
|
||||
fprintf (rtl_dump_file, " %d", reg);
|
||||
fprintf (dump_file, " %d", reg);
|
||||
}
|
||||
|
||||
/* Write the set of target regs live in block BB to the dump file. */
|
||||
static void
|
||||
dump_btrs_live (int bb)
|
||||
{
|
||||
fprintf (rtl_dump_file, "BB%d live:", bb);
|
||||
fprintf (dump_file, "BB%d live:", bb);
|
||||
dump_hard_reg_set (btrs_live[bb]);
|
||||
fprintf (rtl_dump_file, "\n");
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
/* REGNO is the number of a branch target register that is being used or
|
||||
|
|
@ -423,10 +430,10 @@ note_btr_set (rtx dest, rtx set ATTRIBUTE_UNUSED, void *data)
|
|||
defs_uses_info *info = data;
|
||||
int regno, end_regno;
|
||||
|
||||
if (GET_CODE (dest) != REG)
|
||||
if (!REG_P (dest))
|
||||
return;
|
||||
regno = REGNO (dest);
|
||||
end_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (dest));
|
||||
end_regno = regno + hard_regno_nregs[regno][GET_MODE (dest)];
|
||||
for (; regno < end_regno; regno++)
|
||||
if (TEST_HARD_REG_BIT (all_btrs, regno))
|
||||
{
|
||||
|
|
@ -455,13 +462,14 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array,
|
|||
defs_uses_info info;
|
||||
|
||||
sbitmap_vector_zero (bb_gen, n_basic_blocks);
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
int reg;
|
||||
btr_def defs_this_bb = NULL;
|
||||
rtx insn;
|
||||
rtx last;
|
||||
int can_throw = 0;
|
||||
|
||||
info.users_this_bb = NULL;
|
||||
info.bb_gen = bb_gen[i];
|
||||
|
|
@ -471,7 +479,7 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array,
|
|||
CLEAR_HARD_REG_SET (info.btrs_written_in_block);
|
||||
for (reg = first_btr; reg <= last_btr; reg++)
|
||||
if (TEST_HARD_REG_BIT (all_btrs, reg)
|
||||
&& REGNO_REG_SET_P (bb->global_live_at_start, reg))
|
||||
&& REGNO_REG_SET_P (bb->il.rtl->global_live_at_start, reg))
|
||||
SET_HARD_REG_BIT (info.btrs_live_in_block, reg);
|
||||
|
||||
for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb));
|
||||
|
|
@ -501,6 +509,22 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array,
|
|||
SET_BIT (btr_defset[regno - first_btr], insn_uid);
|
||||
note_other_use_this_block (regno, info.users_this_bb);
|
||||
}
|
||||
/* Check for the blockage emitted by expand_nl_goto_receiver. */
|
||||
else if (current_function_has_nonlocal_label
|
||||
&& GET_CODE (PATTERN (insn)) == ASM_INPUT)
|
||||
{
|
||||
btr_user user;
|
||||
|
||||
/* Do the equivalent of calling note_other_use_this_block
|
||||
for every target register. */
|
||||
for (user = info.users_this_bb; user != NULL;
|
||||
user = user->next)
|
||||
if (user->use)
|
||||
user->other_use_this_block = 1;
|
||||
IOR_HARD_REG_SET (info.btrs_written_in_block, all_btrs);
|
||||
IOR_HARD_REG_SET (info.btrs_live_in_block, all_btrs);
|
||||
sbitmap_zero (info.bb_gen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (btr_referenced_p (PATTERN (insn), NULL))
|
||||
|
|
@ -528,7 +552,7 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array,
|
|||
user->next = info.users_this_bb;
|
||||
info.users_this_bb = user;
|
||||
}
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
if (CALL_P (insn))
|
||||
{
|
||||
HARD_REG_SET *clobbered = &call_used_reg_set;
|
||||
HARD_REG_SET call_saved;
|
||||
|
|
@ -544,7 +568,7 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array,
|
|||
call_used_reg_set);
|
||||
clobbered = &call_saved;
|
||||
}
|
||||
|
||||
|
||||
for (regno = first_btr; regno <= last_btr; regno++)
|
||||
if (TEST_HARD_REG_BIT (*clobbered, regno))
|
||||
note_btr_set (regno_reg_rtx[regno], NULL_RTX, &info);
|
||||
|
|
@ -555,7 +579,36 @@ compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array,
|
|||
|
||||
COPY_HARD_REG_SET (btrs_live[i], info.btrs_live_in_block);
|
||||
COPY_HARD_REG_SET (btrs_written[i], info.btrs_written_in_block);
|
||||
if (rtl_dump_file)
|
||||
|
||||
REG_SET_TO_HARD_REG_SET (btrs_live_at_end[i], bb->il.rtl->global_live_at_end);
|
||||
/* If this block ends in a jump insn, add any uses or even clobbers
|
||||
of branch target registers that it might have. */
|
||||
for (insn = BB_END (bb); insn != BB_HEAD (bb) && ! INSN_P (insn); )
|
||||
insn = PREV_INSN (insn);
|
||||
/* ??? for the fall-through edge, it would make sense to insert the
|
||||
btr set on the edge, but that would require to split the block
|
||||
early on so that we can distinguish between dominance from the fall
|
||||
through edge - which can use the call-clobbered registers - from
|
||||
dominance by the throw edge. */
|
||||
if (can_throw_internal (insn))
|
||||
{
|
||||
HARD_REG_SET tmp;
|
||||
|
||||
COPY_HARD_REG_SET (tmp, call_used_reg_set);
|
||||
AND_HARD_REG_SET (tmp, all_btrs);
|
||||
IOR_HARD_REG_SET (btrs_live_at_end[i], tmp);
|
||||
can_throw = 1;
|
||||
}
|
||||
if (can_throw || JUMP_P (insn))
|
||||
{
|
||||
int regno;
|
||||
|
||||
for (regno = first_btr; regno <= last_btr; regno++)
|
||||
if (refers_to_regno_p (regno, regno+1, insn, NULL))
|
||||
SET_HARD_REG_BIT (btrs_live_at_end[i], regno);
|
||||
}
|
||||
|
||||
if (dump_file)
|
||||
dump_btrs_live(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -570,7 +623,7 @@ compute_kill (sbitmap *bb_kill, sbitmap *btr_defset,
|
|||
/* For each basic block, form the set BB_KILL - the set
|
||||
of definitions that the block kills. */
|
||||
sbitmap_vector_zero (bb_kill, n_basic_blocks);
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
|
||||
{
|
||||
for (regno = first_btr; regno <= last_btr; regno++)
|
||||
if (TEST_HARD_REG_BIT (all_btrs, regno)
|
||||
|
|
@ -593,14 +646,14 @@ compute_out (sbitmap *bb_out, sbitmap *bb_gen, sbitmap *bb_kill, int max_uid)
|
|||
int changed;
|
||||
sbitmap bb_in = sbitmap_alloc (max_uid);
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
|
||||
sbitmap_copy (bb_out[i], bb_gen[i]);
|
||||
|
||||
changed = 1;
|
||||
while (changed)
|
||||
{
|
||||
changed = 0;
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
|
||||
{
|
||||
sbitmap_union_of_preds (bb_in, bb_out, i);
|
||||
changed |= sbitmap_union_of_diff_cg (bb_out[i], bb_gen[i],
|
||||
|
|
@ -619,7 +672,7 @@ link_btr_uses (btr_def *def_array, btr_user *use_array, sbitmap *bb_out,
|
|||
|
||||
/* Link uses to the uses lists of all of their reaching defs.
|
||||
Count up the number of reaching defs of each use. */
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
rtx insn;
|
||||
|
|
@ -649,7 +702,8 @@ link_btr_uses (btr_def *def_array, btr_user *use_array, sbitmap *bb_out,
|
|||
{
|
||||
/* Find all the reaching defs for this use. */
|
||||
sbitmap reaching_defs_of_reg = sbitmap_alloc(max_uid);
|
||||
int uid;
|
||||
unsigned int uid = 0;
|
||||
sbitmap_iterator sbi;
|
||||
|
||||
if (user->use)
|
||||
sbitmap_a_and_b (
|
||||
|
|
@ -670,14 +724,14 @@ link_btr_uses (btr_def *def_array, btr_user *use_array, sbitmap *bb_out,
|
|||
reaching_defs,
|
||||
btr_defset[reg - first_btr]);
|
||||
}
|
||||
EXECUTE_IF_SET_IN_SBITMAP (reaching_defs_of_reg, 0, uid,
|
||||
EXECUTE_IF_SET_IN_SBITMAP (reaching_defs_of_reg, 0, uid, sbi)
|
||||
{
|
||||
btr_def def = def_array[uid];
|
||||
|
||||
/* We now know that def reaches user. */
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Def in insn %d reaches use in insn %d\n",
|
||||
uid, insn_uid);
|
||||
|
||||
|
|
@ -691,8 +745,8 @@ link_btr_uses (btr_def *def_array, btr_user *use_array, sbitmap *bb_out,
|
|||
def->has_ambiguous_use = 1;
|
||||
def_array[user->first_reaching_def]
|
||||
->has_ambiguous_use = 1;
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"(use %d has multiple reaching defs)\n",
|
||||
insn_uid);
|
||||
}
|
||||
|
|
@ -702,11 +756,11 @@ link_btr_uses (btr_def *def_array, btr_user *use_array, sbitmap *bb_out,
|
|||
def->other_btr_uses_after_use = 1;
|
||||
user->next = def->uses;
|
||||
def->uses = user;
|
||||
});
|
||||
}
|
||||
sbitmap_free (reaching_defs_of_reg);
|
||||
}
|
||||
|
||||
if (GET_CODE (insn) == CALL_INSN)
|
||||
if (CALL_P (insn))
|
||||
{
|
||||
int regno;
|
||||
|
||||
|
|
@ -726,12 +780,12 @@ static void
|
|||
build_btr_def_use_webs (fibheap_t all_btr_defs)
|
||||
{
|
||||
const int max_uid = get_max_uid ();
|
||||
btr_def *def_array = xcalloc (max_uid, sizeof (btr_def));
|
||||
btr_user *use_array = xcalloc (max_uid, sizeof (btr_user));
|
||||
btr_def *def_array = XCNEWVEC (btr_def, max_uid);
|
||||
btr_user *use_array = XCNEWVEC (btr_user, max_uid);
|
||||
sbitmap *btr_defset = sbitmap_vector_alloc (
|
||||
(last_btr - first_btr) + 1, max_uid);
|
||||
sbitmap *bb_gen = sbitmap_vector_alloc (n_basic_blocks, max_uid);
|
||||
HARD_REG_SET *btrs_written = xcalloc (n_basic_blocks, sizeof (HARD_REG_SET));
|
||||
HARD_REG_SET *btrs_written = XCNEWVEC (HARD_REG_SET, n_basic_blocks);
|
||||
sbitmap *bb_kill;
|
||||
sbitmap *bb_out;
|
||||
|
||||
|
|
@ -787,37 +841,49 @@ block_at_edge_of_live_range_p (int bb, btr_def def)
|
|||
static void
|
||||
clear_btr_from_live_range (btr_def def)
|
||||
{
|
||||
int bb;
|
||||
unsigned bb;
|
||||
bitmap_iterator bi;
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP
|
||||
(def->live_range, 0, bb,
|
||||
{
|
||||
if ((!def->other_btr_uses_before_def
|
||||
&& !def->other_btr_uses_after_use)
|
||||
|| !block_at_edge_of_live_range_p (bb, def))
|
||||
{
|
||||
CLEAR_HARD_REG_BIT (btrs_live[bb], def->btr);
|
||||
if (rtl_dump_file)
|
||||
dump_btrs_live (bb);
|
||||
}
|
||||
});
|
||||
EXECUTE_IF_SET_IN_BITMAP (def->live_range, 0, bb, bi)
|
||||
{
|
||||
if ((!def->other_btr_uses_before_def
|
||||
&& !def->other_btr_uses_after_use)
|
||||
|| !block_at_edge_of_live_range_p (bb, def))
|
||||
{
|
||||
CLEAR_HARD_REG_BIT (btrs_live[bb], def->btr);
|
||||
CLEAR_HARD_REG_BIT (btrs_live_at_end[bb], def->btr);
|
||||
if (dump_file)
|
||||
dump_btrs_live (bb);
|
||||
}
|
||||
}
|
||||
if (def->own_end)
|
||||
CLEAR_HARD_REG_BIT (btrs_live_at_end[def->bb->index], def->btr);
|
||||
}
|
||||
|
||||
|
||||
/* We are adding the def/use web DEF. Add the target register used
|
||||
in this web to the live set of all of the basic blocks that contain
|
||||
the live range of the web. */
|
||||
the live range of the web.
|
||||
If OWN_END is set, also show that the register is live from our
|
||||
definitions at the end of the basic block where it is defined. */
|
||||
static void
|
||||
add_btr_to_live_range (btr_def def)
|
||||
add_btr_to_live_range (btr_def def, int own_end)
|
||||
{
|
||||
int bb;
|
||||
EXECUTE_IF_SET_IN_BITMAP
|
||||
(def->live_range, 0, bb,
|
||||
{
|
||||
SET_HARD_REG_BIT (btrs_live[bb], def->btr);
|
||||
if (rtl_dump_file)
|
||||
dump_btrs_live (bb);
|
||||
});
|
||||
unsigned bb;
|
||||
bitmap_iterator bi;
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP (def->live_range, 0, bb, bi)
|
||||
{
|
||||
SET_HARD_REG_BIT (btrs_live[bb], def->btr);
|
||||
SET_HARD_REG_BIT (btrs_live_at_end[bb], def->btr);
|
||||
if (dump_file)
|
||||
dump_btrs_live (bb);
|
||||
}
|
||||
if (own_end)
|
||||
{
|
||||
SET_HARD_REG_BIT (btrs_live_at_end[def->bb->index], def->btr);
|
||||
def->own_end = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update a live range to contain the basic block NEW_BLOCK, and all
|
||||
|
|
@ -826,39 +892,59 @@ add_btr_to_live_range (btr_def def)
|
|||
all other blocks in the existing live range.
|
||||
Also add to the set BTRS_LIVE_IN_RANGE all target registers that
|
||||
are live in the blocks that we add to the live range.
|
||||
If FULL_RANGE is set, include the full live range of NEW_BB;
|
||||
otherwise, if NEW_BB dominates HEAD_BB, only add registers that
|
||||
are life at the end of NEW_BB for NEW_BB itself.
|
||||
It is a precondition that either NEW_BLOCK dominates HEAD,or
|
||||
HEAD dom NEW_BLOCK. This is used to speed up the
|
||||
implementation of this function. */
|
||||
static void
|
||||
augment_live_range (bitmap live_range, HARD_REG_SET *btrs_live_in_range,
|
||||
basic_block head_bb, basic_block new_bb)
|
||||
basic_block head_bb, basic_block new_bb, int full_range)
|
||||
{
|
||||
basic_block *worklist, *tos;
|
||||
|
||||
tos = worklist = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
|
||||
tos = worklist = XNEWVEC (basic_block, n_basic_blocks + 1);
|
||||
|
||||
if (dominated_by_p (CDI_DOMINATORS, new_bb, head_bb))
|
||||
*tos++ = new_bb;
|
||||
else if (dominated_by_p (CDI_DOMINATORS, head_bb, new_bb))
|
||||
{
|
||||
edge e;
|
||||
int new_block = new_bb->index;
|
||||
|
||||
bitmap_set_bit (live_range, new_block);
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[new_block]);
|
||||
if (rtl_dump_file)
|
||||
if (new_bb == head_bb)
|
||||
{
|
||||
fprintf (rtl_dump_file,
|
||||
"Adding block %d to live range\n", new_block);
|
||||
fprintf (rtl_dump_file,"Now live btrs are ");
|
||||
dump_hard_reg_set (*btrs_live_in_range);
|
||||
fprintf (rtl_dump_file, "\n");
|
||||
if (full_range)
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[new_bb->index]);
|
||||
free (tos);
|
||||
return;
|
||||
}
|
||||
for (e = head_bb->pred; e; e = e->pred_next)
|
||||
*tos++ = e->src;
|
||||
*tos++ = new_bb;
|
||||
}
|
||||
else
|
||||
abort();
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
int new_block = new_bb->index;
|
||||
|
||||
gcc_assert (dominated_by_p (CDI_DOMINATORS, head_bb, new_bb));
|
||||
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[head_bb->index]);
|
||||
bitmap_set_bit (live_range, new_block);
|
||||
/* A previous btr migration could have caused a register to be
|
||||
live just at the end of new_block which we need in full, so
|
||||
use trs_live_at_end even if full_range is set. */
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live_at_end[new_block]);
|
||||
if (full_range)
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[new_block]);
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file,
|
||||
"Adding end of block %d and rest of %d to live range\n",
|
||||
new_block, head_bb->index);
|
||||
fprintf (dump_file,"Now live btrs are ");
|
||||
dump_hard_reg_set (*btrs_live_in_range);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
FOR_EACH_EDGE (e, ei, head_bb->preds)
|
||||
*tos++ = e->src;
|
||||
}
|
||||
|
||||
while (tos != worklist)
|
||||
{
|
||||
|
|
@ -866,20 +952,25 @@ augment_live_range (bitmap live_range, HARD_REG_SET *btrs_live_in_range,
|
|||
if (!bitmap_bit_p (live_range, bb->index))
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
bitmap_set_bit (live_range, bb->index);
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range,
|
||||
btrs_live[bb->index]);
|
||||
if (rtl_dump_file)
|
||||
/* A previous btr migration could have caused a register to be
|
||||
live just at the end of a block which we need in full. */
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range,
|
||||
btrs_live_at_end[bb->index]);
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (rtl_dump_file,
|
||||
fprintf (dump_file,
|
||||
"Adding block %d to live range\n", bb->index);
|
||||
fprintf (rtl_dump_file,"Now live btrs are ");
|
||||
fprintf (dump_file,"Now live btrs are ");
|
||||
dump_hard_reg_set (*btrs_live_in_range);
|
||||
fprintf (rtl_dump_file, "\n");
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
for (e = bb->pred; e != NULL; e = e->pred_next)
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
basic_block pred = e->src;
|
||||
if (!bitmap_bit_p (live_range, pred->index))
|
||||
|
|
@ -926,14 +1017,19 @@ btr_def_live_range (btr_def def, HARD_REG_SET *btrs_live_in_range)
|
|||
{
|
||||
btr_user user;
|
||||
|
||||
def->live_range = BITMAP_XMALLOC ();
|
||||
def->live_range = BITMAP_ALLOC (NULL);
|
||||
|
||||
bitmap_set_bit (def->live_range, def->bb->index);
|
||||
COPY_HARD_REG_SET (*btrs_live_in_range, btrs_live[def->bb->index]);
|
||||
COPY_HARD_REG_SET (*btrs_live_in_range,
|
||||
(flag_btr_bb_exclusive
|
||||
? btrs_live : btrs_live_at_end)[def->bb->index]);
|
||||
|
||||
for (user = def->uses; user != NULL; user = user->next)
|
||||
augment_live_range (def->live_range, btrs_live_in_range,
|
||||
def->bb, user->bb);
|
||||
def->bb, user->bb,
|
||||
(flag_btr_bb_exclusive
|
||||
|| user->insn != BB_END (def->bb)
|
||||
|| !JUMP_P (user->insn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -941,15 +1037,17 @@ btr_def_live_range (btr_def def, HARD_REG_SET *btrs_live_in_range)
|
|||
the set of target registers live over it, because migration
|
||||
of other PT instructions may have affected it.
|
||||
*/
|
||||
int bb;
|
||||
unsigned bb;
|
||||
unsigned def_bb = flag_btr_bb_exclusive ? -1 : def->bb->index;
|
||||
bitmap_iterator bi;
|
||||
|
||||
CLEAR_HARD_REG_SET (*btrs_live_in_range);
|
||||
EXECUTE_IF_SET_IN_BITMAP
|
||||
(def->live_range, 0, bb,
|
||||
{
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range,
|
||||
btrs_live[bb]);
|
||||
});
|
||||
EXECUTE_IF_SET_IN_BITMAP (def->live_range, 0, bb, bi)
|
||||
{
|
||||
IOR_HARD_REG_SET (*btrs_live_in_range,
|
||||
(def_bb == bb
|
||||
? btrs_live_at_end : btrs_live) [bb]);
|
||||
}
|
||||
}
|
||||
if (!def->other_btr_uses_before_def &&
|
||||
!def->other_btr_uses_after_use)
|
||||
|
|
@ -979,7 +1077,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
|
|||
target registers live over the merged range. */
|
||||
int btr;
|
||||
HARD_REG_SET combined_btrs_live;
|
||||
bitmap combined_live_range = BITMAP_XMALLOC ();
|
||||
bitmap combined_live_range = BITMAP_ALLOC (NULL);
|
||||
btr_user user;
|
||||
|
||||
if (other_def->live_range == NULL)
|
||||
|
|
@ -992,14 +1090,17 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
|
|||
|
||||
for (user = other_def->uses; user != NULL; user = user->next)
|
||||
augment_live_range (combined_live_range, &combined_btrs_live,
|
||||
def->bb, user->bb);
|
||||
def->bb, user->bb,
|
||||
(flag_btr_bb_exclusive
|
||||
|| user->insn != BB_END (def->bb)
|
||||
|| !JUMP_P (user->insn)));
|
||||
|
||||
btr = choose_btr (combined_btrs_live);
|
||||
if (btr != -1)
|
||||
{
|
||||
/* We can combine them. */
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Combining def in insn %d with def in insn %d\n",
|
||||
INSN_UID (other_def->insn), INSN_UID (def->insn));
|
||||
|
||||
|
|
@ -1026,7 +1127,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
|
|||
clear_btr_from_live_range (other_def);
|
||||
other_def->uses = NULL;
|
||||
bitmap_copy (def->live_range, combined_live_range);
|
||||
if (other_def->other_btr_uses_after_use)
|
||||
if (other_def->btr == btr && other_def->other_btr_uses_after_use)
|
||||
def->other_btr_uses_after_use = 1;
|
||||
COPY_HARD_REG_SET (*btrs_live_in_range, combined_btrs_live);
|
||||
|
||||
|
|
@ -1034,7 +1135,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
|
|||
delete_insn (other_def->insn);
|
||||
|
||||
}
|
||||
BITMAP_XFREE (combined_live_range);
|
||||
BITMAP_FREE (combined_live_range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1064,8 +1165,8 @@ move_btr_def (basic_block new_def_bb, int btr, btr_def def, bitmap live_range,
|
|||
btr_user user;
|
||||
rtx set;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf(rtl_dump_file, "migrating to basic block %d, using reg %d\n",
|
||||
if (dump_file)
|
||||
fprintf(dump_file, "migrating to basic block %d, using reg %d\n",
|
||||
new_def_bb->index, btr);
|
||||
|
||||
clear_btr_from_live_range (def);
|
||||
|
|
@ -1073,22 +1174,33 @@ move_btr_def (basic_block new_def_bb, int btr, btr_def def, bitmap live_range,
|
|||
def->bb = new_def_bb;
|
||||
def->luid = 0;
|
||||
def->cost = basic_block_freq (new_def_bb);
|
||||
def->other_btr_uses_before_def = 0;
|
||||
bitmap_copy (def->live_range, live_range);
|
||||
combine_btr_defs (def, btrs_live_in_range);
|
||||
btr = def->btr;
|
||||
add_btr_to_live_range (def);
|
||||
if (GET_CODE (insp) == CODE_LABEL)
|
||||
def->other_btr_uses_before_def
|
||||
= TEST_HARD_REG_BIT (btrs_live[b->index], btr) ? 1 : 0;
|
||||
add_btr_to_live_range (def, 1);
|
||||
if (LABEL_P (insp))
|
||||
insp = NEXT_INSN (insp);
|
||||
/* N.B.: insp is expected to be NOTE_INSN_BASIC_BLOCK now. Some
|
||||
optimizations can result in insp being both first and last insn of
|
||||
its basic block. */
|
||||
/* ?? some assertions to check that insp is sensible? */
|
||||
|
||||
if (def->other_btr_uses_before_def)
|
||||
{
|
||||
insp = BB_END (b);
|
||||
for (insp = BB_END (b); ! INSN_P (insp); insp = PREV_INSN (insp))
|
||||
gcc_assert (insp != BB_HEAD (b));
|
||||
|
||||
if (JUMP_P (insp) || can_throw_internal (insp))
|
||||
insp = PREV_INSN (insp);
|
||||
}
|
||||
|
||||
set = single_set (old_insn);
|
||||
src = SET_SRC (set);
|
||||
btr_mode = GET_MODE (SET_DEST (set));
|
||||
btr_rtx = gen_rtx (REG, btr_mode, btr);
|
||||
btr_rtx = gen_rtx_REG (btr_mode, btr);
|
||||
|
||||
new_insn = gen_move_insn (btr_rtx, src);
|
||||
|
||||
|
|
@ -1097,8 +1209,8 @@ move_btr_def (basic_block new_def_bb, int btr, btr_def def, bitmap live_range,
|
|||
|
||||
regs_ever_live[btr] = 1;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "New pt is insn %d, inserted after insn %d\n",
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "New pt is insn %d, inserted after insn %d\n",
|
||||
INSN_UID (def->insn), INSN_UID (insp));
|
||||
|
||||
/* Delete the old target register initialization. */
|
||||
|
|
@ -1117,7 +1229,7 @@ move_btr_def (basic_block new_def_bb, int btr, btr_def def, bitmap live_range,
|
|||
|| GET_MODE (user->use) == VOIDmode)
|
||||
replacement_rtx = btr_rtx;
|
||||
else
|
||||
replacement_rtx = gen_rtx (REG, GET_MODE (user->use), btr);
|
||||
replacement_rtx = gen_rtx_REG (GET_MODE (user->use), btr);
|
||||
replace_rtx (user->insn, user->use, replacement_rtx);
|
||||
user->use = replacement_rtx;
|
||||
}
|
||||
|
|
@ -1170,18 +1282,18 @@ migrate_btr_def (btr_def def, int min_cost)
|
|||
int give_up = 0;
|
||||
int def_moved = 0;
|
||||
btr_user user;
|
||||
int def_latency = 1;
|
||||
int def_latency;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Attempting to migrate pt from insn %d (cost = %d, min_cost = %d) ... ",
|
||||
INSN_UID (def->insn), def->cost, min_cost);
|
||||
|
||||
if (!def->group || def->has_ambiguous_use)
|
||||
/* These defs are not migratable. */
|
||||
{
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "it's not migratable\n");
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "it's not migratable\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1190,24 +1302,21 @@ migrate_btr_def (btr_def def, int min_cost)
|
|||
no need to consider it further.
|
||||
*/
|
||||
{
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "it's already combined with another pt\n");
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "it's already combined with another pt\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
btr_def_live_range (def, &btrs_live_in_range);
|
||||
live_range = BITMAP_XMALLOC ();
|
||||
live_range = BITMAP_ALLOC (NULL);
|
||||
bitmap_copy (live_range, def->live_range);
|
||||
|
||||
#ifdef INSN_SCHEDULING
|
||||
if ((*targetm.sched.use_dfa_pipeline_interface) ())
|
||||
def_latency = insn_default_latency (def->insn);
|
||||
else
|
||||
def_latency = result_ready_cost (def->insn);
|
||||
def_latency = insn_default_latency (def->insn) * issue_rate;
|
||||
#else
|
||||
def_latency = issue_rate;
|
||||
#endif
|
||||
|
||||
def_latency *= issue_rate;
|
||||
|
||||
for (user = def->uses; user != NULL; user = user->next)
|
||||
{
|
||||
if (user->bb == def->bb
|
||||
|
|
@ -1230,20 +1339,30 @@ migrate_btr_def (btr_def def, int min_cost)
|
|||
/* Try to move the instruction that sets the target register into
|
||||
basic block TRY. */
|
||||
int try_freq = basic_block_freq (try);
|
||||
edge_iterator ei;
|
||||
edge e;
|
||||
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "trying block %d ...", try->index);
|
||||
/* If TRY has abnormal edges, skip it. */
|
||||
FOR_EACH_EDGE (e, ei, try->succs)
|
||||
if (e->flags & EDGE_COMPLEX)
|
||||
break;
|
||||
if (e)
|
||||
continue;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "trying block %d ...", try->index);
|
||||
|
||||
if (try_freq < def_basic_block_freq
|
||||
|| (try_freq == def_basic_block_freq && btr_used_near_def))
|
||||
{
|
||||
int btr;
|
||||
augment_live_range (live_range, &btrs_live_in_range, def->bb, try);
|
||||
if (rtl_dump_file)
|
||||
augment_live_range (live_range, &btrs_live_in_range, def->bb, try,
|
||||
flag_btr_bb_exclusive);
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (rtl_dump_file, "Now btrs live in range are: ");
|
||||
fprintf (dump_file, "Now btrs live in range are: ");
|
||||
dump_hard_reg_set (btrs_live_in_range);
|
||||
fprintf (rtl_dump_file, "\n");
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
btr = choose_btr (btrs_live_in_range);
|
||||
if (btr != -1)
|
||||
|
|
@ -1259,8 +1378,8 @@ migrate_btr_def (btr_def def, int min_cost)
|
|||
/* There are no free target registers available to move
|
||||
this far forward, so give up */
|
||||
give_up = 1;
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file,
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"giving up because there are no free target registers\n");
|
||||
}
|
||||
|
||||
|
|
@ -1269,10 +1388,10 @@ migrate_btr_def (btr_def def, int min_cost)
|
|||
if (!def_moved)
|
||||
{
|
||||
give_up = 1;
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "failed to move\n");
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "failed to move\n");
|
||||
}
|
||||
BITMAP_XFREE (live_range);
|
||||
BITMAP_FREE (live_range);
|
||||
return !give_up;
|
||||
}
|
||||
|
||||
|
|
@ -1285,14 +1404,14 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save)
|
|||
int reg;
|
||||
|
||||
gcc_obstack_init (&migrate_btrl_obstack);
|
||||
if (rtl_dump_file)
|
||||
if (dump_file)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_basic_blocks; i++)
|
||||
for (i = NUM_FIXED_BLOCKS; i < n_basic_blocks; i++)
|
||||
{
|
||||
basic_block bb = BASIC_BLOCK (i);
|
||||
fprintf(rtl_dump_file,
|
||||
fprintf(dump_file,
|
||||
"Basic block %d: count = " HOST_WIDEST_INT_PRINT_DEC
|
||||
" loop-depth = %d idom = %d\n",
|
||||
i, (HOST_WIDEST_INT) bb->count, bb->loop_depth,
|
||||
|
|
@ -1312,45 +1431,43 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save)
|
|||
}
|
||||
|
||||
btrs_live = xcalloc (n_basic_blocks, sizeof (HARD_REG_SET));
|
||||
btrs_live_at_end = xcalloc (n_basic_blocks, sizeof (HARD_REG_SET));
|
||||
|
||||
build_btr_def_use_webs (all_btr_defs);
|
||||
|
||||
while (!fibheap_empty (all_btr_defs))
|
||||
{
|
||||
btr_def def =
|
||||
(btr_def) fibheap_extract_min (all_btr_defs);
|
||||
btr_def def = fibheap_extract_min (all_btr_defs);
|
||||
int min_cost = -fibheap_min_key (all_btr_defs);
|
||||
if (migrate_btr_def (def, min_cost))
|
||||
{
|
||||
fibheap_insert (all_btr_defs, -def->cost, (void *) def);
|
||||
if (rtl_dump_file)
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (rtl_dump_file,
|
||||
fprintf (dump_file,
|
||||
"Putting insn %d back on queue with priority %d\n",
|
||||
INSN_UID (def->insn), def->cost);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (def->live_range)
|
||||
BITMAP_XFREE (def->live_range);
|
||||
}
|
||||
BITMAP_FREE (def->live_range);
|
||||
}
|
||||
|
||||
free (btrs_live);
|
||||
free (btrs_live_at_end);
|
||||
obstack_free (&migrate_btrl_obstack, NULL);
|
||||
fibheap_delete (all_btr_defs);
|
||||
}
|
||||
|
||||
void
|
||||
branch_target_load_optimize (rtx insns, bool after_prologue_epilogue_gen)
|
||||
branch_target_load_optimize (bool after_prologue_epilogue_gen)
|
||||
{
|
||||
enum reg_class class = (*targetm.branch_target_register_class) ();
|
||||
enum reg_class class = targetm.branch_target_register_class ();
|
||||
if (class != NO_REGS)
|
||||
{
|
||||
/* Initialize issue_rate. */
|
||||
if (targetm.sched.issue_rate)
|
||||
issue_rate = (*targetm.sched.issue_rate) ();
|
||||
issue_rate = targetm.sched.issue_rate ();
|
||||
else
|
||||
issue_rate = 1;
|
||||
|
||||
|
|
@ -1361,12 +1478,12 @@ branch_target_load_optimize (rtx insns, bool after_prologue_epilogue_gen)
|
|||
cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
|
||||
#endif
|
||||
|
||||
life_analysis (insns, NULL, 0);
|
||||
life_analysis (0);
|
||||
|
||||
/* Dominator info is also needed for migrate_btr_def. */
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
migrate_btr_defs (class,
|
||||
((*targetm.branch_target_register_callee_saved)
|
||||
(targetm.branch_target_register_callee_saved
|
||||
(after_prologue_epilogue_gen)));
|
||||
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
|
|
@ -1375,3 +1492,51 @@ branch_target_load_optimize (rtx insns, bool after_prologue_epilogue_gen)
|
|||
PROP_DEATH_NOTES | PROP_REG_INFO);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
gate_handle_branch_target_load_optimize (void)
|
||||
{
|
||||
return (optimize > 0 && flag_branch_target_load_optimize2);
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
rest_of_handle_branch_target_load_optimize (void)
|
||||
{
|
||||
static int warned = 0;
|
||||
|
||||
/* Leave this a warning for now so that it is possible to experiment
|
||||
with running this pass twice. In 3.6, we should either make this
|
||||
an error, or use separate dump files. */
|
||||
if (flag_branch_target_load_optimize
|
||||
&& flag_branch_target_load_optimize2
|
||||
&& !warned)
|
||||
{
|
||||
warning (0, "branch target register load optimization is not intended "
|
||||
"to be run twice");
|
||||
|
||||
warned = 1;
|
||||
}
|
||||
|
||||
branch_target_load_optimize (epilogue_completed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tree_opt_pass pass_branch_target_load_optimize =
|
||||
{
|
||||
"btl", /* name */
|
||||
gate_handle_branch_target_load_optimize, /* gate */
|
||||
rest_of_handle_branch_target_load_optimize, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
0, /* tv_id */
|
||||
0, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_dump_func |
|
||||
TODO_ggc_collect, /* todo_flags_finish */
|
||||
'd' /* letter */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Joseph Myers <jsm28@cam.ac.uk>.
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -15,8 +15,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* This header provides a declarative way of describing the attributes
|
||||
that are applied to some functions by default.
|
||||
|
|
@ -55,6 +55,8 @@ DEF_ATTR_FOR_INT (1)
|
|||
DEF_ATTR_FOR_INT (2)
|
||||
DEF_ATTR_FOR_INT (3)
|
||||
DEF_ATTR_FOR_INT (4)
|
||||
DEF_ATTR_FOR_INT (5)
|
||||
DEF_ATTR_FOR_INT (6)
|
||||
#undef DEF_ATTR_FOR_INT
|
||||
|
||||
/* Construct a tree for a list of two integers. */
|
||||
|
|
@ -67,9 +69,13 @@ DEF_LIST_INT_INT (2,0)
|
|||
DEF_LIST_INT_INT (2,3)
|
||||
DEF_LIST_INT_INT (3,0)
|
||||
DEF_LIST_INT_INT (3,4)
|
||||
DEF_LIST_INT_INT (4,0)
|
||||
DEF_LIST_INT_INT (4,5)
|
||||
DEF_LIST_INT_INT (5,0)
|
||||
DEF_LIST_INT_INT (5,6)
|
||||
#undef DEF_LIST_INT_INT
|
||||
|
||||
/* Construct tress for identifiers. */
|
||||
/* Construct trees for identifiers. */
|
||||
DEF_ATTR_IDENT (ATTR_CONST, "const")
|
||||
DEF_ATTR_IDENT (ATTR_FORMAT, "format")
|
||||
DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
|
||||
|
|
@ -83,45 +89,65 @@ DEF_ATTR_IDENT (ATTR_GCC_DIAG, "gcc_diag")
|
|||
DEF_ATTR_IDENT (ATTR_GCC_CDIAG, "gcc_cdiag")
|
||||
DEF_ATTR_IDENT (ATTR_GCC_CXXDIAG, "gcc_cxxdiag")
|
||||
DEF_ATTR_IDENT (ATTR_PURE, "pure")
|
||||
DEF_ATTR_IDENT (ATTR_NOVOPS, "no vops")
|
||||
DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
|
||||
DEF_ATTR_IDENT (ATTR_SENTINEL, "sentinel")
|
||||
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
|
||||
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
|
||||
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOVOPS_LIST, ATTR_NOVOPS, ATTR_NULL, ATTR_NULL)
|
||||
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_LIST, ATTR_NOTHROW, ATTR_NULL, ATTR_NULL)
|
||||
|
||||
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_LIST, ATTR_CONST, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NOVOPS_LIST, ATTR_NOVOPS, \
|
||||
ATTR_NULL, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
DEF_ATTR_TREE_LIST (ATTR_SENTINEL_NOTHROW_LIST, ATTR_SENTINEL, \
|
||||
ATTR_NULL, ATTR_NOTHROW_LIST)
|
||||
|
||||
/* Functions whose pointer parameter(s) are all nonnull. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NONNULL_LIST, ATTR_NONNULL, ATTR_NULL, ATTR_NULL)
|
||||
/* Functions whose first parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, ATTR_NULL)
|
||||
/* Functions whose second parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, ATTR_NULL)
|
||||
/* Nothrow functions with the sentinel(1) attribute. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_SENTINEL_1, ATTR_SENTINEL, ATTR_LIST_1, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
/* Nothrow functions whose pointer parameter(s) are all nonnull. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL, ATTR_NONNULL, ATTR_NULL, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
/* Nothrow functions whose first parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
/* Nothrow functions whose second parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
/* Nothrow functions whose third parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
/* Nothrow functions whose first and second parameters are nonnull pointers. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_2, ATTR_NONNULL, ATTR_LIST_2, \
|
||||
ATTR_NOTHROW_NONNULL_1)
|
||||
/* Nothrow functions whose first and fourth parameters are nonnull pointers. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_4, ATTR_NONNULL, ATTR_LIST_4, \
|
||||
ATTR_NOTHROW_NONNULL_1)
|
||||
/* Nothrow const functions whose first parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL_1, ATTR_CONST, ATTR_NULL, \
|
||||
ATTR_NOTHROW_NONNULL_1)
|
||||
/* Nothrow pure functions whose first parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_1, ATTR_PURE, ATTR_NULL, \
|
||||
ATTR_NOTHROW_NONNULL_1)
|
||||
/* Nothrow pure functions whose first and second parameters are nonnull pointers. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_1_2, ATTR_PURE, ATTR_NULL, \
|
||||
ATTR_NOTHROW_NONNULL_1_2)
|
||||
/* Nothrow malloc functions whose first parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_NONNULL_1, ATTR_MALLOC, ATTR_NULL, \
|
||||
ATTR_NOTHROW_NONNULL_1)
|
||||
/* Nothrow functions whose fourth parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_4, ATTR_NONNULL, ATTR_LIST_4, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
/* Nothrow functions whose fifth parameter is a nonnull pointer. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_5, ATTR_NONNULL, ATTR_LIST_5, \
|
||||
ATTR_NOTHROW_LIST)
|
||||
/* Nothrow const functions whose pointer parameter(s) are all nonnull. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL, ATTR_CONST, ATTR_NULL, \
|
||||
ATTR_NOTHROW_NONNULL)
|
||||
/* Nothrow pure functions whose pointer parameter(s) are all nonnull. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL, ATTR_PURE, ATTR_NULL, \
|
||||
ATTR_NOTHROW_NONNULL)
|
||||
/* Nothrow malloc functions whose pointer parameter(s) are all nonnull. */
|
||||
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_NONNULL, ATTR_MALLOC, ATTR_NULL, \
|
||||
ATTR_NOTHROW_NONNULL)
|
||||
|
||||
/* Construct a tree for a format attribute. */
|
||||
#define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \
|
||||
|
|
@ -135,6 +161,10 @@ DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_0)
|
|||
DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_3)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,3,3_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,3,3_4)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,4,4_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,4,4_5)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,5,5_0)
|
||||
DEF_FORMAT_ATTRIBUTE(PRINTF,5,5_6)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,1,1_0)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,1,1_2)
|
||||
DEF_FORMAT_ATTRIBUTE(SCANF,2,2_0)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -14,10 +15,10 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* This header provides a declaritive way of describing the types that
|
||||
/* This header provides a declarative way of describing the types that
|
||||
are used when declaring builtin functions.
|
||||
|
||||
Before including this header, you must define the following macros:
|
||||
|
|
@ -32,6 +33,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
DEF_FUNCTION_TYPE_2 (ENUM, RETURN, ARG1, ARG2)
|
||||
DEF_FUNCTION_TYPE_3 (ENUM, RETURN, ARG1, ARG2, ARG3)
|
||||
DEF_FUNCTION_TYPE_4 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)
|
||||
DEF_FUNCTION_TYPE_5 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)
|
||||
DEF_FUNCTION_TYPE_6 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6)
|
||||
DEF_FUNCTION_TYPE_7 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7)
|
||||
|
||||
These macros describe function types. ENUM is as above. The
|
||||
RETURN type is one of the enumerals already defined. ARG1, ARG2,
|
||||
|
|
@ -41,6 +45,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
DEF_FUNCTION_TYPE_VAR_1 (ENUM, RETURN, ARG1)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (ENUM, RETURN, ARG1, ARG2)
|
||||
DEF_FUNCTION_TYPE_VAR_3 (ENUM, RETURN, ARG1, ARG2, ARG3)
|
||||
DEF_FUNCTION_TYPE_VAR_4 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)
|
||||
DEF_FUNCTION_TYPE_VAR_4 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)
|
||||
|
||||
Similar, but for function types that take variable arguments.
|
||||
For example:
|
||||
|
|
@ -53,20 +59,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
DEF_FUNCTION_TYPE_VAR_1 (BT_INT_DOUBLE_VAR, BT_INT, BT_DOUBLE)
|
||||
|
||||
describes the type `int ()(double, ...)'.
|
||||
|
||||
|
||||
DEF_POINTER_TYPE (ENUM, TYPE)
|
||||
|
||||
This macro describes a pointer type. ENUM is as above; TYPE is
|
||||
the type pointed to. */
|
||||
|
||||
DEF_PRIMITIVE_TYPE (BT_VOID, void_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_BOOL, boolean_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_INT, integer_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UNSIGNED, unsigned_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINT, unsigned_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_LONG, long_integer_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_ULONG, long_unsigned_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_long_integer_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_ULONGLONG, long_long_unsigned_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 0))
|
||||
DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_COMPLEX_FLOAT, complex_float_type_node)
|
||||
|
|
@ -74,58 +84,96 @@ DEF_PRIMITIVE_TYPE (BT_COMPLEX_DOUBLE, complex_double_type_node)
|
|||
DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONGDOUBLE, complex_long_double_type_node)
|
||||
|
||||
DEF_PRIMITIVE_TYPE (BT_PTR, ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_FILEPTR, fileptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_CONST_PTR, const_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_VOLATILE_PTR,
|
||||
build_pointer_type
|
||||
(build_qualified_type (void_type_node,
|
||||
TYPE_QUAL_VOLATILE)))
|
||||
DEF_PRIMITIVE_TYPE (BT_PTRMODE, (*lang_hooks.types.type_for_mode)(ptr_mode, 0))
|
||||
DEF_PRIMITIVE_TYPE (BT_INT_PTR, integer_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_FLOAT_PTR, float_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_DOUBLE_PTR, double_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE_PTR, long_double_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_PID, pid_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_SIZE, size_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_SSIZE, signed_size_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_WINT, wint_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_STRING, string_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
|
||||
|
||||
DEF_PRIMITIVE_TYPE (BT_DFLOAT32, dfloat32_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_DFLOAT64, dfloat64_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_DFLOAT128, dfloat128_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_DFLOAT32_PTR, dfloat32_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_DFLOAT64_PTR, dfloat64_ptr_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_DFLOAT128_PTR, dfloat128_ptr_type_node)
|
||||
|
||||
DEF_PRIMITIVE_TYPE (BT_VALIST_REF, va_list_ref_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
|
||||
|
||||
DEF_PRIMITIVE_TYPE (BT_I1, builtin_type_for_size (BITS_PER_UNIT*1, 1))
|
||||
DEF_PRIMITIVE_TYPE (BT_I2, builtin_type_for_size (BITS_PER_UNIT*2, 1))
|
||||
DEF_PRIMITIVE_TYPE (BT_I4, builtin_type_for_size (BITS_PER_UNIT*4, 1))
|
||||
DEF_PRIMITIVE_TYPE (BT_I8, builtin_type_for_size (BITS_PER_UNIT*8, 1))
|
||||
DEF_PRIMITIVE_TYPE (BT_I16, builtin_type_for_size (BITS_PER_UNIT*16, 1))
|
||||
|
||||
DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING)
|
||||
DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
|
||||
DEF_POINTER_TYPE (BT_PTR_PTR, BT_PTR)
|
||||
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_BOOL, BT_BOOL)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_UNSIGNED, BT_UNSIGNED)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_PID, BT_PID)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
|
||||
/* For "long double" we use LONGDOUBLE (not LONG_DOUBLE) to
|
||||
distinguish it from two types in sequence, "long" followed by
|
||||
"double". */
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_LONGDOUBLE, BT_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT32, BT_DFLOAT32)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT64, BT_DFLOAT64)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_DFLOAT128, BT_DFLOAT128)
|
||||
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONG, BT_LONG, BT_LONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGLONG, BT_LONGLONG, BT_LONGLONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INTMAX_INTMAX, BT_INTMAX, BT_INTMAX)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_FLOAT, BT_FLOAT, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_DOUBLE, BT_DOUBLE, BT_DOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_LONGDOUBLE,
|
||||
BT_LONGDOUBLE, BT_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_LONGDOUBLE,
|
||||
BT_LONGDOUBLE, BT_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
|
||||
BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
|
||||
BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
|
||||
BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_COMPLEX_FLOAT,
|
||||
BT_FLOAT, BT_COMPLEX_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
|
||||
BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_COMPLEX_FLOAT,
|
||||
BT_FLOAT, BT_COMPLEX_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_COMPLEX_DOUBLE,
|
||||
BT_DOUBLE, BT_COMPLEX_DOUBLE)
|
||||
BT_DOUBLE, BT_COMPLEX_DOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE,
|
||||
BT_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_UNSIGNED, BT_PTR, BT_UNSIGNED)
|
||||
BT_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_UINT, BT_PTR, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_SIZE, BT_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_UINT, BT_INT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONG, BT_INT, BT_LONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_ULONG, BT_INT, BT_ULONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGLONG, BT_INT, BT_LONGLONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_ULONGLONG, BT_INT, BT_ULONGLONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_INTMAX, BT_INT, BT_INTMAX)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_UINTMAX, BT_INT, BT_UINTMAX)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_PTR, BT_INT, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_FLOAT, BT_INT, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DOUBLE, BT_INT, BT_DOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGDOUBLE, BT_INT, BT_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DFLOAT32, BT_INT, BT_DFLOAT32)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DFLOAT64, BT_INT, BT_DFLOAT64)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DFLOAT128, BT_INT, BT_DFLOAT128)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_FLOAT, BT_LONG, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE, BT_LONG, BT_DOUBLE)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONGDOUBLE, BT_LONG, BT_LONGDOUBLE)
|
||||
|
|
@ -142,27 +190,43 @@ DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_FLOAT, BT_CONST_STRING)
|
|||
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_CONST_STRING,
|
||||
BT_LONGDOUBLE, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_CONST_STRING, BT_DFLOAT32, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_CONST_STRING, BT_DFLOAT64, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_CONST_STRING,
|
||||
BT_DFLOAT128, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_STRING_CONST_STRING, BT_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_WORD_PTR, BT_WORD, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT_WINT, BT_INT, BT_WINT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_WINT_WINT, BT_WINT, BT_WINT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_DFLOAT32, BT_DFLOAT32, BT_DFLOAT32)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_DFLOAT64, BT_DFLOAT64, BT_DFLOAT64)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_DFLOAT128, BT_DFLOAT128, BT_DFLOAT128)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTRPTR, BT_VOID, BT_PTR_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_UINT, BT_UINT, BT_UINT)
|
||||
|
||||
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
|
||||
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING,
|
||||
BT_STRING, BT_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING,
|
||||
BT_STRING, BT_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_CONST_STRING,
|
||||
BT_INT, BT_CONST_STRING, BT_CONST_STRING)
|
||||
BT_INT, BT_CONST_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_CONST_STRING_CONST_STRING,
|
||||
BT_STRING, BT_CONST_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_SIZE_CONST_STRING_CONST_STRING,
|
||||
BT_SIZE, BT_CONST_STRING, BT_CONST_STRING)
|
||||
BT_SIZE, BT_CONST_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_CONST_STRING_INT,
|
||||
BT_STRING, BT_CONST_STRING, BT_INT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_PTR,
|
||||
BT_INT, BT_CONST_STRING, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_INT_PTR,
|
||||
BT_INT, BT_INT, BT_PTR)
|
||||
BT_STRING, BT_CONST_STRING, BT_INT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_CONST_STRING_SIZE,
|
||||
BT_STRING, BT_CONST_STRING, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_FILEPTR,
|
||||
BT_INT, BT_CONST_STRING, BT_FILEPTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_INT_FILEPTR,
|
||||
BT_INT, BT_INT, BT_FILEPTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRMODE_PTR,
|
||||
BT_VOID, BT_PTRMODE, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VALIST_REF_VALIST_ARG,
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VALIST_REF_VALIST_ARG,
|
||||
BT_VOID, BT_VALIST_REF, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_LONG_LONG_LONG,
|
||||
BT_LONG, BT_LONG, BT_LONG)
|
||||
|
|
@ -214,12 +278,23 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_VALIST_ARG,
|
|||
BT_INT, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_PTR_SIZE_SIZE,
|
||||
BT_PTR, BT_SIZE, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT,
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT,
|
||||
BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
|
||||
BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
|
||||
BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
|
||||
BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTR, BT_VOID, BT_PTR, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_PTR_CONST_STRING,
|
||||
BT_INT, BT_CONST_STRING, BT_PTR_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_SIZE_CONST_PTR_INT, BT_SIZE, BT_CONST_PTR, BT_INT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_I1_VPTR_I1, BT_I1, BT_VOLATILE_PTR, BT_I1)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_I2_VPTR_I2, BT_I2, BT_VOLATILE_PTR, BT_I2)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_I4_VPTR_I4, BT_I4, BT_VOLATILE_PTR, BT_I4)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_I8_VPTR_I8, BT_I8, BT_VOLATILE_PTR, BT_I8)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_I16_VPTR_I16, BT_I16, BT_VOLATILE_PTR, BT_I16)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_LONGPTR_LONGPTR,
|
||||
BT_BOOL, BT_PTR_LONG, BT_PTR_LONG)
|
||||
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_STRING_CONST_STRING_SIZE,
|
||||
BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE)
|
||||
|
|
@ -228,9 +303,9 @@ DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_SIZE,
|
|||
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_CONST_PTR_SIZE,
|
||||
BT_PTR, BT_PTR, BT_CONST_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
|
||||
BT_INT, BT_CONST_PTR, BT_CONST_PTR, BT_SIZE)
|
||||
BT_INT, BT_CONST_PTR, BT_CONST_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_INT_SIZE,
|
||||
BT_PTR, BT_PTR, BT_INT, BT_SIZE)
|
||||
BT_PTR, BT_PTR, BT_INT, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT,
|
||||
BT_VOID, BT_PTR, BT_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_CONST_PTR_PTR_SIZE,
|
||||
|
|
@ -239,8 +314,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
|
|||
BT_INT, BT_STRING, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_CONST_STRING, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTR_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_PTR, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_FILEPTR, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_CONST_STRING_CONST_STRING_INT,
|
||||
BT_STRING, BT_CONST_STRING, BT_CONST_STRING, BT_INT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_FLOAT,
|
||||
|
|
@ -261,37 +336,103 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR,
|
|||
BT_VOID, BT_DOUBLE, BT_DOUBLE_PTR, BT_DOUBLE_PTR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR,
|
||||
BT_VOID, BT_LONGDOUBLE, BT_LONGDOUBLE_PTR, BT_LONGDOUBLE_PTR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_PTR_PTR, BT_VOID, BT_PTR, BT_PTR, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING,
|
||||
BT_INT, BT_CONST_STRING, BT_PTR_CONST_STRING, BT_PTR_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_INT_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_INT, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_VPTR_I1_I1, BT_BOOL, BT_VOLATILE_PTR,
|
||||
BT_I1, BT_I1)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_VPTR_I2_I2, BT_BOOL, BT_VOLATILE_PTR,
|
||||
BT_I2, BT_I2)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_VPTR_I4_I4, BT_BOOL, BT_VOLATILE_PTR,
|
||||
BT_I4, BT_I4)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_VPTR_I8_I8, BT_BOOL, BT_VOLATILE_PTR,
|
||||
BT_I8, BT_I8)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_VPTR_I16_I16, BT_BOOL, BT_VOLATILE_PTR,
|
||||
BT_I16, BT_I16)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_I1_VPTR_I1_I1, BT_I1, BT_VOLATILE_PTR, BT_I1, BT_I1)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_I2_VPTR_I2_I2, BT_I2, BT_VOLATILE_PTR, BT_I2, BT_I2)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_I4, BT_I4, BT_VOLATILE_PTR, BT_I4, BT_I4)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_I8_VPTR_I8_I8, BT_I8, BT_VOLATILE_PTR, BT_I8, BT_I8)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_I16, BT_I16, BT_VOLATILE_PTR,
|
||||
BT_I16, BT_I16)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_OMPFN_PTR_UINT, BT_VOID, BT_PTR_FN_VOID_PTR,
|
||||
BT_PTR, BT_UINT)
|
||||
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
|
||||
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
|
||||
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR,
|
||||
BT_SIZE, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE,
|
||||
BT_PTR, BT_PTR, BT_CONST_PTR, BT_SIZE, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_PTR_PTR_INT_SIZE_SIZE,
|
||||
BT_PTR, BT_PTR, BT_INT, BT_SIZE, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE,
|
||||
BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_FILEPTR, BT_INT, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_VOID_OMPFN_PTR_UINT_UINT,
|
||||
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT)
|
||||
|
||||
DEF_FUNCTION_TYPE_5 (BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_STRING, BT_INT, BT_SIZE, BT_CONST_STRING,
|
||||
BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
BT_BOOL, BT_LONG, BT_LONG, BT_LONG,
|
||||
BT_PTR_LONG, BT_PTR_LONG)
|
||||
|
||||
DEF_FUNCTION_TYPE_6 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG,
|
||||
BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE,
|
||||
BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
|
||||
BT_BOOL, BT_LONG, BT_LONG, BT_LONG, BT_LONG,
|
||||
BT_PTR_LONG, BT_PTR_LONG)
|
||||
DEF_FUNCTION_TYPE_6 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
|
||||
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
|
||||
BT_LONG, BT_LONG, BT_LONG)
|
||||
|
||||
DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
|
||||
BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
|
||||
BT_LONG, BT_LONG, BT_LONG, BT_LONG)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
|
||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
|
||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_PTR_VAR, BT_PTR)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_1 (BT_FN_VOID_VALIST_REF_VAR,
|
||||
DEF_FUNCTION_TYPE_VAR_1 (BT_FN_VOID_VALIST_REF_VAR,
|
||||
BT_VOID, BT_VALIST_REF)
|
||||
DEF_FUNCTION_TYPE_VAR_1 (BT_FN_VOID_CONST_PTR_VAR,
|
||||
BT_VOID, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_VAR_1 (BT_FN_INT_CONST_STRING_VAR,
|
||||
BT_INT, BT_CONST_STRING)
|
||||
BT_INT, BT_CONST_STRING)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_PTR_CONST_STRING_VAR,
|
||||
BT_INT, BT_PTR, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_FILEPTR_CONST_STRING_VAR,
|
||||
BT_INT, BT_FILEPTR, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_STRING_CONST_STRING_VAR,
|
||||
BT_INT, BT_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
|
||||
BT_INT, BT_CONST_STRING, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_INT_CONST_STRING_VAR,
|
||||
BT_INT, BT_INT, BT_CONST_STRING)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_INT_STRING_SIZE_CONST_STRING_VAR,
|
||||
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR,
|
||||
BT_SSIZE, BT_STRING, BT_SIZE, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_INT_FILEPTR_INT_CONST_STRING_VAR,
|
||||
BT_INT, BT_FILEPTR, BT_INT, BT_CONST_STRING)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_4 (BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR,
|
||||
BT_INT, BT_STRING, BT_INT, BT_SIZE, BT_CONST_STRING)
|
||||
|
||||
DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR,
|
||||
BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE,
|
||||
BT_CONST_STRING)
|
||||
|
||||
DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
|
||||
BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,7 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
builtins used in the GNU compiler.
|
||||
Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,13 +17,13 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* Before including this file, you should define a macro:
|
||||
|
||||
DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
|
||||
FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)
|
||||
FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT, COND)
|
||||
|
||||
This macro will be called once for each builtin function. The
|
||||
ENUM will be of type `enum built_in_function', and will indicate
|
||||
|
|
@ -53,22 +54,30 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
exist when compiling in ANSI conformant mode.
|
||||
|
||||
ATTRs is an attribute list as defined in builtin-attrs.def that
|
||||
describes the attributes of this builtin function.
|
||||
describes the attributes of this builtin function.
|
||||
|
||||
IMPLICIT specifies condition when the builtin can be produced by
|
||||
compiler. For instance C90 reserves floorf function, but does not
|
||||
define it's meaning. When user uses floorf we may assume that the
|
||||
floorf has the meaning we expect, but we can't produce floorf by
|
||||
simplifying floor((double)float) since the runtime need not implement
|
||||
it. */
|
||||
|
||||
it.
|
||||
|
||||
The builtins is registered only if COND is true. */
|
||||
|
||||
/* A GCC builtin (like __builtin_saveregs) is provided by the
|
||||
compiler, but does not correspond to a function in the standard
|
||||
library. */
|
||||
#undef DEF_GCC_BUILTIN
|
||||
#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
||||
false, false, false, ATTRS, true)
|
||||
false, false, false, ATTRS, true, true)
|
||||
|
||||
/* Like DEF_GCC_BUILTIN, except we don't prepend "__builtin_". */
|
||||
#undef DEF_SYNC_BUILTIN
|
||||
#define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
|
||||
false, false, false, ATTRS, true, true)
|
||||
|
||||
/* A library builtin (like __builtin_strchr) is a builtin equivalent
|
||||
of an ANSI/ISO standard library function. In addition to the
|
||||
|
|
@ -76,34 +85,62 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
`strchr') as well. If we cannot compute the answer using the
|
||||
builtin function, we will fall back to the standard library
|
||||
version. */
|
||||
#undef DEF_LIB_BUILTIN
|
||||
#undef DEF_LIB_BUILTIN
|
||||
#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, false, ATTRS, true)
|
||||
true, true, false, ATTRS, true, true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is not one that is
|
||||
specified by ANSI/ISO C. So, when we're being fully conformant we
|
||||
ignore the version of these builtins that does not begin with
|
||||
__builtin. */
|
||||
#undef DEF_EXT_LIB_BUILTIN
|
||||
#undef DEF_EXT_LIB_BUILTIN
|
||||
#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, true, ATTRS, false)
|
||||
true, true, true, ATTRS, false, true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C94 or above. */
|
||||
#undef DEF_C94_BUILTIN
|
||||
#define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||
|
||||
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
|
||||
the standard in C99 or above. */
|
||||
#undef DEF_C99_BUILTIN
|
||||
#undef DEF_C99_BUILTIN
|
||||
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS)
|
||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||
|
||||
/* Builtin that is specified by C99 and C90 reserve the name for future use.
|
||||
We can still recognize the builtin in C90 mode but we can't produce it
|
||||
implicitly. */
|
||||
#undef DEF_C99_C90RES_BUILTIN
|
||||
#undef DEF_C99_C90RES_BUILTIN
|
||||
#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS)
|
||||
true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
|
||||
|
||||
/* Builtin that C99 reserve the name for future use. We can still recognize
|
||||
the builtin in C99 mode but we can't produce it implicitly. */
|
||||
#undef DEF_EXT_C99RES_BUILTIN
|
||||
#define DEF_EXT_C99RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
true, true, true, ATTRS, false, true)
|
||||
|
||||
/* Allocate the enum and the name for a builtin, but do not actually
|
||||
define it here at all. */
|
||||
#undef DEF_BUILTIN_STUB
|
||||
#define DEF_BUILTIN_STUB(ENUM, NAME) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, 0, 0, false, false, \
|
||||
false, 0, false, false)
|
||||
|
||||
/* Builtin used by the implementation of GNU OpenMP. None of these are
|
||||
actually implemented in the compiler; they're all in libgomp. */
|
||||
#undef DEF_GOMP_BUILTIN
|
||||
#define DEF_GOMP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true, ATTRS, false, flag_openmp)
|
||||
|
||||
/* Define an attribute list for math functions that are normally
|
||||
"impure" because some of them may write into global memory for
|
||||
|
|
@ -115,11 +152,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
/* Define an attribute list for math functions that are normally
|
||||
"pure" but if flag_unsafe_math_optimizations is set they are
|
||||
instead "const". This distinction accounts for the fact that some
|
||||
math functions check the rounding mode which is akin to examing
|
||||
math functions check the rounding mode which is akin to examining
|
||||
global memory. In "unsafe" mode we can be less careful. */
|
||||
#undef ATTR_MATHFN_FPROUNDING
|
||||
#define ATTR_MATHFN_FPROUNDING (flag_unsafe_math_optimizations ? \
|
||||
ATTR_CONST_NOTHROW_LIST : ATTR_PURE_NOTHROW_LIST)
|
||||
ATTR_CONST_NOTHROW_LIST : ATTR_PURE_NOTHROW_NOVOPS_LIST)
|
||||
|
||||
/* Define an attribute list for math functions that are normally
|
||||
"impure" because some of them may write into global memory for
|
||||
|
|
@ -218,9 +255,9 @@ DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LON
|
|||
DEF_LIB_BUILTIN (BUILT_IN_FREXP, "frexp", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPF, "frexpf", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPL, "frexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA, "gamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF, "gammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL, "gammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA, "gamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF, "gammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL, "gammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
|
|
@ -233,6 +270,9 @@ DEF_C99_BUILTIN (BUILT_IN_ILOGBL, "ilogbl", BT_FN_INT_LONGDOUBLE, ATTR_MA
|
|||
DEF_GCC_BUILTIN (BUILT_IN_INF, "inf", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFF, "inff", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0, "j0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0F, "j0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_J0L, "j0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
|
|
@ -242,12 +282,24 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_J1L, "j1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_M
|
|||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JN, "jn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNF, "jnf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_JNL, "jnl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LCEIL, "lceil", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LCEILF, "lceilf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LCEILL, "lceill", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_LDEXP, "ldexp", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPF, "ldexpf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPL, "ldexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOOR, "lfloor", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOORF, "lfloorf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LFLOORL, "lfloorl", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEIL, "llceil", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEILF, "llceilf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLCEILL, "llceill", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOOR, "llfloor", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORF, "llfloorf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_LLFLOORL, "llfloorl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLRINT, "llrint", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLRINTF, "llrintf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_LLRINTL, "llrintl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
|
|
@ -278,12 +330,15 @@ DEF_C99_BUILTIN (BUILT_IN_LROUNDL, "lroundl", BT_FN_LONG_LONGDOUBLE, ATTR
|
|||
DEF_LIB_BUILTIN (BUILT_IN_MODF, "modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFF, "modff", BT_FN_FLOAT_FLOAT_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_NEARBYINTL, "nearbyintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
|
|
@ -298,6 +353,9 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHF
|
|||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWF, "powf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POWI, "powi", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POWIF, "powif", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POWIL, "powil", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_POWL, "powl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDER, "remainder", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_REMAINDERF, "remainderf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
|
|
@ -320,6 +378,9 @@ DEF_C99_BUILTIN (BUILT_IN_SCALBLNL, "scalblnl", BT_FN_LONGDOUBLE_LONGDOUB
|
|||
DEF_C99_BUILTIN (BUILT_IN_SCALBN, "scalbn", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBNF, "scalbnf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SCALBNL, "scalbnl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBIT, "signbit", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITF, "signbitf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITL, "signbitl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICAND, "significand", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDF, "significandf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDL, "significandl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
|
|
@ -358,8 +419,6 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
|
|||
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
|
||||
|
||||
/* Category: _Complex math builtins. */
|
||||
/* The C99 clog function conflicts with C++ iostreams clog, see
|
||||
http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00510.html */
|
||||
DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
|
|
@ -396,9 +455,12 @@ DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLE
|
|||
DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
/*DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)*/
|
||||
/*DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)*/
|
||||
/*DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)*/
|
||||
DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
|
|
@ -433,60 +495,97 @@ DEF_C99_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLE
|
|||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_NOTHROW_NONNULL_1)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL_1)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL)
|
||||
|
||||
/* Category: stdio builtins. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_PTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_PTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTC, "fputc", BT_FN_INT_INT_PTR, ATTR_NOTHROW_NONNULL_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT_PTR, ATTR_NOTHROW_NONNULL_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_PTR, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_PTR, ATTR_NOTHROW_NONNULL_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_PTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR, ATTR_NOTHROW_NONNULL_1_4)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR, ATTR_NOTHROW_NONNULL_1_4)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTC, "putc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTC_UNLOCKED, "putc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTC, "fputc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PRINTF, "printf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_UNLOCKED, "printf_unlocked", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTCHAR_UNLOCKED, "putchar_unlocked", BT_FN_INT_INT, ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NOTHROW_NONNULL_1)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NOTHROW_NONNULL_1)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTCHAR_UNLOCKED, "putchar_unlocked", BT_FN_INT_INT, ATTR_NULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SCANF, "scanf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_SCANF_1_2)
|
||||
DEF_C99_BUILTIN (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_PTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_PTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VSCANF, "vscanf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_1_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||
DEF_C99_BUILTIN (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
|
||||
|
||||
/* Category: ctype builtins. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISALNUM, "isalnum", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISALPHA, "isalpha", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISASCII, "isascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ISBLANK, "isblank", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISCNTRL, "iscntrl", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISDIGIT, "isdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISGRAPH, "isgraph", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISLOWER, "islower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISPRINT, "isprint", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISPUNCT, "ispunct", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISSPACE, "isspace", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISUPPER, "isupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ISXDIGIT, "isxdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_TOASCII, "toascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_TOLOWER, "tolower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_TOUPPER, "toupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
|
||||
/* Category: wctype builtins. */
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWALNUM, "iswalnum", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWALPHA, "iswalpha", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN_ISWBLANK, "iswblank", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWCNTRL, "iswcntrl", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWDIGIT, "iswdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWGRAPH, "iswgraph", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWLOWER, "iswlower", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWPRINT, "iswprint", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWPUNCT, "iswpunct", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWSPACE, "iswspace", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWUPPER, "iswupper", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_ISWXDIGIT, "iswxdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LIST)
|
||||
|
||||
/* Category: miscellaneous builtins. */
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_ABS, "abs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
|
|
@ -497,28 +596,59 @@ DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_N
|
|||
DEF_GCC_BUILTIN (BUILT_IN_ARGS_INFO, "args_info", BT_FN_INT_INT, ATTR_NULL)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZIMAX, "ctzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DCGETTEXT, "dcgettext", BT_FN_STRING_CONST_STRING_CONST_STRING_INT, ATTR_FORMAT_ARG_2)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_DGETTEXT, "dgettext", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UNSIGNED, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UINT, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN, "eh_return", BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno", BT_FN_INT_INT, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECL, "execl", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLP, "execlp", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLE, "execle", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_SENTINEL_1)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECV, "execv", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVE, "execve", BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_WORD_PTR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UNSIGNED, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
|
||||
DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
|
||||
|
|
@ -530,15 +660,17 @@ DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_C
|
|||
DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_LIB_BUILTIN (BUILT_IN_MALLOC, "malloc", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_NEXT_ARG, "next_arg", BT_FN_PTR_VAR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITY, "parity", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITY, "parity", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYIMAX, "parityimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTIMAX, "popcountimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UNSIGNED, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_STDARG_START, "stdarg_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
|
||||
|
|
@ -546,8 +678,53 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CON
|
|||
DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_3_0)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL)
|
||||
DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
||||
DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
|
||||
|
||||
/* Implementing nested functions. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_INIT_TRAMPOLINE, "__builtin_init_trampoline")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, "__builtin_adjust_trampoline")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto")
|
||||
|
||||
/* Implementing __builtin_setjmp. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_DISPATCHER, "__builtin_setjmp_dispatcher")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_SETJMP_RECEIVER, "__builtin_setjmp_receiver")
|
||||
|
||||
/* Implementing variable sized local variables. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_STACK_SAVE, "__builtin_stack_save")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_STACK_RESTORE, "__builtin_stack_restore")
|
||||
|
||||
/* Object size checking builtins. */
|
||||
DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LIST)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_5_6)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_4_5)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_5_0)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VSPRINTF_CHK, "__vsprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_4_0)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_CHK, "__fprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_CHK, "__printf_chk", BT_FN_INT_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
|
||||
DEF_EXT_LIB_BUILTIN (BUILT_IN_VPRINTF_CHK, "__vprintf_chk", BT_FN_INT_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
|
||||
|
||||
/* Profiling hooks. */
|
||||
DEF_BUILTIN_STUB (BUILT_IN_PROFILE_FUNC_ENTER, "profile_func_enter")
|
||||
DEF_BUILTIN_STUB (BUILT_IN_PROFILE_FUNC_EXIT, "profile_func_exit")
|
||||
|
||||
/* Synchronization Primitives. */
|
||||
#include "sync-builtins.def"
|
||||
|
||||
/* OpenMP builtins. */
|
||||
#include "omp-builtins.def"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
on information stored in GCC's tree structure. This code implements the
|
||||
-aux-info option.
|
||||
Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998,
|
||||
1999, 2000, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Ron Guilmette (rfg@segfault.us.com).
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -19,8 +19,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -75,15 +75,15 @@ affix_data_type (const char *param)
|
|||
for (;;)
|
||||
{
|
||||
if (!strncmp (p, "volatile ", 9))
|
||||
{
|
||||
p += 9;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
p += 9;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp (p, "const ", 6))
|
||||
{
|
||||
p += 6;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
p += 6;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ gen_formal_list_for_type (tree fntype, formals_style style)
|
|||
const char *this_type;
|
||||
|
||||
if (*formal_list)
|
||||
formal_list = concat (formal_list, ", ", NULL);
|
||||
formal_list = concat (formal_list, ", ", NULL);
|
||||
|
||||
this_type = gen_type ("", TREE_VALUE (formal_type), ansi);
|
||||
formal_list
|
||||
|
|
@ -167,18 +167,18 @@ gen_formal_list_for_type (tree fntype, formals_style style)
|
|||
if (!*formal_list)
|
||||
{
|
||||
if (TYPE_ARG_TYPES (fntype))
|
||||
/* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */
|
||||
formal_list = "void";
|
||||
/* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node); */
|
||||
formal_list = "void";
|
||||
else
|
||||
formal_list = "/* ??? */";
|
||||
formal_list = "/* ??? */";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If there were at least some parameters, and if the formals-types-list
|
||||
petered out to a NULL (i.e. without being terminated by a
|
||||
void_type_node) then we need to tack on an ellipsis. */
|
||||
petered out to a NULL (i.e. without being terminated by a
|
||||
void_type_node) then we need to tack on an ellipsis. */
|
||||
if (!formal_type)
|
||||
formal_list = concat (formal_list, ", ...", NULL);
|
||||
formal_list = concat (formal_list, ", ...", NULL);
|
||||
}
|
||||
|
||||
return concat (" (", formal_list, ")", NULL);
|
||||
|
|
@ -237,20 +237,20 @@ gen_formal_list_for_func_def (tree fndecl, formals_style style)
|
|||
const char *this_formal;
|
||||
|
||||
if (*formal_list && ((style == ansi) || (style == k_and_r_names)))
|
||||
formal_list = concat (formal_list, ", ", NULL);
|
||||
formal_list = concat (formal_list, ", ", NULL);
|
||||
this_formal = gen_decl (formal_decl, 0, style);
|
||||
if (style == k_and_r_decls)
|
||||
formal_list = concat (formal_list, this_formal, "; ", NULL);
|
||||
formal_list = concat (formal_list, this_formal, "; ", NULL);
|
||||
else
|
||||
formal_list = concat (formal_list, this_formal, NULL);
|
||||
formal_list = concat (formal_list, this_formal, NULL);
|
||||
formal_decl = TREE_CHAIN (formal_decl);
|
||||
}
|
||||
if (style == ansi)
|
||||
{
|
||||
if (!DECL_ARGUMENTS (fndecl))
|
||||
formal_list = concat (formal_list, "void", NULL);
|
||||
formal_list = concat (formal_list, "void", NULL);
|
||||
if (deserves_ellipsis (TREE_TYPE (fndecl)))
|
||||
formal_list = concat (formal_list, ", ...", NULL);
|
||||
formal_list = concat (formal_list, ", ...", NULL);
|
||||
}
|
||||
if ((style == ansi) || (style == k_and_r_names))
|
||||
formal_list = concat (" (", formal_list, ")", NULL);
|
||||
|
|
@ -309,23 +309,23 @@ gen_type (const char *ret_val, tree t, formals_style style)
|
|||
else
|
||||
{
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case POINTER_TYPE:
|
||||
if (TYPE_READONLY (t))
|
||||
ret_val = concat ("const ", ret_val, NULL);
|
||||
if (TYPE_VOLATILE (t))
|
||||
ret_val = concat ("volatile ", ret_val, NULL);
|
||||
{
|
||||
case POINTER_TYPE:
|
||||
if (TYPE_READONLY (t))
|
||||
ret_val = concat ("const ", ret_val, NULL);
|
||||
if (TYPE_VOLATILE (t))
|
||||
ret_val = concat ("volatile ", ret_val, NULL);
|
||||
|
||||
ret_val = concat ("*", ret_val, NULL);
|
||||
ret_val = concat ("*", ret_val, NULL);
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
|
||||
ret_val = concat ("(", ret_val, ")", NULL);
|
||||
|
||||
ret_val = gen_type (ret_val, TREE_TYPE (t), style);
|
||||
ret_val = gen_type (ret_val, TREE_TYPE (t), style);
|
||||
|
||||
return ret_val;
|
||||
return ret_val;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
case ARRAY_TYPE:
|
||||
if (!COMPLETE_TYPE_P (t) || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST)
|
||||
ret_val = gen_type (concat (ret_val, "[]", NULL),
|
||||
TREE_TYPE (t), style);
|
||||
|
|
@ -340,23 +340,23 @@ gen_type (const char *ret_val, tree t, formals_style style)
|
|||
ret_val = gen_type (concat (ret_val, buff, NULL),
|
||||
TREE_TYPE (t), style);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case FUNCTION_TYPE:
|
||||
ret_val = gen_type (concat (ret_val,
|
||||
case FUNCTION_TYPE:
|
||||
ret_val = gen_type (concat (ret_val,
|
||||
gen_formal_list_for_type (t, style),
|
||||
NULL),
|
||||
TREE_TYPE (t), style);
|
||||
break;
|
||||
break;
|
||||
|
||||
case IDENTIFIER_NODE:
|
||||
data_type = IDENTIFIER_POINTER (t);
|
||||
break;
|
||||
case IDENTIFIER_NODE:
|
||||
data_type = IDENTIFIER_POINTER (t);
|
||||
break;
|
||||
|
||||
/* The following three cases are complicated by the fact that a
|
||||
user may do something really stupid, like creating a brand new
|
||||
"anonymous" type specification in a formal argument list (or as
|
||||
part of a function return type specification). For example:
|
||||
user may do something really stupid, like creating a brand new
|
||||
"anonymous" type specification in a formal argument list (or as
|
||||
part of a function return type specification). For example:
|
||||
|
||||
int f (enum { red, green, blue } color);
|
||||
|
||||
|
|
@ -364,7 +364,7 @@ gen_type (const char *ret_val, tree t, formals_style style)
|
|||
to represent the (anonymous) type. Thus, we have to generate the
|
||||
whole darn type specification. Yuck! */
|
||||
|
||||
case RECORD_TYPE:
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
||||
else
|
||||
|
|
@ -383,7 +383,7 @@ gen_type (const char *ret_val, tree t, formals_style style)
|
|||
data_type = concat ("struct ", data_type, NULL);
|
||||
break;
|
||||
|
||||
case UNION_TYPE:
|
||||
case UNION_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
||||
else
|
||||
|
|
@ -402,7 +402,7 @@ gen_type (const char *ret_val, tree t, formals_style style)
|
|||
data_type = concat ("union ", data_type, NULL);
|
||||
break;
|
||||
|
||||
case ENUMERAL_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
|
||||
else
|
||||
|
|
@ -422,33 +422,33 @@ gen_type (const char *ret_val, tree t, formals_style style)
|
|||
data_type = concat ("enum ", data_type, NULL);
|
||||
break;
|
||||
|
||||
case TYPE_DECL:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (t));
|
||||
break;
|
||||
case TYPE_DECL:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (t));
|
||||
break;
|
||||
|
||||
case INTEGER_TYPE:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
/* Normally, `unsigned' is part of the deal. Not so if it comes
|
||||
case INTEGER_TYPE:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
/* Normally, `unsigned' is part of the deal. Not so if it comes
|
||||
with a type qualifier. */
|
||||
if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
|
||||
if (TYPE_UNSIGNED (t) && TYPE_QUALS (t))
|
||||
data_type = concat ("unsigned ", data_type, NULL);
|
||||
break;
|
||||
|
||||
case REAL_TYPE:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
break;
|
||||
case REAL_TYPE:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
break;
|
||||
|
||||
case VOID_TYPE:
|
||||
data_type = "void";
|
||||
break;
|
||||
case VOID_TYPE:
|
||||
data_type = "void";
|
||||
break;
|
||||
|
||||
case ERROR_MARK:
|
||||
data_type = "[ERROR]";
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
if (TYPE_READONLY (t))
|
||||
ret_val = concat ("const ", ret_val, NULL);
|
||||
|
|
@ -518,11 +518,11 @@ gen_decl (tree decl, int is_func_definition, formals_style style)
|
|||
NULL);
|
||||
|
||||
/* Since we have already added in the formals list stuff, here we don't
|
||||
add the whole "type" of the function we are considering (which
|
||||
would include its parameter-list info), rather, we only add in
|
||||
the "type" of the "type" of the function, which is really just
|
||||
the return-type of the function (and does not include the parameter
|
||||
list info). */
|
||||
add the whole "type" of the function we are considering (which
|
||||
would include its parameter-list info), rather, we only add in
|
||||
the "type" of the "type" of the function, which is really just
|
||||
the return-type of the function (and does not include the parameter
|
||||
list info). */
|
||||
|
||||
ret_val = gen_type (ret_val, TREE_TYPE (TREE_TYPE (decl)), style);
|
||||
}
|
||||
|
|
@ -531,7 +531,7 @@ gen_decl (tree decl, int is_func_definition, formals_style style)
|
|||
|
||||
ret_val = affix_data_type (ret_val);
|
||||
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL && C_DECL_REGISTER (decl))
|
||||
ret_val = concat ("register ", ret_val, NULL);
|
||||
if (TREE_PUBLIC (decl))
|
||||
ret_val = concat ("extern ", ret_val, NULL);
|
||||
|
|
@ -554,11 +554,12 @@ gen_aux_info_record (tree fndecl, int is_definition, int is_implicit,
|
|||
if (flag_gen_aux_info)
|
||||
{
|
||||
static int compiled_from_record = 0;
|
||||
expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (fndecl));
|
||||
|
||||
/* Each output .X file must have a header line. Write one now if we
|
||||
have not yet done so. */
|
||||
|
||||
if (! compiled_from_record++)
|
||||
if (!compiled_from_record++)
|
||||
{
|
||||
/* The first line tells which directory file names are relative to.
|
||||
Currently, -aux-info works only for files in the working
|
||||
|
|
@ -569,8 +570,7 @@ gen_aux_info_record (tree fndecl, int is_definition, int is_implicit,
|
|||
/* Write the actual line of auxiliary info. */
|
||||
|
||||
fprintf (aux_info_file, "/* %s:%d:%c%c */ %s;",
|
||||
DECL_SOURCE_FILE (fndecl),
|
||||
DECL_SOURCE_LINE (fndecl),
|
||||
xloc.file, xloc.line,
|
||||
(is_implicit) ? 'I' : (is_prototyped) ? 'N' : 'O',
|
||||
(is_definition) ? 'F' : 'C',
|
||||
gen_decl (fndecl, is_definition, ansi));
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
additional tree codes used in the GNU C++ compiler (see tree.def
|
||||
additional tree codes used in the GNU C compiler (see tree.def
|
||||
for the standard codes).
|
||||
Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2004, 2005 Free Software Foundation, Inc.
|
||||
Written by Benjamin Chelf <chelf@codesourcery.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -19,101 +19,18 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* Tree nodes relevant to both C and C++. These were originally in
|
||||
cp-tree.def in the cp subdir. */
|
||||
|
||||
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", '1', 1)
|
||||
DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
|
||||
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)
|
||||
|
||||
/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
|
||||
obtain the expression. */
|
||||
DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a brace-enclosed block. The operand is
|
||||
COMPOUND_BODY. */
|
||||
DEFTREECODE (COMPOUND_STMT, "compound_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a local declaration. The operand is
|
||||
DECL_STMT_DECL. */
|
||||
DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 1)
|
||||
|
||||
/* Represents an 'if' statement. The operands are IF_COND,
|
||||
THEN_CLAUSE, and ELSE_CLAUSE, respectively. */
|
||||
DEFTREECODE (IF_STMT, "if_stmt", 'e', 3)
|
||||
|
||||
/* Used to represent a `for' statement. The operands are
|
||||
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
|
||||
DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4)
|
||||
|
||||
/* Used to represent a 'while' statement. The operands are WHILE_COND
|
||||
and WHILE_BODY, respectively. */
|
||||
DEFTREECODE (WHILE_STMT, "while_stmt", 'e', 2)
|
||||
|
||||
/* Used to represent a 'do' statement. The operands are DO_BODY and
|
||||
DO_COND, respectively. */
|
||||
DEFTREECODE (DO_STMT, "do_stmt", 'e', 2)
|
||||
|
||||
/* Used to represent a 'return' statement. The operand is
|
||||
RETURN_STMT_EXPR. */
|
||||
DEFTREECODE (RETURN_STMT, "return_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a 'break' statement. */
|
||||
DEFTREECODE (BREAK_STMT, "break_stmt", 'e', 0)
|
||||
|
||||
/* Used to represent a 'continue' statement. */
|
||||
DEFTREECODE (CONTINUE_STMT, "continue_stmt", 'e', 0)
|
||||
|
||||
/* Used to represent a 'switch' statement. The operands are
|
||||
SWITCH_COND, SWITCH_BODY and SWITCH_TYPE, respectively. */
|
||||
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 3)
|
||||
|
||||
/* Used to represent a 'goto' statement. The operand is GOTO_DESTINATION. */
|
||||
DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a 'label' statement. The operand is a LABEL_DECL
|
||||
and can be obtained through the macro LABEL_STMT_LABEL. */
|
||||
DEFTREECODE (LABEL_STMT, "label_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent an inline assembly statement. */
|
||||
DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
|
||||
|
||||
/* A SCOPE_STMT marks the beginning or end of a scope. If
|
||||
SCOPE_BEGIN_P holds, then this is the start of a scope. If
|
||||
SCOPE_END_P holds, then this is the end of a scope. If
|
||||
SCOPE_NULLIFIED_P holds then there turned out to be no variables in
|
||||
this scope. The SCOPE_STMT_BLOCK is the BLOCK containing the
|
||||
variables declared in this scope. */
|
||||
DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 1)
|
||||
|
||||
/* A FILE_STMT marks the spot where a function changes files. It has no
|
||||
other semantics. FILE_STMT_FILENAME gives the name. */
|
||||
DEFTREECODE (FILE_STMT, "file_stmt", 'e', 1)
|
||||
|
||||
/* Used to represent a CASE_LABEL. The operands are CASE_LOW and
|
||||
CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
|
||||
'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
|
||||
label. The CASE_LABEL_DECL is a LABEL_DECL for this node. */
|
||||
DEFTREECODE (CASE_LABEL, "case_label", 'e', 3)
|
||||
|
||||
/* A STMT_EXPR represents a statement-expression. The
|
||||
STMT_EXPR_STMT is the statement given by the expression. */
|
||||
DEFTREECODE (STMT_EXPR, "stmt_expr", 'e', 1)
|
||||
/* Tree nodes used in the C frontend. These are also shared with the
|
||||
C++ and Objective C frontends. */
|
||||
|
||||
/* A COMPOUND_LITERAL_EXPR represents a C99 compound literal. The
|
||||
COMPOUND_LITERAL_EXPR_DECL_STMT is the a DECL_STMT containing the decl
|
||||
for the anonymous object represented by the COMPOUND_LITERAL;
|
||||
the DECL_INITIAL of that decl is the CONSTRUCTOR that initializes
|
||||
the compound literal. */
|
||||
DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", 'e', 1)
|
||||
|
||||
/* A CLEANUP_STMT marks the point at which a declaration is fully
|
||||
constructed. If, after this point, the CLEANUP_DECL goes out of
|
||||
scope, the CLEANUP_EXPR must be run. */
|
||||
DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
|
||||
DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", tcc_expression, 1)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
# Top level configure fragment for GNU C - C language.
|
||||
# Copyright (C) 1994, 1995, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GCC.
|
||||
|
||||
|
|
@ -15,12 +15,12 @@
|
|||
|
||||
#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.
|
||||
#the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
#Boston, MA 02110-1301, USA.
|
||||
|
||||
# This file c-config-lang.c is a special pseudo config-lang.in file
|
||||
# for the language C. It has limited use, specifically to record the
|
||||
# files used by C that have garbage collection GTY macros in them
|
||||
# which therefore need to be scanned by gengtype.c.
|
||||
|
||||
gtfiles="\$(srcdir)/c-lang.c \$(srcdir)/c-parse.in \$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c \$(srcdir)/c-objc-common.c"
|
||||
gtfiles="\$(srcdir)/c-lang.c \$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c \$(srcdir)/c-objc-common.c \$(srcdir)/c-parser.c"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Language-level data type conversion for GNU C.
|
||||
Copyright (C) 1987, 1988, 1991, 1998, 2002, 2003
|
||||
Copyright (C) 1987, 1988, 1991, 1998, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
|
||||
/* This file contains the functions for converting C expressions
|
||||
|
|
@ -33,7 +33,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "flags.h"
|
||||
#include "convert.h"
|
||||
#include "c-common.h"
|
||||
#include "c-tree.h"
|
||||
#include "langhooks.h"
|
||||
#include "toplev.h"
|
||||
#include "target.h"
|
||||
|
||||
/* Change of width--truncation and extension of integers or reals--
|
||||
is represented with NOP_EXPR. Proper functioning of many things
|
||||
|
|
@ -67,14 +70,25 @@ convert (tree type, tree expr)
|
|||
{
|
||||
tree e = expr;
|
||||
enum tree_code code = TREE_CODE (type);
|
||||
const char *invalid_conv_diag;
|
||||
|
||||
if (type == TREE_TYPE (expr)
|
||||
|| TREE_CODE (expr) == ERROR_MARK
|
||||
|| code == ERROR_MARK || TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
|
||||
if (type == error_mark_node
|
||||
|| expr == error_mark_node
|
||||
|| TREE_TYPE (expr) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if ((invalid_conv_diag
|
||||
= targetm.invalid_conversion (TREE_TYPE (expr), type)))
|
||||
{
|
||||
error (invalid_conv_diag);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (type == TREE_TYPE (expr))
|
||||
return expr;
|
||||
|
||||
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
|
||||
return fold (build1 (NOP_EXPR, type, expr));
|
||||
return fold_convert (type, expr);
|
||||
if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
|
||||
return error_mark_node;
|
||||
if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
|
||||
|
|
@ -83,25 +97,11 @@ convert (tree type, tree expr)
|
|||
return error_mark_node;
|
||||
}
|
||||
if (code == VOID_TYPE)
|
||||
return build1 (CONVERT_EXPR, type, e);
|
||||
#if 0
|
||||
/* This is incorrect. A truncation can't be stripped this way.
|
||||
Extensions will be stripped by the use of get_unwidened. */
|
||||
if (TREE_CODE (expr) == NOP_EXPR)
|
||||
return convert (type, TREE_OPERAND (expr, 0));
|
||||
#endif
|
||||
return fold_convert (type, e);
|
||||
if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
|
||||
return fold (convert_to_integer (type, e));
|
||||
if (code == BOOLEAN_TYPE)
|
||||
{
|
||||
tree t = c_common_truthvalue_conversion (expr);
|
||||
/* If it returns a NOP_EXPR, we must fold it here to avoid
|
||||
infinite recursion between fold () and convert (). */
|
||||
if (TREE_CODE (t) == NOP_EXPR)
|
||||
return fold (build1 (NOP_EXPR, type, TREE_OPERAND (t, 0)));
|
||||
else
|
||||
return fold (build1 (NOP_EXPR, type, t));
|
||||
}
|
||||
return fold_convert (type, c_objc_common_truthvalue_conversion (expr));
|
||||
if (code == POINTER_TYPE || code == REFERENCE_TYPE)
|
||||
return fold (convert_to_pointer (type, e));
|
||||
if (code == REAL_TYPE)
|
||||
|
|
@ -110,6 +110,9 @@ convert (tree type, tree expr)
|
|||
return fold (convert_to_complex (type, e));
|
||||
if (code == VECTOR_TYPE)
|
||||
return fold (convert_to_vector (type, e));
|
||||
if ((code == RECORD_TYPE || code == UNION_TYPE)
|
||||
&& lang_hooks.types_compatible_p (type, TREE_TYPE (expr)))
|
||||
return e;
|
||||
|
||||
error ("conversion to non-scalar type requested");
|
||||
return error_mark_node;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Define builtin-in macros for the C family front ends.
|
||||
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -15,14 +15,15 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "version.h"
|
||||
#include "flags.h"
|
||||
#include "real.h"
|
||||
#include "c-common.h"
|
||||
|
|
@ -31,6 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
|
||||
#include "toplev.h"
|
||||
#include "tm_p.h" /* Target prototypes. */
|
||||
#include "target.h"
|
||||
|
||||
#ifndef TARGET_OS_CPP_BUILTINS
|
||||
# define TARGET_OS_CPP_BUILTINS()
|
||||
|
|
@ -51,10 +53,14 @@ static void builtin_define_with_value_n (const char *, const char *,
|
|||
static void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
|
||||
static void builtin_define_with_hex_fp_value (const char *, tree,
|
||||
int, const char *,
|
||||
const char *,
|
||||
const char *);
|
||||
static void builtin_define_stdint_macros (void);
|
||||
static void builtin_define_type_max (const char *, tree, int);
|
||||
static void builtin_define_type_precision (const char *, tree);
|
||||
static void builtin_define_float_constants (const char *, const char *,
|
||||
static void builtin_define_float_constants (const char *,
|
||||
const char *,
|
||||
const char *,
|
||||
tree);
|
||||
static void define__GNUC__ (void);
|
||||
|
||||
|
|
@ -65,9 +71,13 @@ builtin_define_type_precision (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. */
|
||||
/* Define the float.h constants for TYPE using NAME_PREFIX, FP_SUFFIX,
|
||||
and FP_CAST. */
|
||||
static void
|
||||
builtin_define_float_constants (const char *name_prefix, const char *fp_suffix, tree type)
|
||||
builtin_define_float_constants (const char *name_prefix,
|
||||
const char *fp_suffix,
|
||||
const char *fp_cast,
|
||||
tree type)
|
||||
{
|
||||
/* Used to convert radix-based values to base 10 values in several cases.
|
||||
|
||||
|
|
@ -86,6 +96,7 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
|
|||
int decimal_dig;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
|
||||
gcc_assert (fmt->b != 10);
|
||||
|
||||
/* The radix of the exponent representation. */
|
||||
if (type == float_type_node)
|
||||
|
|
@ -205,19 +216,24 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
|
|||
}
|
||||
}
|
||||
sprintf (name, "__%s_MAX__", name_prefix);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
|
||||
|
||||
/* 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);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
|
||||
|
||||
/* 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);
|
||||
if (fmt->pnan < fmt->p)
|
||||
/* This is an IBM extended double format, so 1.0 + any double is
|
||||
representable precisely. */
|
||||
sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
|
||||
else
|
||||
sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
|
||||
|
||||
/* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized
|
||||
positive floating-point number, b**(emin-p). Zero for formats that
|
||||
|
|
@ -227,7 +243,7 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
|
|||
{
|
||||
sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
|
||||
builtin_define_with_hex_fp_value (name, type, decimal_dig,
|
||||
buf, fp_suffix);
|
||||
buf, fp_suffix, fp_cast);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -235,6 +251,9 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
|
|||
builtin_define_with_value (name, buf, 0);
|
||||
}
|
||||
|
||||
sprintf (name, "__%s_HAS_DENORM__", name_prefix);
|
||||
builtin_define_with_value (name, fmt->has_denorm ? "1" : "0", 0);
|
||||
|
||||
/* For C++ std::numeric_limits<T>::has_infinity. */
|
||||
sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
|
||||
builtin_define_with_int_value (name,
|
||||
|
|
@ -248,6 +267,70 @@ builtin_define_float_constants (const char *name_prefix, const char *fp_suffix,
|
|||
builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
|
||||
}
|
||||
|
||||
/* Define __DECx__ constants for TYPE using NAME_PREFIX and SUFFIX. */
|
||||
static void
|
||||
builtin_define_decimal_float_constants (const char *name_prefix,
|
||||
const char *suffix,
|
||||
tree type)
|
||||
{
|
||||
const struct real_format *fmt;
|
||||
char name[64], buf[128], *p;
|
||||
int digits;
|
||||
|
||||
fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
|
||||
|
||||
/* The number of radix digits, p, in the significand. */
|
||||
sprintf (name, "__%s_MANT_DIG__", name_prefix);
|
||||
builtin_define_with_int_value (name, fmt->p);
|
||||
|
||||
/* 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 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);
|
||||
|
||||
/* Compute the minimum representable value. */
|
||||
sprintf (name, "__%s_MIN__", name_prefix);
|
||||
sprintf (buf, "1E%d%s", fmt->emin, suffix);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
|
||||
/* Compute the maximum representable value. */
|
||||
sprintf (name, "__%s_MAX__", name_prefix);
|
||||
p = buf;
|
||||
for (digits = fmt->p; digits; digits--)
|
||||
{
|
||||
*p++ = '9';
|
||||
if (digits == fmt->p)
|
||||
*p++ = '.';
|
||||
}
|
||||
*p = 0;
|
||||
/* fmt->p plus 1, to account for the decimal point. */
|
||||
sprintf (&buf[fmt->p + 1], "E%d%s", fmt->emax, suffix);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
|
||||
/* Compute epsilon (the difference between 1 and least value greater
|
||||
than 1 representable). */
|
||||
sprintf (name, "__%s_EPSILON__", name_prefix);
|
||||
sprintf (buf, "1E-%d%s", fmt->p - 1, suffix);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
|
||||
/* Minimum denormalized postive decimal value. */
|
||||
sprintf (name, "__%s_DEN__", name_prefix);
|
||||
p = buf;
|
||||
for (digits = fmt->p; digits > 1; digits--)
|
||||
{
|
||||
*p++ = '0';
|
||||
if (digits == fmt->p)
|
||||
*p++ = '.';
|
||||
}
|
||||
*p = 0;
|
||||
sprintf (&buf[fmt->p], "1E%d%s", fmt->emin, suffix);
|
||||
builtin_define_with_value (name, buf, 0);
|
||||
}
|
||||
|
||||
/* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. */
|
||||
static void
|
||||
define__GNUC__ (void)
|
||||
|
|
@ -256,10 +339,9 @@ define__GNUC__ (void)
|
|||
([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
|
||||
const char *q, *v = version_string;
|
||||
|
||||
while (*v && ! ISDIGIT (*v))
|
||||
while (*v && !ISDIGIT (*v))
|
||||
v++;
|
||||
if (!*v || (v > version_string && v[-1] != '-'))
|
||||
abort ();
|
||||
gcc_assert (*v && (v <= version_string || v[-1] == '-'));
|
||||
|
||||
q = v;
|
||||
while (ISDIGIT (*v))
|
||||
|
|
@ -268,8 +350,8 @@ define__GNUC__ (void)
|
|||
if (c_dialect_cxx ())
|
||||
builtin_define_with_value_n ("__GNUG__", q, v - q);
|
||||
|
||||
if (*v != '.' || !ISDIGIT (v[1]))
|
||||
abort ();
|
||||
gcc_assert (*v == '.' && ISDIGIT (v[1]));
|
||||
|
||||
q = ++v;
|
||||
while (ISDIGIT (*v))
|
||||
v++;
|
||||
|
|
@ -277,8 +359,7 @@ define__GNUC__ (void)
|
|||
|
||||
if (*v == '.')
|
||||
{
|
||||
if (!ISDIGIT (v[1]))
|
||||
abort ();
|
||||
gcc_assert (ISDIGIT (v[1]));
|
||||
q = ++v;
|
||||
while (ISDIGIT (*v))
|
||||
v++;
|
||||
|
|
@ -287,8 +368,24 @@ define__GNUC__ (void)
|
|||
else
|
||||
builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", "0", 1);
|
||||
|
||||
if (*v && *v != ' ' && *v != '-')
|
||||
abort ();
|
||||
gcc_assert (!*v || *v == ' ' || *v == '-');
|
||||
}
|
||||
|
||||
/* Define macros used by <stdint.h>. Currently only defines limits
|
||||
for intmax_t, used by the testsuite. */
|
||||
static void
|
||||
builtin_define_stdint_macros (void)
|
||||
{
|
||||
int intmax_long;
|
||||
if (intmax_type_node == long_long_integer_type_node)
|
||||
intmax_long = 2;
|
||||
else if (intmax_type_node == long_integer_type_node)
|
||||
intmax_long = 1;
|
||||
else if (intmax_type_node == integer_type_node)
|
||||
intmax_long = 0;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
builtin_define_type_max ("__INTMAX_MAX__", intmax_type_node, intmax_long);
|
||||
}
|
||||
|
||||
/* Hook that registers front end and target-specific built-ins. */
|
||||
|
|
@ -306,7 +403,7 @@ c_cpp_builtins (cpp_reader *pfile)
|
|||
|
||||
if (c_dialect_cxx ())
|
||||
{
|
||||
if (SUPPORTS_ONE_ONLY)
|
||||
if (flag_weak && SUPPORTS_ONE_ONLY)
|
||||
cpp_define (pfile, "__GXX_WEAK__=1");
|
||||
else
|
||||
cpp_define (pfile, "__GXX_WEAK__=0");
|
||||
|
|
@ -323,19 +420,19 @@ c_cpp_builtins (cpp_reader *pfile)
|
|||
if (flag_abi_version == 0)
|
||||
/* Use a very large value so that:
|
||||
|
||||
#if __GXX_ABI_VERSION >= <value for version X>
|
||||
#if __GXX_ABI_VERSION >= <value for version X>
|
||||
|
||||
will work whether the user explicitly says "-fabi-version=x" or
|
||||
"-fabi-version=0". Do not use INT_MAX because that will be
|
||||
different from system to system. */
|
||||
builtin_define_with_int_value ("__GXX_ABI_VERSION", 999999);
|
||||
else if (flag_abi_version == 1)
|
||||
/* Due to an historical accident, this version had the value
|
||||
/* Due to a historical accident, this version had the value
|
||||
"102". */
|
||||
builtin_define_with_int_value ("__GXX_ABI_VERSION", 102);
|
||||
else
|
||||
/* Newer versions have values 1002, 1003, .... */
|
||||
builtin_define_with_int_value ("__GXX_ABI_VERSION",
|
||||
builtin_define_with_int_value ("__GXX_ABI_VERSION",
|
||||
1000 + flag_abi_version);
|
||||
|
||||
/* libgcc needs to know this. */
|
||||
|
|
@ -352,14 +449,33 @@ c_cpp_builtins (cpp_reader *pfile)
|
|||
|
||||
builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
|
||||
|
||||
/* stdint.h (eventually) and the testsuite need to know these. */
|
||||
builtin_define_stdint_macros ();
|
||||
|
||||
/* 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);
|
||||
/* And decfloat.h needs this. */
|
||||
builtin_define_with_int_value ("__DEC_EVAL_METHOD__",
|
||||
TARGET_DEC_EVAL_METHOD);
|
||||
|
||||
builtin_define_float_constants ("FLT", "F", "%s", float_type_node);
|
||||
/* Cast the double precision constants when single precision constants are
|
||||
specified. The correct result is computed by the compiler when using
|
||||
macros that include a cast. This has the side-effect of making the value
|
||||
unusable in const expressions. */
|
||||
if (flag_single_precision_constant)
|
||||
builtin_define_float_constants ("DBL", "L", "((double)%s)", double_type_node);
|
||||
else
|
||||
builtin_define_float_constants ("DBL", "", "%s", double_type_node);
|
||||
builtin_define_float_constants ("LDBL", "L", "%s", long_double_type_node);
|
||||
|
||||
/* For decfloat.h. */
|
||||
builtin_define_decimal_float_constants ("DEC32", "DF", dfloat32_type_node);
|
||||
builtin_define_decimal_float_constants ("DEC64", "DD", dfloat64_type_node);
|
||||
builtin_define_decimal_float_constants ("DEC128", "DL", dfloat128_type_node);
|
||||
|
||||
/* For use in assembly language. */
|
||||
builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
|
||||
|
|
@ -368,6 +484,8 @@ c_cpp_builtins (cpp_reader *pfile)
|
|||
/* Misc. */
|
||||
builtin_define_with_value ("__VERSION__", version_string, 1);
|
||||
|
||||
cpp_define (pfile, "__GNUC_GNU_INLINE__");
|
||||
|
||||
/* Definitions for LP64 model. */
|
||||
if (TYPE_PRECISION (long_integer_type_node) == 64
|
||||
&& POINTER_SIZE == 64
|
||||
|
|
@ -394,6 +512,11 @@ c_cpp_builtins (cpp_reader *pfile)
|
|||
cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
|
||||
else
|
||||
cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
|
||||
if (flag_pic)
|
||||
{
|
||||
builtin_define_with_int_value ("__pic__", flag_pic);
|
||||
builtin_define_with_int_value ("__PIC__", flag_pic);
|
||||
}
|
||||
|
||||
if (flag_iso)
|
||||
cpp_define (pfile, "__STRICT_ANSI__");
|
||||
|
|
@ -401,13 +524,31 @@ c_cpp_builtins (cpp_reader *pfile)
|
|||
if (!flag_signed_char)
|
||||
cpp_define (pfile, "__CHAR_UNSIGNED__");
|
||||
|
||||
if (c_dialect_cxx () && TREE_UNSIGNED (wchar_type_node))
|
||||
if (c_dialect_cxx () && TYPE_UNSIGNED (wchar_type_node))
|
||||
cpp_define (pfile, "__WCHAR_UNSIGNED__");
|
||||
|
||||
/* Make the choice of ObjC runtime visible to source code. */
|
||||
if (c_dialect_objc () && flag_next_runtime)
|
||||
cpp_define (pfile, "__NEXT_RUNTIME__");
|
||||
|
||||
/* Show the availability of some target pragmas. */
|
||||
if (flag_mudflap || targetm.handle_pragma_redefine_extname)
|
||||
cpp_define (pfile, "__PRAGMA_REDEFINE_EXTNAME");
|
||||
|
||||
if (targetm.handle_pragma_extern_prefix)
|
||||
cpp_define (pfile, "__PRAGMA_EXTERN_PREFIX");
|
||||
|
||||
/* Make the choice of the stack protector runtime visible to source code.
|
||||
The macro names and values here were chosen for compatibility with an
|
||||
earlier implementation, i.e. ProPolice. */
|
||||
if (flag_stack_protect == 2)
|
||||
cpp_define (pfile, "__SSP_ALL__=2");
|
||||
else if (flag_stack_protect == 1)
|
||||
cpp_define (pfile, "__SSP__=1");
|
||||
|
||||
if (flag_openmp)
|
||||
cpp_define (pfile, "_OPENMP=200505");
|
||||
|
||||
/* 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)
|
||||
|
|
@ -417,6 +558,15 @@ c_cpp_builtins (cpp_reader *pfile)
|
|||
TARGET_CPU_CPP_BUILTINS ();
|
||||
TARGET_OS_CPP_BUILTINS ();
|
||||
TARGET_OBJFMT_CPP_BUILTINS ();
|
||||
|
||||
/* Support the __declspec keyword by turning them into attributes.
|
||||
Note that the current way we do this may result in a collision
|
||||
with predefined attributes later on. This can be solved by using
|
||||
one attribute, say __declspec__, and passing args to it. The
|
||||
problem with that approach is that args are not accumulated: each
|
||||
new appearance would clobber any existing args. */
|
||||
if (TARGET_DECLSPEC)
|
||||
builtin_define ("__declspec(x)=__attribute__((x))");
|
||||
}
|
||||
|
||||
/* Pass an object-like macro. If it doesn't lie in the user's
|
||||
|
|
@ -432,7 +582,7 @@ void
|
|||
builtin_define_std (const char *macro)
|
||||
{
|
||||
size_t len = strlen (macro);
|
||||
char *buff = alloca (len + 5);
|
||||
char *buff = (char *) alloca (len + 5);
|
||||
char *p = buff + 2;
|
||||
char *q = p + len;
|
||||
|
||||
|
|
@ -478,7 +628,7 @@ builtin_define_with_value (const char *macro, const char *expansion, int is_str)
|
|||
if (is_str)
|
||||
extra += 2; /* space for two quote marks */
|
||||
|
||||
buf = alloca (mlen + elen + extra);
|
||||
buf = (char *) alloca (mlen + elen + extra);
|
||||
if (is_str)
|
||||
sprintf (buf, "%s=\"%s\"", macro, expansion);
|
||||
else
|
||||
|
|
@ -496,7 +646,7 @@ builtin_define_with_value_n (const char *macro, const char *expansion, size_t el
|
|||
size_t mlen = strlen (macro);
|
||||
|
||||
/* Space for an = and a NUL. */
|
||||
buf = alloca (mlen + elen + 2);
|
||||
buf = (char *) alloca (mlen + elen + 2);
|
||||
memcpy (buf, macro, mlen);
|
||||
buf[mlen] = '=';
|
||||
memcpy (buf + mlen + 1, expansion, elen);
|
||||
|
|
@ -514,7 +664,7 @@ builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value)
|
|||
size_t vlen = 18;
|
||||
size_t extra = 2; /* space for = and NUL. */
|
||||
|
||||
buf = alloca (mlen + vlen + extra);
|
||||
buf = (char *) alloca (mlen + vlen + extra);
|
||||
memcpy (buf, macro, mlen);
|
||||
buf[mlen] = '=';
|
||||
sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value);
|
||||
|
|
@ -526,10 +676,12 @@ builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value)
|
|||
static void
|
||||
builtin_define_with_hex_fp_value (const char *macro,
|
||||
tree type ATTRIBUTE_UNUSED, int digits,
|
||||
const char *hex_str, const char *fp_suffix)
|
||||
const char *hex_str,
|
||||
const char *fp_suffix,
|
||||
const char *fp_cast)
|
||||
{
|
||||
REAL_VALUE_TYPE real;
|
||||
char dec_str[64], buf[256];
|
||||
char dec_str[64], buf1[256], buf2[256];
|
||||
|
||||
/* Hex values are really cool and convenient, except that they're
|
||||
not supported in strict ISO C90 mode. First, the "p-" sequence
|
||||
|
|
@ -544,8 +696,13 @@ builtin_define_with_hex_fp_value (const char *macro,
|
|||
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);
|
||||
/* Assemble the macro in the following fashion
|
||||
macro = fp_cast [dec_str fp_suffix] */
|
||||
sprintf (buf1, "%s%s", dec_str, fp_suffix);
|
||||
sprintf (buf2, fp_cast, buf1);
|
||||
sprintf (buf1, "%s=%s", macro, buf2);
|
||||
|
||||
cpp_define (parse_in, buf1);
|
||||
}
|
||||
|
||||
/* Define MAX for TYPE based on the precision of the type. IS_LONG is
|
||||
|
|
@ -578,13 +735,14 @@ builtin_define_type_max (const char *macro, tree type, int is_long)
|
|||
case 32: idx = 4; break;
|
||||
case 64: idx = 6; break;
|
||||
case 128: idx = 8; break;
|
||||
default: abort ();
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
|
||||
value = values[idx + TREE_UNSIGNED (type)];
|
||||
suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
|
||||
value = values[idx + TYPE_UNSIGNED (type)];
|
||||
suffix = suffixes[is_long * 2 + TYPE_UNSIGNED (type)];
|
||||
|
||||
buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
|
||||
buf = (char *) alloca (strlen (macro) + 1 + strlen (value)
|
||||
+ strlen (suffix) + 1);
|
||||
sprintf (buf, "%s=%s%s", macro, value, suffix);
|
||||
|
||||
cpp_define (parse_in, buf);
|
||||
|
|
|
|||
7323
contrib/gcc/c-decl.c
7323
contrib/gcc/c-decl.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Tree-dumping functionality for C-family languages.
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
|
||||
Written by Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -32,15 +32,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
void
|
||||
dump_stmt (dump_info_p di, tree t)
|
||||
{
|
||||
dump_int (di, "line", STMT_LINENO (t));
|
||||
}
|
||||
|
||||
/* Dump the next statement after STMT. */
|
||||
|
||||
void
|
||||
dump_next_stmt (dump_info_p di, tree t)
|
||||
{
|
||||
dump_child ("next", TREE_CHAIN (t));
|
||||
if (EXPR_HAS_LOCATION (t))
|
||||
dump_int (di, "line", EXPR_LINENO (t));
|
||||
}
|
||||
|
||||
/* Dump any C-specific tree codes and attributes of common codes. */
|
||||
|
|
@ -61,129 +54,6 @@ c_dump_tree (void *dump_info, tree t)
|
|||
dump_string (di, "bitfield");
|
||||
break;
|
||||
|
||||
case ASM_STMT:
|
||||
dump_stmt (di, t);
|
||||
if (ASM_VOLATILE_P (t))
|
||||
dump_string (di, "volatile");
|
||||
dump_child ("strg", ASM_STRING (t));
|
||||
dump_child ("outs", ASM_OUTPUTS (t));
|
||||
dump_child ("ins", ASM_INPUTS (t));
|
||||
dump_child ("clbr", ASM_CLOBBERS (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case BREAK_STMT:
|
||||
case CONTINUE_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case CASE_LABEL:
|
||||
/* Note that a case label is not like other statements; there is
|
||||
no way to get the line-number of a case label. */
|
||||
dump_child ("low", CASE_LOW (t));
|
||||
dump_child ("high", CASE_HIGH (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case CLEANUP_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("decl", CLEANUP_DECL (t));
|
||||
dump_child ("expr", CLEANUP_EXPR (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case COMPOUND_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("body", COMPOUND_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case DECL_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("decl", DECL_STMT_DECL (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case DO_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("body", DO_BODY (t));
|
||||
dump_child ("cond", DO_COND (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case EXPR_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("expr", EXPR_STMT_EXPR (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case FOR_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("init", FOR_INIT_STMT (t));
|
||||
dump_child ("cond", FOR_COND (t));
|
||||
dump_child ("expr", FOR_EXPR (t));
|
||||
dump_child ("body", FOR_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case GOTO_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("dest", GOTO_DESTINATION (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case IF_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("cond", IF_COND (t));
|
||||
dump_child ("then", THEN_CLAUSE (t));
|
||||
dump_child ("else", ELSE_CLAUSE (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case LABEL_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("labl", LABEL_STMT_LABEL (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case RETURN_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("expr", RETURN_STMT_EXPR (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case SWITCH_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("cond", SWITCH_COND (t));
|
||||
dump_child ("body", SWITCH_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case WHILE_STMT:
|
||||
dump_stmt (di, t);
|
||||
dump_child ("cond", WHILE_COND (t));
|
||||
dump_child ("body", WHILE_BODY (t));
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case SCOPE_STMT:
|
||||
dump_stmt (di, t);
|
||||
if (SCOPE_BEGIN_P (t))
|
||||
dump_string (di, "begn");
|
||||
else
|
||||
dump_string (di, "end");
|
||||
if (SCOPE_NULLIFIED_P (t))
|
||||
dump_string (di, "null");
|
||||
if (!SCOPE_NO_CLEANUPS_P (t))
|
||||
dump_string (di, "clnp");
|
||||
dump_next_stmt (di, t);
|
||||
break;
|
||||
|
||||
case STMT_EXPR:
|
||||
dump_child ("stmt", STMT_EXPR_STMT (t));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -32,14 +32,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
/* Issue an ISO C99 pedantic warning MSGID. */
|
||||
|
||||
void
|
||||
pedwarn_c99 (const char *msgid, ...)
|
||||
pedwarn_c99 (const char *gmsgid, ...)
|
||||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, msgid);
|
||||
diagnostic_set_info (&diagnostic, msgid, &ap, input_location,
|
||||
flag_isoc99 ? pedantic_error_kind () : DK_WARNING);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
|
||||
flag_isoc99 ? pedantic_error_kind () : DK_WARNING);
|
||||
report_diagnostic (&diagnostic);
|
||||
va_end (ap);
|
||||
}
|
||||
|
|
@ -50,14 +50,14 @@ pedwarn_c99 (const char *msgid, ...)
|
|||
(There is no flag_c90.) */
|
||||
|
||||
void
|
||||
pedwarn_c90 (const char *msgid, ...)
|
||||
pedwarn_c90 (const char *gmsgid, ...)
|
||||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, msgid);
|
||||
diagnostic_set_info (&diagnostic, msgid, &ap, input_location,
|
||||
flag_isoc99 ? DK_WARNING : pedantic_error_kind ());
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
|
||||
flag_isoc99 ? DK_WARNING : pedantic_error_kind ());
|
||||
report_diagnostic (&diagnostic);
|
||||
va_end (ap);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
308
contrib/gcc/c-format.h
Normal file
308
contrib/gcc/c-format.h
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/* Check calls to formatted I/O functions (-Wformat).
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004 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, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_C_FORMAT_H
|
||||
#define GCC_C_FORMAT_H
|
||||
|
||||
/* The meaningfully distinct length modifiers for format checking recognized
|
||||
by GCC. */
|
||||
enum format_lengths
|
||||
{
|
||||
FMT_LEN_none,
|
||||
FMT_LEN_hh,
|
||||
FMT_LEN_h,
|
||||
FMT_LEN_l,
|
||||
FMT_LEN_ll,
|
||||
FMT_LEN_L,
|
||||
FMT_LEN_z,
|
||||
FMT_LEN_t,
|
||||
FMT_LEN_j,
|
||||
FMT_LEN_H,
|
||||
FMT_LEN_D,
|
||||
FMT_LEN_DD,
|
||||
FMT_LEN_MAX
|
||||
};
|
||||
|
||||
|
||||
/* The standard versions in which various format features appeared. */
|
||||
enum format_std_version
|
||||
{
|
||||
STD_C89,
|
||||
STD_C94,
|
||||
STD_C9L, /* C99, but treat as C89 if -Wno-long-long. */
|
||||
STD_C99,
|
||||
STD_EXT
|
||||
};
|
||||
|
||||
/* Flags that may apply to a particular kind of format checked by GCC. */
|
||||
enum
|
||||
{
|
||||
/* This format converts arguments of types determined by the
|
||||
format string. */
|
||||
FMT_FLAG_ARG_CONVERT = 1,
|
||||
/* The scanf allocation 'a' kludge applies to this format kind. */
|
||||
FMT_FLAG_SCANF_A_KLUDGE = 2,
|
||||
/* A % during parsing a specifier is allowed to be a modified % rather
|
||||
that indicating the format is broken and we are out-of-sync. */
|
||||
FMT_FLAG_FANCY_PERCENT_OK = 4,
|
||||
/* With $ operand numbers, it is OK to reference the same argument more
|
||||
than once. */
|
||||
FMT_FLAG_DOLLAR_MULTIPLE = 8,
|
||||
/* This format type uses $ operand numbers (strfmon doesn't). */
|
||||
FMT_FLAG_USE_DOLLAR = 16,
|
||||
/* Zero width is bad in this type of format (scanf). */
|
||||
FMT_FLAG_ZERO_WIDTH_BAD = 32,
|
||||
/* Empty precision specification is OK in this type of format (printf). */
|
||||
FMT_FLAG_EMPTY_PREC_OK = 64,
|
||||
/* Gaps are allowed in the arguments with $ operand numbers if all
|
||||
arguments are pointers (scanf). */
|
||||
FMT_FLAG_DOLLAR_GAP_POINTER_OK = 128
|
||||
/* Not included here: details of whether width or precision may occur
|
||||
(controlled by width_char and precision_char); details of whether
|
||||
'*' can be used for these (width_type and precision_type); details
|
||||
of whether length modifiers can occur (length_char_specs). */
|
||||
};
|
||||
|
||||
|
||||
/* Structure describing a length modifier supported in format checking, and
|
||||
possibly a doubled version such as "hh". */
|
||||
typedef struct
|
||||
{
|
||||
/* Name of the single-character length modifier. */
|
||||
const char *name;
|
||||
/* Index into a format_char_info.types array. */
|
||||
enum format_lengths index;
|
||||
/* Standard version this length appears in. */
|
||||
enum format_std_version std;
|
||||
/* Same, if the modifier can be repeated, or NULL if it can't. */
|
||||
const char *double_name;
|
||||
enum format_lengths double_index;
|
||||
enum format_std_version double_std;
|
||||
} format_length_info;
|
||||
|
||||
|
||||
/* Structure describing the combination of a conversion specifier
|
||||
(or a set of specifiers which act identically) and a length modifier. */
|
||||
typedef struct
|
||||
{
|
||||
/* The standard version this combination of length and type appeared in.
|
||||
This is only relevant if greater than those for length and type
|
||||
individually; otherwise it is ignored. */
|
||||
enum format_std_version std;
|
||||
/* The name to use for the type, if different from that generated internally
|
||||
(e.g., "signed size_t"). */
|
||||
const char *name;
|
||||
/* The type itself. */
|
||||
tree *type;
|
||||
} format_type_detail;
|
||||
|
||||
|
||||
/* Macros to fill out tables of these. */
|
||||
#define NOARGUMENTS { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }
|
||||
#define BADLEN { 0, NULL, NULL }
|
||||
#define NOLENGTHS { BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }
|
||||
|
||||
|
||||
/* Structure describing a format conversion specifier (or a set of specifiers
|
||||
which act identically), and the length modifiers used with it. */
|
||||
typedef struct format_char_info
|
||||
{
|
||||
const char *format_chars;
|
||||
int pointer_count;
|
||||
enum format_std_version std;
|
||||
/* Types accepted for each length modifier. */
|
||||
format_type_detail types[FMT_LEN_MAX];
|
||||
/* List of other modifier characters allowed with these specifiers.
|
||||
This lists flags, and additionally "w" for width, "p" for precision
|
||||
(right precision, for strfmon), "#" for left precision (strfmon),
|
||||
"a" for scanf "a" allocation extension (not applicable in C99 mode),
|
||||
"*" for scanf suppression, and "E" and "O" for those strftime
|
||||
modifiers. */
|
||||
const char *flag_chars;
|
||||
/* List of additional flags describing these conversion specifiers.
|
||||
"c" for generic character pointers being allowed, "2" for strftime
|
||||
two digit year formats, "3" for strftime formats giving two digit
|
||||
years in some locales, "4" for "2" which becomes "3" with an "E" modifier,
|
||||
"o" if use of strftime "O" is a GNU extension beyond C99,
|
||||
"W" if the argument is a pointer which is dereferenced and written into,
|
||||
"R" if the argument is a pointer which is dereferenced and read from,
|
||||
"i" for printf integer formats where the '0' flag is ignored with
|
||||
precision, and "[" for the starting character of a scanf scanset. */
|
||||
const char *flags2;
|
||||
/* If this format conversion character consumes more than one argument,
|
||||
CHAIN points to information about the next argument. For later
|
||||
arguments, only POINTER_COUNT, TYPES, and the "c", "R", and "W" flags
|
||||
in FLAGS2 are used. */
|
||||
const struct format_char_info *chain;
|
||||
} format_char_info;
|
||||
|
||||
|
||||
/* Structure describing a flag accepted by some kind of format. */
|
||||
typedef struct
|
||||
{
|
||||
/* The flag character in question (0 for end of array). */
|
||||
int flag_char;
|
||||
/* Zero if this entry describes the flag character in general, or a
|
||||
nonzero character that may be found in flags2 if it describes the
|
||||
flag when used with certain formats only. If the latter, only
|
||||
the first such entry found that applies to the current conversion
|
||||
specifier is used; the values of 'name' and 'long_name' it supplies
|
||||
will be used, if non-NULL and the standard version is higher than
|
||||
the unpredicated one, for any pedantic warning. For example, 'o'
|
||||
for strftime formats (meaning 'O' is an extension over C99). */
|
||||
int predicate;
|
||||
/* Nonzero if the next character after this flag in the format should
|
||||
be skipped ('=' in strfmon), zero otherwise. */
|
||||
int skip_next_char;
|
||||
/* The name to use for this flag in diagnostic messages. For example,
|
||||
N_("'0' flag"), N_("field width"). */
|
||||
const char *name;
|
||||
/* Long name for this flag in diagnostic messages; currently only used for
|
||||
"ISO C does not support ...". For example, N_("the 'I' printf flag"). */
|
||||
const char *long_name;
|
||||
/* The standard version in which it appeared. */
|
||||
enum format_std_version std;
|
||||
} format_flag_spec;
|
||||
|
||||
|
||||
/* Structure describing a combination of flags that is bad for some kind
|
||||
of format. */
|
||||
typedef struct
|
||||
{
|
||||
/* The first flag character in question (0 for end of array). */
|
||||
int flag_char1;
|
||||
/* The second flag character. */
|
||||
int flag_char2;
|
||||
/* Nonzero if the message should say that the first flag is ignored with
|
||||
the second, zero if the combination should simply be objected to. */
|
||||
int ignored;
|
||||
/* Zero if this entry applies whenever this flag combination occurs,
|
||||
a nonzero character from flags2 if it only applies in some
|
||||
circumstances (e.g. 'i' for printf formats ignoring 0 with precision). */
|
||||
int predicate;
|
||||
} format_flag_pair;
|
||||
|
||||
|
||||
/* Structure describing a particular kind of format processed by GCC. */
|
||||
typedef struct
|
||||
{
|
||||
/* The name of this kind of format, for use in diagnostics. Also
|
||||
the name of the attribute (without preceding and following __). */
|
||||
const char *name;
|
||||
/* Specifications of the length modifiers accepted; possibly NULL. */
|
||||
const format_length_info *length_char_specs;
|
||||
/* Details of the conversion specification characters accepted. */
|
||||
const format_char_info *conversion_specs;
|
||||
/* String listing the flag characters that are accepted. */
|
||||
const char *flag_chars;
|
||||
/* String listing modifier characters (strftime) accepted. May be NULL. */
|
||||
const char *modifier_chars;
|
||||
/* Details of the flag characters, including pseudo-flags. */
|
||||
const format_flag_spec *flag_specs;
|
||||
/* Details of bad combinations of flags. */
|
||||
const format_flag_pair *bad_flag_pairs;
|
||||
/* Flags applicable to this kind of format. */
|
||||
int flags;
|
||||
/* Flag character to treat a width as, or 0 if width not used. */
|
||||
int width_char;
|
||||
/* Flag character to treat a left precision (strfmon) as,
|
||||
or 0 if left precision not used. */
|
||||
int left_precision_char;
|
||||
/* Flag character to treat a precision (for strfmon, right precision) as,
|
||||
or 0 if precision not used. */
|
||||
int precision_char;
|
||||
/* If a flag character has the effect of suppressing the conversion of
|
||||
an argument ('*' in scanf), that flag character, otherwise 0. */
|
||||
int suppression_char;
|
||||
/* Flag character to treat a length modifier as (ignored if length
|
||||
modifiers not used). Need not be placed in flag_chars for conversion
|
||||
specifiers, but is used to check for bad combinations such as length
|
||||
modifier with assignment suppression in scanf. */
|
||||
int length_code_char;
|
||||
/* Pointer to type of argument expected if '*' is used for a width,
|
||||
or NULL if '*' not used for widths. */
|
||||
tree *width_type;
|
||||
/* Pointer to type of argument expected if '*' is used for a precision,
|
||||
or NULL if '*' not used for precisions. */
|
||||
tree *precision_type;
|
||||
} format_kind_info;
|
||||
|
||||
#define T_I &integer_type_node
|
||||
#define T89_I { STD_C89, NULL, T_I }
|
||||
#define T_L &long_integer_type_node
|
||||
#define T89_L { STD_C89, NULL, T_L }
|
||||
#define T_LL &long_long_integer_type_node
|
||||
#define T9L_LL { STD_C9L, NULL, T_LL }
|
||||
#define TEX_LL { STD_EXT, NULL, T_LL }
|
||||
#define T_S &short_integer_type_node
|
||||
#define T89_S { STD_C89, NULL, T_S }
|
||||
#define T_UI &unsigned_type_node
|
||||
#define T89_UI { STD_C89, NULL, T_UI }
|
||||
#define T_UL &long_unsigned_type_node
|
||||
#define T89_UL { STD_C89, NULL, T_UL }
|
||||
#define T_ULL &long_long_unsigned_type_node
|
||||
#define T9L_ULL { STD_C9L, NULL, T_ULL }
|
||||
#define TEX_ULL { STD_EXT, NULL, T_ULL }
|
||||
#define T_US &short_unsigned_type_node
|
||||
#define T89_US { STD_C89, NULL, T_US }
|
||||
#define T_F &float_type_node
|
||||
#define T89_F { STD_C89, NULL, T_F }
|
||||
#define T99_F { STD_C99, NULL, T_F }
|
||||
#define T_D &double_type_node
|
||||
#define T89_D { STD_C89, NULL, T_D }
|
||||
#define T99_D { STD_C99, NULL, T_D }
|
||||
#define T_LD &long_double_type_node
|
||||
#define T89_LD { STD_C89, NULL, T_LD }
|
||||
#define T99_LD { STD_C99, NULL, T_LD }
|
||||
#define T_C &char_type_node
|
||||
#define T89_C { STD_C89, NULL, T_C }
|
||||
#define T_SC &signed_char_type_node
|
||||
#define T99_SC { STD_C99, NULL, T_SC }
|
||||
#define T_UC &unsigned_char_type_node
|
||||
#define T99_UC { STD_C99, NULL, T_UC }
|
||||
#define T_V &void_type_node
|
||||
#define T89_V { STD_C89, NULL, T_V }
|
||||
#define T_W &wchar_type_node
|
||||
#define T94_W { STD_C94, "wchar_t", T_W }
|
||||
#define TEX_W { STD_EXT, "wchar_t", T_W }
|
||||
#define T_WI &wint_type_node
|
||||
#define T94_WI { STD_C94, "wint_t", T_WI }
|
||||
#define TEX_WI { STD_EXT, "wint_t", T_WI }
|
||||
#define T_ST &size_type_node
|
||||
#define T99_ST { STD_C99, "size_t", T_ST }
|
||||
#define T_SST &signed_size_type_node
|
||||
#define T99_SST { STD_C99, "signed size_t", T_SST }
|
||||
#define T_PD &ptrdiff_type_node
|
||||
#define T99_PD { STD_C99, "ptrdiff_t", T_PD }
|
||||
#define T_UPD &unsigned_ptrdiff_type_node
|
||||
#define T99_UPD { STD_C99, "unsigned ptrdiff_t", T_UPD }
|
||||
#define T_IM &intmax_type_node
|
||||
#define T99_IM { STD_C99, "intmax_t", T_IM }
|
||||
#define T_UIM &uintmax_type_node
|
||||
#define T99_UIM { STD_C99, "uintmax_t", T_UIM }
|
||||
#define T_D32 &dfloat32_type_node
|
||||
#define TEX_D32 { STD_EXT, "_Decimal32", T_D32 }
|
||||
#define T_D64 &dfloat64_type_node
|
||||
#define TEX_D64 { STD_EXT, "_Decimal64", T_D64 }
|
||||
#define T_D128 &dfloat128_type_node
|
||||
#define TEX_D128 { STD_EXT, "_Decimal128", T_D128 }
|
||||
|
||||
#endif /* GCC_C_FORMAT_H */
|
||||
226
contrib/gcc/c-gimplify.c
Normal file
226
contrib/gcc/c-gimplify.c
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
/* Tree lowering pass. This pass gimplifies the tree representation built
|
||||
by the C-based front ends. The structure of gimplified, or
|
||||
language-independent, trees is dictated by the grammar described in this
|
||||
file.
|
||||
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
|
||||
Re-written to support lowering of whole function trees, documentation
|
||||
and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
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, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "varray.h"
|
||||
#include "c-tree.h"
|
||||
#include "c-common.h"
|
||||
#include "tree-gimple.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
#include "tree-flow.h"
|
||||
#include "tree-inline.h"
|
||||
#include "diagnostic.h"
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
#include "flags.h"
|
||||
#include "rtl.h"
|
||||
#include "toplev.h"
|
||||
#include "tree-dump.h"
|
||||
#include "c-pretty-print.h"
|
||||
#include "cgraph.h"
|
||||
|
||||
|
||||
/* The gimplification pass converts the language-dependent trees
|
||||
(ld-trees) emitted by the parser into language-independent trees
|
||||
(li-trees) that are the target of SSA analysis and transformations.
|
||||
|
||||
Language-independent trees are based on the SIMPLE intermediate
|
||||
representation used in the McCAT compiler framework:
|
||||
|
||||
"Designing the McCAT Compiler Based on a Family of Structured
|
||||
Intermediate Representations,"
|
||||
L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
|
||||
Proceedings of the 5th International Workshop on Languages and
|
||||
Compilers for Parallel Computing, no. 757 in Lecture Notes in
|
||||
Computer Science, New Haven, Connecticut, pp. 406-420,
|
||||
Springer-Verlag, August 3-5, 1992.
|
||||
|
||||
http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
|
||||
|
||||
Basically, we walk down gimplifying the nodes that we encounter. As we
|
||||
walk back up, we check that they fit our constraints, and copy them
|
||||
into temporaries if not. */
|
||||
|
||||
/* Gimplification of statement trees. */
|
||||
|
||||
/* Convert the tree representation of FNDECL from C frontend trees to
|
||||
GENERIC. */
|
||||
|
||||
void
|
||||
c_genericize (tree fndecl)
|
||||
{
|
||||
FILE *dump_orig;
|
||||
int local_dump_flags;
|
||||
struct cgraph_node *cgn;
|
||||
|
||||
/* Dump the C-specific tree IR. */
|
||||
dump_orig = dump_begin (TDI_original, &local_dump_flags);
|
||||
if (dump_orig)
|
||||
{
|
||||
fprintf (dump_orig, "\n;; Function %s",
|
||||
lang_hooks.decl_printable_name (fndecl, 2));
|
||||
fprintf (dump_orig, " (%s)\n",
|
||||
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
|
||||
fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
|
||||
fprintf (dump_orig, "\n");
|
||||
|
||||
if (local_dump_flags & TDF_RAW)
|
||||
dump_node (DECL_SAVED_TREE (fndecl),
|
||||
TDF_SLIM | local_dump_flags, dump_orig);
|
||||
else
|
||||
print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
|
||||
fprintf (dump_orig, "\n");
|
||||
|
||||
dump_end (TDI_original, dump_orig);
|
||||
}
|
||||
|
||||
/* Go ahead and gimplify for now. */
|
||||
gimplify_function_tree (fndecl);
|
||||
|
||||
/* Dump the genericized tree IR. */
|
||||
dump_function (TDI_generic, fndecl);
|
||||
|
||||
/* Genericize all nested functions now. We do things in this order so
|
||||
that items like VLA sizes are expanded properly in the context of
|
||||
the correct function. */
|
||||
cgn = cgraph_node (fndecl);
|
||||
for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
|
||||
c_genericize (cgn->decl);
|
||||
}
|
||||
|
||||
static void
|
||||
add_block_to_enclosing (tree block)
|
||||
{
|
||||
tree enclosing;
|
||||
|
||||
for (enclosing = gimple_current_bind_expr ();
|
||||
enclosing; enclosing = TREE_CHAIN (enclosing))
|
||||
if (BIND_EXPR_BLOCK (enclosing))
|
||||
break;
|
||||
|
||||
enclosing = BIND_EXPR_BLOCK (enclosing);
|
||||
BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
|
||||
}
|
||||
|
||||
/* Genericize a scope by creating a new BIND_EXPR.
|
||||
BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
|
||||
In the latter case, we need to create a new BLOCK and add it to the
|
||||
BLOCK_SUBBLOCKS of the enclosing block.
|
||||
BODY is a chain of C _STMT nodes for the contents of the scope, to be
|
||||
genericized. */
|
||||
|
||||
tree
|
||||
c_build_bind_expr (tree block, tree body)
|
||||
{
|
||||
tree decls, bind;
|
||||
|
||||
if (block == NULL_TREE)
|
||||
decls = NULL_TREE;
|
||||
else if (TREE_CODE (block) == BLOCK)
|
||||
decls = BLOCK_VARS (block);
|
||||
else
|
||||
{
|
||||
decls = block;
|
||||
if (DECL_ARTIFICIAL (decls))
|
||||
block = NULL_TREE;
|
||||
else
|
||||
{
|
||||
block = make_node (BLOCK);
|
||||
BLOCK_VARS (block) = decls;
|
||||
add_block_to_enclosing (block);
|
||||
}
|
||||
}
|
||||
|
||||
if (!body)
|
||||
body = build_empty_stmt ();
|
||||
if (decls || block)
|
||||
{
|
||||
bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
|
||||
TREE_SIDE_EFFECTS (bind) = 1;
|
||||
}
|
||||
else
|
||||
bind = body;
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
||||
/* Gimplification of expression trees. */
|
||||
|
||||
/* Gimplify a C99 compound literal expression. This just means adding
|
||||
the DECL_EXPR before the current statement and using its anonymous
|
||||
decl instead. */
|
||||
|
||||
static enum gimplify_status
|
||||
gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
|
||||
{
|
||||
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
|
||||
tree decl = DECL_EXPR_DECL (decl_s);
|
||||
|
||||
/* This decl isn't mentioned in the enclosing block, so add it to the
|
||||
list of temps. FIXME it seems a bit of a kludge to say that
|
||||
anonymous artificial vars aren't pushed, but everything else is. */
|
||||
if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
|
||||
gimple_add_tmp_var (decl);
|
||||
|
||||
gimplify_and_add (decl_s, pre_p);
|
||||
*expr_p = decl;
|
||||
return GS_OK;
|
||||
}
|
||||
|
||||
/* Do C-specific gimplification. Args are as for gimplify_expr. */
|
||||
|
||||
int
|
||||
c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (*expr_p);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case DECL_EXPR:
|
||||
/* This is handled mostly by gimplify.c, but we have to deal with
|
||||
not warning about int x = x; as it is a GCC extension to turn off
|
||||
this warning but only if warn_init_self is zero. */
|
||||
if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
|
||||
&& !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
|
||||
&& !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
|
||||
&& (DECL_INITIAL (DECL_EXPR_DECL (*expr_p))
|
||||
== DECL_EXPR_DECL (*expr_p))
|
||||
&& !warn_init_self)
|
||||
TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
|
||||
return GS_UNHANDLED;
|
||||
|
||||
case COMPOUND_LITERAL_EXPR:
|
||||
return gimplify_compound_literal_expr (expr_p, pre_p);
|
||||
|
||||
default:
|
||||
return GS_UNHANDLED;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
/* Set up combined include path chain for the preprocessor.
|
||||
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
|
||||
|
||||
|
|
@ -16,11 +17,13 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "machmode.h"
|
||||
#include "target.h"
|
||||
#include "tm.h"
|
||||
#include "cpplib.h"
|
||||
#include "prefix.h"
|
||||
|
|
@ -35,7 +38,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
|
||||
# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
|
||||
#else
|
||||
# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
|
||||
# if (defined _WIN32 && !defined (_UWIN)) || defined __MSDOS__
|
||||
# define INO_T_EQ(A, B) 0
|
||||
# else
|
||||
# define INO_T_EQ(A, B) ((A) == (B))
|
||||
|
|
@ -43,8 +46,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
|
||||
#endif
|
||||
|
||||
static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
|
||||
|
||||
static void add_env_var_paths (const char *, int);
|
||||
static void add_standard_paths (const char *, const char *, int);
|
||||
static void add_standard_paths (const char *, const char *, const char *, int);
|
||||
static void free_path (struct cpp_dir *, int);
|
||||
static void merge_include_chains (cpp_reader *, int);
|
||||
static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
|
||||
|
|
@ -107,18 +112,19 @@ add_env_var_paths (const char *env_var, int chain)
|
|||
path = xstrdup (".");
|
||||
else
|
||||
{
|
||||
path = xmalloc (q - p + 1);
|
||||
path = XNEWVEC (char, q - p + 1);
|
||||
memcpy (path, p, q - p);
|
||||
path[q - p] = '\0';
|
||||
}
|
||||
|
||||
add_path (path, chain, chain == SYSTEM);
|
||||
add_path (path, chain, chain == SYSTEM, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the standard include chain defined in cppdefault.c. */
|
||||
static void
|
||||
add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
|
||||
add_standard_paths (const char *sysroot, const char *iprefix,
|
||||
const char *imultilib, int cxx_stdinc)
|
||||
{
|
||||
const struct default_include *p;
|
||||
size_t len;
|
||||
|
|
@ -126,7 +132,7 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
|
|||
if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
|
||||
{
|
||||
/* Look for directories that start with the standard prefix.
|
||||
"Translate" them, ie. replace /usr/local/lib/gcc... with
|
||||
"Translate" them, i.e. replace /usr/local/lib/gcc... with
|
||||
IPREFIX and search them first. */
|
||||
for (p = cpp_include_defaults; p->fname; p++)
|
||||
{
|
||||
|
|
@ -140,7 +146,9 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
|
|||
if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
|
||||
{
|
||||
char *str = concat (iprefix, p->fname + len, NULL);
|
||||
add_path (str, SYSTEM, p->cxx_aware);
|
||||
if (p->multilib && imultilib)
|
||||
str = concat (str, dir_separator_str, imultilib, NULL);
|
||||
add_path (str, SYSTEM, p->cxx_aware, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -158,7 +166,10 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
|
|||
else
|
||||
str = update_path (p->fname, p->component);
|
||||
|
||||
add_path (str, SYSTEM, p->cxx_aware);
|
||||
if (p->multilib && imultilib)
|
||||
str = concat (str, dir_separator_str, imultilib, NULL);
|
||||
|
||||
add_path (str, SYSTEM, p->cxx_aware, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -169,6 +180,7 @@ add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
|
|||
JOIN, unless it duplicates JOIN in which case the last path is
|
||||
removed. Return the head of the resulting chain. Any of HEAD,
|
||||
JOIN and SYSTEM can be NULL. */
|
||||
|
||||
static struct cpp_dir *
|
||||
remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
|
||||
struct cpp_dir *system, struct cpp_dir *join,
|
||||
|
|
@ -189,7 +201,13 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
|
|||
if (errno != ENOENT)
|
||||
cpp_errno (pfile, CPP_DL_ERROR, cur->name);
|
||||
else
|
||||
reason = REASON_NOENT;
|
||||
{
|
||||
/* If -Wmissing-include-dirs is given, warn. */
|
||||
cpp_options *opts = cpp_get_options (pfile);
|
||||
if (opts->warn_missing_include_dirs && cur->user_supplied_p)
|
||||
cpp_errno (pfile, CPP_DL_WARNING, cur->name);
|
||||
reason = REASON_NOENT;
|
||||
}
|
||||
}
|
||||
else if (!S_ISDIR (st.st_mode))
|
||||
cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
|
||||
|
|
@ -202,7 +220,8 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
|
|||
/* Remove this one if it is in the system chain. */
|
||||
reason = REASON_DUP_SYS;
|
||||
for (tmp = system; tmp; tmp = tmp->next)
|
||||
if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev)
|
||||
if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev
|
||||
&& cur->construct == tmp->construct)
|
||||
break;
|
||||
|
||||
if (!tmp)
|
||||
|
|
@ -210,14 +229,16 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
|
|||
/* Duplicate of something earlier in the same chain? */
|
||||
reason = REASON_DUP;
|
||||
for (tmp = head; tmp != cur; tmp = tmp->next)
|
||||
if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev)
|
||||
if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev
|
||||
&& cur->construct == tmp->construct)
|
||||
break;
|
||||
|
||||
if (tmp == cur
|
||||
/* Last in the chain and duplicate of JOIN? */
|
||||
&& !(cur->next == NULL && join
|
||||
&& INO_T_EQ (cur->ino, join->ino)
|
||||
&& cur->dev == join->dev))
|
||||
&& cur->dev == join->dev
|
||||
&& cur->construct == join->construct))
|
||||
{
|
||||
/* Unique, so keep this directory. */
|
||||
pcur = &cur->next;
|
||||
|
|
@ -241,9 +262,10 @@ remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
|
|||
|
||||
We can't just merge the lists and then uniquify them because then
|
||||
we may lose directories from the <> search path that should be
|
||||
there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however safe
|
||||
to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo
|
||||
-Iquux. */
|
||||
there; consider -iquote foo -iquote bar -Ifoo -Iquux. It is
|
||||
however safe to treat -iquote bar -iquote foo -Ifoo -Iquux as if
|
||||
written -iquote bar -Ifoo -Iquux. */
|
||||
|
||||
static void
|
||||
merge_include_chains (cpp_reader *pfile, int verbose)
|
||||
{
|
||||
|
|
@ -298,31 +320,11 @@ split_quote_chain (void)
|
|||
quote_ignores_source_dir = true;
|
||||
}
|
||||
|
||||
/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
|
||||
NUL-terminated. */
|
||||
/* Add P to the chain specified by CHAIN. */
|
||||
|
||||
void
|
||||
add_path (char *path, int chain, int cxx_aware)
|
||||
add_cpp_dir_path (cpp_dir *p, int chain)
|
||||
{
|
||||
struct cpp_dir *p;
|
||||
|
||||
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
|
||||
/* Convert all backslashes to slashes. The native CRT stat()
|
||||
function does not recognise a directory that ends in a backslash
|
||||
(unless it is a drive root dir, such "c:\"). Forward slashes,
|
||||
trailing or otherwise, cause no problems for stat(). */
|
||||
char* c;
|
||||
for (c = path; *c; c++)
|
||||
if (*c == '\\') *c = '/';
|
||||
#endif
|
||||
|
||||
p = xmalloc (sizeof (struct cpp_dir));
|
||||
p->next = NULL;
|
||||
p->name = path;
|
||||
if (chain == SYSTEM || chain == AFTER)
|
||||
p->sysp = 1 + !cxx_aware;
|
||||
else
|
||||
p->sysp = 0;
|
||||
|
||||
if (tails[chain])
|
||||
tails[chain]->next = p;
|
||||
else
|
||||
|
|
@ -330,12 +332,42 @@ add_path (char *path, int chain, int cxx_aware)
|
|||
tails[chain] = p;
|
||||
}
|
||||
|
||||
/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
|
||||
NUL-terminated. */
|
||||
void
|
||||
add_path (char *path, int chain, int cxx_aware, bool user_supplied_p)
|
||||
{
|
||||
cpp_dir *p;
|
||||
|
||||
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
|
||||
/* Convert all backslashes to slashes. The native CRT stat()
|
||||
function does not recognize a directory that ends in a backslash
|
||||
(unless it is a drive root dir, such "c:\"). Forward slashes,
|
||||
trailing or otherwise, cause no problems for stat(). */
|
||||
char* c;
|
||||
for (c = path; *c; c++)
|
||||
if (*c == '\\') *c = '/';
|
||||
#endif
|
||||
|
||||
p = XNEW (cpp_dir);
|
||||
p->next = NULL;
|
||||
p->name = path;
|
||||
if (chain == SYSTEM || chain == AFTER)
|
||||
p->sysp = 1 + !cxx_aware;
|
||||
else
|
||||
p->sysp = 0;
|
||||
p->construct = 0;
|
||||
p->user_supplied_p = user_supplied_p;
|
||||
|
||||
add_cpp_dir_path (p, chain);
|
||||
}
|
||||
|
||||
/* Exported function to handle include chain merging, duplicate
|
||||
removal, and registration with cpplib. */
|
||||
void
|
||||
register_include_chains (cpp_reader *pfile, const char *sysroot,
|
||||
const char *iprefix, int stdinc, int cxx_stdinc,
|
||||
int verbose)
|
||||
const char *iprefix, const char *imultilib,
|
||||
int stdinc, int cxx_stdinc, int verbose)
|
||||
{
|
||||
static const char *const lang_env_vars[] =
|
||||
{ "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
|
||||
|
|
@ -353,12 +385,33 @@ register_include_chains (cpp_reader *pfile, const char *sysroot,
|
|||
add_env_var_paths ("CPATH", BRACKET);
|
||||
add_env_var_paths (lang_env_vars[idx], SYSTEM);
|
||||
|
||||
target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
|
||||
|
||||
/* Finally chain on the standard directories. */
|
||||
if (stdinc)
|
||||
add_standard_paths (sysroot, iprefix, cxx_stdinc);
|
||||
add_standard_paths (sysroot, iprefix, imultilib, cxx_stdinc);
|
||||
|
||||
target_c_incpath.extra_includes (sysroot, iprefix, stdinc);
|
||||
|
||||
merge_include_chains (pfile, verbose);
|
||||
|
||||
cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
|
||||
quote_ignores_source_dir);
|
||||
}
|
||||
#if !(defined TARGET_EXTRA_INCLUDES) || !(defined TARGET_EXTRA_PRE_INCLUDES)
|
||||
static void hook_void_charptr_charptr_int (const char *sysroot ATTRIBUTE_UNUSED,
|
||||
const char *iprefix ATTRIBUTE_UNUSED,
|
||||
int stdinc ATTRIBUTE_UNUSED)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_EXTRA_INCLUDES
|
||||
#define TARGET_EXTRA_INCLUDES hook_void_charptr_charptr_int
|
||||
#endif
|
||||
#ifndef TARGET_EXTRA_PRE_INCLUDES
|
||||
#define TARGET_EXTRA_PRE_INCLUDES hook_void_charptr_charptr_int
|
||||
#endif
|
||||
|
||||
struct target_c_incpath_s target_c_incpath = { TARGET_EXTRA_PRE_INCLUDES, TARGET_EXTRA_INCLUDES };
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Set up combined include path for the preprocessor.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
|
|
@ -13,11 +13,21 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
extern void split_quote_chain (void);
|
||||
extern void add_path (char *, int, int);
|
||||
extern void add_path (char *, int, int, bool);
|
||||
extern void register_include_chains (cpp_reader *, const char *,
|
||||
const char *, int, int, int);
|
||||
const char *, const char *,
|
||||
int, int, int);
|
||||
extern void add_cpp_dir_path (struct cpp_dir *, int);
|
||||
|
||||
struct target_c_incpath_s {
|
||||
/* Do extra includes processing. STDINC is false iff -nostdinc was given. */
|
||||
void (*extra_pre_includes) (const char *, const char *, int);
|
||||
void (*extra_includes) (const char *, const char *, int);
|
||||
};
|
||||
|
||||
extern struct target_c_incpath_s target_c_incpath;
|
||||
|
||||
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* Language-specific hook definitions for C front end.
|
||||
Copyright (C) 1991, 1995, 1997, 1998,
|
||||
1999, 2000, 2001, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
|
@ -30,127 +30,31 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "ggc.h"
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
#include "tree-inline.h"
|
||||
#include "diagnostic.h"
|
||||
#include "c-pretty-print.h"
|
||||
|
||||
static void c_initialize_diagnostics (diagnostic_context *);
|
||||
#include "c-objc-common.h"
|
||||
#include "c-pragma.h"
|
||||
|
||||
enum c_language_kind c_language = clk_c;
|
||||
|
||||
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
|
||||
/* Lang hooks common to C and ObjC are declared in c-objc-common.h;
|
||||
consequently, there should be very few hooks below. */
|
||||
|
||||
#undef LANG_HOOKS_NAME
|
||||
#define LANG_HOOKS_NAME "GNU C"
|
||||
#undef LANG_HOOKS_INIT
|
||||
#define LANG_HOOKS_INIT c_objc_common_init
|
||||
#undef LANG_HOOKS_FINISH
|
||||
#define LANG_HOOKS_FINISH c_common_finish
|
||||
#undef LANG_HOOKS_INIT_OPTIONS
|
||||
#define LANG_HOOKS_INIT_OPTIONS c_common_init_options
|
||||
#undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
|
||||
#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS c_initialize_diagnostics
|
||||
#undef LANG_HOOKS_HANDLE_OPTION
|
||||
#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
|
||||
#undef LANG_HOOKS_MISSING_ARGUMENT
|
||||
#define LANG_HOOKS_MISSING_ARGUMENT c_common_missing_argument
|
||||
#undef LANG_HOOKS_POST_OPTIONS
|
||||
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
|
||||
#undef LANG_HOOKS_GET_ALIAS_SET
|
||||
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
|
||||
#undef LANG_HOOKS_SAFE_FROM_P
|
||||
#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
|
||||
#undef LANG_HOOKS_EXPAND_EXPR
|
||||
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
|
||||
#undef LANG_HOOKS_MARK_ADDRESSABLE
|
||||
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
|
||||
#undef LANG_HOOKS_PARSE_FILE
|
||||
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
|
||||
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
|
||||
#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
|
||||
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
|
||||
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
|
||||
#undef LANG_HOOKS_UNSAFE_FOR_REEVAL
|
||||
#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
|
||||
#undef LANG_HOOKS_STATICP
|
||||
#define LANG_HOOKS_STATICP c_staticp
|
||||
#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
|
||||
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME c_static_assembler_name
|
||||
#undef LANG_HOOKS_NO_BODY_BLOCKS
|
||||
#define LANG_HOOKS_NO_BODY_BLOCKS true
|
||||
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
|
||||
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
|
||||
#undef LANG_HOOKS_PRINT_IDENTIFIER
|
||||
#define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier
|
||||
#undef LANG_HOOKS_FUNCTION_ENTER_NESTED
|
||||
#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
|
||||
#undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
|
||||
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
|
||||
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
|
||||
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
|
||||
#undef LANG_HOOKS_DECL_UNINIT
|
||||
#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
|
||||
|
||||
#undef LANG_HOOKS_RTL_EXPAND_STMT
|
||||
#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
|
||||
|
||||
/* Attribute hooks. */
|
||||
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
|
||||
#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table
|
||||
|
||||
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
|
||||
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
|
||||
c_cannot_inline_tree_fn
|
||||
#undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
|
||||
#define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
|
||||
c_disregard_inline_limits
|
||||
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
|
||||
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
|
||||
anon_aggr_type_p
|
||||
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
|
||||
c_convert_parm_for_inlining
|
||||
#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
|
||||
#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
|
||||
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
|
||||
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
|
||||
|
||||
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
|
||||
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body
|
||||
|
||||
#undef LANG_HOOKS_TYPE_FOR_MODE
|
||||
#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
|
||||
#undef LANG_HOOKS_TYPE_FOR_SIZE
|
||||
#define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size
|
||||
#undef LANG_HOOKS_SIGNED_TYPE
|
||||
#define LANG_HOOKS_SIGNED_TYPE c_common_signed_type
|
||||
#undef LANG_HOOKS_UNSIGNED_TYPE
|
||||
#define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type
|
||||
#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
|
||||
#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type
|
||||
#undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR
|
||||
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error
|
||||
#undef LANG_HOOKS_TYPE_PROMOTES_TO
|
||||
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
|
||||
#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
|
||||
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
|
||||
|
||||
#undef LANG_HOOKS_WRITE_GLOBALS
|
||||
#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
|
||||
|
||||
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
|
||||
|
||||
/* Each front end provides its own. */
|
||||
/* Each front end provides its own lang hook initializer. */
|
||||
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
/* Tree code classes. */
|
||||
|
||||
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
|
||||
|
||||
const char tree_code_type[] = {
|
||||
const enum tree_code_class tree_code_type[] = {
|
||||
#include "tree.def"
|
||||
'x',
|
||||
tcc_exceptional,
|
||||
#include "c-common.def"
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
|
@ -179,23 +83,11 @@ const char *const tree_code_name[] = {
|
|||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Final processing of file-scope data. The Objective-C version of
|
||||
this function still does something. */
|
||||
void
|
||||
finish_file (void)
|
||||
{
|
||||
c_objc_common_finish_file ();
|
||||
}
|
||||
|
||||
static void
|
||||
c_initialize_diagnostics (diagnostic_context *context)
|
||||
{
|
||||
pretty_printer *base = context->printer;
|
||||
c_pretty_printer *pp = xmalloc (sizeof (c_pretty_printer));
|
||||
memcpy (pp_base (pp), base, sizeof (pretty_printer));
|
||||
pp_c_pretty_printer_init (pp);
|
||||
context->printer = (pretty_printer *) pp;
|
||||
|
||||
/* It is safe to free this object because it was previously malloc()'d. */
|
||||
free (base);
|
||||
}
|
||||
|
||||
#include "gtype-c.h"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* Mainly the interface between cpplib and the C front ends.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,8 +17,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -27,7 +28,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "real.h"
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "expr.h"
|
||||
#include "input.h"
|
||||
#include "output.h"
|
||||
#include "c-tree.h"
|
||||
|
|
@ -42,28 +42,29 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "splay-tree.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* The current line map. */
|
||||
static const struct line_map *map;
|
||||
|
||||
/* We may keep statistics about how long which files took to compile. */
|
||||
static int header_time, body_time;
|
||||
static splay_tree file_info_tree;
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node)
|
||||
|
||||
/* Number of bytes in a wide character. */
|
||||
#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
|
||||
|
||||
int pending_lang_change; /* If we need to switch languages - C++ only */
|
||||
int c_header_level; /* depth in C headers - C++ only */
|
||||
|
||||
/* If we need to translate characters received. This is tri-state:
|
||||
0 means use only the untranslated string; 1 means use only
|
||||
the translated string; -1 means chain the translated string
|
||||
to the untranslated one. */
|
||||
int c_lex_string_translate = 1;
|
||||
|
||||
/* True if strings should be passed to the caller of c_lex completely
|
||||
unmolested (no concatenation, no translation). */
|
||||
bool c_lex_return_raw_strings = false;
|
||||
|
||||
static tree interpret_integer (const cpp_token *, unsigned int);
|
||||
static tree interpret_float (const cpp_token *, unsigned int);
|
||||
static enum integer_type_kind
|
||||
narrowest_unsigned_type (tree, unsigned int);
|
||||
static enum integer_type_kind
|
||||
narrowest_signed_type (tree, unsigned int);
|
||||
static enum integer_type_kind narrowest_unsigned_type
|
||||
(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
|
||||
static enum integer_type_kind narrowest_signed_type
|
||||
(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
|
||||
static enum cpp_ttype lex_string (const cpp_token *, tree *, bool);
|
||||
static tree lex_charconst (const cpp_token *);
|
||||
static void update_header_times (const char *);
|
||||
|
|
@ -80,10 +81,8 @@ init_c_lex (void)
|
|||
struct cpp_callbacks *cb;
|
||||
struct c_fileinfo *toplevel;
|
||||
|
||||
/* Set up filename timing. Must happen before cpp_read_main_file. */
|
||||
file_info_tree = splay_tree_new ((splay_tree_compare_fn)strcmp,
|
||||
0,
|
||||
(splay_tree_delete_value_fn)free);
|
||||
/* The get_fileinfo data structure must be initialized before
|
||||
cpp_read_main_file is called. */
|
||||
toplevel = get_fileinfo ("<top level>");
|
||||
if (flag_detailed_statistics)
|
||||
{
|
||||
|
|
@ -102,8 +101,8 @@ init_c_lex (void)
|
|||
|
||||
/* Set the debug callbacks if we can use them. */
|
||||
if (debug_info_level == DINFO_LEVEL_VERBOSE
|
||||
&& (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG
|
||||
|| write_symbols == VMS_AND_DWARF2_DEBUG))
|
||||
&& (write_symbols == DWARF2_DEBUG
|
||||
|| write_symbols == VMS_AND_DWARF2_DEBUG))
|
||||
{
|
||||
cb->define = cb_define;
|
||||
cb->undef = cb_undef;
|
||||
|
|
@ -116,11 +115,16 @@ get_fileinfo (const char *name)
|
|||
splay_tree_node n;
|
||||
struct c_fileinfo *fi;
|
||||
|
||||
if (!file_info_tree)
|
||||
file_info_tree = splay_tree_new ((splay_tree_compare_fn) strcmp,
|
||||
0,
|
||||
(splay_tree_delete_value_fn) free);
|
||||
|
||||
n = splay_tree_lookup (file_info_tree, (splay_tree_key) name);
|
||||
if (n)
|
||||
return (struct c_fileinfo *) n->value;
|
||||
|
||||
fi = xmalloc (sizeof (struct c_fileinfo));
|
||||
fi = XNEW (struct c_fileinfo);
|
||||
fi->time = 0;
|
||||
fi->interface_only = 0;
|
||||
fi->interface_unknown = 1;
|
||||
|
|
@ -145,7 +149,7 @@ update_header_times (const char *name)
|
|||
}
|
||||
|
||||
static int
|
||||
dump_one_header (splay_tree_node n, void *dummy ATTRIBUTE_UNUSED)
|
||||
dump_one_header (splay_tree_node n, void * ARG_UNUSED (dummy))
|
||||
{
|
||||
print_time ((const char *) n->key,
|
||||
((struct c_fileinfo *) n->value)->time);
|
||||
|
|
@ -163,26 +167,26 @@ dump_time_statistics (void)
|
|||
print_time ("header files (total)", header_time);
|
||||
print_time ("main file (total)", this_time - body_time);
|
||||
fprintf (stderr, "ratio = %g : 1\n",
|
||||
(double)header_time / (double)(this_time - body_time));
|
||||
(double) header_time / (double) (this_time - body_time));
|
||||
fprintf (stderr, "\n******\n");
|
||||
|
||||
splay_tree_foreach (file_info_tree, dump_one_header, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED,
|
||||
unsigned int line ATTRIBUTE_UNUSED,
|
||||
const cpp_string *str ATTRIBUTE_UNUSED)
|
||||
cb_ident (cpp_reader * ARG_UNUSED (pfile),
|
||||
unsigned int ARG_UNUSED (line),
|
||||
const cpp_string * ARG_UNUSED (str))
|
||||
{
|
||||
#ifdef ASM_OUTPUT_IDENT
|
||||
if (! flag_no_ident)
|
||||
if (!flag_no_ident)
|
||||
{
|
||||
/* Convert escapes in the string. */
|
||||
cpp_string cstr = { 0, 0 };
|
||||
if (cpp_interpret_string (pfile, str, 1, &cstr, false))
|
||||
{
|
||||
ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text);
|
||||
free ((void *)cstr.text);
|
||||
free ((void *) cstr.text);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -191,34 +195,44 @@ cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED,
|
|||
/* Called at the start of every non-empty line. TOKEN is the first
|
||||
lexed token on the line. Used for diagnostic line numbers. */
|
||||
static void
|
||||
cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
|
||||
cb_line_change (cpp_reader * ARG_UNUSED (pfile), const cpp_token *token,
|
||||
int parsing_args)
|
||||
{
|
||||
if (token->type == CPP_EOF || parsing_args)
|
||||
return;
|
||||
|
||||
input_line = SOURCE_LINE (map, token->line);
|
||||
if (token->type != CPP_EOF && !parsing_args)
|
||||
#ifdef USE_MAPPED_LOCATION
|
||||
input_location = token->src_loc;
|
||||
#else
|
||||
{
|
||||
source_location loc = token->src_loc;
|
||||
const struct line_map *map = linemap_lookup (&line_table, loc);
|
||||
input_line = SOURCE_LINE (map, loc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
fe_file_change (const struct line_map *new_map)
|
||||
{
|
||||
if (new_map == NULL)
|
||||
{
|
||||
map = NULL;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
if (new_map->reason == LC_ENTER)
|
||||
{
|
||||
/* Don't stack the main buffer on the input stack;
|
||||
we already did in compile_file. */
|
||||
if (map != NULL)
|
||||
if (!MAIN_FILE_P (new_map))
|
||||
{
|
||||
int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
|
||||
#ifdef USE_MAPPED_LOCATION
|
||||
int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
|
||||
|
||||
input_location = included_at;
|
||||
push_srcloc (new_map->start_location);
|
||||
#else
|
||||
int included_at = LAST_SOURCE_LINE (new_map - 1);
|
||||
|
||||
input_line = included_at;
|
||||
push_srcloc (new_map->to_file, 1);
|
||||
#endif
|
||||
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
|
||||
#ifndef NO_IMPLICIT_EXTERN_C
|
||||
if (c_header_level)
|
||||
|
|
@ -237,7 +251,7 @@ fe_file_change (const struct line_map *new_map)
|
|||
if (c_header_level && --c_header_level == 0)
|
||||
{
|
||||
if (new_map->sysp == 2)
|
||||
warning ("badly nested C headers from preprocessor");
|
||||
warning (0, "badly nested C headers from preprocessor");
|
||||
--pending_lang_change;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -248,16 +262,16 @@ fe_file_change (const struct line_map *new_map)
|
|||
|
||||
update_header_times (new_map->to_file);
|
||||
in_system_header = new_map->sysp != 0;
|
||||
#ifdef USE_MAPPED_LOCATION
|
||||
input_location = new_map->start_location;
|
||||
#else
|
||||
input_filename = new_map->to_file;
|
||||
input_line = new_map->to_line;
|
||||
map = new_map;
|
||||
|
||||
/* Hook for C++. */
|
||||
extract_interface_info ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
cb_def_pragma (cpp_reader *pfile, unsigned int line)
|
||||
cb_def_pragma (cpp_reader *pfile, source_location loc)
|
||||
{
|
||||
/* Issue a warning message if we have been asked to do so. Ignore
|
||||
unknown pragmas in system headers unless an explicit
|
||||
|
|
@ -266,6 +280,14 @@ cb_def_pragma (cpp_reader *pfile, unsigned int line)
|
|||
{
|
||||
const unsigned char *space, *name;
|
||||
const cpp_token *s;
|
||||
#ifndef USE_MAPPED_LOCATION
|
||||
location_t fe_loc;
|
||||
const struct line_map *map = linemap_lookup (&line_table, loc);
|
||||
fe_loc.file = map->to_file;
|
||||
fe_loc.line = SOURCE_LINE (map, loc);
|
||||
#else
|
||||
location_t fe_loc = loc;
|
||||
#endif
|
||||
|
||||
space = name = (const unsigned char *) "";
|
||||
s = cpp_get_token (pfile);
|
||||
|
|
@ -277,54 +299,58 @@ cb_def_pragma (cpp_reader *pfile, unsigned int line)
|
|||
name = cpp_token_as_text (pfile, s);
|
||||
}
|
||||
|
||||
input_line = SOURCE_LINE (map, line);
|
||||
warning ("ignoring #pragma %s %s", space, name);
|
||||
warning (OPT_Wunknown_pragmas, "%Hignoring #pragma %s %s",
|
||||
&fe_loc, space, name);
|
||||
}
|
||||
}
|
||||
|
||||
/* #define callback for DWARF and DWARF2 debug info. */
|
||||
static void
|
||||
cb_define (cpp_reader *pfile, unsigned int line, cpp_hashnode *node)
|
||||
cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
|
||||
{
|
||||
(*debug_hooks->define) (SOURCE_LINE (map, line),
|
||||
const struct line_map *map = linemap_lookup (&line_table, loc);
|
||||
(*debug_hooks->define) (SOURCE_LINE (map, loc),
|
||||
(const char *) cpp_macro_definition (pfile, node));
|
||||
}
|
||||
|
||||
/* #undef callback for DWARF and DWARF2 debug info. */
|
||||
static void
|
||||
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, unsigned int line,
|
||||
cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
|
||||
cpp_hashnode *node)
|
||||
{
|
||||
(*debug_hooks->undef) (SOURCE_LINE (map, line),
|
||||
const struct line_map *map = linemap_lookup (&line_table, loc);
|
||||
(*debug_hooks->undef) (SOURCE_LINE (map, loc),
|
||||
(const char *) NODE_NAME (node));
|
||||
}
|
||||
|
||||
static inline const cpp_token *
|
||||
get_nonpadding_token (void)
|
||||
{
|
||||
const cpp_token *tok;
|
||||
timevar_push (TV_CPP);
|
||||
do
|
||||
tok = cpp_get_token (parse_in);
|
||||
while (tok->type == CPP_PADDING);
|
||||
timevar_pop (TV_CPP);
|
||||
/* Read a token and return its type. Fill *VALUE with its value, if
|
||||
applicable. Fill *CPP_FLAGS with the token's flags, if it is
|
||||
non-NULL. */
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
int
|
||||
c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
||||
enum cpp_ttype
|
||||
c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
|
||||
{
|
||||
const cpp_token *tok;
|
||||
location_t atloc;
|
||||
static bool no_more_pch;
|
||||
const cpp_token *tok;
|
||||
enum cpp_ttype type;
|
||||
unsigned char add_flags = 0;
|
||||
|
||||
timevar_push (TV_CPP);
|
||||
retry:
|
||||
tok = get_nonpadding_token ();
|
||||
tok = cpp_get_token (parse_in);
|
||||
type = tok->type;
|
||||
|
||||
retry_after_at:
|
||||
switch (tok->type)
|
||||
#ifdef USE_MAPPED_LOCATION
|
||||
*loc = tok->src_loc;
|
||||
#else
|
||||
*loc = input_location;
|
||||
#endif
|
||||
switch (type)
|
||||
{
|
||||
case CPP_PADDING:
|
||||
goto retry;
|
||||
|
||||
case CPP_NAME:
|
||||
*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
|
||||
break;
|
||||
|
|
@ -338,9 +364,14 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
case CPP_N_INVALID:
|
||||
/* cpplib has issued an error. */
|
||||
*value = error_mark_node;
|
||||
errorcount++;
|
||||
break;
|
||||
|
||||
case CPP_N_INTEGER:
|
||||
/* C++ uses '0' to mark virtual functions as pure.
|
||||
Set PURE_ZERO to pass this information to the C++ parser. */
|
||||
if (tok->val.str.len == 1 && *tok->val.str.text == '0')
|
||||
add_flags = PURE_ZERO;
|
||||
*value = interpret_integer (tok, flags);
|
||||
break;
|
||||
|
||||
|
|
@ -349,41 +380,59 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CPP_ATSIGN:
|
||||
/* An @ may give the next token special significance in Objective-C. */
|
||||
atloc = input_location;
|
||||
tok = get_nonpadding_token ();
|
||||
if (c_dialect_objc ())
|
||||
{
|
||||
tree val;
|
||||
switch (tok->type)
|
||||
location_t atloc = input_location;
|
||||
|
||||
retry_at:
|
||||
tok = cpp_get_token (parse_in);
|
||||
type = tok->type;
|
||||
switch (type)
|
||||
{
|
||||
case CPP_NAME:
|
||||
val = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
|
||||
if (C_IS_RESERVED_WORD (val)
|
||||
&& OBJC_IS_AT_KEYWORD (C_RID_CODE (val)))
|
||||
{
|
||||
*value = val;
|
||||
return CPP_AT_NAME;
|
||||
}
|
||||
break;
|
||||
case CPP_PADDING:
|
||||
goto retry_at;
|
||||
|
||||
case CPP_STRING:
|
||||
case CPP_WSTRING:
|
||||
return lex_string (tok, value, true);
|
||||
type = lex_string (tok, value, true);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
case CPP_NAME:
|
||||
*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
|
||||
if (objc_is_reserved_word (*value))
|
||||
{
|
||||
type = CPP_AT_NAME;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
/* ... or not. */
|
||||
error ("%Hstray %<@%> in program", &atloc);
|
||||
goto retry_after_at;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* ... or not. */
|
||||
error ("%Hstray '@' in program", &atloc);
|
||||
goto retry_after_at;
|
||||
/* FALLTHROUGH */
|
||||
case CPP_HASH:
|
||||
case CPP_PASTE:
|
||||
{
|
||||
unsigned char name[4];
|
||||
|
||||
*cpp_spell_token (parse_in, tok, name, true) = 0;
|
||||
|
||||
error ("stray %qs in program", name);
|
||||
}
|
||||
|
||||
goto retry;
|
||||
|
||||
case CPP_OTHER:
|
||||
{
|
||||
|
|
@ -392,9 +441,9 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
if (c == '"' || c == '\'')
|
||||
error ("missing terminating %c character", (int) c);
|
||||
else if (ISGRAPH (c))
|
||||
error ("stray '%c' in program", (int) c);
|
||||
error ("stray %qc in program", (int) c);
|
||||
else
|
||||
error ("stray '\\%o' in program", (int) c);
|
||||
error ("stray %<\\%o%> in program", (int) c);
|
||||
}
|
||||
goto retry;
|
||||
|
||||
|
|
@ -405,42 +454,51 @@ c_lex_with_flags (tree *value, unsigned char *cpp_flags)
|
|||
|
||||
case CPP_STRING:
|
||||
case CPP_WSTRING:
|
||||
return lex_string (tok, value, false);
|
||||
if (!c_lex_return_raw_strings)
|
||||
{
|
||||
type = lex_string (tok, value, false);
|
||||
break;
|
||||
}
|
||||
*value = build_string (tok->val.str.len, (char *) tok->val.str.text);
|
||||
break;
|
||||
|
||||
case CPP_PRAGMA:
|
||||
*value = build_int_cst (NULL, tok->val.pragma);
|
||||
break;
|
||||
|
||||
/* These tokens should not be visible outside cpplib. */
|
||||
case CPP_HEADER_NAME:
|
||||
case CPP_COMMENT:
|
||||
case CPP_MACRO_ARG:
|
||||
abort ();
|
||||
gcc_unreachable ();
|
||||
|
||||
default:
|
||||
*value = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (! no_more_pch)
|
||||
if (cpp_flags)
|
||||
*cpp_flags = tok->flags | add_flags;
|
||||
|
||||
if (!no_more_pch)
|
||||
{
|
||||
no_more_pch = true;
|
||||
c_common_no_more_pch ();
|
||||
}
|
||||
|
||||
if (cpp_flags)
|
||||
*cpp_flags = tok->flags;
|
||||
return tok->type;
|
||||
}
|
||||
timevar_pop (TV_CPP);
|
||||
|
||||
int
|
||||
c_lex (tree *value)
|
||||
{
|
||||
return c_lex_with_flags (value, NULL);
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Returns the narrowest C-visible unsigned type, starting with the
|
||||
minimum specified by FLAGS, that can fit VALUE, or itk_none if
|
||||
minimum specified by FLAGS, that can fit HIGH:LOW, or itk_none if
|
||||
there isn't one. */
|
||||
|
||||
static enum integer_type_kind
|
||||
narrowest_unsigned_type (tree value, unsigned int flags)
|
||||
narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
|
||||
unsigned HOST_WIDE_INT high,
|
||||
unsigned int flags)
|
||||
{
|
||||
enum integer_type_kind itk;
|
||||
|
||||
|
|
@ -451,20 +509,23 @@ narrowest_unsigned_type (tree value, unsigned int flags)
|
|||
else
|
||||
itk = itk_unsigned_long_long;
|
||||
|
||||
/* int_fits_type_p must think the type of its first argument is
|
||||
wider than its second argument, or it won't do the proper check. */
|
||||
TREE_TYPE (value) = widest_unsigned_literal_type_node;
|
||||
|
||||
for (; itk < itk_none; itk += 2 /* skip unsigned types */)
|
||||
if (int_fits_type_p (value, integer_types[itk]))
|
||||
return itk;
|
||||
{
|
||||
tree upper = TYPE_MAX_VALUE (integer_types[itk]);
|
||||
|
||||
if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
|
||||
|| ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
|
||||
&& TREE_INT_CST_LOW (upper) >= low))
|
||||
return itk;
|
||||
}
|
||||
|
||||
return itk_none;
|
||||
}
|
||||
|
||||
/* Ditto, but narrowest signed type. */
|
||||
static enum integer_type_kind
|
||||
narrowest_signed_type (tree value, unsigned int flags)
|
||||
narrowest_signed_type (unsigned HOST_WIDE_INT low,
|
||||
unsigned HOST_WIDE_INT high, unsigned int flags)
|
||||
{
|
||||
enum integer_type_kind itk;
|
||||
|
||||
|
|
@ -475,13 +536,16 @@ narrowest_signed_type (tree value, unsigned int flags)
|
|||
else
|
||||
itk = itk_long_long;
|
||||
|
||||
/* int_fits_type_p must think the type of its first argument is
|
||||
wider than its second argument, or it won't do the proper check. */
|
||||
TREE_TYPE (value) = widest_unsigned_literal_type_node;
|
||||
|
||||
for (; itk < itk_none; itk += 2 /* skip signed types */)
|
||||
if (int_fits_type_p (value, integer_types[itk]))
|
||||
return itk;
|
||||
{
|
||||
tree upper = TYPE_MAX_VALUE (integer_types[itk]);
|
||||
|
||||
if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
|
||||
|| ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
|
||||
&& TREE_INT_CST_LOW (upper) >= low))
|
||||
return itk;
|
||||
}
|
||||
|
||||
return itk_none;
|
||||
}
|
||||
|
|
@ -497,18 +561,19 @@ interpret_integer (const cpp_token *token, unsigned int flags)
|
|||
|
||||
integer = cpp_interpret_integer (parse_in, token, flags);
|
||||
integer = cpp_num_sign_extend (integer, options->precision);
|
||||
value = build_int_2_wide (integer.low, integer.high);
|
||||
|
||||
/* The type of a constant with a U suffix is straightforward. */
|
||||
if (flags & CPP_N_UNSIGNED)
|
||||
itk = narrowest_unsigned_type (value, flags);
|
||||
itk = narrowest_unsigned_type (integer.low, integer.high, flags);
|
||||
else
|
||||
{
|
||||
/* The type of a potentially-signed integer constant varies
|
||||
depending on the base it's in, the standard in use, and the
|
||||
length suffixes. */
|
||||
enum integer_type_kind itk_u = narrowest_unsigned_type (value, flags);
|
||||
enum integer_type_kind itk_s = narrowest_signed_type (value, flags);
|
||||
enum integer_type_kind itk_u
|
||||
= narrowest_unsigned_type (integer.low, integer.high, flags);
|
||||
enum integer_type_kind itk_s
|
||||
= narrowest_signed_type (integer.low, integer.high, flags);
|
||||
|
||||
/* In both C89 and C99, octal and hex constants may be signed or
|
||||
unsigned, whichever fits tighter. We do not warn about this
|
||||
|
|
@ -532,10 +597,11 @@ interpret_integer (const cpp_token *token, unsigned int flags)
|
|||
if (itk_u < itk_unsigned_long)
|
||||
itk_u = itk_unsigned_long;
|
||||
itk = itk_u;
|
||||
warning ("this decimal constant is unsigned only in ISO C90");
|
||||
warning (0, "this decimal constant is unsigned only in ISO C90");
|
||||
}
|
||||
else if (warn_traditional)
|
||||
warning ("this decimal constant would be unsigned in ISO C90");
|
||||
else
|
||||
warning (OPT_Wtraditional,
|
||||
"this decimal constant would be unsigned in ISO C90");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -550,15 +616,15 @@ interpret_integer (const cpp_token *token, unsigned int flags)
|
|||
|
||||
if (itk > itk_unsigned_long
|
||||
&& (flags & CPP_N_WIDTH) != CPP_N_LARGE
|
||||
&& ! in_system_header && ! flag_isoc99)
|
||||
pedwarn ("integer constant is too large for \"%s\" type",
|
||||
&& !in_system_header && !flag_isoc99)
|
||||
pedwarn ("integer constant is too large for %qs type",
|
||||
(flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
|
||||
|
||||
TREE_TYPE (value) = type;
|
||||
value = build_int_cst_wide (type, integer.low, integer.high);
|
||||
|
||||
/* Convert imaginary to a complex type. */
|
||||
if (flags & CPP_N_IMAGINARY)
|
||||
value = build_complex (NULL_TREE, convert (type, integer_zero_node), value);
|
||||
value = build_complex (NULL_TREE, build_int_cst (type, 0), value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
@ -573,51 +639,53 @@ interpret_float (const cpp_token *token, unsigned int flags)
|
|||
REAL_VALUE_TYPE real;
|
||||
char *copy;
|
||||
size_t copylen;
|
||||
const char *typename;
|
||||
|
||||
/* FIXME: make %T work in error/warning, then we don't need typename. */
|
||||
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
|
||||
{
|
||||
type = long_double_type_node;
|
||||
typename = "long double";
|
||||
}
|
||||
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
|
||||
|| flag_single_precision_constant)
|
||||
{
|
||||
type = float_type_node;
|
||||
typename = "float";
|
||||
}
|
||||
/* Decode type based on width and properties. */
|
||||
if (flags & CPP_N_DFLOAT)
|
||||
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
|
||||
type = dfloat128_type_node;
|
||||
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
|
||||
type = dfloat32_type_node;
|
||||
else
|
||||
type = dfloat64_type_node;
|
||||
else
|
||||
{
|
||||
if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
|
||||
type = long_double_type_node;
|
||||
else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
|
||||
|| flag_single_precision_constant)
|
||||
type = float_type_node;
|
||||
else
|
||||
type = double_type_node;
|
||||
typename = "double";
|
||||
}
|
||||
|
||||
/* Copy the constant to a nul-terminated buffer. If the constant
|
||||
has any suffixes, cut them off; REAL_VALUE_ATOF/ REAL_VALUE_HTOF
|
||||
can't handle them. */
|
||||
copylen = token->val.str.len;
|
||||
if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
|
||||
/* Must be an F or L suffix. */
|
||||
copylen--;
|
||||
if (flags & CPP_N_IMAGINARY)
|
||||
/* I or J suffix. */
|
||||
copylen--;
|
||||
if (flags & CPP_N_DFLOAT)
|
||||
copylen -= 2;
|
||||
else
|
||||
{
|
||||
if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
|
||||
/* Must be an F or L suffix. */
|
||||
copylen--;
|
||||
if (flags & CPP_N_IMAGINARY)
|
||||
/* I or J suffix. */
|
||||
copylen--;
|
||||
}
|
||||
|
||||
copy = alloca (copylen + 1);
|
||||
copy = (char *) alloca (copylen + 1);
|
||||
memcpy (copy, token->val.str.text, copylen);
|
||||
copy[copylen] = '\0';
|
||||
|
||||
real_from_string (&real, copy);
|
||||
real_convert (&real, TYPE_MODE (type), &real);
|
||||
real_from_string3 (&real, copy, TYPE_MODE (type));
|
||||
|
||||
/* A diagnostic is required for "soft" overflow by some ISO C
|
||||
testsuites. This is not pedwarn, because some people don't want
|
||||
an error for this.
|
||||
??? That's a dubious reason... is this a mandatory diagnostic or
|
||||
isn't it? -- zw, 2001-08-21. */
|
||||
/* Both C and C++ require a diagnostic for a floating constant
|
||||
outside the range of representable values of its type. Since we
|
||||
have __builtin_inf* to produce an infinity, it might now be
|
||||
appropriate for this to be a mandatory pedwarn rather than
|
||||
conditioned on -pedantic. */
|
||||
if (REAL_VALUE_ISINF (real) && pedantic)
|
||||
warning ("floating constant exceeds range of \"%s\"", typename);
|
||||
pedwarn ("floating constant exceeds range of %qT", type);
|
||||
|
||||
/* Create a node with determined type and value. */
|
||||
value = build_real (type, real);
|
||||
|
|
@ -648,7 +716,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
|
|||
{
|
||||
tree value;
|
||||
bool wide = false;
|
||||
size_t count = 1;
|
||||
size_t concats = 0;
|
||||
struct obstack str_ob;
|
||||
cpp_string istr;
|
||||
|
||||
|
|
@ -660,45 +728,76 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
|
|||
if (tok->type == CPP_WSTRING)
|
||||
wide = true;
|
||||
|
||||
tok = get_nonpadding_token ();
|
||||
if (c_dialect_objc () && tok->type == CPP_ATSIGN)
|
||||
retry:
|
||||
tok = cpp_get_token (parse_in);
|
||||
switch (tok->type)
|
||||
{
|
||||
objc_string = true;
|
||||
tok = get_nonpadding_token ();
|
||||
}
|
||||
if (tok->type == CPP_STRING || tok->type == CPP_WSTRING)
|
||||
{
|
||||
gcc_obstack_init (&str_ob);
|
||||
obstack_grow (&str_ob, &str, sizeof (cpp_string));
|
||||
|
||||
do
|
||||
case CPP_PADDING:
|
||||
goto retry;
|
||||
case CPP_ATSIGN:
|
||||
if (c_dialect_objc ())
|
||||
{
|
||||
count++;
|
||||
if (tok->type == CPP_WSTRING)
|
||||
wide = true;
|
||||
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
|
||||
|
||||
tok = get_nonpadding_token ();
|
||||
if (c_dialect_objc () && tok->type == CPP_ATSIGN)
|
||||
{
|
||||
objc_string = true;
|
||||
tok = get_nonpadding_token ();
|
||||
}
|
||||
objc_string = true;
|
||||
goto retry;
|
||||
}
|
||||
while (tok->type == CPP_STRING || tok->type == CPP_WSTRING);
|
||||
strs = obstack_finish (&str_ob);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
case CPP_WSTRING:
|
||||
wide = true;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case CPP_STRING:
|
||||
if (!concats)
|
||||
{
|
||||
gcc_obstack_init (&str_ob);
|
||||
obstack_grow (&str_ob, &str, sizeof (cpp_string));
|
||||
}
|
||||
|
||||
concats++;
|
||||
obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
|
||||
goto retry;
|
||||
}
|
||||
|
||||
/* We have read one more token than we want. */
|
||||
_cpp_backup_tokens (parse_in, 1);
|
||||
if (concats)
|
||||
strs = XOBFINISH (&str_ob, cpp_string *);
|
||||
|
||||
if (count > 1 && !objc_string && warn_traditional && !in_system_header)
|
||||
warning ("traditional C rejects string constant concatenation");
|
||||
if (concats && !objc_string && !in_system_header)
|
||||
warning (OPT_Wtraditional,
|
||||
"traditional C rejects string constant concatenation");
|
||||
|
||||
if (cpp_interpret_string (parse_in, strs, count, &istr, wide))
|
||||
if ((c_lex_string_translate
|
||||
? cpp_interpret_string : cpp_interpret_string_notranslate)
|
||||
(parse_in, strs, concats + 1, &istr, wide))
|
||||
{
|
||||
value = build_string (istr.len, (char *)istr.text);
|
||||
free ((void *)istr.text);
|
||||
value = build_string (istr.len, (char *) istr.text);
|
||||
free ((void *) istr.text);
|
||||
|
||||
if (c_lex_string_translate == -1)
|
||||
{
|
||||
int xlated = cpp_interpret_string_notranslate (parse_in, strs,
|
||||
concats + 1,
|
||||
&istr, wide);
|
||||
/* Assume that, if we managed to translate the string above,
|
||||
then the untranslated parsing will always succeed. */
|
||||
gcc_assert (xlated);
|
||||
|
||||
if (TREE_STRING_LENGTH (value) != (int) istr.len
|
||||
|| 0 != strncmp (TREE_STRING_POINTER (value), (char *) istr.text,
|
||||
istr.len))
|
||||
{
|
||||
/* Arrange for us to return the untranslated string in
|
||||
*valp, but to set up the C type of the translated
|
||||
one. */
|
||||
*valp = build_string (istr.len, (char *) istr.text);
|
||||
valp = &TREE_CHAIN (*valp);
|
||||
}
|
||||
free ((void *) istr.text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -717,7 +816,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
|
|||
TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
|
||||
*valp = fix_string_type (value);
|
||||
|
||||
if (strs != &str)
|
||||
if (concats)
|
||||
obstack_free (&str_ob, 0);
|
||||
|
||||
return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
|
||||
|
|
@ -735,13 +834,6 @@ lex_charconst (const cpp_token *token)
|
|||
result = cpp_interpret_charconst (parse_in, token,
|
||||
&chars_seen, &unsignedp);
|
||||
|
||||
/* Cast to cppchar_signed_t to get correct sign-extension of RESULT
|
||||
before possibly widening to HOST_WIDE_INT for build_int_2. */
|
||||
if (unsignedp || (cppchar_signed_t) result >= 0)
|
||||
value = build_int_2 (result, 0);
|
||||
else
|
||||
value = build_int_2 ((cppchar_signed_t) result, -1);
|
||||
|
||||
if (token->type == CPP_WCHAR)
|
||||
type = wchar_type_node;
|
||||
/* In C, a character constant has type 'int'.
|
||||
|
|
@ -751,6 +843,12 @@ lex_charconst (const cpp_token *token)
|
|||
else
|
||||
type = char_type_node;
|
||||
|
||||
TREE_TYPE (value) = type;
|
||||
/* Cast to cppchar_signed_t to get correct sign-extension of RESULT
|
||||
before possibly widening to HOST_WIDE_INT for build_int_cst. */
|
||||
if (unsignedp || (cppchar_signed_t) result >= 0)
|
||||
value = build_int_cst_wide (type, result, 0);
|
||||
else
|
||||
value = build_int_cst_wide (type, (cppchar_signed_t) result, -1);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Some code common to C and ObjC front ends.
|
||||
Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -15,8 +15,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -26,8 +26,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "rtl.h"
|
||||
#include "insn-config.h"
|
||||
#include "integrate.h"
|
||||
#include "expr.h"
|
||||
#include "c-tree.h"
|
||||
#include "c-pretty-print.h"
|
||||
#include "function.h"
|
||||
#include "flags.h"
|
||||
#include "toplev.h"
|
||||
|
|
@ -36,14 +36,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "varray.h"
|
||||
#include "ggc.h"
|
||||
#include "langhooks.h"
|
||||
#include "tree-mudflap.h"
|
||||
#include "target.h"
|
||||
#include "cgraph.h"
|
||||
#include "c-objc-common.h"
|
||||
|
||||
static bool c_tree_printer (pretty_printer *, text_info *);
|
||||
static tree start_cdtor (int);
|
||||
static void finish_cdtor (tree);
|
||||
static bool c_tree_printer (pretty_printer *, text_info *, const char *,
|
||||
int, bool, bool, bool);
|
||||
|
||||
int
|
||||
bool
|
||||
c_missing_noreturn_ok_p (tree decl)
|
||||
{
|
||||
/* A missing noreturn is not ok for freestanding implementations and
|
||||
|
|
@ -69,7 +69,6 @@ int
|
|||
c_cannot_inline_tree_fn (tree *fnp)
|
||||
{
|
||||
tree fn = *fnp;
|
||||
tree t;
|
||||
bool do_warning = (warn_inline
|
||||
&& DECL_INLINE (fn)
|
||||
&& DECL_DECLARED_INLINE_P (fn)
|
||||
|
|
@ -79,50 +78,26 @@ c_cannot_inline_tree_fn (tree *fnp)
|
|||
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
|
||||
{
|
||||
if (do_warning)
|
||||
warning ("%Jfunction '%F' can never be inlined because it "
|
||||
"is suppressed using -fno-inline", fn, fn);
|
||||
warning (OPT_Winline, "function %q+F can never be inlined because it "
|
||||
"is suppressed using -fno-inline", fn);
|
||||
goto cannot_inline;
|
||||
}
|
||||
|
||||
/* Don't auto-inline anything that might not be bound within
|
||||
this unit of translation. */
|
||||
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
|
||||
if (!DECL_DECLARED_INLINE_P (fn) && !targetm.binds_local_p (fn))
|
||||
{
|
||||
if (do_warning)
|
||||
warning ("%Jfunction '%F' can never be inlined because it might not "
|
||||
"be bound within this unit of translation", fn, fn);
|
||||
warning (OPT_Winline, "function %q+F can never be inlined because it "
|
||||
"might not be bound within this unit of translation", fn);
|
||||
goto cannot_inline;
|
||||
}
|
||||
|
||||
if (! function_attribute_inlinable_p (fn))
|
||||
if (!function_attribute_inlinable_p (fn))
|
||||
{
|
||||
if (do_warning)
|
||||
warning ("%Jfunction '%F' can never be inlined because it uses "
|
||||
"attributes conflicting with inlining", fn, fn);
|
||||
goto cannot_inline;
|
||||
}
|
||||
|
||||
/* If a function has pending sizes, we must not defer its
|
||||
compilation, and we can't inline it as a tree. */
|
||||
if (fn == current_function_decl)
|
||||
{
|
||||
t = get_pending_sizes ();
|
||||
put_pending_sizes (t);
|
||||
|
||||
if (t)
|
||||
{
|
||||
if (do_warning)
|
||||
warning ("%Jfunction '%F' can never be inlined because it has "
|
||||
"pending sizes", fn, fn);
|
||||
goto cannot_inline;
|
||||
}
|
||||
}
|
||||
|
||||
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
|
||||
{
|
||||
if (do_warning)
|
||||
warning ("%Jfunction '%F' can never be inlined because it has "
|
||||
"pending sizes", fn, fn);
|
||||
warning (OPT_Winline, "function %q+F can never be inlined because it "
|
||||
"uses attributes conflicting with inlining", fn);
|
||||
goto cannot_inline;
|
||||
}
|
||||
|
||||
|
|
@ -150,24 +125,15 @@ c_warn_unused_global_decl (tree decl)
|
|||
bool
|
||||
c_objc_common_init (void)
|
||||
{
|
||||
static const enum tree_code stmt_codes[] = {
|
||||
c_common_stmt_codes
|
||||
};
|
||||
|
||||
INIT_STATEMENT_CODES (stmt_codes);
|
||||
|
||||
c_init_decl_processing ();
|
||||
|
||||
if (c_common_init () == false)
|
||||
return false;
|
||||
|
||||
lang_expand_decl_stmt = c_expand_decl_stmt;
|
||||
|
||||
/* These were not defined in the Objective-C front end, but I'm
|
||||
putting them here anyway. The diagnostic format decoder might
|
||||
want an enhanced ObjC implementation. */
|
||||
diagnostic_format_decoder (global_dc) = &c_tree_printer;
|
||||
lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
|
||||
|
||||
/* If still unspecified, make it match -std=c99
|
||||
(allowing for -pedantic-errors). */
|
||||
|
|
@ -182,102 +148,11 @@ c_objc_common_init (void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static tree
|
||||
start_cdtor (int method_type)
|
||||
{
|
||||
tree fnname = get_file_function_name (method_type);
|
||||
tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
|
||||
tree body;
|
||||
|
||||
start_function (void_list_node_1,
|
||||
build_nt (CALL_EXPR, fnname,
|
||||
tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
|
||||
NULL_TREE),
|
||||
NULL_TREE);
|
||||
store_parm_decls ();
|
||||
|
||||
current_function_cannot_inline
|
||||
= "static constructors and destructors cannot be inlined";
|
||||
|
||||
body = c_begin_compound_stmt ();
|
||||
|
||||
pushlevel (0);
|
||||
clear_last_expr ();
|
||||
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
static void
|
||||
finish_cdtor (tree body)
|
||||
{
|
||||
tree scope;
|
||||
tree block;
|
||||
|
||||
scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
|
||||
block = poplevel (0, 0, 0);
|
||||
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
|
||||
SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
|
||||
|
||||
RECHAIN_STMTS (body, COMPOUND_BODY (body));
|
||||
|
||||
finish_function ();
|
||||
}
|
||||
|
||||
/* Called at end of parsing, but before end-of-file processing. */
|
||||
|
||||
void
|
||||
c_objc_common_finish_file (void)
|
||||
{
|
||||
if (pch_file)
|
||||
c_common_write_pch ();
|
||||
|
||||
/* If multiple translation units were built, copy information between
|
||||
them based on linkage rules. */
|
||||
merge_translation_unit_decls ();
|
||||
|
||||
cgraph_finalize_compilation_unit ();
|
||||
cgraph_optimize ();
|
||||
|
||||
if (static_ctors)
|
||||
{
|
||||
tree body = start_cdtor ('I');
|
||||
|
||||
for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
|
||||
c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
|
||||
NULL_TREE));
|
||||
|
||||
finish_cdtor (body);
|
||||
}
|
||||
|
||||
if (static_dtors)
|
||||
{
|
||||
tree body = start_cdtor ('D');
|
||||
|
||||
for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
|
||||
c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
|
||||
NULL_TREE));
|
||||
|
||||
finish_cdtor (body);
|
||||
}
|
||||
|
||||
{
|
||||
int flags;
|
||||
FILE *stream = dump_begin (TDI_all, &flags);
|
||||
|
||||
if (stream)
|
||||
{
|
||||
dump_node (getdecls (), flags & ~TDF_SLIM, stream);
|
||||
dump_end (TDI_all, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called during diagnostic message formatting process to print a
|
||||
source-level entity onto BUFFER. The meaning of the format specifiers
|
||||
is as follows:
|
||||
%D: a general decl,
|
||||
%E: An expression,
|
||||
%E: an identifier or expression,
|
||||
%F: a function declaration,
|
||||
%T: a type.
|
||||
|
||||
|
|
@ -286,30 +161,56 @@ c_objc_common_finish_file (void)
|
|||
Please notice when called, the `%' part was already skipped by the
|
||||
diagnostic machinery. */
|
||||
static bool
|
||||
c_tree_printer (pretty_printer *pp, text_info *text)
|
||||
c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
|
||||
int precision, bool wide, bool set_locus, bool hash)
|
||||
{
|
||||
tree t = va_arg (*text->args_ptr, tree);
|
||||
tree name;
|
||||
const char *n = "({anonymous})";
|
||||
c_pretty_printer *cpp = (c_pretty_printer *) pp;
|
||||
pp->padding = pp_none;
|
||||
|
||||
switch (*text->format_spec)
|
||||
if (precision != 0 || wide || hash)
|
||||
return false;
|
||||
|
||||
if (set_locus && text->locus)
|
||||
*text->locus = DECL_SOURCE_LOCATION (t);
|
||||
|
||||
switch (*spec)
|
||||
{
|
||||
case 'D':
|
||||
if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
|
||||
{
|
||||
t = DECL_DEBUG_EXPR (t);
|
||||
if (!DECL_P (t))
|
||||
{
|
||||
pp_c_expression (cpp, t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* FALLTHRU */
|
||||
|
||||
case 'F':
|
||||
if (DECL_NAME (t))
|
||||
n = (*lang_hooks.decl_printable_name) (t, 2);
|
||||
n = lang_hooks.decl_printable_name (t, 2);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if (TREE_CODE (t) == TYPE_DECL)
|
||||
gcc_assert (TYPE_P (t));
|
||||
name = TYPE_NAME (t);
|
||||
|
||||
if (name && TREE_CODE (name) == TYPE_DECL)
|
||||
{
|
||||
if (DECL_NAME (t))
|
||||
n = (*lang_hooks.decl_printable_name) (t, 2);
|
||||
if (DECL_NAME (name))
|
||||
pp_string (cpp, lang_hooks.decl_printable_name (name, 2));
|
||||
else
|
||||
pp_type_id (cpp, t);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
t = TYPE_NAME (t);
|
||||
if (t)
|
||||
n = IDENTIFIER_POINTER (t);
|
||||
pp_type_id (cpp, t);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -317,13 +218,50 @@ c_tree_printer (pretty_printer *pp, text_info *text)
|
|||
if (TREE_CODE (t) == IDENTIFIER_NODE)
|
||||
n = IDENTIFIER_POINTER (t);
|
||||
else
|
||||
return false;
|
||||
{
|
||||
pp_expression (cpp, t);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
pp_string (pp, n);
|
||||
pp_string (cpp, n);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* In C and ObjC, all decls have "C" linkage. */
|
||||
bool
|
||||
has_c_linkage (tree decl ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
c_initialize_diagnostics (diagnostic_context *context)
|
||||
{
|
||||
pretty_printer *base = context->printer;
|
||||
c_pretty_printer *pp = XNEW (c_pretty_printer);
|
||||
memcpy (pp_base (pp), base, sizeof (pretty_printer));
|
||||
pp_c_pretty_printer_init (pp);
|
||||
context->printer = (pretty_printer *) pp;
|
||||
|
||||
/* It is safe to free this object because it was previously XNEW()'d. */
|
||||
XDELETE (base);
|
||||
}
|
||||
|
||||
int
|
||||
c_types_compatible_p (tree x, tree y)
|
||||
{
|
||||
return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
|
||||
}
|
||||
|
||||
/* Determine if the type is a vla type for the backend. */
|
||||
|
||||
bool
|
||||
c_vla_unspec_p (tree x, tree fn ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return c_vla_type_p (x);
|
||||
}
|
||||
|
|
|
|||
143
contrib/gcc/c-objc-common.h
Normal file
143
contrib/gcc/c-objc-common.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/* Language hooks common to C and ObjC front ends.
|
||||
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
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, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_C_OBJC_COMMON
|
||||
#define GCC_C_OBJC_COMMON
|
||||
|
||||
/* In c-objc-common.c. */
|
||||
extern void c_initialize_diagnostics (diagnostic_context *);
|
||||
|
||||
/* Lang hooks that are shared between C and ObjC are defined here. Hooks
|
||||
specific to C or ObjC go in c-lang.c and objc/objc-lang.c, respectively. */
|
||||
|
||||
#undef LANG_HOOKS_IDENTIFIER_SIZE
|
||||
#define LANG_HOOKS_IDENTIFIER_SIZE C_SIZEOF_STRUCT_LANG_IDENTIFIER
|
||||
#undef LANG_HOOKS_FINISH
|
||||
#define LANG_HOOKS_FINISH c_common_finish
|
||||
#undef LANG_HOOKS_INIT_OPTIONS
|
||||
#define LANG_HOOKS_INIT_OPTIONS c_common_init_options
|
||||
#undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
|
||||
#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS c_initialize_diagnostics
|
||||
#undef LANG_HOOKS_HANDLE_OPTION
|
||||
#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
|
||||
#undef LANG_HOOKS_MISSING_ARGUMENT
|
||||
#define LANG_HOOKS_MISSING_ARGUMENT c_common_missing_argument
|
||||
#undef LANG_HOOKS_POST_OPTIONS
|
||||
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
|
||||
#undef LANG_HOOKS_GET_ALIAS_SET
|
||||
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
|
||||
#undef LANG_HOOKS_EXPAND_EXPR
|
||||
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
|
||||
#undef LANG_HOOKS_EXPAND_DECL
|
||||
#define LANG_HOOKS_EXPAND_DECL c_expand_decl
|
||||
#undef LANG_HOOKS_MARK_ADDRESSABLE
|
||||
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
|
||||
#undef LANG_HOOKS_PARSE_FILE
|
||||
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
|
||||
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
|
||||
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
|
||||
#undef LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS
|
||||
#define LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS true
|
||||
#undef LANG_HOOKS_STATICP
|
||||
#define LANG_HOOKS_STATICP c_staticp
|
||||
#undef LANG_HOOKS_NO_BODY_BLOCKS
|
||||
#define LANG_HOOKS_NO_BODY_BLOCKS true
|
||||
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
|
||||
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
|
||||
#undef LANG_HOOKS_PRINT_IDENTIFIER
|
||||
#define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier
|
||||
#undef LANG_HOOKS_TYPES_COMPATIBLE_P
|
||||
#define LANG_HOOKS_TYPES_COMPATIBLE_P c_types_compatible_p
|
||||
#undef LANG_HOOKS_FUNCTION_ENTER_NESTED
|
||||
#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
|
||||
#undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
|
||||
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
|
||||
#undef LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P
|
||||
#define LANG_HOOKS_FUNCTION_MISSING_NORETURN_OK_P c_missing_noreturn_ok_p
|
||||
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
|
||||
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
|
||||
|
||||
/* Attribute hooks. */
|
||||
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
|
||||
#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
|
||||
#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table
|
||||
|
||||
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
|
||||
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
|
||||
c_cannot_inline_tree_fn
|
||||
#undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
|
||||
#define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
|
||||
c_disregard_inline_limits
|
||||
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
|
||||
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
|
||||
anon_aggr_type_p
|
||||
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
|
||||
c_convert_parm_for_inlining
|
||||
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
|
||||
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
|
||||
|
||||
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
|
||||
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body
|
||||
|
||||
#undef LANG_HOOKS_TYPE_FOR_MODE
|
||||
#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
|
||||
#undef LANG_HOOKS_TYPE_FOR_SIZE
|
||||
#define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size
|
||||
#undef LANG_HOOKS_SIGNED_TYPE
|
||||
#define LANG_HOOKS_SIGNED_TYPE c_common_signed_type
|
||||
#undef LANG_HOOKS_UNSIGNED_TYPE
|
||||
#define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type
|
||||
#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
|
||||
#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type
|
||||
#undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR
|
||||
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error
|
||||
#undef LANG_HOOKS_TYPE_PROMOTES_TO
|
||||
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
|
||||
#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
|
||||
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
|
||||
#undef LANG_HOOKS_TO_TARGET_CHARSET
|
||||
#define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
|
||||
#undef LANG_HOOKS_EXPR_TO_DECL
|
||||
#define LANG_HOOKS_EXPR_TO_DECL c_expr_to_decl
|
||||
|
||||
/* The C front end's scoping structure is very different from
|
||||
that expected by the language-independent code; it is best
|
||||
to disable getdecls.
|
||||
This means it must also provide its own write_globals. */
|
||||
|
||||
#undef LANG_HOOKS_GETDECLS
|
||||
#define LANG_HOOKS_GETDECLS lhd_return_null_tree_v
|
||||
#undef LANG_HOOKS_WRITE_GLOBALS
|
||||
#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
|
||||
|
||||
/* Hooks for tree gimplification. */
|
||||
#undef LANG_HOOKS_GIMPLIFY_EXPR
|
||||
#define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr
|
||||
|
||||
#undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
|
||||
#define LANG_HOOKS_OMP_PREDETERMINED_SHARING c_omp_predetermined_sharing
|
||||
|
||||
#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
|
||||
#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P c_vla_unspec_p
|
||||
|
||||
#endif /* GCC_C_OBJC_COMMON */
|
||||
441
contrib/gcc/c-omp.c
Normal file
441
contrib/gcc/c-omp.c
Normal file
|
|
@ -0,0 +1,441 @@
|
|||
/* This file contains routines to construct GNU OpenMP constructs,
|
||||
called from parsing in the C and C++ front ends.
|
||||
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
Contributed by Richard Henderson <rth@redhat.com>,
|
||||
Diego Novillo <dnovillo@redhat.com>.
|
||||
|
||||
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, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "function.h"
|
||||
#include "c-common.h"
|
||||
#include "toplev.h"
|
||||
#include "tree-gimple.h"
|
||||
#include "bitmap.h"
|
||||
#include "langhooks.h"
|
||||
|
||||
|
||||
/* Complete a #pragma omp master construct. STMT is the structured-block
|
||||
that follows the pragma. */
|
||||
|
||||
tree
|
||||
c_finish_omp_master (tree stmt)
|
||||
{
|
||||
return add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
|
||||
}
|
||||
|
||||
/* Complete a #pragma omp critical construct. STMT is the structured-block
|
||||
that follows the pragma, NAME is the identifier in the pragma, or null
|
||||
if it was omitted. */
|
||||
|
||||
tree
|
||||
c_finish_omp_critical (tree body, tree name)
|
||||
{
|
||||
tree stmt = make_node (OMP_CRITICAL);
|
||||
TREE_TYPE (stmt) = void_type_node;
|
||||
OMP_CRITICAL_BODY (stmt) = body;
|
||||
OMP_CRITICAL_NAME (stmt) = name;
|
||||
return add_stmt (stmt);
|
||||
}
|
||||
|
||||
/* Complete a #pragma omp ordered construct. STMT is the structured-block
|
||||
that follows the pragma. */
|
||||
|
||||
tree
|
||||
c_finish_omp_ordered (tree stmt)
|
||||
{
|
||||
return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt));
|
||||
}
|
||||
|
||||
|
||||
/* Complete a #pragma omp barrier construct. */
|
||||
|
||||
void
|
||||
c_finish_omp_barrier (void)
|
||||
{
|
||||
tree x;
|
||||
|
||||
x = built_in_decls[BUILT_IN_GOMP_BARRIER];
|
||||
x = build_function_call_expr (x, NULL);
|
||||
add_stmt (x);
|
||||
}
|
||||
|
||||
|
||||
/* Complete a #pragma omp atomic construct. The expression to be
|
||||
implemented atomically is LHS code= RHS. The value returned is
|
||||
either error_mark_node (if the construct was erroneous) or an
|
||||
OMP_ATOMIC node which should be added to the current statement tree
|
||||
with add_stmt. */
|
||||
|
||||
tree
|
||||
c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
|
||||
{
|
||||
tree x, type, addr;
|
||||
|
||||
if (lhs == error_mark_node || rhs == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* ??? According to one reading of the OpenMP spec, complex type are
|
||||
supported, but there are no atomic stores for any architecture.
|
||||
But at least icc 9.0 doesn't support complex types here either.
|
||||
And lets not even talk about vector types... */
|
||||
type = TREE_TYPE (lhs);
|
||||
if (!INTEGRAL_TYPE_P (type)
|
||||
&& !POINTER_TYPE_P (type)
|
||||
&& !SCALAR_FLOAT_TYPE_P (type))
|
||||
{
|
||||
error ("invalid expression type for %<#pragma omp atomic%>");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* ??? Validate that rhs does not overlap lhs. */
|
||||
|
||||
/* Take and save the address of the lhs. From then on we'll reference it
|
||||
via indirection. */
|
||||
addr = build_unary_op (ADDR_EXPR, lhs, 0);
|
||||
if (addr == error_mark_node)
|
||||
return error_mark_node;
|
||||
addr = save_expr (addr);
|
||||
if (TREE_CODE (addr) != SAVE_EXPR
|
||||
&& (TREE_CODE (addr) != ADDR_EXPR
|
||||
|| TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
|
||||
{
|
||||
/* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
|
||||
it even after unsharing function body. */
|
||||
tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
|
||||
addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
|
||||
}
|
||||
lhs = build_indirect_ref (addr, NULL);
|
||||
|
||||
/* There are lots of warnings, errors, and conversions that need to happen
|
||||
in the course of interpreting a statement. Use the normal mechanisms
|
||||
to do this, and then take it apart again. */
|
||||
x = build_modify_expr (lhs, code, rhs);
|
||||
if (x == error_mark_node)
|
||||
return error_mark_node;
|
||||
gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
|
||||
rhs = TREE_OPERAND (x, 1);
|
||||
|
||||
/* Punt the actual generation of atomic operations to common code. */
|
||||
return build2 (OMP_ATOMIC, void_type_node, addr, rhs);
|
||||
}
|
||||
|
||||
|
||||
/* Complete a #pragma omp flush construct. We don't do anything with the
|
||||
variable list that the syntax allows. */
|
||||
|
||||
void
|
||||
c_finish_omp_flush (void)
|
||||
{
|
||||
tree x;
|
||||
|
||||
x = built_in_decls[BUILT_IN_SYNCHRONIZE];
|
||||
x = build_function_call_expr (x, NULL);
|
||||
add_stmt (x);
|
||||
}
|
||||
|
||||
|
||||
/* Check and canonicalize #pragma omp for increment expression.
|
||||
Helper function for c_finish_omp_for. */
|
||||
|
||||
static tree
|
||||
check_omp_for_incr_expr (tree exp, tree decl)
|
||||
{
|
||||
tree t;
|
||||
|
||||
if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
|
||||
|| TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
|
||||
return error_mark_node;
|
||||
|
||||
if (exp == decl)
|
||||
return build_int_cst (TREE_TYPE (exp), 0);
|
||||
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
case NOP_EXPR:
|
||||
t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
|
||||
if (t != error_mark_node)
|
||||
return fold_convert (TREE_TYPE (exp), t);
|
||||
break;
|
||||
case MINUS_EXPR:
|
||||
t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
|
||||
if (t != error_mark_node)
|
||||
return fold_build2 (MINUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
|
||||
break;
|
||||
case PLUS_EXPR:
|
||||
t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
|
||||
if (t != error_mark_node)
|
||||
return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
|
||||
t = check_omp_for_incr_expr (TREE_OPERAND (exp, 1), decl);
|
||||
if (t != error_mark_node)
|
||||
return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Validate and emit code for the OpenMP directive #pragma omp for.
|
||||
INIT, COND, INCR, BODY and PRE_BODY are the five basic elements
|
||||
of the loop (initialization expression, controlling predicate, increment
|
||||
expression, body of the loop and statements to go before the loop).
|
||||
DECL is the iteration variable. */
|
||||
|
||||
tree
|
||||
c_finish_omp_for (location_t locus, tree decl, tree init, tree cond,
|
||||
tree incr, tree body, tree pre_body)
|
||||
{
|
||||
location_t elocus = locus;
|
||||
bool fail = false;
|
||||
|
||||
if (EXPR_HAS_LOCATION (init))
|
||||
elocus = EXPR_LOCATION (init);
|
||||
|
||||
/* Validate the iteration variable. */
|
||||
if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
|
||||
{
|
||||
error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
|
||||
fail = true;
|
||||
}
|
||||
if (TYPE_UNSIGNED (TREE_TYPE (decl)))
|
||||
warning (0, "%Hiteration variable %qE is unsigned", &elocus, decl);
|
||||
|
||||
/* In the case of "for (int i = 0...)", init will be a decl. It should
|
||||
have a DECL_INITIAL that we can turn into an assignment. */
|
||||
if (init == decl)
|
||||
{
|
||||
elocus = DECL_SOURCE_LOCATION (decl);
|
||||
|
||||
init = DECL_INITIAL (decl);
|
||||
if (init == NULL)
|
||||
{
|
||||
error ("%H%qE is not initialized", &elocus, decl);
|
||||
init = integer_zero_node;
|
||||
fail = true;
|
||||
}
|
||||
|
||||
init = build_modify_expr (decl, NOP_EXPR, init);
|
||||
SET_EXPR_LOCATION (init, elocus);
|
||||
}
|
||||
gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
|
||||
gcc_assert (TREE_OPERAND (init, 0) == decl);
|
||||
|
||||
if (cond == NULL_TREE)
|
||||
{
|
||||
error ("%Hmissing controlling predicate", &elocus);
|
||||
fail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool cond_ok = false;
|
||||
|
||||
if (EXPR_HAS_LOCATION (cond))
|
||||
elocus = EXPR_LOCATION (cond);
|
||||
|
||||
if (TREE_CODE (cond) == LT_EXPR
|
||||
|| TREE_CODE (cond) == LE_EXPR
|
||||
|| TREE_CODE (cond) == GT_EXPR
|
||||
|| TREE_CODE (cond) == GE_EXPR)
|
||||
{
|
||||
tree op0 = TREE_OPERAND (cond, 0);
|
||||
tree op1 = TREE_OPERAND (cond, 1);
|
||||
|
||||
/* 2.5.1. The comparison in the condition is computed in the type
|
||||
of DECL, otherwise the behavior is undefined.
|
||||
|
||||
For example:
|
||||
long n; int i;
|
||||
i < n;
|
||||
|
||||
according to ISO will be evaluated as:
|
||||
(long)i < n;
|
||||
|
||||
We want to force:
|
||||
i < (int)n; */
|
||||
if (TREE_CODE (op0) == NOP_EXPR
|
||||
&& decl == TREE_OPERAND (op0, 0))
|
||||
{
|
||||
TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
|
||||
TREE_OPERAND (cond, 1) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
|
||||
TREE_OPERAND (cond, 1));
|
||||
}
|
||||
else if (TREE_CODE (op1) == NOP_EXPR
|
||||
&& decl == TREE_OPERAND (op1, 0))
|
||||
{
|
||||
TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
|
||||
TREE_OPERAND (cond, 0) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
|
||||
TREE_OPERAND (cond, 0));
|
||||
}
|
||||
|
||||
if (decl == TREE_OPERAND (cond, 0))
|
||||
cond_ok = true;
|
||||
else if (decl == TREE_OPERAND (cond, 1))
|
||||
{
|
||||
TREE_SET_CODE (cond, swap_tree_comparison (TREE_CODE (cond)));
|
||||
TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
|
||||
TREE_OPERAND (cond, 0) = decl;
|
||||
cond_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cond_ok)
|
||||
{
|
||||
error ("%Hinvalid controlling predicate", &elocus);
|
||||
fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (incr == NULL_TREE)
|
||||
{
|
||||
error ("%Hmissing increment expression", &elocus);
|
||||
fail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool incr_ok = false;
|
||||
|
||||
if (EXPR_HAS_LOCATION (incr))
|
||||
elocus = EXPR_LOCATION (incr);
|
||||
|
||||
/* Check all the valid increment expressions: v++, v--, ++v, --v,
|
||||
v = v + incr, v = incr + v and v = v - incr. */
|
||||
switch (TREE_CODE (incr))
|
||||
{
|
||||
case POSTINCREMENT_EXPR:
|
||||
case PREINCREMENT_EXPR:
|
||||
case POSTDECREMENT_EXPR:
|
||||
case PREDECREMENT_EXPR:
|
||||
incr_ok = (TREE_OPERAND (incr, 0) == decl);
|
||||
break;
|
||||
|
||||
case MODIFY_EXPR:
|
||||
if (TREE_OPERAND (incr, 0) != decl)
|
||||
break;
|
||||
if (TREE_OPERAND (incr, 1) == decl)
|
||||
break;
|
||||
if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
|
||||
&& (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
|
||||
|| TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
|
||||
incr_ok = true;
|
||||
else if (TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
|
||||
&& TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
|
||||
incr_ok = true;
|
||||
else
|
||||
{
|
||||
tree t = check_omp_for_incr_expr (TREE_OPERAND (incr, 1), decl);
|
||||
if (t != error_mark_node)
|
||||
{
|
||||
incr_ok = true;
|
||||
t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
|
||||
incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!incr_ok)
|
||||
{
|
||||
error ("%Hinvalid increment expression", &elocus);
|
||||
fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fail)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
tree t = make_node (OMP_FOR);
|
||||
|
||||
TREE_TYPE (t) = void_type_node;
|
||||
OMP_FOR_INIT (t) = init;
|
||||
OMP_FOR_COND (t) = cond;
|
||||
OMP_FOR_INCR (t) = incr;
|
||||
OMP_FOR_BODY (t) = body;
|
||||
OMP_FOR_PRE_BODY (t) = pre_body;
|
||||
|
||||
SET_EXPR_LOCATION (t, locus);
|
||||
return add_stmt (t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Divide CLAUSES into two lists: those that apply to a parallel construct,
|
||||
and those that apply to a work-sharing construct. Place the results in
|
||||
*PAR_CLAUSES and *WS_CLAUSES respectively. In addition, add a nowait
|
||||
clause to the work-sharing list. */
|
||||
|
||||
void
|
||||
c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses)
|
||||
{
|
||||
tree next;
|
||||
|
||||
*par_clauses = NULL;
|
||||
*ws_clauses = build_omp_clause (OMP_CLAUSE_NOWAIT);
|
||||
|
||||
for (; clauses ; clauses = next)
|
||||
{
|
||||
next = OMP_CLAUSE_CHAIN (clauses);
|
||||
|
||||
switch (OMP_CLAUSE_CODE (clauses))
|
||||
{
|
||||
case OMP_CLAUSE_PRIVATE:
|
||||
case OMP_CLAUSE_SHARED:
|
||||
case OMP_CLAUSE_FIRSTPRIVATE:
|
||||
case OMP_CLAUSE_LASTPRIVATE:
|
||||
case OMP_CLAUSE_REDUCTION:
|
||||
case OMP_CLAUSE_COPYIN:
|
||||
case OMP_CLAUSE_IF:
|
||||
case OMP_CLAUSE_NUM_THREADS:
|
||||
case OMP_CLAUSE_DEFAULT:
|
||||
OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
|
||||
*par_clauses = clauses;
|
||||
break;
|
||||
|
||||
case OMP_CLAUSE_SCHEDULE:
|
||||
case OMP_CLAUSE_ORDERED:
|
||||
OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
|
||||
*ws_clauses = clauses;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* True if OpenMP sharing attribute of DECL is predetermined. */
|
||||
|
||||
enum omp_clause_default_kind
|
||||
c_omp_predetermined_sharing (tree decl)
|
||||
{
|
||||
/* Variables with const-qualified type having no mutable member
|
||||
are predetermined shared. */
|
||||
if (TREE_READONLY (decl))
|
||||
return OMP_CLAUSE_DEFAULT_SHARED;
|
||||
|
||||
return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
7868
contrib/gcc/c-parser.c
Normal file
7868
contrib/gcc/c-parser.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Precompiled header implementation for the C languages.
|
||||
Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -15,8 +15,8 @@ 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. */
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -35,37 +35,41 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "hosthooks.h"
|
||||
#include "target.h"
|
||||
|
||||
/* This structure is read very early when validating the PCH, and
|
||||
might be read for a PCH which is for a completely different compiler
|
||||
for a different operating system. Thus, it should really only contain
|
||||
'unsigned char' entries, at least in the initial entries.
|
||||
/* This is a list of flag variables that must match exactly, and their
|
||||
names for the error message. The possible values for *flag_var must
|
||||
fit in a 'signed char'. */
|
||||
|
||||
If you add or change entries before version_length, you should increase
|
||||
the version number in get_ident().
|
||||
static const struct c_pch_matching
|
||||
{
|
||||
int *flag_var;
|
||||
const char *flag_name;
|
||||
} pch_matching[] = {
|
||||
{ &flag_exceptions, "-fexceptions" },
|
||||
{ &flag_unit_at_a_time, "-funit-at-a-time" }
|
||||
};
|
||||
|
||||
There are a bunch of fields named *_length; those are lengths of data that
|
||||
follows this structure in the same order as the fields in the structure.
|
||||
enum {
|
||||
MATCH_SIZE = ARRAY_SIZE (pch_matching)
|
||||
};
|
||||
|
||||
The flags_info field is used to verify that certain flags settings that
|
||||
have to be the same during the compilation of the PCH and a compilation
|
||||
using the PCH are indeed the same. */
|
||||
/* The value of the checksum in the dummy compiler that is actually
|
||||
checksummed. That compiler should never be run. */
|
||||
static const char no_checksum[16] = { 0 };
|
||||
|
||||
/* Information about flags and suchlike that affect PCH validity.
|
||||
|
||||
Before this structure is read, both an initial 8-character identification
|
||||
string, and a 16-byte checksum, have been read and validated. */
|
||||
|
||||
struct c_pch_validity
|
||||
{
|
||||
unsigned char host_machine_length;
|
||||
unsigned char target_machine_length;
|
||||
unsigned char version_length;
|
||||
unsigned char debug_info_type;
|
||||
unsigned int flags_info;
|
||||
signed char match[MATCH_SIZE];
|
||||
void (*pch_init) (void);
|
||||
size_t target_data_length;
|
||||
};
|
||||
|
||||
/* If -funit-at-a-time is set, we require that it was also set during the
|
||||
compilation of the PCH we may be using. */
|
||||
#define FLAG_UNIT_AT_A_TIME_SET 1 << 0
|
||||
|
||||
struct c_pch_header
|
||||
struct c_pch_header
|
||||
{
|
||||
unsigned long asm_size;
|
||||
};
|
||||
|
|
@ -78,10 +82,6 @@ static FILE *pch_outfile;
|
|||
/* The position in the assembler output file when pch_init was called. */
|
||||
static long asm_file_startpos;
|
||||
|
||||
/* The host and target machines. */
|
||||
static const char host_machine[] = HOST_MACHINE;
|
||||
static const char target_machine[] = TARGET_MACHINE;
|
||||
|
||||
static const char *get_ident (void);
|
||||
|
||||
/* Compute an appropriate 8-byte magic number for the PCH file, so that
|
||||
|
|
@ -90,20 +90,22 @@ static const char *get_ident (void);
|
|||
format. */
|
||||
|
||||
static const char *
|
||||
get_ident(void)
|
||||
get_ident (void)
|
||||
{
|
||||
static char result[IDENT_LENGTH];
|
||||
static const char template[IDENT_LENGTH] = "gpch.012";
|
||||
static const char template[IDENT_LENGTH] = "gpch.013";
|
||||
static const char c_language_chars[] = "Co+O";
|
||||
|
||||
|
||||
memcpy (result, template, IDENT_LENGTH);
|
||||
result[4] = c_language_chars[c_language];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Prepare to write a PCH file. This is called at the start of
|
||||
compilation. */
|
||||
/* Prepare to write a PCH file, if one is being written. This is
|
||||
called at the start of compilation.
|
||||
|
||||
Also, print out the executable checksum if -fverbose-asm is in effect. */
|
||||
|
||||
void
|
||||
pch_init (void)
|
||||
|
|
@ -112,50 +114,55 @@ pch_init (void)
|
|||
struct c_pch_validity v;
|
||||
void *target_validity;
|
||||
static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
|
||||
unsigned int current_flags_info = 0;
|
||||
|
||||
if (! pch_file)
|
||||
return;
|
||||
|
||||
if (flag_unit_at_a_time)
|
||||
current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
|
||||
#ifdef ASM_COMMENT_START
|
||||
if (flag_verbose_asm)
|
||||
{
|
||||
fprintf (asm_out_file, "%s ", ASM_COMMENT_START);
|
||||
c_common_print_pch_checksum (asm_out_file);
|
||||
fputc ('\n', asm_out_file);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!pch_file)
|
||||
return;
|
||||
|
||||
f = fopen (pch_file, "w+b");
|
||||
if (f == NULL)
|
||||
fatal_error ("can't create precompiled header %s: %m", pch_file);
|
||||
fatal_error ("can%'t create precompiled header %s: %m", pch_file);
|
||||
pch_outfile = f;
|
||||
|
||||
if (strlen (host_machine) > 255 || strlen (target_machine) > 255
|
||||
|| strlen (version_string) > 255)
|
||||
abort ();
|
||||
|
||||
v.host_machine_length = strlen (host_machine);
|
||||
v.target_machine_length = strlen (target_machine);
|
||||
v.version_length = strlen (version_string);
|
||||
|
||||
gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
|
||||
|
||||
v.debug_info_type = write_symbols;
|
||||
v.flags_info = current_flags_info;
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < MATCH_SIZE; i++)
|
||||
{
|
||||
v.match[i] = *pch_matching[i].flag_var;
|
||||
gcc_assert (v.match[i] == *pch_matching[i].flag_var);
|
||||
}
|
||||
}
|
||||
v.pch_init = &pch_init;
|
||||
target_validity = targetm.get_pch_validity (&v.target_data_length);
|
||||
|
||||
|
||||
if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
|
||||
|| fwrite (executable_checksum, 16, 1, f) != 1
|
||||
|| fwrite (&v, sizeof (v), 1, f) != 1
|
||||
|| fwrite (host_machine, v.host_machine_length, 1, f) != 1
|
||||
|| fwrite (target_machine, v.target_machine_length, 1, f) != 1
|
||||
|| fwrite (version_string, v.version_length, 1, f) != 1
|
||||
|| fwrite (target_validity, v.target_data_length, 1, f) != 1)
|
||||
fatal_error ("can't write to %s: %m", pch_file);
|
||||
fatal_error ("can%'t write to %s: %m", pch_file);
|
||||
|
||||
/* We need to be able to re-read the output. */
|
||||
/* The driver always provides a valid -o option. */
|
||||
if (asm_file_name == NULL
|
||||
|| strcmp (asm_file_name, "-") == 0)
|
||||
fatal_error ("`%s' is not a valid output file", asm_file_name);
|
||||
|
||||
fatal_error ("%qs is not a valid output file", asm_file_name);
|
||||
|
||||
asm_file_startpos = ftell (asm_out_file);
|
||||
|
||||
|
||||
/* Let the debugging format deal with the PCHness. */
|
||||
(*debug_hooks->handle_pch) (0);
|
||||
|
||||
|
||||
cpp_save_state (parse_in, f);
|
||||
}
|
||||
|
||||
|
|
@ -176,15 +183,14 @@ c_common_write_pch (void)
|
|||
|
||||
asm_file_end = ftell (asm_out_file);
|
||||
h.asm_size = asm_file_end - asm_file_startpos;
|
||||
|
||||
|
||||
if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
|
||||
fatal_error ("can't write %s: %m", pch_file);
|
||||
|
||||
buf = xmalloc (16384);
|
||||
fflush (asm_out_file);
|
||||
fatal_error ("can%'t write %s: %m", pch_file);
|
||||
|
||||
buf = XNEWVEC (char, 16384);
|
||||
|
||||
if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
|
||||
fatal_error ("can't seek in %s: %m", asm_file_name);
|
||||
fatal_error ("can%'t seek in %s: %m", asm_file_name);
|
||||
|
||||
for (written = asm_file_startpos; written < asm_file_end; )
|
||||
{
|
||||
|
|
@ -192,21 +198,23 @@ c_common_write_pch (void)
|
|||
if (size > 16384)
|
||||
size = 16384;
|
||||
if (fread (buf, size, 1, asm_out_file) != 1)
|
||||
fatal_error ("can't read %s: %m", asm_file_name);
|
||||
fatal_error ("can%'t read %s: %m", asm_file_name);
|
||||
if (fwrite (buf, size, 1, pch_outfile) != 1)
|
||||
fatal_error ("can't write %s: %m", pch_file);
|
||||
fatal_error ("can%'t write %s: %m", pch_file);
|
||||
written += size;
|
||||
}
|
||||
free (buf);
|
||||
/* asm_out_file can be written afterwards, so must be flushed first. */
|
||||
fflush (asm_out_file);
|
||||
/* asm_out_file can be written afterwards, so fseek to clear
|
||||
_IOREAD flag. */
|
||||
if (fseek (asm_out_file, 0, SEEK_END) != 0)
|
||||
fatal_error ("can%'t seek in %s: %m", asm_file_name);
|
||||
|
||||
gt_pch_save (pch_outfile);
|
||||
cpp_write_pch_state (parse_in, pch_outfile);
|
||||
|
||||
if (fseek (pch_outfile, 0, SEEK_SET) != 0
|
||||
|| fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
|
||||
fatal_error ("can't write %s: %m", pch_file);
|
||||
fatal_error ("can%'t write %s: %m", pch_file);
|
||||
|
||||
fclose (pch_outfile);
|
||||
}
|
||||
|
|
@ -221,26 +229,25 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
|
|||
{
|
||||
int sizeread;
|
||||
int result;
|
||||
char ident[IDENT_LENGTH];
|
||||
char short_strings[256 * 3];
|
||||
int strings_length;
|
||||
char ident[IDENT_LENGTH + 16];
|
||||
const char *pch_ident;
|
||||
struct c_pch_validity v;
|
||||
unsigned int current_flags_info = 0;
|
||||
|
||||
if (flag_unit_at_a_time)
|
||||
current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
|
||||
|
||||
/* Perform a quick test of whether this is a valid
|
||||
precompiled header for the current language
|
||||
and with the current flag settings. */
|
||||
precompiled header for the current language. */
|
||||
|
||||
sizeread = read (fd, ident, IDENT_LENGTH);
|
||||
gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
|
||||
|
||||
sizeread = read (fd, ident, IDENT_LENGTH + 16);
|
||||
if (sizeread == -1)
|
||||
fatal_error ("can't read %s: %m", name);
|
||||
else if (sizeread != IDENT_LENGTH)
|
||||
return 2;
|
||||
|
||||
fatal_error ("can%'t read %s: %m", name);
|
||||
else if (sizeread != IDENT_LENGTH + 16)
|
||||
{
|
||||
cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file",
|
||||
name);
|
||||
return 2;
|
||||
}
|
||||
|
||||
pch_ident = get_ident();
|
||||
if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
|
||||
{
|
||||
|
|
@ -249,71 +256,31 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
|
|||
if (memcmp (ident, pch_ident, 5) == 0)
|
||||
/* It's a PCH, for the right language, but has the wrong version.
|
||||
*/
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: not compatible with this GCC version", name);
|
||||
else if (memcmp (ident, pch_ident, 4) == 0)
|
||||
/* It's a PCH for the wrong language. */
|
||||
cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
|
||||
lang_hooks.name);
|
||||
else
|
||||
else
|
||||
/* Not any kind of PCH. */
|
||||
cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: created by a different GCC executable", name);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* At this point, we know it's a PCH file, so it ought to be long enough
|
||||
that we can read a c_pch_validity structure. */
|
||||
/* At this point, we know it's a PCH file created by this
|
||||
executable, so it ought to be long enough that we can read a
|
||||
c_pch_validity structure. */
|
||||
if (read (fd, &v, sizeof (v)) != sizeof (v))
|
||||
fatal_error ("can't read %s: %m", name);
|
||||
|
||||
strings_length = (v.host_machine_length + v.target_machine_length
|
||||
+ v.version_length);
|
||||
if (read (fd, short_strings, strings_length) != strings_length)
|
||||
fatal_error ("can't read %s: %m", name);
|
||||
if (v.host_machine_length != strlen (host_machine)
|
||||
|| memcmp (host_machine, short_strings, strlen (host_machine)) != 0)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: created on host `%.*s', but used on host `%s'", name,
|
||||
v.host_machine_length, short_strings, host_machine);
|
||||
return 2;
|
||||
}
|
||||
if (v.target_machine_length != strlen (target_machine)
|
||||
|| memcmp (target_machine, short_strings + v.host_machine_length,
|
||||
strlen (target_machine)) != 0)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: created for target `%.*s', but used for target `%s'",
|
||||
name, v.target_machine_length,
|
||||
short_strings + v.host_machine_length, target_machine);
|
||||
return 2;
|
||||
}
|
||||
if (v.version_length != strlen (version_string)
|
||||
|| memcmp (version_string,
|
||||
(short_strings + v.host_machine_length
|
||||
+ v.target_machine_length),
|
||||
v.version_length) != 0)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: created by version `%.*s', but this is version `%s'",
|
||||
name, v.version_length,
|
||||
(short_strings + v.host_machine_length
|
||||
+ v.target_machine_length),
|
||||
version_string);
|
||||
return 2;
|
||||
}
|
||||
if (v.flags_info != current_flags_info)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: created using different flags",
|
||||
name);
|
||||
return 2;
|
||||
}
|
||||
fatal_error ("can%'t read %s: %m", name);
|
||||
|
||||
/* The allowable debug info combinations are that either the PCH file
|
||||
was built with the same as is being used now, or the PCH file was
|
||||
|
|
@ -322,21 +289,37 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
|
|||
&& write_symbols != NO_DEBUG)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: created with -g%s, but used with -g%s", name,
|
||||
debug_type_names[v.debug_info_type],
|
||||
debug_type_names[write_symbols]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Check flags that must match exactly. */
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < MATCH_SIZE; i++)
|
||||
if (*pch_matching[i].flag_var != v.match[i])
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: settings for %s do not match", name,
|
||||
pch_matching[i].flag_name);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the text segment was not loaded at the same address as it was
|
||||
when the PCH file was created, function pointers loaded from the
|
||||
PCH will not be valid. We could in theory remap all the function
|
||||
pointers, but no support for that exists at present. */
|
||||
pointers, but no support for that exists at present.
|
||||
Since we have the same executable, it should only be necessary to
|
||||
check one function. */
|
||||
if (v.pch_init != &pch_init)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
cpp_error (pfile, CPP_DL_WARNING,
|
||||
"%s: had text segment at different address", name);
|
||||
return 2;
|
||||
}
|
||||
|
|
@ -345,10 +328,10 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
|
|||
{
|
||||
void *this_file_data = xmalloc (v.target_data_length);
|
||||
const char *msg;
|
||||
|
||||
|
||||
if ((size_t) read (fd, this_file_data, v.target_data_length)
|
||||
!= v.target_data_length)
|
||||
fatal_error ("can't read %s: %m", name);
|
||||
fatal_error ("can%'t read %s: %m", name);
|
||||
msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
|
||||
free (this_file_data);
|
||||
if (msg != NULL)
|
||||
|
|
@ -361,7 +344,7 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
|
|||
|
||||
/* Check the preprocessor macros are the same as when the PCH was
|
||||
generated. */
|
||||
|
||||
|
||||
result = cpp_valid_state (pfile, name, fd);
|
||||
if (result == -1)
|
||||
return 2;
|
||||
|
|
@ -369,6 +352,10 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
|
|||
return result == 0;
|
||||
}
|
||||
|
||||
/* If non-NULL, this function is called after a precompile header file
|
||||
is loaded. */
|
||||
void (*lang_post_pch_load) (void);
|
||||
|
||||
/* Load in the PCH file NAME, open on FD. It was originally searched for
|
||||
by ORIG_NAME. */
|
||||
|
||||
|
|
@ -378,10 +365,8 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
|
|||
{
|
||||
FILE *f;
|
||||
struct c_pch_header h;
|
||||
char *buf;
|
||||
unsigned long written;
|
||||
struct save_macro_data *smd;
|
||||
|
||||
|
||||
f = fdopen (fd, "rb");
|
||||
if (f == NULL)
|
||||
{
|
||||
|
|
@ -397,18 +382,30 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
|
|||
return;
|
||||
}
|
||||
|
||||
buf = xmalloc (16384);
|
||||
for (written = 0; written < h.asm_size; )
|
||||
if (!flag_preprocess_only)
|
||||
{
|
||||
long size = h.asm_size - written;
|
||||
if (size > 16384)
|
||||
size = 16384;
|
||||
if (fread (buf, size, 1, f) != 1
|
||||
|| fwrite (buf, size, 1, asm_out_file) != 1)
|
||||
cpp_errno (pfile, CPP_DL_ERROR, "reading");
|
||||
written += size;
|
||||
unsigned long written;
|
||||
char * buf = XNEWVEC (char, 16384);
|
||||
|
||||
for (written = 0; written < h.asm_size; )
|
||||
{
|
||||
long size = h.asm_size - written;
|
||||
if (size > 16384)
|
||||
size = 16384;
|
||||
if (fread (buf, size, 1, f) != 1
|
||||
|| fwrite (buf, size, 1, asm_out_file) != 1)
|
||||
cpp_errno (pfile, CPP_DL_ERROR, "reading");
|
||||
written += size;
|
||||
}
|
||||
free (buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we're preprocessing, don't write to a NULL
|
||||
asm_out_file. */
|
||||
if (fseek (f, h.asm_size, SEEK_CUR) != 0)
|
||||
cpp_errno (pfile, CPP_DL_ERROR, "seeking");
|
||||
}
|
||||
free (buf);
|
||||
|
||||
cpp_prepare_state (pfile, &smd);
|
||||
|
||||
|
|
@ -418,6 +415,11 @@ c_common_read_pch (cpp_reader *pfile, const char *name,
|
|||
return;
|
||||
|
||||
fclose (f);
|
||||
|
||||
/* Give the front end a chance to take action after a PCH file has
|
||||
been loaded. */
|
||||
if (lang_post_pch_load)
|
||||
(*lang_post_pch_load) ();
|
||||
}
|
||||
|
||||
/* Indicate that no more PCH files should be read. */
|
||||
|
|
@ -431,3 +433,49 @@ c_common_no_more_pch (void)
|
|||
host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle #pragma GCC pch_preprocess, to load in the PCH file. */
|
||||
|
||||
#ifndef O_BINARY
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
void
|
||||
c_common_pch_pragma (cpp_reader *pfile, const char *name)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (!cpp_get_options (pfile)->preprocessed)
|
||||
{
|
||||
error ("pch_preprocess pragma should only be used with -fpreprocessed");
|
||||
inform ("use #include instead");
|
||||
return;
|
||||
}
|
||||
|
||||
fd = open (name, O_RDONLY | O_BINARY, 0666);
|
||||
if (fd == -1)
|
||||
fatal_error ("%s: couldn%'t open PCH file: %m", name);
|
||||
|
||||
if (c_common_valid_pch (pfile, name, fd) != 1)
|
||||
{
|
||||
if (!cpp_get_options (pfile)->warn_invalid_pch)
|
||||
inform ("use -Winvalid-pch for more information");
|
||||
fatal_error ("%s: PCH file was invalid", name);
|
||||
}
|
||||
|
||||
c_common_read_pch (pfile, name, fd, name);
|
||||
|
||||
close (fd);
|
||||
}
|
||||
|
||||
/* Print out executable_checksum[]. */
|
||||
|
||||
void
|
||||
c_common_print_pch_checksum (FILE *f)
|
||||
{
|
||||
int i;
|
||||
fputs ("Compiler executable checksum: ", f);
|
||||
for (i = 0; i < 16; i++)
|
||||
fprintf (f, "%02x", executable_checksum[i]);
|
||||
putc ('\n', f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@ GNU General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "cpplib.h"
|
||||
#include "cpphash.h"
|
||||
#include "../libcpp/internal.h"
|
||||
#include "tree.h"
|
||||
#include "c-common.h" /* For flags. */
|
||||
#include "c-pragma.h" /* For parse_in. */
|
||||
|
|
@ -32,11 +32,11 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
static struct
|
||||
{
|
||||
FILE *outf; /* Stream to write to. */
|
||||
const struct line_map *map; /* Logical to physical line mappings. */
|
||||
const cpp_token *prev; /* Previous token. */
|
||||
const cpp_token *source; /* Source token for spacing. */
|
||||
fileline line; /* Line currently being written. */
|
||||
int src_line; /* Line number currently being written. */
|
||||
unsigned char printed; /* Nonzero if something output at line. */
|
||||
bool first_time; /* pp_file_change hasn't been called yet. */
|
||||
} print;
|
||||
|
||||
/* General output routines. */
|
||||
|
|
@ -45,18 +45,20 @@ static void scan_translation_unit_trad (cpp_reader *);
|
|||
static void account_for_newlines (const unsigned char *, size_t);
|
||||
static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
|
||||
|
||||
static void print_line (const struct line_map *, fileline, const char *);
|
||||
static void maybe_print_line (const struct line_map *, fileline);
|
||||
static void print_line (source_location, const char *);
|
||||
static void maybe_print_line (source_location);
|
||||
|
||||
/* Callback routines for the parser. Most of these are active only
|
||||
in specific modes. */
|
||||
static void cb_line_change (cpp_reader *, const cpp_token *, int);
|
||||
static void cb_define (cpp_reader *, fileline, cpp_hashnode *);
|
||||
static void cb_undef (cpp_reader *, fileline, cpp_hashnode *);
|
||||
static void cb_include (cpp_reader *, fileline, const unsigned char *,
|
||||
const char *, int);
|
||||
static void cb_ident (cpp_reader *, fileline, const cpp_string *);
|
||||
static void cb_def_pragma (cpp_reader *, fileline);
|
||||
static void cb_define (cpp_reader *, source_location, cpp_hashnode *);
|
||||
static void cb_undef (cpp_reader *, source_location, cpp_hashnode *);
|
||||
static void cb_include (cpp_reader *, source_location, const unsigned char *,
|
||||
const char *, int, const cpp_token **);
|
||||
static void cb_ident (cpp_reader *, source_location, const cpp_string *);
|
||||
static void cb_def_pragma (cpp_reader *, source_location);
|
||||
static void cb_read_pch (cpp_reader *pfile, const char *name,
|
||||
int fd, const char *orig_name);
|
||||
|
||||
/* Preprocess and output. */
|
||||
void
|
||||
|
|
@ -106,20 +108,26 @@ init_pp_output (FILE *out_stream)
|
|||
if (flag_dump_includes)
|
||||
cb->include = cb_include;
|
||||
|
||||
if (flag_pch_preprocess)
|
||||
{
|
||||
cb->valid_pch = c_common_valid_pch;
|
||||
cb->read_pch = cb_read_pch;
|
||||
}
|
||||
|
||||
if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
|
||||
{
|
||||
cb->define = cb_define;
|
||||
cb->undef = cb_undef;
|
||||
}
|
||||
|
||||
/* Initialize the print structure. Setting print.line to -1 here is
|
||||
/* Initialize the print structure. Setting print.src_line to -1 here is
|
||||
a trick to guarantee that the first token of the file will cause
|
||||
a linemarker to be output by maybe_print_line. */
|
||||
print.line = (fileline) -1;
|
||||
print.src_line = -1;
|
||||
print.printed = 0;
|
||||
print.prev = 0;
|
||||
print.map = 0;
|
||||
print.outf = out_stream;
|
||||
print.first_time = 1;
|
||||
}
|
||||
|
||||
/* Writes out the preprocessed file, handling spacing and paste
|
||||
|
|
@ -171,13 +179,13 @@ scan_translation_unit (cpp_reader *pfile)
|
|||
}
|
||||
}
|
||||
|
||||
/* Adjust print.line for newlines embedded in output. */
|
||||
/* Adjust print.src_line for newlines embedded in output. */
|
||||
static void
|
||||
account_for_newlines (const unsigned char *str, size_t len)
|
||||
{
|
||||
while (len--)
|
||||
if (*str++ == '\n')
|
||||
print.line++;
|
||||
print.src_line++;
|
||||
}
|
||||
|
||||
/* Writes out a traditionally preprocessed file. */
|
||||
|
|
@ -187,7 +195,7 @@ scan_translation_unit_trad (cpp_reader *pfile)
|
|||
while (_cpp_read_logical_line_trad (pfile))
|
||||
{
|
||||
size_t len = pfile->out.cur - pfile->out.base;
|
||||
maybe_print_line (print.map, pfile->out.first_line);
|
||||
maybe_print_line (pfile->out.first_line);
|
||||
fwrite (pfile->out.base, 1, len, print.outf);
|
||||
print.printed = 1;
|
||||
if (!CPP_OPTION (pfile, discard_comments))
|
||||
|
|
@ -199,52 +207,58 @@ scan_translation_unit_trad (cpp_reader *pfile)
|
|||
different line to the current one, output the required newlines or
|
||||
a line marker, and return 1. Otherwise return 0. */
|
||||
static void
|
||||
maybe_print_line (const struct line_map *map, fileline line)
|
||||
maybe_print_line (source_location src_loc)
|
||||
{
|
||||
const struct line_map *map = linemap_lookup (&line_table, src_loc);
|
||||
int src_line = SOURCE_LINE (map, src_loc);
|
||||
/* End the previous line of text. */
|
||||
if (print.printed)
|
||||
{
|
||||
putc ('\n', print.outf);
|
||||
print.line++;
|
||||
print.src_line++;
|
||||
print.printed = 0;
|
||||
}
|
||||
|
||||
if (line >= print.line && line < print.line + 8)
|
||||
if (src_line >= print.src_line && src_line < print.src_line + 8)
|
||||
{
|
||||
while (line > print.line)
|
||||
while (src_line > print.src_line)
|
||||
{
|
||||
putc ('\n', print.outf);
|
||||
print.line++;
|
||||
print.src_line++;
|
||||
}
|
||||
}
|
||||
else
|
||||
print_line (map, line, "");
|
||||
print_line (src_loc, "");
|
||||
}
|
||||
|
||||
/* Output a line marker for logical line LINE. Special flags are "1"
|
||||
or "2" indicating entering or leaving a file. */
|
||||
static void
|
||||
print_line (const struct line_map *map, fileline line, const char *special_flags)
|
||||
print_line (source_location src_loc, const char *special_flags)
|
||||
{
|
||||
/* End any previous line of text. */
|
||||
if (print.printed)
|
||||
putc ('\n', print.outf);
|
||||
print.printed = 0;
|
||||
|
||||
print.line = line;
|
||||
if (!flag_no_line_commands)
|
||||
{
|
||||
const struct line_map *map = linemap_lookup (&line_table, src_loc);
|
||||
|
||||
size_t to_file_len = strlen (map->to_file);
|
||||
unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
|
||||
unsigned char *to_file_quoted =
|
||||
(unsigned char *) alloca (to_file_len * 4 + 1);
|
||||
unsigned char *p;
|
||||
|
||||
print.src_line = SOURCE_LINE (map, src_loc);
|
||||
|
||||
/* cpp_quote_string does not nul-terminate, so we have to do it
|
||||
ourselves. */
|
||||
p = cpp_quote_string (to_file_quoted,
|
||||
(unsigned char *)map->to_file, to_file_len);
|
||||
(unsigned char *) map->to_file, to_file_len);
|
||||
*p = '\0';
|
||||
fprintf (print.outf, "# %u \"%s\"%s",
|
||||
SOURCE_LINE (map, print.line),
|
||||
print.src_line == 0 ? 1 : print.src_line,
|
||||
to_file_quoted, special_flags);
|
||||
|
||||
if (map->sysp == 2)
|
||||
|
|
@ -262,10 +276,12 @@ static void
|
|||
cb_line_change (cpp_reader *pfile, const cpp_token *token,
|
||||
int parsing_args)
|
||||
{
|
||||
source_location src_loc = token->src_loc;
|
||||
|
||||
if (token->type == CPP_EOF || parsing_args)
|
||||
return;
|
||||
|
||||
maybe_print_line (print.map, token->line);
|
||||
maybe_print_line (src_loc);
|
||||
print.prev = 0;
|
||||
print.source = 0;
|
||||
|
||||
|
|
@ -276,30 +292,28 @@ cb_line_change (cpp_reader *pfile, const cpp_token *token,
|
|||
ought to care. Some things do care; the fault lies with them. */
|
||||
if (!CPP_OPTION (pfile, traditional))
|
||||
{
|
||||
const struct line_map *map = linemap_lookup (&line_table, src_loc);
|
||||
int spaces = SOURCE_COLUMN (map, src_loc) - 2;
|
||||
print.printed = 1;
|
||||
if (token->col > 2)
|
||||
{
|
||||
unsigned int spaces = token->col - 2;
|
||||
|
||||
while (spaces--)
|
||||
putc (' ', print.outf);
|
||||
}
|
||||
while (-- spaces >= 0)
|
||||
putc (' ', print.outf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
|
||||
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
|
||||
const cpp_string *str)
|
||||
{
|
||||
maybe_print_line (print.map, line);
|
||||
maybe_print_line (line);
|
||||
fprintf (print.outf, "#ident %s\n", str->text);
|
||||
print.line++;
|
||||
print.src_line++;
|
||||
}
|
||||
|
||||
static void
|
||||
cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
|
||||
cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node)
|
||||
{
|
||||
maybe_print_line (print.map, line);
|
||||
maybe_print_line (line);
|
||||
fputs ("#define ", print.outf);
|
||||
|
||||
/* 'D' is whole definition; 'N' is name only. */
|
||||
|
|
@ -310,49 +324,64 @@ cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
|
|||
fputs ((const char *) NODE_NAME (node), print.outf);
|
||||
|
||||
putc ('\n', print.outf);
|
||||
print.line++;
|
||||
if (linemap_lookup (&line_table, line)->to_line != 0)
|
||||
print.src_line++;
|
||||
}
|
||||
|
||||
static void
|
||||
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
|
||||
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
|
||||
cpp_hashnode *node)
|
||||
{
|
||||
maybe_print_line (print.map, line);
|
||||
maybe_print_line (line);
|
||||
fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
|
||||
print.line++;
|
||||
print.src_line++;
|
||||
}
|
||||
|
||||
static void
|
||||
cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
|
||||
const unsigned char *dir, const char *header, int angle_brackets)
|
||||
cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
|
||||
const unsigned char *dir, const char *header, int angle_brackets,
|
||||
const cpp_token **comments)
|
||||
{
|
||||
maybe_print_line (print.map, line);
|
||||
maybe_print_line (line);
|
||||
if (angle_brackets)
|
||||
fprintf (print.outf, "#%s <%s>\n", dir, header);
|
||||
fprintf (print.outf, "#%s <%s>", dir, header);
|
||||
else
|
||||
fprintf (print.outf, "#%s \"%s\"\n", dir, header);
|
||||
print.line++;
|
||||
fprintf (print.outf, "#%s \"%s\"", dir, header);
|
||||
|
||||
if (comments != NULL)
|
||||
{
|
||||
while (*comments != NULL)
|
||||
{
|
||||
if ((*comments)->flags & PREV_WHITE)
|
||||
putc (' ', print.outf);
|
||||
cpp_output_token (*comments, print.outf);
|
||||
++comments;
|
||||
}
|
||||
}
|
||||
|
||||
putc ('\n', print.outf);
|
||||
print.src_line++;
|
||||
}
|
||||
|
||||
/* Callback called when -fworking-director and -E to emit working
|
||||
diretory in cpp output file. */
|
||||
directory in cpp output file. */
|
||||
|
||||
void
|
||||
pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
|
||||
{
|
||||
size_t to_file_len = strlen (dir);
|
||||
unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
|
||||
unsigned char *to_file_quoted =
|
||||
(unsigned char *) alloca (to_file_len * 4 + 1);
|
||||
unsigned char *p;
|
||||
|
||||
/* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */
|
||||
/* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */
|
||||
p = cpp_quote_string (to_file_quoted, (unsigned char *) dir, to_file_len);
|
||||
*p = '\0';
|
||||
fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
|
||||
}
|
||||
|
||||
/* The file name, line number or system header flags have changed, as
|
||||
described in MAP. From this point on, the old print.map might be
|
||||
pointing to freed memory, and so must not be dereferenced. */
|
||||
described in MAP. */
|
||||
|
||||
void
|
||||
pp_file_change (const struct line_map *map)
|
||||
|
|
@ -364,38 +393,38 @@ pp_file_change (const struct line_map *map)
|
|||
|
||||
if (map != NULL)
|
||||
{
|
||||
/* First time? */
|
||||
if (print.map == NULL)
|
||||
if (print.first_time)
|
||||
{
|
||||
/* Avoid printing foo.i when the main file is foo.c. */
|
||||
if (!cpp_get_options (parse_in)->preprocessed)
|
||||
print_line (map, map->from_line, flags);
|
||||
print_line (map->start_location, flags);
|
||||
print.first_time = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bring current file to correct line when entering a new file. */
|
||||
if (map->reason == LC_ENTER)
|
||||
maybe_print_line (map - 1, map->from_line - 1);
|
||||
|
||||
{
|
||||
const struct line_map *from = INCLUDED_FROM (&line_table, map);
|
||||
maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
|
||||
}
|
||||
if (map->reason == LC_ENTER)
|
||||
flags = " 1";
|
||||
else if (map->reason == LC_LEAVE)
|
||||
flags = " 2";
|
||||
print_line (map, map->from_line, flags);
|
||||
print_line (map->start_location, flags);
|
||||
}
|
||||
}
|
||||
|
||||
print.map = map;
|
||||
}
|
||||
|
||||
/* Copy a #pragma directive to the preprocessed output. */
|
||||
static void
|
||||
cb_def_pragma (cpp_reader *pfile, fileline line)
|
||||
cb_def_pragma (cpp_reader *pfile, source_location line)
|
||||
{
|
||||
maybe_print_line (print.map, line);
|
||||
maybe_print_line (line);
|
||||
fputs ("#pragma ", print.outf);
|
||||
cpp_output_line (pfile, print.outf);
|
||||
print.line++;
|
||||
print.src_line++;
|
||||
}
|
||||
|
||||
/* Dump out the hash table. */
|
||||
|
|
@ -408,8 +437,22 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
|
|||
fputs ((const char *) cpp_macro_definition (pfile, node),
|
||||
print.outf);
|
||||
putc ('\n', print.outf);
|
||||
print.line++;
|
||||
print.src_line++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load in the PCH file NAME, open on FD. It was originally searched for
|
||||
by ORIG_NAME. Also, print out a #include command so that the PCH
|
||||
file can be loaded when the preprocessed output is compiled. */
|
||||
|
||||
static void
|
||||
cb_read_pch (cpp_reader *pfile, const char *name,
|
||||
int fd, const char *orig_name ATTRIBUTE_UNUSED)
|
||||
{
|
||||
c_common_read_pch (pfile, name, fd, orig_name);
|
||||
|
||||
fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name);
|
||||
print.src_line++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
|
||||
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -34,15 +34,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "c-common.h"
|
||||
#include "output.h"
|
||||
#include "tm_p.h"
|
||||
#include "vec.h"
|
||||
#include "target.h"
|
||||
#include "diagnostic.h"
|
||||
#include "opts.h"
|
||||
|
||||
#define GCC_BAD(msgid) do { warning (msgid); return; } while (0)
|
||||
#define GCC_BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0)
|
||||
#define GCC_BAD(gmsgid) \
|
||||
do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
|
||||
#define GCC_BAD2(gmsgid, arg) \
|
||||
do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0)
|
||||
|
||||
typedef struct align_stack GTY(())
|
||||
{
|
||||
int alignment;
|
||||
unsigned int num_pushes;
|
||||
tree id;
|
||||
int alignment;
|
||||
tree id;
|
||||
struct align_stack * prev;
|
||||
} align_stack;
|
||||
|
||||
|
|
@ -53,13 +58,14 @@ static void handle_pragma_pack (cpp_reader *);
|
|||
|
||||
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
|
||||
/* If we have a "global" #pragma pack(<n>) in effect when the first
|
||||
#pragma pack(push,<n>) is encountered, this stores the value of
|
||||
maximum_field_alignment in effect. When the final pop_alignment()
|
||||
#pragma pack(push,<n>) is encountered, this stores the value of
|
||||
maximum_field_alignment in effect. When the final pop_alignment()
|
||||
happens, we restore the value to this, not to a value of 0 for
|
||||
maximum_field_alignment. Value is in bits. */
|
||||
static int default_alignment;
|
||||
#define SET_GLOBAL_ALIGNMENT(ALIGN) \
|
||||
(default_alignment = maximum_field_alignment = (ALIGN))
|
||||
#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = *(alignment_stack == NULL \
|
||||
? &default_alignment \
|
||||
: &alignment_stack->alignment) = (ALIGN))
|
||||
|
||||
static void push_alignment (int, tree);
|
||||
static void pop_alignment (tree);
|
||||
|
|
@ -68,31 +74,23 @@ static void pop_alignment (tree);
|
|||
static void
|
||||
push_alignment (int alignment, tree id)
|
||||
{
|
||||
if (alignment_stack == NULL
|
||||
|| alignment_stack->alignment != alignment
|
||||
|| id != NULL_TREE)
|
||||
{
|
||||
align_stack * entry;
|
||||
align_stack * entry;
|
||||
|
||||
entry = ggc_alloc (sizeof (* entry));
|
||||
entry = GGC_NEW (align_stack);
|
||||
|
||||
entry->alignment = alignment;
|
||||
entry->num_pushes = 1;
|
||||
entry->id = id;
|
||||
entry->prev = alignment_stack;
|
||||
|
||||
/* The current value of maximum_field_alignment is not necessarily
|
||||
0 since there may be a #pragma pack(<n>) in effect; remember it
|
||||
so that we can restore it after the final #pragma pop(). */
|
||||
if (alignment_stack == NULL)
|
||||
default_alignment = maximum_field_alignment;
|
||||
|
||||
alignment_stack = entry;
|
||||
entry->alignment = alignment;
|
||||
entry->id = id;
|
||||
entry->prev = alignment_stack;
|
||||
|
||||
maximum_field_alignment = alignment;
|
||||
}
|
||||
else
|
||||
alignment_stack->num_pushes ++;
|
||||
/* The current value of maximum_field_alignment is not necessarily
|
||||
0 since there may be a #pragma pack(<n>) in effect; remember it
|
||||
so that we can restore it after the final #pragma pop(). */
|
||||
if (alignment_stack == NULL)
|
||||
default_alignment = maximum_field_alignment;
|
||||
|
||||
alignment_stack = entry;
|
||||
|
||||
maximum_field_alignment = alignment;
|
||||
}
|
||||
|
||||
/* Undo a push of an alignment onto the stack. */
|
||||
|
|
@ -100,14 +98,9 @@ static void
|
|||
pop_alignment (tree id)
|
||||
{
|
||||
align_stack * entry;
|
||||
|
||||
|
||||
if (alignment_stack == NULL)
|
||||
{
|
||||
warning ("\
|
||||
#pragma pack (pop) encountered without matching #pragma pack (push, <n>)"
|
||||
);
|
||||
return;
|
||||
}
|
||||
GCC_BAD ("#pragma pack (pop) encountered without matching #pragma pack (push)");
|
||||
|
||||
/* If we got an identifier, strip away everything above the target
|
||||
entry so that the next step will restore the state just below it. */
|
||||
|
|
@ -116,73 +109,70 @@ pop_alignment (tree id)
|
|||
for (entry = alignment_stack; entry; entry = entry->prev)
|
||||
if (entry->id == id)
|
||||
{
|
||||
entry->num_pushes = 1;
|
||||
alignment_stack = entry;
|
||||
break;
|
||||
}
|
||||
if (entry == NULL)
|
||||
warning ("\
|
||||
#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, <n>)"
|
||||
warning (OPT_Wpragmas, "\
|
||||
#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s)"
|
||||
, IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id));
|
||||
}
|
||||
|
||||
if (-- alignment_stack->num_pushes == 0)
|
||||
{
|
||||
entry = alignment_stack->prev;
|
||||
entry = alignment_stack->prev;
|
||||
|
||||
if (entry == NULL)
|
||||
maximum_field_alignment = default_alignment;
|
||||
else
|
||||
maximum_field_alignment = entry->alignment;
|
||||
maximum_field_alignment = entry ? entry->alignment : default_alignment;
|
||||
|
||||
alignment_stack = entry;
|
||||
}
|
||||
alignment_stack = entry;
|
||||
}
|
||||
#else /* not HANDLE_PRAGMA_PACK_PUSH_POP */
|
||||
#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
|
||||
#define push_alignment(ID, N) \
|
||||
GCC_BAD("#pragma pack(push[, id], <n>) is not supported on this target")
|
||||
GCC_BAD ("#pragma pack(push[, id], <n>) is not supported on this target")
|
||||
#define pop_alignment(ID) \
|
||||
GCC_BAD("#pragma pack(pop[, id], <n>) is not supported on this target")
|
||||
GCC_BAD ("#pragma pack(pop[, id], <n>) is not supported on this target")
|
||||
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
|
||||
|
||||
/* #pragma pack ()
|
||||
#pragma pack (N)
|
||||
|
||||
|
||||
#pragma pack (push)
|
||||
#pragma pack (push, N)
|
||||
#pragma pack (push, ID)
|
||||
#pragma pack (push, ID, N)
|
||||
#pragma pack (pop)
|
||||
#pragma pack (pop, ID) */
|
||||
static void
|
||||
handle_pragma_pack (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
||||
handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
|
||||
{
|
||||
tree x, id = 0;
|
||||
int align = -1;
|
||||
enum cpp_ttype token;
|
||||
enum { set, push, pop } action;
|
||||
|
||||
if (c_lex (&x) != CPP_OPEN_PAREN)
|
||||
GCC_BAD ("missing '(' after '#pragma pack' - ignored");
|
||||
if (pragma_lex (&x) != CPP_OPEN_PAREN)
|
||||
GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored");
|
||||
|
||||
token = c_lex (&x);
|
||||
token = pragma_lex (&x);
|
||||
if (token == CPP_CLOSE_PAREN)
|
||||
{
|
||||
action = set;
|
||||
align = 0;
|
||||
align = initial_max_fld_align;
|
||||
}
|
||||
else if (token == CPP_NUMBER)
|
||||
{
|
||||
if (TREE_CODE (x) != INTEGER_CST)
|
||||
GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
|
||||
align = TREE_INT_CST_LOW (x);
|
||||
action = set;
|
||||
if (c_lex (&x) != CPP_CLOSE_PAREN)
|
||||
GCC_BAD ("malformed '#pragma pack' - ignored");
|
||||
if (pragma_lex (&x) != CPP_CLOSE_PAREN)
|
||||
GCC_BAD ("malformed %<#pragma pack%> - ignored");
|
||||
}
|
||||
else if (token == CPP_NAME)
|
||||
{
|
||||
#define GCC_BAD_ACTION do { if (action == push) \
|
||||
GCC_BAD ("malformed '#pragma pack(push[, id], <n>)' - ignored"); \
|
||||
#define GCC_BAD_ACTION do { if (action != pop) \
|
||||
GCC_BAD ("malformed %<#pragma pack(push[, id][, <n>])%> - ignored"); \
|
||||
else \
|
||||
GCC_BAD ("malformed '#pragma pack(pop[, id])' - ignored"); \
|
||||
GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \
|
||||
} while (0)
|
||||
|
||||
const char *op = IDENTIFIER_POINTER (x);
|
||||
|
|
@ -191,33 +181,25 @@ handle_pragma_pack (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
|||
else if (!strcmp (op, "pop"))
|
||||
action = pop;
|
||||
else
|
||||
GCC_BAD2 ("unknown action '%s' for '#pragma pack' - ignored", op);
|
||||
GCC_BAD2 ("unknown action %qs for %<#pragma pack%> - ignored", op);
|
||||
|
||||
token = c_lex (&x);
|
||||
if (token != CPP_COMMA && action == push)
|
||||
GCC_BAD_ACTION;
|
||||
|
||||
if (token == CPP_COMMA)
|
||||
while ((token = pragma_lex (&x)) == CPP_COMMA)
|
||||
{
|
||||
token = c_lex (&x);
|
||||
if (token == CPP_NAME)
|
||||
token = pragma_lex (&x);
|
||||
if (token == CPP_NAME && id == 0)
|
||||
{
|
||||
id = x;
|
||||
if (action == push && c_lex (&x) != CPP_COMMA)
|
||||
GCC_BAD_ACTION;
|
||||
token = c_lex (&x);
|
||||
}
|
||||
|
||||
if (action == push)
|
||||
else if (token == CPP_NUMBER && action == push && align == -1)
|
||||
{
|
||||
if (token == CPP_NUMBER)
|
||||
{
|
||||
align = TREE_INT_CST_LOW (x);
|
||||
token = c_lex (&x);
|
||||
}
|
||||
else
|
||||
GCC_BAD_ACTION;
|
||||
if (TREE_CODE (x) != INTEGER_CST)
|
||||
GCC_BAD ("invalid constant in %<#pragma pack%> - ignored");
|
||||
align = TREE_INT_CST_LOW (x);
|
||||
if (align == -1)
|
||||
action = set;
|
||||
}
|
||||
else
|
||||
GCC_BAD_ACTION;
|
||||
}
|
||||
|
||||
if (token != CPP_CLOSE_PAREN)
|
||||
|
|
@ -225,10 +207,13 @@ handle_pragma_pack (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
|||
#undef GCC_BAD_ACTION
|
||||
}
|
||||
else
|
||||
GCC_BAD ("malformed '#pragma pack' - ignored");
|
||||
GCC_BAD ("malformed %<#pragma pack%> - ignored");
|
||||
|
||||
if (c_lex (&x) != CPP_EOF)
|
||||
warning ("junk at end of '#pragma pack'");
|
||||
if (pragma_lex (&x) != CPP_EOF)
|
||||
warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>");
|
||||
|
||||
if (flag_pack_struct)
|
||||
GCC_BAD ("#pragma pack has no effect with -fpack-struct - ignored");
|
||||
|
||||
if (action != pop)
|
||||
switch (align)
|
||||
|
|
@ -241,6 +226,12 @@ handle_pragma_pack (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
|||
case 16:
|
||||
align *= BITS_PER_UNIT;
|
||||
break;
|
||||
case -1:
|
||||
if (action == push)
|
||||
{
|
||||
align = maximum_field_alignment;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GCC_BAD2 ("alignment must be a small power of two, not %d", align);
|
||||
}
|
||||
|
|
@ -249,7 +240,7 @@ handle_pragma_pack (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
|||
{
|
||||
case set: SET_GLOBAL_ALIGNMENT (align); break;
|
||||
case push: push_alignment (align, id); break;
|
||||
case pop: pop_alignment (id); break;
|
||||
case pop: pop_alignment (id); break;
|
||||
}
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_PACK */
|
||||
|
|
@ -275,8 +266,8 @@ apply_pragma_weak (tree decl, tree value)
|
|||
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
|
||||
&& !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */
|
||||
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
|
||||
warning ("%Japplying #pragma weak '%D' after first use results "
|
||||
"in unspecified behavior", decl, decl);
|
||||
warning (OPT_Wpragmas, "applying #pragma weak %q+D after first use "
|
||||
"results in unspecified behavior", decl);
|
||||
|
||||
declare_weak (decl);
|
||||
}
|
||||
|
|
@ -297,7 +288,7 @@ maybe_apply_pragma_weak (tree decl)
|
|||
return;
|
||||
/* If it's not a function or a variable, it can't be weak.
|
||||
FIXME: what kinds of things are visible outside this file but
|
||||
aren't functions or variables? Should this be an abort() instead? */
|
||||
aren't functions or variables? Should this be an assert instead? */
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
|
||||
return;
|
||||
|
||||
|
|
@ -312,29 +303,56 @@ maybe_apply_pragma_weak (tree decl)
|
|||
}
|
||||
}
|
||||
|
||||
/* Process all "#pragma weak A = B" directives where we have not seen
|
||||
a decl for A. */
|
||||
void
|
||||
maybe_apply_pending_pragma_weaks (void)
|
||||
{
|
||||
tree *p, t, alias_id, id, decl, *next;
|
||||
|
||||
for (p = &pending_weaks; (t = *p) ; p = next)
|
||||
{
|
||||
next = &TREE_CHAIN (t);
|
||||
alias_id = TREE_PURPOSE (t);
|
||||
id = TREE_VALUE (t);
|
||||
|
||||
if (TREE_VALUE (t) == NULL)
|
||||
continue;
|
||||
|
||||
decl = build_decl (FUNCTION_DECL, alias_id, default_function_type);
|
||||
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
DECL_WEAK (decl) = 1;
|
||||
|
||||
assemble_alias (decl, id);
|
||||
}
|
||||
}
|
||||
|
||||
/* #pragma weak name [= value] */
|
||||
static void
|
||||
handle_pragma_weak (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
||||
handle_pragma_weak (cpp_reader * ARG_UNUSED (dummy))
|
||||
{
|
||||
tree name, value, x, decl;
|
||||
enum cpp_ttype t;
|
||||
|
||||
value = 0;
|
||||
|
||||
if (c_lex (&name) != CPP_NAME)
|
||||
if (pragma_lex (&name) != CPP_NAME)
|
||||
GCC_BAD ("malformed #pragma weak, ignored");
|
||||
t = c_lex (&x);
|
||||
t = pragma_lex (&x);
|
||||
if (t == CPP_EQ)
|
||||
{
|
||||
if (c_lex (&value) != CPP_NAME)
|
||||
if (pragma_lex (&value) != CPP_NAME)
|
||||
GCC_BAD ("malformed #pragma weak, ignored");
|
||||
t = c_lex (&x);
|
||||
t = pragma_lex (&x);
|
||||
}
|
||||
if (t != CPP_EOF)
|
||||
warning ("junk at end of #pragma weak");
|
||||
warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>");
|
||||
|
||||
decl = identifier_global_value (name);
|
||||
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
|
||||
if (decl && DECL_P (decl))
|
||||
{
|
||||
apply_pragma_weak (decl, value);
|
||||
if (value)
|
||||
|
|
@ -345,83 +363,142 @@ handle_pragma_weak (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
|||
}
|
||||
#else
|
||||
void
|
||||
maybe_apply_pragma_weak (tree decl ATTRIBUTE_UNUSED)
|
||||
maybe_apply_pragma_weak (tree ARG_UNUSED (decl))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
maybe_apply_pending_pragma_weaks (void)
|
||||
{
|
||||
}
|
||||
#endif /* HANDLE_PRAGMA_WEAK */
|
||||
|
||||
/* GCC supports two #pragma directives for renaming the external
|
||||
symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
|
||||
compatibility with the Solaris and Tru64 system headers. GCC also
|
||||
has its own notation for this, __asm__("name") annotations.
|
||||
|
||||
Corner cases of these features and their interaction:
|
||||
|
||||
1) Both pragmas silently apply only to declarations with external
|
||||
linkage (that is, TREE_PUBLIC || DECL_EXTERNAL). Asm labels
|
||||
do not have this restriction.
|
||||
|
||||
2) In C++, both #pragmas silently apply only to extern "C" declarations.
|
||||
Asm labels do not have this restriction.
|
||||
|
||||
3) If any of the three ways of changing DECL_ASSEMBLER_NAME is
|
||||
applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the
|
||||
new name is different, a warning issues and the name does not change.
|
||||
|
||||
4) The "source name" for #pragma redefine_extname is the DECL_NAME,
|
||||
*not* the DECL_ASSEMBLER_NAME.
|
||||
|
||||
5) If #pragma extern_prefix is in effect and a declaration occurs
|
||||
with an __asm__ name, the #pragma extern_prefix is silently
|
||||
ignored for that declaration.
|
||||
|
||||
6) If #pragma extern_prefix and #pragma redefine_extname apply to
|
||||
the same declaration, whichever triggered first wins, and a warning
|
||||
is issued. (We would like to have #pragma redefine_extname always
|
||||
win, but it can appear either before or after the declaration, and
|
||||
if it appears afterward, we have no way of knowing whether a modified
|
||||
DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */
|
||||
|
||||
static GTY(()) tree pending_redefine_extname;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
static void handle_pragma_redefine_extname (cpp_reader *);
|
||||
|
||||
/* #pragma redefined_extname oldname newname */
|
||||
/* #pragma redefine_extname oldname newname */
|
||||
static void
|
||||
handle_pragma_redefine_extname (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
||||
handle_pragma_redefine_extname (cpp_reader * ARG_UNUSED (dummy))
|
||||
{
|
||||
tree oldname, newname, decl, x;
|
||||
enum cpp_ttype t;
|
||||
|
||||
if (c_lex (&oldname) != CPP_NAME)
|
||||
{
|
||||
warning ("malformed #pragma redefine_extname, ignored");
|
||||
return;
|
||||
}
|
||||
if (c_lex (&newname) != CPP_NAME)
|
||||
{
|
||||
warning ("malformed #pragma redefine_extname, ignored");
|
||||
return;
|
||||
}
|
||||
t = c_lex (&x);
|
||||
if (pragma_lex (&oldname) != CPP_NAME)
|
||||
GCC_BAD ("malformed #pragma redefine_extname, ignored");
|
||||
if (pragma_lex (&newname) != CPP_NAME)
|
||||
GCC_BAD ("malformed #pragma redefine_extname, ignored");
|
||||
t = pragma_lex (&x);
|
||||
if (t != CPP_EOF)
|
||||
warning ("junk at end of #pragma redefine_extname");
|
||||
warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>");
|
||||
|
||||
if (!flag_mudflap && !targetm.handle_pragma_redefine_extname)
|
||||
{
|
||||
if (warn_unknown_pragmas > in_system_header)
|
||||
warning (OPT_Wunknown_pragmas,
|
||||
"#pragma redefine_extname not supported on this target");
|
||||
return;
|
||||
}
|
||||
|
||||
decl = identifier_global_value (oldname);
|
||||
if (decl && (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| TREE_CODE (decl) == VAR_DECL))
|
||||
if (decl
|
||||
&& (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
|
||||
&& (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| TREE_CODE (decl) == VAR_DECL)
|
||||
&& has_c_linkage (decl))
|
||||
{
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (decl)
|
||||
&& DECL_ASSEMBLER_NAME (decl) != newname)
|
||||
warning ("#pragma redefine_extname conflicts with declaration");
|
||||
change_decl_assembler_name (decl, newname);
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (decl))
|
||||
{
|
||||
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
name = targetm.strip_name_encoding (name);
|
||||
|
||||
if (strcmp (name, IDENTIFIER_POINTER (newname)))
|
||||
warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
|
||||
"conflict with previous rename");
|
||||
}
|
||||
else
|
||||
change_decl_assembler_name (decl, newname);
|
||||
}
|
||||
else
|
||||
add_to_renaming_pragma_list(oldname, newname);
|
||||
/* We have to add this to the rename list even if there's already
|
||||
a global value that doesn't meet the above criteria, because in
|
||||
C++ "struct foo {...};" puts "foo" in the current namespace but
|
||||
does *not* conflict with a subsequent declaration of a function
|
||||
or variable foo. See g++.dg/other/pragma-re-2.C. */
|
||||
add_to_renaming_pragma_list (oldname, newname);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is called from here and from ia64.c. */
|
||||
void
|
||||
add_to_renaming_pragma_list (tree oldname, tree newname)
|
||||
{
|
||||
tree previous = purpose_member (oldname, pending_redefine_extname);
|
||||
if (previous)
|
||||
{
|
||||
if (TREE_VALUE (previous) != newname)
|
||||
warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
|
||||
"conflict with previous #pragma redefine_extname");
|
||||
return;
|
||||
}
|
||||
|
||||
pending_redefine_extname
|
||||
= tree_cons (oldname, newname, pending_redefine_extname);
|
||||
}
|
||||
|
||||
static GTY(()) tree pragma_extern_prefix;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
static void handle_pragma_extern_prefix (cpp_reader *);
|
||||
|
||||
/* #pragma extern_prefix "prefix" */
|
||||
static void
|
||||
handle_pragma_extern_prefix (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
||||
handle_pragma_extern_prefix (cpp_reader * ARG_UNUSED (dummy))
|
||||
{
|
||||
tree prefix, x;
|
||||
enum cpp_ttype t;
|
||||
|
||||
if (c_lex (&prefix) != CPP_STRING)
|
||||
{
|
||||
warning ("malformed #pragma extern_prefix, ignored");
|
||||
return;
|
||||
}
|
||||
t = c_lex (&x);
|
||||
if (pragma_lex (&prefix) != CPP_STRING)
|
||||
GCC_BAD ("malformed #pragma extern_prefix, ignored");
|
||||
t = pragma_lex (&x);
|
||||
if (t != CPP_EOF)
|
||||
warning ("junk at end of #pragma extern_prefix");
|
||||
warning (OPT_Wpragmas, "junk at end of %<#pragma extern_prefix%>");
|
||||
|
||||
/* Note that the length includes the null terminator. */
|
||||
pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
|
||||
if (targetm.handle_pragma_extern_prefix)
|
||||
/* Note that the length includes the null terminator. */
|
||||
pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
|
||||
else if (warn_unknown_pragmas > in_system_header)
|
||||
warning (OPT_Wunknown_pragmas,
|
||||
"#pragma extern_prefix not supported on this target");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Hook from the front ends to apply the results of one of the preceding
|
||||
pragmas that rename variables. */
|
||||
|
|
@ -429,83 +506,330 @@ handle_pragma_extern_prefix (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
|||
tree
|
||||
maybe_apply_renaming_pragma (tree decl, tree asmname)
|
||||
{
|
||||
tree oldname;
|
||||
tree *p, t;
|
||||
|
||||
/* Copied from the check in set_decl_assembler_name. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
|| (TREE_CODE (decl) == VAR_DECL
|
||||
&& (TREE_STATIC (decl)
|
||||
|| DECL_EXTERNAL (decl)
|
||||
|| TREE_PUBLIC (decl))))
|
||||
oldname = DECL_ASSEMBLER_NAME (decl);
|
||||
else
|
||||
/* The renaming pragmas are only applied to declarations with
|
||||
external linkage. */
|
||||
if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
|
||||
|| (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
|
||||
|| !has_c_linkage (decl))
|
||||
return asmname;
|
||||
|
||||
/* If the name begins with a *, that's a sign of an asmname attached to
|
||||
a previous declaration. */
|
||||
if (IDENTIFIER_POINTER (oldname)[0] == '*')
|
||||
/* If the DECL_ASSEMBLER_NAME is already set, it does not change,
|
||||
but we may warn about a rename that conflicts. */
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (decl))
|
||||
{
|
||||
const char *oldasmname = IDENTIFIER_POINTER (oldname) + 1;
|
||||
if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldasmname) != 0)
|
||||
warning ("asm declaration conflicts with previous rename");
|
||||
asmname = build_string (strlen (oldasmname), oldasmname);
|
||||
const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
oldname = targetm.strip_name_encoding (oldname);
|
||||
|
||||
if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
|
||||
warning (OPT_Wpragmas, "asm declaration ignored due to "
|
||||
"conflict with previous rename");
|
||||
|
||||
/* Take any pending redefine_extname off the list. */
|
||||
for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
|
||||
if (DECL_NAME (decl) == TREE_PURPOSE (t))
|
||||
{
|
||||
/* Only warn if there is a conflict. */
|
||||
if (strcmp (IDENTIFIER_POINTER (TREE_VALUE (t)), oldname))
|
||||
warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
|
||||
"conflict with previous rename");
|
||||
|
||||
*p = TREE_CHAIN (t);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
tree *p, t;
|
||||
/* Find out if we have a pending #pragma redefine_extname. */
|
||||
for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
|
||||
if (DECL_NAME (decl) == TREE_PURPOSE (t))
|
||||
{
|
||||
tree newname = TREE_VALUE (t);
|
||||
*p = TREE_CHAIN (t);
|
||||
|
||||
for (p = &pending_redefine_extname; (t = *p) ; p = &TREE_CHAIN (t))
|
||||
if (oldname == TREE_PURPOSE (t))
|
||||
{
|
||||
const char *newname = IDENTIFIER_POINTER (TREE_VALUE (t));
|
||||
/* If we already have an asmname, #pragma redefine_extname is
|
||||
ignored (with a warning if it conflicts). */
|
||||
if (asmname)
|
||||
{
|
||||
if (strcmp (TREE_STRING_POINTER (asmname),
|
||||
IDENTIFIER_POINTER (newname)) != 0)
|
||||
warning (OPT_Wpragmas, "#pragma redefine_extname ignored due to "
|
||||
"conflict with __asm__ declaration");
|
||||
return asmname;
|
||||
}
|
||||
|
||||
if (asmname && strcmp (TREE_STRING_POINTER (asmname), newname) != 0)
|
||||
warning ("#pragma redefine_extname conflicts with declaration");
|
||||
*p = TREE_CHAIN (t);
|
||||
/* Otherwise we use what we've got; #pragma extern_prefix is
|
||||
silently ignored. */
|
||||
return build_string (IDENTIFIER_LENGTH (newname),
|
||||
IDENTIFIER_POINTER (newname));
|
||||
}
|
||||
|
||||
return build_string (strlen (newname), newname);
|
||||
}
|
||||
}
|
||||
/* If we've got an asmname, #pragma extern_prefix is silently ignored. */
|
||||
if (asmname)
|
||||
return asmname;
|
||||
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
if (pragma_extern_prefix && !asmname)
|
||||
/* If #pragma extern_prefix is in effect, apply it. */
|
||||
if (pragma_extern_prefix)
|
||||
{
|
||||
char *x = concat (TREE_STRING_POINTER (pragma_extern_prefix),
|
||||
IDENTIFIER_POINTER (oldname), NULL);
|
||||
asmname = build_string (strlen (x), x);
|
||||
free (x);
|
||||
return asmname;
|
||||
}
|
||||
#endif
|
||||
const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
|
||||
size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
|
||||
|
||||
return asmname;
|
||||
const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
|
||||
size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
|
||||
|
||||
char *newname = (char *) alloca (plen + ilen + 1);
|
||||
|
||||
memcpy (newname, prefix, plen);
|
||||
memcpy (newname + plen, id, ilen + 1);
|
||||
|
||||
return build_string (plen + ilen, newname);
|
||||
}
|
||||
|
||||
/* Nada. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Front-end wrapper for pragma registration to avoid dragging
|
||||
cpplib.h in almost everywhere. */
|
||||
|
||||
#ifdef HANDLE_PRAGMA_VISIBILITY
|
||||
static void handle_pragma_visibility (cpp_reader *);
|
||||
|
||||
typedef enum symbol_visibility visibility;
|
||||
DEF_VEC_I (visibility);
|
||||
DEF_VEC_ALLOC_I (visibility, heap);
|
||||
static VEC (visibility, heap) *visstack;
|
||||
|
||||
/* Push the visibility indicated by STR onto the top of the #pragma
|
||||
visibility stack. */
|
||||
|
||||
void
|
||||
c_register_pragma (const char *space, const char *name,
|
||||
void (*handler) (struct cpp_reader *))
|
||||
push_visibility (const char *str)
|
||||
{
|
||||
cpp_register_pragma (parse_in, space, name, handler);
|
||||
VEC_safe_push (visibility, heap, visstack,
|
||||
default_visibility);
|
||||
if (!strcmp (str, "default"))
|
||||
default_visibility = VISIBILITY_DEFAULT;
|
||||
else if (!strcmp (str, "internal"))
|
||||
default_visibility = VISIBILITY_INTERNAL;
|
||||
else if (!strcmp (str, "hidden"))
|
||||
default_visibility = VISIBILITY_HIDDEN;
|
||||
else if (!strcmp (str, "protected"))
|
||||
default_visibility = VISIBILITY_PROTECTED;
|
||||
else
|
||||
GCC_BAD ("#pragma GCC visibility push() must specify default, internal, hidden or protected");
|
||||
visibility_options.inpragma = 1;
|
||||
}
|
||||
|
||||
/* Pop a level of the #pragma visibility stack. */
|
||||
|
||||
void
|
||||
pop_visibility (void)
|
||||
{
|
||||
default_visibility = VEC_pop (visibility, visstack);
|
||||
visibility_options.inpragma
|
||||
= VEC_length (visibility, visstack) != 0;
|
||||
}
|
||||
|
||||
/* Sets the default visibility for symbols to something other than that
|
||||
specified on the command line. */
|
||||
|
||||
static void
|
||||
handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Form is #pragma GCC visibility push(hidden)|pop */
|
||||
tree x;
|
||||
enum cpp_ttype token;
|
||||
enum { bad, push, pop } action = bad;
|
||||
|
||||
token = pragma_lex (&x);
|
||||
if (token == CPP_NAME)
|
||||
{
|
||||
const char *op = IDENTIFIER_POINTER (x);
|
||||
if (!strcmp (op, "push"))
|
||||
action = push;
|
||||
else if (!strcmp (op, "pop"))
|
||||
action = pop;
|
||||
}
|
||||
if (bad == action)
|
||||
GCC_BAD ("#pragma GCC visibility must be followed by push or pop");
|
||||
else
|
||||
{
|
||||
if (pop == action)
|
||||
{
|
||||
if (!VEC_length (visibility, visstack))
|
||||
GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>");
|
||||
else
|
||||
pop_visibility ();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pragma_lex (&x) != CPP_OPEN_PAREN)
|
||||
GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
|
||||
token = pragma_lex (&x);
|
||||
if (token != CPP_NAME)
|
||||
GCC_BAD ("malformed #pragma GCC visibility push");
|
||||
else
|
||||
push_visibility (IDENTIFIER_POINTER (x));
|
||||
if (pragma_lex (&x) != CPP_CLOSE_PAREN)
|
||||
GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored");
|
||||
}
|
||||
}
|
||||
if (pragma_lex (&x) != CPP_EOF)
|
||||
warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
|
||||
{
|
||||
const char *kind_string, *option_string;
|
||||
unsigned int option_index;
|
||||
enum cpp_ttype token;
|
||||
diagnostic_t kind;
|
||||
tree x;
|
||||
|
||||
if (cfun)
|
||||
{
|
||||
error ("#pragma GCC diagnostic not allowed inside functions");
|
||||
return;
|
||||
}
|
||||
|
||||
token = pragma_lex (&x);
|
||||
if (token != CPP_NAME)
|
||||
GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
|
||||
kind_string = IDENTIFIER_POINTER (x);
|
||||
if (strcmp (kind_string, "error") == 0)
|
||||
kind = DK_ERROR;
|
||||
else if (strcmp (kind_string, "warning") == 0)
|
||||
kind = DK_WARNING;
|
||||
else if (strcmp (kind_string, "ignored") == 0)
|
||||
kind = DK_IGNORED;
|
||||
else
|
||||
GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>");
|
||||
|
||||
token = pragma_lex (&x);
|
||||
if (token != CPP_STRING)
|
||||
GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
|
||||
option_string = TREE_STRING_POINTER (x);
|
||||
for (option_index = 0; option_index < cl_options_count; option_index++)
|
||||
if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
|
||||
{
|
||||
/* This overrides -Werror, for example. */
|
||||
diagnostic_classify_diagnostic (global_dc, option_index, kind);
|
||||
/* This makes sure the option is enabled, like -Wfoo would do. */
|
||||
if (cl_options[option_index].var_type == CLVC_BOOLEAN
|
||||
&& cl_options[option_index].flag_var
|
||||
&& kind != DK_IGNORED)
|
||||
*(int *) cl_options[option_index].flag_var = 1;
|
||||
return;
|
||||
}
|
||||
GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
|
||||
}
|
||||
|
||||
/* A vector of registered pragma callbacks. */
|
||||
|
||||
DEF_VEC_O (pragma_handler);
|
||||
DEF_VEC_ALLOC_O (pragma_handler, heap);
|
||||
|
||||
static VEC(pragma_handler, heap) *registered_pragmas;
|
||||
|
||||
/* Front-end wrappers for pragma registration to avoid dragging
|
||||
cpplib.h in almost everywhere. */
|
||||
|
||||
static void
|
||||
c_register_pragma_1 (const char *space, const char *name,
|
||||
pragma_handler handler, bool allow_expansion)
|
||||
{
|
||||
unsigned id;
|
||||
|
||||
VEC_safe_push (pragma_handler, heap, registered_pragmas, &handler);
|
||||
id = VEC_length (pragma_handler, registered_pragmas);
|
||||
id += PRAGMA_FIRST_EXTERNAL - 1;
|
||||
|
||||
/* The C++ front end allocates 6 bits in cp_token; the C front end
|
||||
allocates 7 bits in c_token. At present this is sufficient. */
|
||||
gcc_assert (id < 64);
|
||||
|
||||
cpp_register_deferred_pragma (parse_in, space, name, id,
|
||||
allow_expansion, false);
|
||||
}
|
||||
|
||||
void
|
||||
c_register_pragma (const char *space, const char *name, pragma_handler handler)
|
||||
{
|
||||
c_register_pragma_1 (space, name, handler, false);
|
||||
}
|
||||
|
||||
void
|
||||
c_register_pragma_with_expansion (const char *space, const char *name,
|
||||
pragma_handler handler)
|
||||
{
|
||||
c_register_pragma_1 (space, name, handler, true);
|
||||
}
|
||||
|
||||
void
|
||||
c_invoke_pragma_handler (unsigned int id)
|
||||
{
|
||||
pragma_handler handler;
|
||||
|
||||
id -= PRAGMA_FIRST_EXTERNAL;
|
||||
handler = *VEC_index (pragma_handler, registered_pragmas, id);
|
||||
|
||||
handler (parse_in);
|
||||
}
|
||||
|
||||
/* Set up front-end pragmas. */
|
||||
void
|
||||
init_pragma (void)
|
||||
{
|
||||
if (flag_openmp && !flag_preprocess_only)
|
||||
{
|
||||
struct omp_pragma_def { const char *name; unsigned int id; };
|
||||
static const struct omp_pragma_def omp_pragmas[] = {
|
||||
{ "atomic", PRAGMA_OMP_ATOMIC },
|
||||
{ "barrier", PRAGMA_OMP_BARRIER },
|
||||
{ "critical", PRAGMA_OMP_CRITICAL },
|
||||
{ "flush", PRAGMA_OMP_FLUSH },
|
||||
{ "for", PRAGMA_OMP_FOR },
|
||||
{ "master", PRAGMA_OMP_MASTER },
|
||||
{ "ordered", PRAGMA_OMP_ORDERED },
|
||||
{ "parallel", PRAGMA_OMP_PARALLEL },
|
||||
{ "section", PRAGMA_OMP_SECTION },
|
||||
{ "sections", PRAGMA_OMP_SECTIONS },
|
||||
{ "single", PRAGMA_OMP_SINGLE },
|
||||
{ "threadprivate", PRAGMA_OMP_THREADPRIVATE }
|
||||
};
|
||||
|
||||
const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_omp_pragmas; ++i)
|
||||
cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
|
||||
omp_pragmas[i].id, true, true);
|
||||
}
|
||||
|
||||
cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
|
||||
PRAGMA_GCC_PCH_PREPROCESS, false, false);
|
||||
|
||||
#ifdef HANDLE_PRAGMA_PACK
|
||||
#ifdef HANDLE_PRAGMA_PACK_WITH_EXPANSION
|
||||
c_register_pragma_with_expansion (0, "pack", handle_pragma_pack);
|
||||
#else
|
||||
c_register_pragma (0, "pack", handle_pragma_pack);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
c_register_pragma (0, "weak", handle_pragma_weak);
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
|
||||
c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
|
||||
#ifdef HANDLE_PRAGMA_VISIBILITY
|
||||
c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
|
||||
#endif
|
||||
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
|
||||
|
||||
c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
|
||||
|
||||
c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
|
||||
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
|
||||
#endif
|
||||
|
||||
#ifdef REGISTER_TARGET_PRAGMAS
|
||||
REGISTER_TARGET_PRAGMAS ();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Pragma related interfaces.
|
||||
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,12 +16,39 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_C_PRAGMA_H
|
||||
#define GCC_C_PRAGMA_H
|
||||
|
||||
#include <cpplib.h> /* For enum cpp_ttype. */
|
||||
|
||||
/* Pragma identifiers built in to the front end parsers. Identifiers
|
||||
for ancillary handlers will follow these. */
|
||||
typedef enum pragma_kind {
|
||||
PRAGMA_NONE = 0,
|
||||
|
||||
PRAGMA_OMP_ATOMIC,
|
||||
PRAGMA_OMP_BARRIER,
|
||||
PRAGMA_OMP_CRITICAL,
|
||||
PRAGMA_OMP_FLUSH,
|
||||
PRAGMA_OMP_FOR,
|
||||
PRAGMA_OMP_MASTER,
|
||||
PRAGMA_OMP_ORDERED,
|
||||
PRAGMA_OMP_PARALLEL,
|
||||
PRAGMA_OMP_PARALLEL_FOR,
|
||||
PRAGMA_OMP_PARALLEL_SECTIONS,
|
||||
PRAGMA_OMP_SECTION,
|
||||
PRAGMA_OMP_SECTIONS,
|
||||
PRAGMA_OMP_SINGLE,
|
||||
PRAGMA_OMP_THREADPRIVATE,
|
||||
|
||||
PRAGMA_GCC_PCH_PREPROCESS,
|
||||
|
||||
PRAGMA_FIRST_EXTERNAL
|
||||
} pragma_kind;
|
||||
|
||||
/* Cause the `yydebug' variable to be defined. */
|
||||
#define YYDEBUG 1
|
||||
extern int yydebug;
|
||||
|
|
@ -44,17 +71,42 @@ extern struct cpp_reader* parse_in;
|
|||
#define HANDLE_PRAGMA_PACK 1
|
||||
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
|
||||
|
||||
/* It's safe to always leave visibility pragma enabled as if
|
||||
visibility is not supported on the host OS platform the
|
||||
statements are ignored. */
|
||||
#define HANDLE_PRAGMA_VISIBILITY 1
|
||||
extern void push_visibility (const char *);
|
||||
extern void pop_visibility (void);
|
||||
|
||||
extern void init_pragma (void);
|
||||
|
||||
/* Front-end wrapper for pragma registration to avoid dragging
|
||||
cpplib.h in almost everywhere. */
|
||||
extern void c_register_pragma (const char *, const char *,
|
||||
void (*) (struct cpp_reader *));
|
||||
/* Front-end wrappers for pragma registration. */
|
||||
typedef void (*pragma_handler)(struct cpp_reader *);
|
||||
extern void c_register_pragma (const char *, const char *, pragma_handler);
|
||||
extern void c_register_pragma_with_expansion (const char *, const char *,
|
||||
pragma_handler);
|
||||
extern void c_invoke_pragma_handler (unsigned int);
|
||||
|
||||
extern void maybe_apply_pragma_weak (tree);
|
||||
extern void maybe_apply_pending_pragma_weaks (void);
|
||||
extern tree maybe_apply_renaming_pragma (tree, tree);
|
||||
extern void add_to_renaming_pragma_list (tree, tree);
|
||||
|
||||
extern int c_lex (tree *);
|
||||
extern int c_lex_with_flags (tree *, unsigned char *);
|
||||
extern enum cpp_ttype pragma_lex (tree *);
|
||||
|
||||
/* This is not actually available to pragma parsers. It's merely a
|
||||
convenient location to declare this function for c-lex, after
|
||||
having enum cpp_ttype declared. */
|
||||
extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *);
|
||||
|
||||
/* If 1, then lex strings into the execution character set.
|
||||
If 0, lex strings into the host character set.
|
||||
If -1, lex both, and chain them together, such that the former
|
||||
is the TREE_CHAIN of the latter. */
|
||||
extern int c_lex_string_translate;
|
||||
|
||||
/* If true, strings should be passed to the caller of c_lex completely
|
||||
unmolested (no concatenation, no translation). */
|
||||
extern bool c_lex_return_raw_strings;
|
||||
|
||||
#endif /* GCC_C_PRAGMA_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Various declarations for the C and C++ pretty-printers.
|
||||
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_C_PRETTY_PRINTER
|
||||
#define GCC_C_PRETTY_PRINTER
|
||||
|
|
@ -30,7 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
typedef enum
|
||||
{
|
||||
pp_c_flag_abstract = 1 << 1,
|
||||
pp_c_flag_last_bit = 2
|
||||
pp_c_flag_last_bit = 2
|
||||
} pp_c_pretty_print_flags;
|
||||
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ struct c_pretty_print_info
|
|||
int *offset_list;
|
||||
|
||||
pp_flags flags;
|
||||
|
||||
|
||||
/* These must be overridden by each of the C and C++ front-end to
|
||||
reflect their understanding of syntactic productions when they differ. */
|
||||
c_pretty_print_fn declaration;
|
||||
|
|
@ -80,6 +80,7 @@ struct c_pretty_print_info
|
|||
|
||||
c_pretty_print_fn statement;
|
||||
|
||||
c_pretty_print_fn constant;
|
||||
c_pretty_print_fn id_expression;
|
||||
c_pretty_print_fn primary_expression;
|
||||
c_pretty_print_fn postfix_expression;
|
||||
|
|
@ -95,7 +96,7 @@ struct c_pretty_print_info
|
|||
#undef pp_base
|
||||
#define pp_base(PP) (&pp_c_base (PP)->base)
|
||||
|
||||
|
||||
|
||||
#define pp_c_tree_identifier(PPI, ID) \
|
||||
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
|
||||
|
||||
|
|
@ -129,6 +130,8 @@ struct c_pretty_print_info
|
|||
#define pp_statement(PPI, S) \
|
||||
pp_c_base (PPI)->statement (pp_c_base (PPI), S)
|
||||
|
||||
#define pp_constant(PP, E) \
|
||||
pp_c_base (PP)->constant (pp_c_base (PP), E)
|
||||
#define pp_id_expression(PP, E) \
|
||||
pp_c_base (PP)->id_expression (pp_c_base (PP), E)
|
||||
#define pp_primary_expression(PPI, E) \
|
||||
|
|
@ -159,13 +162,19 @@ void pp_c_left_paren (c_pretty_printer *);
|
|||
void pp_c_right_paren (c_pretty_printer *);
|
||||
void pp_c_left_brace (c_pretty_printer *);
|
||||
void pp_c_right_brace (c_pretty_printer *);
|
||||
void pp_c_left_bracket (c_pretty_printer *);
|
||||
void pp_c_right_bracket (c_pretty_printer *);
|
||||
void pp_c_dot (c_pretty_printer *);
|
||||
void pp_c_ampersand (c_pretty_printer *);
|
||||
void pp_c_star (c_pretty_printer *);
|
||||
void pp_c_arrow (c_pretty_printer *);
|
||||
void pp_c_semicolon (c_pretty_printer *);
|
||||
void pp_c_complement (c_pretty_printer *);
|
||||
void pp_c_exclamation (c_pretty_printer *);
|
||||
void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
|
||||
|
||||
/* Declarations. */
|
||||
void pp_c_tree_decl_identifier (c_pretty_printer *, tree);
|
||||
void pp_c_function_definition (c_pretty_printer *, tree);
|
||||
void pp_c_attributes (c_pretty_printer *, tree);
|
||||
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
|
||||
|
|
@ -186,6 +195,7 @@ void pp_c_statement (c_pretty_printer *, tree);
|
|||
void pp_c_expression (c_pretty_printer *, tree);
|
||||
void pp_c_logical_or_expression (c_pretty_printer *, tree);
|
||||
void pp_c_expression_list (c_pretty_printer *, tree);
|
||||
void pp_c_constructor_elts (c_pretty_printer *, VEC(constructor_elt,gc) *);
|
||||
void pp_c_call_argument_list (c_pretty_printer *, tree);
|
||||
void pp_c_unary_expression (c_pretty_printer *, tree);
|
||||
void pp_c_cast_expression (c_pretty_printer *, tree);
|
||||
|
|
@ -197,4 +207,6 @@ void pp_c_id_expression (c_pretty_printer *, tree);
|
|||
void pp_c_identifier (c_pretty_printer *, const char *);
|
||||
void pp_c_string_literal (c_pretty_printer *, tree);
|
||||
|
||||
void print_c_tree (FILE *file, tree t);
|
||||
|
||||
#endif /* GCC_C_PRETTY_PRINTER */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/* Definitions for C parsing and type checking.
|
||||
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,74 +16,28 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_C_TREE_H
|
||||
#define GCC_C_TREE_H
|
||||
|
||||
#include "c-common.h"
|
||||
#include "toplev.h"
|
||||
#include "diagnostic.h"
|
||||
|
||||
/* Language-dependent contents of an identifier. */
|
||||
|
||||
/* The limbo_value is used for block level extern declarations, which need
|
||||
to be type checked against subsequent extern declarations. They can't
|
||||
be referenced after they fall out of scope, so they can't be global.
|
||||
|
||||
The rid_code field is used for keywords. It is in all
|
||||
lang_identifier nodes, because some keywords are only special in a
|
||||
particular context. */
|
||||
|
||||
struct lang_identifier GTY(())
|
||||
{
|
||||
struct c_common_identifier common_id;
|
||||
tree symbol_value;
|
||||
tree tag_value;
|
||||
tree label_value;
|
||||
};
|
||||
|
||||
/* The resulting tree type. */
|
||||
|
||||
union lang_tree_node
|
||||
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
|
||||
chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *)TYPE_NEXT_VARIANT (&%h.generic) : (union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
|
||||
{
|
||||
union tree_node GTY ((tag ("0"),
|
||||
desc ("tree_node_structure (&%h)")))
|
||||
generic;
|
||||
struct lang_identifier GTY ((tag ("1"))) identifier;
|
||||
};
|
||||
/* struct lang_identifier is private to c-decl.c, but langhooks.c needs to
|
||||
know how big it is. This is sanity-checked in c-decl.c. */
|
||||
#define C_SIZEOF_STRUCT_LANG_IDENTIFIER \
|
||||
(sizeof (struct c_common_identifier) + 3 * sizeof (void *))
|
||||
|
||||
/* Language-specific declaration information. */
|
||||
|
||||
struct lang_decl GTY(())
|
||||
{
|
||||
/* The return types and parameter types may have variable size.
|
||||
This is a list of any SAVE_EXPRs that need to be evaluated to
|
||||
compute those sizes. */
|
||||
tree pending_sizes;
|
||||
char dummy;
|
||||
};
|
||||
|
||||
/* Macros for access to language-specific slots in an identifier. */
|
||||
/* Each of these slots contains a DECL node or null. */
|
||||
|
||||
/* The value of the identifier in the namespace of "ordinary identifiers"
|
||||
(data objects, enum constants, functions, typedefs). */
|
||||
#define IDENTIFIER_SYMBOL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->symbol_value)
|
||||
/* The value of the identifier in the namespace of struct, union,
|
||||
and enum tags. */
|
||||
#define IDENTIFIER_TAG_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->tag_value)
|
||||
/* The value of the identifier in the namespace of labels. */
|
||||
#define IDENTIFIER_LABEL_VALUE(NODE) \
|
||||
(((struct lang_identifier *) (NODE))->label_value)
|
||||
|
||||
/* In identifiers, C uses the following fields in a special way:
|
||||
TREE_PUBLIC to record that there was a previous local extern decl.
|
||||
TREE_USED to record that such a decl was used.
|
||||
TREE_ADDRESSABLE to record that the address of such a decl was used. */
|
||||
|
||||
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
|
||||
#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1 (TYPE)
|
||||
|
||||
|
|
@ -103,10 +57,17 @@ struct lang_decl GTY(())
|
|||
and C_RID_YYCODE is the token number wanted by Yacc. */
|
||||
#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_0 (ID)
|
||||
|
||||
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
|
||||
struct lang_type GTY(())
|
||||
{
|
||||
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
|
||||
struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) s;
|
||||
/* In an ENUMERAL_TYPE, the min and max values. */
|
||||
tree enum_min;
|
||||
tree enum_max;
|
||||
/* In a RECORD_TYPE, information specific to Objective-C, such
|
||||
as a list of adopted protocols or a pointer to a corresponding
|
||||
@interface. See objc/objc-act.h for details. */
|
||||
tree objc_info;
|
||||
};
|
||||
|
||||
/* Record whether a type or decl was written with nonconstant size.
|
||||
|
|
@ -114,10 +75,6 @@ struct lang_type GTY(())
|
|||
#define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE)
|
||||
#define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE)
|
||||
|
||||
/* Store a value in that field. */
|
||||
#define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \
|
||||
(TREE_COMPLEXITY (EXP) = (int) (CODE))
|
||||
|
||||
/* Record whether a typedef for type `int' was actually `signed int'. */
|
||||
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
|
||||
|
||||
|
|
@ -128,11 +85,53 @@ struct lang_type GTY(())
|
|||
/* For a FUNCTION_DECL, nonzero if it was an implicit declaration. */
|
||||
#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
|
||||
|
||||
/* Nonzero for a declaration of an external object which is not
|
||||
currently in scope. This is either a built-in declaration of
|
||||
a library function, before a real declaration has been seen,
|
||||
or a declaration that appeared in an inner scope that has ended. */
|
||||
#define C_DECL_INVISIBLE(EXP) DECL_LANG_FLAG_3 (EXP)
|
||||
/* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
|
||||
been declared. */
|
||||
#define C_DECL_DECLARED_BUILTIN(EXP) \
|
||||
DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (EXP))
|
||||
|
||||
/* For FUNCTION_DECLs, evaluates true if the decl is built-in, has a
|
||||
built-in prototype and does not have a non-built-in prototype. */
|
||||
#define C_DECL_BUILTIN_PROTOTYPE(EXP) \
|
||||
DECL_LANG_FLAG_6 (FUNCTION_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a decl was declared register. This is strictly a
|
||||
front-end flag, whereas DECL_REGISTER is used for code generation;
|
||||
they may differ for structures with volatile fields. */
|
||||
#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4 (EXP)
|
||||
|
||||
/* Record whether a decl was used in an expression anywhere except an
|
||||
unevaluated operand of sizeof / typeof / alignof. This is only
|
||||
used for functions declared static but not defined, though outside
|
||||
sizeof and typeof it is set for other function decls as well. */
|
||||
#define C_DECL_USED(EXP) DECL_LANG_FLAG_5 (FUNCTION_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a label was defined in a statement expression which
|
||||
has finished and so can no longer be jumped to. */
|
||||
#define C_DECL_UNJUMPABLE_STMT_EXPR(EXP) \
|
||||
DECL_LANG_FLAG_6 (LABEL_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a label was the subject of a goto from outside the
|
||||
current level of statement expression nesting and so cannot be
|
||||
defined right now. */
|
||||
#define C_DECL_UNDEFINABLE_STMT_EXPR(EXP) \
|
||||
DECL_LANG_FLAG_7 (LABEL_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a label was defined in the scope of an identifier
|
||||
with variably modified type which has finished and so can no longer
|
||||
be jumped to. */
|
||||
#define C_DECL_UNJUMPABLE_VM(EXP) \
|
||||
DECL_LANG_FLAG_3 (LABEL_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a label was the subject of a goto from outside the
|
||||
current level of scopes of identifiers with variably modified type
|
||||
and so cannot be defined right now. */
|
||||
#define C_DECL_UNDEFINABLE_VM(EXP) \
|
||||
DECL_LANG_FLAG_5 (LABEL_DECL_CHECK (EXP))
|
||||
|
||||
/* Record whether a variable has been declared threadprivate by
|
||||
#pragma omp threadprivate. */
|
||||
#define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL))
|
||||
|
||||
/* Nonzero for a decl which either doesn't exist or isn't a prototype.
|
||||
N.B. Could be simplified if all built-in decls had complete prototypes
|
||||
|
|
@ -145,12 +144,230 @@ struct lang_type GTY(())
|
|||
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
|
||||
TYPE_ARG_TYPES for functions with prototypes, but created for functions
|
||||
without prototypes. */
|
||||
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_BINFO (NODE)
|
||||
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE)
|
||||
|
||||
/* Values for the first parameter to poplevel. */
|
||||
#define KEEP_NO 0
|
||||
#define KEEP_YES 1
|
||||
#define KEEP_MAYBE 2
|
||||
/* Record parser information about an expression that is irrelevant
|
||||
for code generation alongside a tree representing its value. */
|
||||
struct c_expr
|
||||
{
|
||||
/* The value of the expression. */
|
||||
tree value;
|
||||
/* Record the original binary operator of an expression, which may
|
||||
have been changed by fold, STRING_CST for unparenthesized string
|
||||
constants, or ERROR_MARK for other expressions (including
|
||||
parenthesized expressions). */
|
||||
enum tree_code original_code;
|
||||
};
|
||||
|
||||
/* A kind of type specifier. Note that this information is currently
|
||||
only used to distinguish tag definitions, tag references and typeof
|
||||
uses. */
|
||||
enum c_typespec_kind {
|
||||
/* A reserved keyword type specifier. */
|
||||
ctsk_resword,
|
||||
/* A reference to a tag, previously declared, such as "struct foo".
|
||||
This includes where the previous declaration was as a different
|
||||
kind of tag, in which case this is only valid if shadowing that
|
||||
tag in an inner scope. */
|
||||
ctsk_tagref,
|
||||
/* A reference to a tag, not previously declared in a visible
|
||||
scope. */
|
||||
ctsk_tagfirstref,
|
||||
/* A definition of a tag such as "struct foo { int a; }". */
|
||||
ctsk_tagdef,
|
||||
/* A typedef name. */
|
||||
ctsk_typedef,
|
||||
/* An ObjC-specific kind of type specifier. */
|
||||
ctsk_objc,
|
||||
/* A typeof specifier. */
|
||||
ctsk_typeof
|
||||
};
|
||||
|
||||
/* A type specifier: this structure is created in the parser and
|
||||
passed to declspecs_add_type only. */
|
||||
struct c_typespec {
|
||||
/* What kind of type specifier this is. */
|
||||
enum c_typespec_kind kind;
|
||||
/* The specifier itself. */
|
||||
tree spec;
|
||||
};
|
||||
|
||||
/* A storage class specifier. */
|
||||
enum c_storage_class {
|
||||
csc_none,
|
||||
csc_auto,
|
||||
csc_extern,
|
||||
csc_register,
|
||||
csc_static,
|
||||
csc_typedef
|
||||
};
|
||||
|
||||
/* A type specifier keyword "void", "_Bool", "char", "int", "float",
|
||||
"double", or none of these. */
|
||||
enum c_typespec_keyword {
|
||||
cts_none,
|
||||
cts_void,
|
||||
cts_bool,
|
||||
cts_char,
|
||||
cts_int,
|
||||
cts_float,
|
||||
cts_double,
|
||||
cts_dfloat32,
|
||||
cts_dfloat64,
|
||||
cts_dfloat128
|
||||
};
|
||||
|
||||
/* A sequence of declaration specifiers in C. */
|
||||
struct c_declspecs {
|
||||
/* The type specified, if a single type specifier such as a struct,
|
||||
union or enum specifier, typedef name or typeof specifies the
|
||||
whole type, or NULL_TREE if none or a keyword such as "void" or
|
||||
"char" is used. Does not include qualifiers. */
|
||||
tree type;
|
||||
/* The attributes from a typedef decl. */
|
||||
tree decl_attr;
|
||||
/* When parsing, the attributes. Outside the parser, this will be
|
||||
NULL; attributes (possibly from multiple lists) will be passed
|
||||
separately. */
|
||||
tree attrs;
|
||||
/* Any type specifier keyword used such as "int", not reflecting
|
||||
modifiers such as "short", or cts_none if none. */
|
||||
enum c_typespec_keyword typespec_word;
|
||||
/* The storage class specifier, or csc_none if none. */
|
||||
enum c_storage_class storage_class;
|
||||
/* Whether any declaration specifiers have been seen at all. */
|
||||
BOOL_BITFIELD declspecs_seen_p : 1;
|
||||
/* Whether a type specifier has been seen. */
|
||||
BOOL_BITFIELD type_seen_p : 1;
|
||||
/* Whether something other than a storage class specifier or
|
||||
attribute has been seen. This is used to warn for the
|
||||
obsolescent usage of storage class specifiers other than at the
|
||||
start of the list. (Doing this properly would require function
|
||||
specifiers to be handled separately from storage class
|
||||
specifiers.) */
|
||||
BOOL_BITFIELD non_sc_seen_p : 1;
|
||||
/* Whether the type is specified by a typedef or typeof name. */
|
||||
BOOL_BITFIELD typedef_p : 1;
|
||||
/* Whether a struct, union or enum type either had its content
|
||||
defined by a type specifier in the list or was the first visible
|
||||
declaration of its tag. */
|
||||
BOOL_BITFIELD tag_defined_p : 1;
|
||||
/* Whether the type is explicitly "signed" or specified by a typedef
|
||||
whose type is explicitly "signed". */
|
||||
BOOL_BITFIELD explicit_signed_p : 1;
|
||||
/* Whether the specifiers include a deprecated typedef. */
|
||||
BOOL_BITFIELD deprecated_p : 1;
|
||||
/* Whether the type defaulted to "int" because there were no type
|
||||
specifiers. */
|
||||
BOOL_BITFIELD default_int_p;
|
||||
/* Whether "long" was specified. */
|
||||
BOOL_BITFIELD long_p : 1;
|
||||
/* Whether "long" was specified more than once. */
|
||||
BOOL_BITFIELD long_long_p : 1;
|
||||
/* Whether "short" was specified. */
|
||||
BOOL_BITFIELD short_p : 1;
|
||||
/* Whether "signed" was specified. */
|
||||
BOOL_BITFIELD signed_p : 1;
|
||||
/* Whether "unsigned" was specified. */
|
||||
BOOL_BITFIELD unsigned_p : 1;
|
||||
/* Whether "complex" was specified. */
|
||||
BOOL_BITFIELD complex_p : 1;
|
||||
/* Whether "inline" was specified. */
|
||||
BOOL_BITFIELD inline_p : 1;
|
||||
/* Whether "__thread" was specified. */
|
||||
BOOL_BITFIELD thread_p : 1;
|
||||
/* Whether "const" was specified. */
|
||||
BOOL_BITFIELD const_p : 1;
|
||||
/* Whether "volatile" was specified. */
|
||||
BOOL_BITFIELD volatile_p : 1;
|
||||
/* Whether "restrict" was specified. */
|
||||
BOOL_BITFIELD restrict_p : 1;
|
||||
};
|
||||
|
||||
/* The various kinds of declarators in C. */
|
||||
enum c_declarator_kind {
|
||||
/* An identifier. */
|
||||
cdk_id,
|
||||
/* A function. */
|
||||
cdk_function,
|
||||
/* An array. */
|
||||
cdk_array,
|
||||
/* A pointer. */
|
||||
cdk_pointer,
|
||||
/* Parenthesized declarator with nested attributes. */
|
||||
cdk_attrs
|
||||
};
|
||||
|
||||
/* Information about the parameters in a function declarator. */
|
||||
struct c_arg_info {
|
||||
/* A list of parameter decls. */
|
||||
tree parms;
|
||||
/* A list of structure, union and enum tags defined. */
|
||||
tree tags;
|
||||
/* A list of argument types to go in the FUNCTION_TYPE. */
|
||||
tree types;
|
||||
/* A list of non-parameter decls (notably enumeration constants)
|
||||
defined with the parameters. */
|
||||
tree others;
|
||||
/* A list of VLA sizes from the parameters. In a function
|
||||
definition, these are used to ensure that side-effects in sizes
|
||||
of arrays converted to pointers (such as a parameter int i[n++])
|
||||
take place; otherwise, they are ignored. */
|
||||
tree pending_sizes;
|
||||
/* True when these arguments had [*]. */
|
||||
BOOL_BITFIELD had_vla_unspec : 1;
|
||||
};
|
||||
|
||||
/* A declarator. */
|
||||
struct c_declarator {
|
||||
/* The kind of declarator. */
|
||||
enum c_declarator_kind kind;
|
||||
/* Except for cdk_id, the contained declarator. For cdk_id, NULL. */
|
||||
struct c_declarator *declarator;
|
||||
location_t id_loc; /* Currently only set for cdk_id. */
|
||||
union {
|
||||
/* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
|
||||
declarator. */
|
||||
tree id;
|
||||
/* For functions. */
|
||||
struct c_arg_info *arg_info;
|
||||
/* For arrays. */
|
||||
struct {
|
||||
/* The array dimension, or NULL for [] and [*]. */
|
||||
tree dimen;
|
||||
/* The qualifiers inside []. */
|
||||
int quals;
|
||||
/* The attributes (currently ignored) inside []. */
|
||||
tree attrs;
|
||||
/* Whether [static] was used. */
|
||||
BOOL_BITFIELD static_p : 1;
|
||||
/* Whether [*] was used. */
|
||||
BOOL_BITFIELD vla_unspec_p : 1;
|
||||
} array;
|
||||
/* For pointers, the qualifiers on the pointer type. */
|
||||
int pointer_quals;
|
||||
/* For attributes. */
|
||||
tree attrs;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* A type name. */
|
||||
struct c_type_name {
|
||||
/* The declaration specifiers. */
|
||||
struct c_declspecs *specs;
|
||||
/* The declarator. */
|
||||
struct c_declarator *declarator;
|
||||
};
|
||||
|
||||
/* A parameter. */
|
||||
struct c_parm {
|
||||
/* The declaration specifiers, minus any prefix attributes. */
|
||||
struct c_declspecs *specs;
|
||||
/* The attributes. */
|
||||
tree attrs;
|
||||
/* The declarator. */
|
||||
struct c_declarator *declarator;
|
||||
};
|
||||
|
||||
/* Save and restore the variables in this file and elsewhere
|
||||
that keep track of the progress of compilation of the current function.
|
||||
|
|
@ -159,140 +376,219 @@ struct lang_type GTY(())
|
|||
struct language_function GTY(())
|
||||
{
|
||||
struct c_language_function base;
|
||||
tree x_break_label;
|
||||
tree x_cont_label;
|
||||
struct c_switch * GTY((skip)) x_switch_stack;
|
||||
struct c_arg_info * GTY((skip)) arg_info;
|
||||
int returns_value;
|
||||
int returns_null;
|
||||
int returns_abnormally;
|
||||
int warn_about_return_type;
|
||||
int extern_inline;
|
||||
int x_in_iteration_stmt;
|
||||
int x_in_case_stmt;
|
||||
};
|
||||
|
||||
/* Save lists of labels used or defined in particular contexts.
|
||||
Allocated on the parser obstack. */
|
||||
|
||||
struct c_label_list
|
||||
{
|
||||
/* The label at the head of the list. */
|
||||
tree label;
|
||||
/* The rest of the list. */
|
||||
struct c_label_list *next;
|
||||
};
|
||||
|
||||
/* Statement expression context. */
|
||||
|
||||
struct c_label_context_se
|
||||
{
|
||||
/* The labels defined at this level of nesting. */
|
||||
struct c_label_list *labels_def;
|
||||
/* The labels used at this level of nesting. */
|
||||
struct c_label_list *labels_used;
|
||||
/* The next outermost context. */
|
||||
struct c_label_context_se *next;
|
||||
};
|
||||
|
||||
/* Context of variably modified declarations. */
|
||||
|
||||
struct c_label_context_vm
|
||||
{
|
||||
/* The labels defined at this level of nesting. */
|
||||
struct c_label_list *labels_def;
|
||||
/* The labels used at this level of nesting. */
|
||||
struct c_label_list *labels_used;
|
||||
/* The scope of this context. Multiple contexts may be at the same
|
||||
numbered scope, since each variably modified declaration starts a
|
||||
new context. */
|
||||
unsigned scope;
|
||||
/* The next outermost context. */
|
||||
struct c_label_context_vm *next;
|
||||
};
|
||||
|
||||
|
||||
/* in c-parse.in */
|
||||
/* in c-parser.c */
|
||||
extern void c_parse_init (void);
|
||||
|
||||
/* in c-aux-info.c */
|
||||
extern void gen_aux_info_record (tree, int, int, int);
|
||||
|
||||
/* in c-decl.c */
|
||||
extern int c_in_iteration_stmt;
|
||||
extern int c_in_case_stmt;
|
||||
extern struct obstack parser_obstack;
|
||||
extern tree c_break_label;
|
||||
extern tree c_cont_label;
|
||||
|
||||
extern int global_bindings_p (void);
|
||||
extern tree getdecls (void);
|
||||
extern void pushlevel (int);
|
||||
extern void push_scope (void);
|
||||
extern tree pop_scope (void);
|
||||
extern void insert_block (tree);
|
||||
extern void set_block (tree);
|
||||
extern tree pushdecl (tree);
|
||||
extern void c_expand_body (tree);
|
||||
|
||||
extern void c_init_decl_processing (void);
|
||||
extern void c_dup_lang_specific_decl (tree);
|
||||
extern void c_print_identifier (FILE *, tree, int);
|
||||
extern tree build_array_declarator (tree, tree, int, int);
|
||||
extern int quals_from_declspecs (const struct c_declspecs *);
|
||||
extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
|
||||
bool, bool);
|
||||
extern tree build_enumerator (tree, tree);
|
||||
extern void check_for_loop_decls (void);
|
||||
extern tree check_for_loop_decls (void);
|
||||
extern void mark_forward_parm_decls (void);
|
||||
extern int complete_array_type (tree, tree, int);
|
||||
extern void declare_parm_level (void);
|
||||
extern void undeclared_variable (tree);
|
||||
extern void undeclared_variable (tree, location_t);
|
||||
extern tree declare_label (tree);
|
||||
extern tree define_label (location_t, tree);
|
||||
extern void c_maybe_initialize_eh (void);
|
||||
extern void finish_decl (tree, tree, tree);
|
||||
extern tree finish_enum (tree, tree, tree);
|
||||
extern void finish_function (void);
|
||||
extern tree finish_struct (tree, tree, tree);
|
||||
extern tree get_parm_info (int);
|
||||
extern tree grokfield (tree, tree, tree);
|
||||
extern tree groktypename (tree);
|
||||
extern tree groktypename_in_parm_context (tree);
|
||||
extern struct c_arg_info *get_parm_info (bool);
|
||||
extern tree grokfield (struct c_declarator *, struct c_declspecs *, tree);
|
||||
extern tree groktypename (struct c_type_name *);
|
||||
extern tree grokparm (const struct c_parm *);
|
||||
extern tree implicitly_declare (tree);
|
||||
extern int in_parm_level_p (void);
|
||||
extern void keep_next_level (void);
|
||||
extern tree lookup_name (tree);
|
||||
extern void pending_xref_error (void);
|
||||
extern void c_push_function_context (struct function *);
|
||||
extern void c_pop_function_context (struct function *);
|
||||
extern void push_parm_decl (tree);
|
||||
extern tree pushdecl_top_level (tree);
|
||||
extern void pushtag (tree, tree);
|
||||
extern tree set_array_declarator_type (tree, tree, int);
|
||||
extern void shadow_tag (tree);
|
||||
extern void shadow_tag_warned (tree, int);
|
||||
extern void push_parm_decl (const struct c_parm *);
|
||||
extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
|
||||
struct c_declarator *,
|
||||
bool);
|
||||
extern tree builtin_function (const char *, tree, int, enum built_in_class,
|
||||
const char *, tree);
|
||||
extern void shadow_tag (const struct c_declspecs *);
|
||||
extern void shadow_tag_warned (const struct c_declspecs *, int);
|
||||
extern tree start_enum (tree);
|
||||
extern int start_function (tree, tree, tree);
|
||||
extern tree start_decl (tree, tree, int, tree);
|
||||
extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
|
||||
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
|
||||
tree);
|
||||
extern tree start_struct (enum tree_code, tree);
|
||||
extern void store_parm_decls (void);
|
||||
extern void store_parm_decls_from (struct c_arg_info *);
|
||||
extern tree xref_tag (enum tree_code, tree);
|
||||
extern tree c_begin_compound_stmt (void);
|
||||
extern void c_expand_deferred_function (tree);
|
||||
extern void c_expand_decl_stmt (tree);
|
||||
extern void c_static_assembler_name (tree);
|
||||
extern tree make_pointer_declarator (tree, tree);
|
||||
extern void merge_translation_unit_decls (void);
|
||||
extern struct c_typespec parser_xref_tag (enum tree_code, tree);
|
||||
extern int c_expand_decl (tree);
|
||||
extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
|
||||
struct c_declarator *);
|
||||
extern struct c_declarator *build_attrs_declarator (tree,
|
||||
struct c_declarator *);
|
||||
extern struct c_declarator *build_function_declarator (struct c_arg_info *,
|
||||
struct c_declarator *);
|
||||
extern struct c_declarator *build_id_declarator (tree);
|
||||
extern struct c_declarator *make_pointer_declarator (struct c_declspecs *,
|
||||
struct c_declarator *);
|
||||
extern struct c_declspecs *build_null_declspecs (void);
|
||||
extern struct c_declspecs *declspecs_add_qual (struct c_declspecs *, tree);
|
||||
extern struct c_declspecs *declspecs_add_type (struct c_declspecs *,
|
||||
struct c_typespec);
|
||||
extern struct c_declspecs *declspecs_add_scspec (struct c_declspecs *, tree);
|
||||
extern struct c_declspecs *declspecs_add_attrs (struct c_declspecs *, tree);
|
||||
extern struct c_declspecs *finish_declspecs (struct c_declspecs *);
|
||||
|
||||
/* in c-objc-common.c */
|
||||
extern int c_disregard_inline_limits (tree);
|
||||
extern int c_cannot_inline_tree_fn (tree *);
|
||||
extern bool c_objc_common_init (void);
|
||||
extern int c_missing_noreturn_ok_p (tree);
|
||||
extern void c_objc_common_finish_file (void);
|
||||
extern int defer_fn (tree);
|
||||
extern bool c_missing_noreturn_ok_p (tree);
|
||||
extern tree c_objc_common_truthvalue_conversion (tree expr);
|
||||
extern bool c_warn_unused_global_decl (tree);
|
||||
extern void c_initialize_diagnostics (diagnostic_context *);
|
||||
extern bool c_vla_unspec_p (tree x, tree fn);
|
||||
|
||||
#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \
|
||||
c_build_qualified_type ((TYPE), \
|
||||
((CONST_P) ? TYPE_QUAL_CONST : 0) | \
|
||||
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
|
||||
|
||||
#define c_sizeof_nowarn(T) c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 0)
|
||||
|
||||
/* in c-typeck.c */
|
||||
extern int in_alignof;
|
||||
extern int in_sizeof;
|
||||
extern int in_typeof;
|
||||
|
||||
/* For use with comptypes. */
|
||||
enum {
|
||||
COMPARE_STRICT = 0
|
||||
};
|
||||
extern struct c_switch *c_switch_stack;
|
||||
extern struct c_label_context_se *label_context_stack_se;
|
||||
extern struct c_label_context_vm *label_context_stack_vm;
|
||||
|
||||
extern tree require_complete_type (tree);
|
||||
extern int comptypes (tree, tree, int);
|
||||
extern tree c_size_in_bytes (tree);
|
||||
extern int same_translation_unit_p (tree, tree);
|
||||
extern int comptypes (tree, tree);
|
||||
extern bool c_vla_type_p (tree);
|
||||
extern bool c_mark_addressable (tree);
|
||||
extern void c_incomplete_type_error (tree, tree);
|
||||
extern tree c_type_promotes_to (tree);
|
||||
extern struct c_expr default_function_array_conversion (struct c_expr);
|
||||
extern tree composite_type (tree, tree);
|
||||
extern tree build_component_ref (tree, tree);
|
||||
extern tree build_indirect_ref (tree, const char *);
|
||||
extern tree build_array_ref (tree, tree);
|
||||
extern tree build_external_ref (tree, int);
|
||||
extern tree parser_build_binary_op (enum tree_code, tree, tree);
|
||||
extern int c_tree_expr_nonnegative_p (tree);
|
||||
extern void readonly_error (tree, const char *);
|
||||
extern tree build_external_ref (tree, int, location_t);
|
||||
extern void pop_maybe_used (bool);
|
||||
extern struct c_expr c_expr_sizeof_expr (struct c_expr);
|
||||
extern struct c_expr c_expr_sizeof_type (struct c_type_name *);
|
||||
extern struct c_expr parser_build_unary_op (enum tree_code, struct c_expr);
|
||||
extern struct c_expr parser_build_binary_op (enum tree_code, struct c_expr,
|
||||
struct c_expr);
|
||||
extern tree build_conditional_expr (tree, tree, tree);
|
||||
extern tree build_compound_expr (tree);
|
||||
extern tree c_cast_expr (tree, tree);
|
||||
extern tree build_compound_expr (tree, tree);
|
||||
extern tree c_cast_expr (struct c_type_name *, tree);
|
||||
extern tree build_c_cast (tree, tree);
|
||||
extern tree build_modify_expr (tree, enum tree_code, tree);
|
||||
extern void store_init_value (tree, tree);
|
||||
extern void error_init (const char *);
|
||||
extern void pedwarn_init (const char *);
|
||||
extern void maybe_warn_string_init (tree, struct c_expr);
|
||||
extern void start_init (tree, tree, int);
|
||||
extern void finish_init (void);
|
||||
extern void really_start_incremental_init (tree);
|
||||
extern void push_init_level (int);
|
||||
extern tree pop_init_level (int);
|
||||
extern struct c_expr pop_init_level (int);
|
||||
extern void set_init_index (tree, tree);
|
||||
extern void set_init_label (tree);
|
||||
extern void process_init_element (tree);
|
||||
extern void process_init_element (struct c_expr);
|
||||
extern tree build_compound_literal (tree, tree);
|
||||
extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||||
extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||||
extern tree c_start_case (tree);
|
||||
extern void c_finish_case (void);
|
||||
extern tree simple_asm_stmt (tree);
|
||||
extern tree build_asm_stmt (tree, tree, tree, tree, tree);
|
||||
extern void c_finish_case (tree);
|
||||
extern tree build_asm_expr (tree, tree, tree, tree, bool);
|
||||
extern tree build_asm_stmt (tree, tree);
|
||||
extern tree c_convert_parm_for_inlining (tree, tree, tree, int);
|
||||
extern int c_types_compatible_p (tree, tree);
|
||||
extern tree c_begin_compound_stmt (bool);
|
||||
extern tree c_end_compound_stmt (tree, bool);
|
||||
extern void c_finish_if_stmt (location_t, tree, tree, tree, bool);
|
||||
extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool);
|
||||
extern tree c_begin_stmt_expr (void);
|
||||
extern tree c_finish_stmt_expr (tree);
|
||||
extern tree c_process_expr_stmt (tree);
|
||||
extern tree c_finish_expr_stmt (tree);
|
||||
extern tree c_finish_return (tree);
|
||||
extern tree c_finish_bc_stmt (tree *, bool);
|
||||
extern tree c_finish_goto_label (tree);
|
||||
extern tree c_finish_goto_ptr (tree);
|
||||
extern void c_begin_vm_scope (unsigned int);
|
||||
extern void c_end_vm_scope (unsigned int);
|
||||
extern tree c_expr_to_decl (tree, bool *, bool *, bool *);
|
||||
extern tree c_begin_omp_parallel (void);
|
||||
extern tree c_finish_omp_parallel (tree, tree);
|
||||
extern tree c_finish_omp_clauses (tree);
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a return statement that specifies a return value is seen. */
|
||||
|
|
@ -313,18 +609,28 @@ extern int current_function_returns_abnormally;
|
|||
|
||||
extern int system_header_p;
|
||||
|
||||
/* True means global_bindings_p should return false even if the scope stack
|
||||
says we are in file scope. */
|
||||
|
||||
extern bool c_override_global_bindings_to_false;
|
||||
|
||||
/* True means we've initialized exception handling. */
|
||||
extern bool c_eh_initialized_p;
|
||||
|
||||
/* In c-decl.c */
|
||||
extern void c_finish_incomplete_decl (tree);
|
||||
extern void *get_current_scope (void);
|
||||
extern void objc_mark_locals_volatile (void *);
|
||||
extern void c_write_global_declarations (void);
|
||||
|
||||
extern GTY(()) tree static_ctors;
|
||||
extern GTY(()) tree static_dtors;
|
||||
|
||||
/* In order for the format checking to accept the C frontend
|
||||
diagnostic framework extensions, you must include this file before
|
||||
toplev.h, not after. */
|
||||
#define GCC_DIAG_STYLE __gcc_cdiag__
|
||||
#if GCC_VERSION >= 4001
|
||||
#define ATTRIBUTE_GCC_CDIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m ,n))) ATTRIBUTE_NONNULL(m)
|
||||
#else
|
||||
#define ATTRIBUTE_GCC_CDIAG(m, n) ATTRIBUTE_NONNULL(m)
|
||||
#endif
|
||||
|
||||
extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
|
||||
extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
|
||||
|
||||
#endif /* ! GCC_C_TREE_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
; Options for the C, ObjC, C++ and ObjC++ front ends.
|
||||
; Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
;
|
||||
; This file is part of GCC.
|
||||
;
|
||||
|
|
@ -7,55 +7,18 @@
|
|||
; 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.
|
||||
; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
; 02110-1301, USA.
|
||||
|
||||
|
||||
; This file is processed by the script opts.sh. It is a database of
|
||||
; command line options, with each record separated by a blank line,
|
||||
; and each field appearing on its own line. The first field is the
|
||||
; command-line switch with the leading "-" removed. All options
|
||||
; beginning with "f" or "W" are implicitly assumed to take a "no-"
|
||||
; form; this form should not be listed. If you do not want this
|
||||
; negative form and you want it to be automatically rejected, add
|
||||
; RejectNegative to the second field.
|
||||
|
||||
; The second field is a space-separated list of which parts of the
|
||||
; compiler recognize the switch, as declared by "Language" entries.
|
||||
; If the switch takes an argument, then you should also specify
|
||||
; "Joined" and/or "Separate" to indicate where the argument can
|
||||
; appear. If a Joined argument can legitimately be omitted, specify
|
||||
; "JoinedOrMissing" instead of "Joined". If the argument to a switch
|
||||
; is a non-negative integer, you can specify "UInteger" and the switch
|
||||
; decoder will convert the argument for you, or complain to the user
|
||||
; if the argument is invalid.
|
||||
|
||||
; The third field is the help text to output with --help. This is
|
||||
; automatically line-wrapped on output. Normally the switch is output
|
||||
; automatically, with the help text on the right hand side of the
|
||||
; output. However, if the help text contains a tab character, the
|
||||
; text to the left of the tab is output instead of the switch, and the
|
||||
; text to its right forms the help. This is useful for elaborating on
|
||||
; what type of argument a switch takes, for example. If the second
|
||||
; field contains "Undocumented" then nothing is output with --help.
|
||||
; Only do this with good reason like the switch being internal between
|
||||
; the driver and the front end - it is not an excuse to leave a switch
|
||||
; undocumented.
|
||||
|
||||
; Comments can appear on their own line anwhere in the file, preceded
|
||||
; by a semicolon. Whitespace is permitted before the semicolon.
|
||||
|
||||
; For each switch XXX below, an enumeration constant is created by the
|
||||
; script opts.sh spelt OPT_XXX, but with all non-alphanumeric
|
||||
; characters replaced with an underscore.
|
||||
; See the GCC internals manual for a description of this file's format.
|
||||
|
||||
; Please try to keep this file in ASCII collating order.
|
||||
|
||||
|
|
@ -93,13 +56,17 @@ C ObjC C++ ObjC++ Joined Separate
|
|||
E
|
||||
C ObjC C++ ObjC++ Undocumented
|
||||
|
||||
F
|
||||
C ObjC C++ ObjC++ Joined Separate
|
||||
-F <dir> Add <dir> to the end of the main framework include path
|
||||
|
||||
H
|
||||
C ObjC C++ ObjC++
|
||||
Print the name of header files as they are used
|
||||
|
||||
I
|
||||
C ObjC C++ ObjC++ Joined Separate
|
||||
-I <dir> Add <dir> to the end of the main include path. -I- gives more include path control; see info documentation
|
||||
-I <dir> Add <dir> to the end of the main include path
|
||||
|
||||
M
|
||||
C ObjC C++ ObjC++
|
||||
|
|
@ -146,22 +113,36 @@ C ObjC C++ ObjC++ Joined Separate
|
|||
-U<macro> Undefine <macro>
|
||||
|
||||
Wabi
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_abi)
|
||||
Warn about things that will change when compiling with an ABI-compliant compiler
|
||||
|
||||
Waddress
|
||||
C ObjC C++ ObjC++ Var(warn_address)
|
||||
Warn about suspicious uses of memory addresses
|
||||
|
||||
Wall
|
||||
C ObjC C++ ObjC++
|
||||
Enable most warning messages
|
||||
|
||||
Wassign-intercept
|
||||
ObjC ObjC++ Var(warn_assign_intercept)
|
||||
Warn whenever an Objective-C assignment is being intercepted by the garbage collector
|
||||
|
||||
Wbad-function-cast
|
||||
C ObjC
|
||||
C ObjC Var(warn_bad_function_cast)
|
||||
Warn about casting functions to incompatible types
|
||||
|
||||
Wc++-compat
|
||||
C ObjC Var(warn_cxx_compat)
|
||||
Warn about C constructs that are not in the common subset of C and C++
|
||||
|
||||
|
||||
Wcast-qual
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_cast_qual)
|
||||
Warn about casts which discard qualifiers
|
||||
|
||||
Wchar-subscripts
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_char_subscripts)
|
||||
Warn about subscripts whose type is \"char\"
|
||||
|
||||
Wcomment
|
||||
|
|
@ -173,27 +154,27 @@ C ObjC C++ ObjC++
|
|||
Synonym for -Wcomment
|
||||
|
||||
Wconversion
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_conversion)
|
||||
Warn about possibly confusing type conversions
|
||||
|
||||
Wctor-dtor-privacy
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_ctor_dtor_privacy)
|
||||
Warn when all constructors and destructors are private
|
||||
|
||||
Wdeclaration-after-statement
|
||||
C ObjC
|
||||
C ObjC Var(warn_declaration_after_statement)
|
||||
Warn when a declaration is found after a statement
|
||||
|
||||
Wdeprecated
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_deprecated) Init(1)
|
||||
Warn about deprecated compiler features
|
||||
|
||||
Wdiv-by-zero
|
||||
C ObjC
|
||||
C ObjC C++ ObjC++ Var(warn_div_by_zero) Init(1)
|
||||
Warn about compile-time integer division by zero
|
||||
|
||||
Weffc++
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_ecpp)
|
||||
Warn about violations of Effective C++ style rules
|
||||
|
||||
Wendif-labels
|
||||
|
|
@ -209,7 +190,7 @@ C ObjC RejectNegative
|
|||
Make implicit function declarations an error
|
||||
|
||||
Wfloat-equal
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_float_equal)
|
||||
Warn if testing floating point numbers for equality
|
||||
|
||||
Wformat
|
||||
|
|
@ -217,48 +198,53 @@ C ObjC C++ ObjC++
|
|||
Warn about printf/scanf/strftime/strfmon format string anomalies
|
||||
|
||||
Wformat-extra-args
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_format_extra_args)
|
||||
Warn if passing too many arguments to a function for its format string
|
||||
|
||||
Wformat-nonliteral
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_format_nonliteral)
|
||||
Warn about format strings that are not literals
|
||||
|
||||
Wformat-security
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_format_security)
|
||||
Warn about possible security problems with format functions
|
||||
|
||||
Wformat-y2k
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_format_y2k)
|
||||
Warn about strftime formats yielding 2-digit years
|
||||
|
||||
Wformat-zero-length
|
||||
C ObjC
|
||||
C ObjC Var(warn_format_zero_length)
|
||||
Warn about zero-length formats
|
||||
|
||||
Wformat=
|
||||
C ObjC C++ ObjC++ Joined
|
||||
|
||||
Winit-self
|
||||
C ObjC C++ ObjC++
|
||||
Warn about variables which are initialized to themselves.
|
||||
C ObjC C++ ObjC++ Var(warn_init_self)
|
||||
Warn about variables which are initialized to themselves
|
||||
|
||||
Wimplicit
|
||||
C ObjC C++ ObjC++
|
||||
|
||||
Wimplicit-function-declaration
|
||||
C ObjC
|
||||
C ObjC Var(mesg_implicit_function_declaration) Init(-1)
|
||||
Warn about implicit function declarations
|
||||
|
||||
Wimplicit-int
|
||||
C ObjC
|
||||
C ObjC Var(warn_implicit_int)
|
||||
Warn when a declaration does not specify a type
|
||||
|
||||
Wimport
|
||||
C ObjC C++ ObjC++
|
||||
Deprecated. This switch has no effect.
|
||||
Deprecated. This switch has no effect
|
||||
|
||||
Wint-to-pointer-cast
|
||||
C ObjC Var(warn_int_to_pointer_cast) Init(1)
|
||||
Warn when there is a cast to a pointer from an integer of a different size
|
||||
|
||||
Winvalid-offsetof
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_invalid_offsetof) Init(1)
|
||||
Warn about invalid uses of the \"offsetof\" macro
|
||||
|
||||
Winvalid-pch
|
||||
|
|
@ -266,7 +252,7 @@ C ObjC C++ ObjC++
|
|||
Warn about PCH files that are found but not used
|
||||
|
||||
Wlong-long
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_long_long) Init(1)
|
||||
Do not warn about using \"long long\" when -pedantic
|
||||
|
||||
Wmain
|
||||
|
|
@ -274,19 +260,27 @@ C ObjC
|
|||
Warn about suspicious declarations of \"main\"
|
||||
|
||||
Wmissing-braces
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_missing_braces)
|
||||
Warn about possibly missing braces around initializers
|
||||
|
||||
Wmissing-declarations
|
||||
C ObjC
|
||||
C ObjC Var(warn_missing_declarations)
|
||||
Warn about global functions without previous declarations
|
||||
|
||||
Wmissing-field-initializers
|
||||
C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Init(-1)
|
||||
Warn about missing fields in struct initializers
|
||||
|
||||
Wmissing-format-attribute
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_missing_format_attribute)
|
||||
Warn about functions which might be candidates for format attributes
|
||||
|
||||
Wmissing-include-dirs
|
||||
C ObjC C++ ObjC++
|
||||
Warn about user-specified include directories that do not exist
|
||||
|
||||
Wmissing-prototypes
|
||||
C ObjC
|
||||
C ObjC Var(warn_missing_prototypes)
|
||||
Warn about global functions without prototypes
|
||||
|
||||
Wmultichar
|
||||
|
|
@ -294,82 +288,111 @@ C ObjC C++ ObjC++
|
|||
Warn about use of multi-character character constants
|
||||
|
||||
Wnested-externs
|
||||
C ObjC
|
||||
C ObjC Var(warn_nested_externs)
|
||||
Warn about \"extern\" declarations not at file scope
|
||||
|
||||
Wnon-template-friend
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_nontemplate_friend) Init(1)
|
||||
Warn when non-templatized friend functions are declared within a template
|
||||
|
||||
Wnon-virtual-dtor
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_nonvdtor)
|
||||
Warn about non-virtual destructors
|
||||
|
||||
Wnonnull
|
||||
C ObjC
|
||||
C ObjC Var(warn_nonnull)
|
||||
Warn about NULL being passed to argument slots marked as requiring non-NULL
|
||||
|
||||
Wnormalized=
|
||||
C ObjC C++ ObjC++ Joined
|
||||
-Wnormalized=<id|nfc|nfkc> Warn about non-normalised Unicode strings
|
||||
|
||||
Wold-style-cast
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_old_style_cast)
|
||||
Warn if a C-style cast is used in a program
|
||||
|
||||
Wold-style-definition
|
||||
C ObjC
|
||||
C ObjC Var(warn_old_style_definition)
|
||||
Warn if an old-style parameter definition is used
|
||||
|
||||
Woverlength-strings
|
||||
C ObjC C++ ObjC++ Var(warn_overlength_strings) Init(-1)
|
||||
Warn if a string is longer than the maximum portable length specified by the standard
|
||||
|
||||
Woverloaded-virtual
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_overloaded_virtual)
|
||||
Warn about overloaded virtual function names
|
||||
|
||||
Woverride-init
|
||||
C ObjC Var(warn_override_init) Init(-1)
|
||||
Warn about overriding initializers without side effects
|
||||
|
||||
Wparentheses
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_parentheses)
|
||||
Warn about possibly missing parentheses
|
||||
|
||||
Wpmf-conversions
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_pmf2ptr) Init(1)
|
||||
Warn when converting the type of pointers to member functions
|
||||
|
||||
Wpointer-arith
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_pointer_arith)
|
||||
Warn about function pointer arithmetic
|
||||
|
||||
Wpointer-to-int-cast
|
||||
C ObjC Var(warn_pointer_to_int_cast) Init(1)
|
||||
Warn when a pointer is cast to an integer of a different size
|
||||
|
||||
Wpragmas
|
||||
C ObjC C++ ObjC++ Var(warn_pragmas) Init(1)
|
||||
Warn about misuses of pragmas
|
||||
|
||||
Wprotocol
|
||||
ObjC ObjC++
|
||||
ObjC ObjC++ Var(warn_protocol) Init(1)
|
||||
Warn if inherited methods are unimplemented
|
||||
|
||||
Wredundant-decls
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_redundant_decls)
|
||||
Warn about multiple declarations of the same object
|
||||
|
||||
Wreorder
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_reorder)
|
||||
Warn when the compiler reorders code
|
||||
|
||||
Wreturn-type
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_return_type)
|
||||
Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)
|
||||
|
||||
Wselector
|
||||
ObjC ObjC++
|
||||
ObjC ObjC++ Var(warn_selector)
|
||||
Warn if a selector has multiple methods
|
||||
|
||||
Wsequence-point
|
||||
C ObjC
|
||||
C ObjC C++ ObjC++ Var(warn_sequence_point)
|
||||
Warn about possible violations of sequence point rules
|
||||
|
||||
Wsign-compare
|
||||
C ObjC C++ ObjC++
|
||||
C ObjC C++ ObjC++ Var(warn_sign_compare) Init(-1)
|
||||
Warn about signed-unsigned comparisons
|
||||
|
||||
Wsign-promo
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_sign_promo)
|
||||
Warn when overload promotes from unsigned to signed
|
||||
|
||||
Wstrict-null-sentinel
|
||||
C++ ObjC++
|
||||
Warn about uncasted NULL used as sentinel
|
||||
|
||||
Wstrict-prototypes
|
||||
C ObjC
|
||||
C ObjC Var(warn_strict_prototypes)
|
||||
Warn about unprototyped function declarations
|
||||
|
||||
Wstrict-selector-match
|
||||
ObjC ObjC++ Var(warn_strict_selector_match)
|
||||
Warn if type signatures of candidate methods do not match exactly
|
||||
|
||||
Wsynth
|
||||
C++ ObjC++
|
||||
C++ ObjC++ Var(warn_synth)
|
||||
Warn when synthesis behavior differs from Cfront
|
||||
|
||||
Wsystem-headers
|
||||
|
|
@ -377,7 +400,7 @@ C ObjC C++ ObjC++
|
|||
Do not suppress warnings from system headers
|
||||
|
||||
Wtraditional
|
||||
C ObjC
|
||||
C ObjC Var(warn_traditional)
|
||||
Warn about features not present in traditional C
|
||||
|
||||
Wtrigraphs
|
||||
|
|
@ -385,7 +408,8 @@ C ObjC C++ ObjC++
|
|||
Warn if trigraphs are encountered that might affect the meaning of the program
|
||||
|
||||
Wundeclared-selector
|
||||
ObjC ObjC++
|
||||
ObjC ObjC++ Var(warn_undeclared_selector)
|
||||
Warn about @selector()s without previously declared methods
|
||||
|
||||
Wundef
|
||||
C ObjC C++ ObjC++
|
||||
|
|
@ -399,13 +423,21 @@ Wunused-macros
|
|||
C ObjC C++ ObjC++
|
||||
Warn about macros defined in the main file that are not used
|
||||
|
||||
Wwrite-strings
|
||||
Wvariadic-macros
|
||||
C ObjC C++ ObjC++
|
||||
Give strings the type \"array of char\"
|
||||
Do not warn about using variadic macros when -pedantic
|
||||
|
||||
Wwrite-strings
|
||||
C ObjC C++ ObjC++ Var(warn_write_strings)
|
||||
In C++, nonzero means warn about deprecated conversion from string literals to `char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.
|
||||
|
||||
Wpointer-sign
|
||||
C ObjC Var(warn_pointer_sign) Init(-1)
|
||||
Warn when a pointer differs in signedness in an assignment
|
||||
|
||||
ansi
|
||||
C ObjC C++ ObjC++
|
||||
A synonym for -std=c89 (for C) or -std=c++98 (for C++).
|
||||
A synonym for -std=c89 (for C) or -std=c++98 (for C++)
|
||||
|
||||
d
|
||||
C ObjC C++ ObjC++ Joined
|
||||
|
|
@ -445,10 +477,6 @@ fconserve-space
|
|||
C++ ObjC++
|
||||
Reduce the size of object files
|
||||
|
||||
fconst-strings
|
||||
C++ ObjC++
|
||||
Make string literals \"const char[]\" not \"char[]\"
|
||||
|
||||
fconstant-string-class=
|
||||
ObjC ObjC++ Joined
|
||||
-fconst-string-class=<name> Use class <name> for constant strings
|
||||
|
|
@ -461,10 +489,6 @@ fdollars-in-identifiers
|
|||
C ObjC C++ ObjC++
|
||||
Permit '$' as an identifier character
|
||||
|
||||
fdump-
|
||||
C ObjC C++ ObjC++ Joined RejectNegative
|
||||
-fdump-<type> Dump various compiler internals to a file
|
||||
|
||||
felide-constructors
|
||||
C++ ObjC++
|
||||
|
||||
|
|
@ -479,20 +503,18 @@ fexec-charset=
|
|||
C ObjC C++ ObjC++ Joined RejectNegative
|
||||
-fexec-charset=<cset> Convert all strings and character constants to character set <cset>
|
||||
|
||||
fextended-identifiers
|
||||
C ObjC C++ ObjC++
|
||||
Permit universal character names (\\u and \\U) in identifiers
|
||||
|
||||
finput-charset=
|
||||
C ObjC C++ ObjC++ Joined RejectNegative
|
||||
-finput-charset=<cset> Specify the default character set for source files.
|
||||
-finput-charset=<cset> Specify the default character set for source files
|
||||
|
||||
|
||||
fexternal-templates
|
||||
C++ ObjC++
|
||||
|
||||
ffixed-form
|
||||
C ObjC
|
||||
|
||||
ffixed-line-length-
|
||||
C ObjC Joined
|
||||
|
||||
ffor-scope
|
||||
C++ ObjC++
|
||||
Scope of for-init-statement variables is local to the loop
|
||||
|
|
@ -509,6 +531,10 @@ fgnu-runtime
|
|||
ObjC ObjC++
|
||||
Generate code for GNU runtime environment
|
||||
|
||||
fgnu89-inline
|
||||
C ObjC Var(flag_gnu89_inline) Init(-1)
|
||||
Use traditional GNU semantics for inline functions
|
||||
|
||||
fguiding-decls
|
||||
C++ ObjC++
|
||||
|
||||
|
|
@ -538,6 +564,10 @@ fimplicit-templates
|
|||
C++ ObjC++
|
||||
Emit implicit instantiations of templates
|
||||
|
||||
ffriend-injection
|
||||
C++ ObjC++ Var(flag_friend_injection)
|
||||
Inject friend functions into enclosing namespace
|
||||
|
||||
flabels-ok
|
||||
C++ ObjC++
|
||||
|
||||
|
|
@ -565,10 +595,35 @@ C++ ObjC++
|
|||
fnonnull-objects
|
||||
C++ ObjC++
|
||||
|
||||
; Generate special '- .cxx_construct' and '- .cxx_destruct' methods
|
||||
; to initialize any non-POD ivars in Objective-C++ classes.
|
||||
fobjc-call-cxx-cdtors
|
||||
ObjC++ Var(flag_objc_call_cxx_cdtors)
|
||||
Generate special Objective-C methods to initialize/destroy non-POD C++ ivars, if needed
|
||||
|
||||
fobjc-direct-dispatch
|
||||
ObjC ObjC++ Var(flag_objc_direct_dispatch)
|
||||
Allow fast jumps to the message dispatcher
|
||||
|
||||
; Nonzero means that we will allow new ObjC exception syntax (@throw,
|
||||
; @try, etc.) in source code.
|
||||
fobjc-exceptions
|
||||
ObjC ObjC++
|
||||
ObjC ObjC++ Var(flag_objc_exceptions)
|
||||
Enable Objective-C exception and synchronization syntax
|
||||
|
||||
fobjc-gc
|
||||
ObjC ObjC++ Var(flag_objc_gc)
|
||||
Enable garbage collection (GC) in Objective-C/Objective-C++ programs
|
||||
|
||||
; Nonzero means that we generate NeXT setjmp based exceptions.
|
||||
fobjc-sjlj-exceptions
|
||||
ObjC ObjC++ Var(flag_objc_sjlj_exceptions) Init(-1)
|
||||
Enable Objective-C setjmp exception handling runtime
|
||||
|
||||
fopenmp
|
||||
C ObjC C++ ObjC++ Var(flag_openmp)
|
||||
Enable OpenMP
|
||||
|
||||
foperator-names
|
||||
C++ ObjC++
|
||||
Recognize C++ kewords like \"compl\" and \"xor\"
|
||||
|
|
@ -580,6 +635,10 @@ Enable optional diagnostics
|
|||
fpch-deps
|
||||
C ObjC C++ ObjC++
|
||||
|
||||
fpch-preprocess
|
||||
C ObjC C++ ObjC++
|
||||
Look for and use PCH files even when preprocessing
|
||||
|
||||
fpermissive
|
||||
C++ ObjC++
|
||||
Downgrade conformance errors to warnings
|
||||
|
|
@ -612,9 +671,6 @@ fshort-wchar
|
|||
C ObjC C++ ObjC++
|
||||
Force the underlying type for \"wchar_t\" to be \"unsigned short\"
|
||||
|
||||
fshow-column
|
||||
C ObjC C++ ObjC++
|
||||
|
||||
fsigned-bitfields
|
||||
C ObjC C++ ObjC++
|
||||
When \"signed\" or \"unsigned\" is not given make the bitfield signed
|
||||
|
|
@ -638,12 +694,16 @@ C ObjC C++ ObjC++ Joined RejectNegative UInteger
|
|||
-ftabstop=<number> Distance between tab stops for column reporting
|
||||
|
||||
ftemplate-depth-
|
||||
C++ ObjC++ Joined RejectNegative UInteger
|
||||
C++ ObjC++ Joined RejectNegative UInteger
|
||||
-ftemplate-depth-<number> Specify maximum template instantiation depth
|
||||
|
||||
fthis-is-variable
|
||||
C++ ObjC++
|
||||
|
||||
fthreadsafe-statics
|
||||
C++ ObjC++
|
||||
-fno-threadsafe-statics Do not generate thread-safe code for initializing local statics
|
||||
|
||||
funsigned-bitfields
|
||||
C ObjC C++ ObjC++
|
||||
When \"signed\" or \"unsigned\" is not given make the bitfield unsigned
|
||||
|
|
@ -656,6 +716,14 @@ fuse-cxa-atexit
|
|||
C++ ObjC++
|
||||
Use __cxa_atexit to register destructors
|
||||
|
||||
fuse-cxa-get-exception-ptr
|
||||
C++ ObjC++
|
||||
Use __cxa_get_exception_ptr in exception handling
|
||||
|
||||
fvisibility-inlines-hidden
|
||||
C++ ObjC++
|
||||
Marks all inlined methods as having hidden visibility
|
||||
|
||||
fvtable-gc
|
||||
C++ ObjC++
|
||||
Discard unused virtual functions
|
||||
|
|
@ -696,6 +764,10 @@ imacros
|
|||
C ObjC C++ ObjC++ Joined Separate
|
||||
-imacros <file> Accept definition of macros in <file>
|
||||
|
||||
imultilib
|
||||
C ObjC C++ ObjC++ Joined Separate
|
||||
-imultilib <dir> Set <dir> to be the multilib include subdirectory
|
||||
|
||||
include
|
||||
C ObjC C++ ObjC++ Joined Separate
|
||||
-include <file> Include the contents of <file> before other files
|
||||
|
|
@ -712,6 +784,10 @@ isystem
|
|||
C ObjC C++ ObjC++ Joined Separate
|
||||
-isystem <dir> Add <dir> to the start of the system include path
|
||||
|
||||
iquote
|
||||
C ObjC C++ ObjC++ Joined Separate
|
||||
-iquote <dir> Add <dir> to the end of the quote include path
|
||||
|
||||
iwithprefix
|
||||
C ObjC C++ ObjC++ Joined Separate
|
||||
-iwithprefix <dir> Add <dir> to the end of the system include path
|
||||
|
|
@ -723,6 +799,9 @@ C ObjC C++ ObjC++ Joined Separate
|
|||
lang-asm
|
||||
C Undocumented
|
||||
|
||||
lang-fortran
|
||||
C Undocumented
|
||||
|
||||
lang-objc
|
||||
C ObjC C++ ObjC++ Undocumented
|
||||
|
||||
|
|
@ -750,6 +829,10 @@ print-objc-runtime-info
|
|||
ObjC ObjC++
|
||||
Generate C header of platform-specific features
|
||||
|
||||
print-pch-checksum
|
||||
C ObjC C++ ObjC++
|
||||
Print a checksum of the executable for PCH validity checking, and stop
|
||||
|
||||
remap
|
||||
C ObjC C++ ObjC++
|
||||
Remap file names when including files
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* Save and restore call-clobbered registers which are live across a call.
|
||||
Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,17 +16,17 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "rtl.h"
|
||||
#include "regs.h"
|
||||
#include "insn-config.h"
|
||||
#include "flags.h"
|
||||
#include "regs.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "recog.h"
|
||||
#include "basic-block.h"
|
||||
|
|
@ -35,6 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "expr.h"
|
||||
#include "toplev.h"
|
||||
#include "tm_p.h"
|
||||
#include "addresses.h"
|
||||
|
||||
#ifndef MAX_MOVE_MAX
|
||||
#define MAX_MOVE_MAX MOVE_MAX
|
||||
|
|
@ -83,10 +84,6 @@ static int n_regs_saved;
|
|||
insn. */
|
||||
static HARD_REG_SET referenced_regs;
|
||||
|
||||
/* Computed in mark_set_regs, holds all registers set by the current
|
||||
instruction. */
|
||||
static HARD_REG_SET this_insn_sets;
|
||||
|
||||
|
||||
static void mark_set_regs (rtx, rtx, void *);
|
||||
static void mark_referenced_regs (rtx);
|
||||
|
|
@ -157,11 +154,10 @@ init_caller_save (void)
|
|||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (TEST_HARD_REG_BIT
|
||||
(reg_class_contents
|
||||
[(int) MODE_BASE_REG_CLASS (regno_save_mode [i][1])], i))
|
||||
[(int) base_reg_class (regno_save_mode [i][1], PLUS, CONST_INT)], i))
|
||||
break;
|
||||
|
||||
if (i == FIRST_PSEUDO_REGISTER)
|
||||
abort ();
|
||||
gcc_assert (i < FIRST_PSEUDO_REGISTER);
|
||||
|
||||
addr_reg = gen_rtx_REG (Pmode, i);
|
||||
|
||||
|
|
@ -199,7 +195,7 @@ init_caller_save (void)
|
|||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++)
|
||||
if (HARD_REGNO_MODE_OK (i, mode))
|
||||
{
|
||||
{
|
||||
int ok;
|
||||
|
||||
/* Update the register number and modes of the register
|
||||
|
|
@ -216,7 +212,7 @@ init_caller_save (void)
|
|||
reg_restore_code[i][mode] = recog_memoized (restinsn);
|
||||
|
||||
/* Now extract both insns and see if we can meet their
|
||||
constraints. */
|
||||
constraints. */
|
||||
ok = (reg_save_code[i][mode] != -1
|
||||
&& reg_restore_code[i][mode] != -1);
|
||||
if (ok)
|
||||
|
|
@ -232,7 +228,7 @@ init_caller_save (void)
|
|||
reg_save_code[i][mode] = -1;
|
||||
reg_restore_code[i][mode] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reg_save_code[i][mode] = -1;
|
||||
|
|
@ -300,7 +296,7 @@ setup_save_areas (void)
|
|||
{
|
||||
unsigned int regno = reg_renumber[i];
|
||||
unsigned int endregno
|
||||
= regno + HARD_REGNO_NREGS (regno, GET_MODE (regno_reg_rtx[i]));
|
||||
= regno + hard_regno_nregs[regno][GET_MODE (regno_reg_rtx[i])];
|
||||
|
||||
for (r = regno; r < endregno; r++)
|
||||
if (call_used_regs[r])
|
||||
|
|
@ -371,6 +367,10 @@ save_call_clobbered_regs (void)
|
|||
struct insn_chain *chain, *next;
|
||||
enum machine_mode save_mode [FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* Computed in mark_set_regs, holds all registers set by the current
|
||||
instruction. */
|
||||
HARD_REG_SET this_insn_sets;
|
||||
|
||||
CLEAR_HARD_REG_SET (hard_regs_saved);
|
||||
n_regs_saved = 0;
|
||||
|
||||
|
|
@ -381,10 +381,9 @@ save_call_clobbered_regs (void)
|
|||
|
||||
next = chain->next;
|
||||
|
||||
if (chain->is_caller_save_insn)
|
||||
abort ();
|
||||
gcc_assert (!chain->is_caller_save_insn);
|
||||
|
||||
if (GET_RTX_CLASS (code) == 'i')
|
||||
if (INSN_P (insn))
|
||||
{
|
||||
/* If some registers have been saved, see if INSN references
|
||||
any of them. We must restore them before the insn if so. */
|
||||
|
|
@ -410,8 +409,9 @@ save_call_clobbered_regs (void)
|
|||
|
||||
if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL))
|
||||
{
|
||||
int regno;
|
||||
unsigned regno;
|
||||
HARD_REG_SET hard_regs_to_save;
|
||||
reg_set_iterator rsi;
|
||||
|
||||
/* Use the register life information in CHAIN to compute which
|
||||
regs are live during the call. */
|
||||
|
|
@ -427,34 +427,34 @@ save_call_clobbered_regs (void)
|
|||
/* Look through all live pseudos, mark their hard registers
|
||||
and choose proper mode for saving. */
|
||||
EXECUTE_IF_SET_IN_REG_SET
|
||||
(&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno,
|
||||
{
|
||||
int r = reg_renumber[regno];
|
||||
int nregs;
|
||||
(&chain->live_throughout, FIRST_PSEUDO_REGISTER, regno, rsi)
|
||||
{
|
||||
int r = reg_renumber[regno];
|
||||
int nregs;
|
||||
enum machine_mode mode;
|
||||
|
||||
if (r >= 0)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
|
||||
nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (regno));
|
||||
mode = HARD_REGNO_CALLER_SAVE_MODE
|
||||
(r, nregs, PSEUDO_REGNO_MODE (regno));
|
||||
if (GET_MODE_BITSIZE (mode)
|
||||
> GET_MODE_BITSIZE (save_mode[r]))
|
||||
save_mode[r] = mode;
|
||||
while (nregs-- > 0)
|
||||
SET_HARD_REG_BIT (hard_regs_to_save, r + nregs);
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
});
|
||||
gcc_assert (r >= 0);
|
||||
nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
|
||||
mode = HARD_REGNO_CALLER_SAVE_MODE
|
||||
(r, nregs, PSEUDO_REGNO_MODE (regno));
|
||||
if (GET_MODE_BITSIZE (mode)
|
||||
> GET_MODE_BITSIZE (save_mode[r]))
|
||||
save_mode[r] = mode;
|
||||
while (nregs-- > 0)
|
||||
SET_HARD_REG_BIT (hard_regs_to_save, r + nregs);
|
||||
}
|
||||
|
||||
/* Record all registers set in this call insn. These don't need
|
||||
to be saved. N.B. the call insn might set a subreg of a
|
||||
multi-hard-reg pseudo; then the pseudo is considered live
|
||||
during the call, but the subreg that is set isn't. */
|
||||
CLEAR_HARD_REG_SET (this_insn_sets);
|
||||
note_stores (PATTERN (insn), mark_set_regs, NULL);
|
||||
note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets);
|
||||
/* Sibcalls are considered to set the return value,
|
||||
compare flow.c:propagate_one_insn. */
|
||||
if (SIBLING_CALL_P (insn) && current_function_return_rtx)
|
||||
mark_set_regs (current_function_return_rtx, NULL_RTX,
|
||||
&this_insn_sets);
|
||||
|
||||
/* Compute which hard regs must be saved before this call. */
|
||||
AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set);
|
||||
|
|
@ -484,41 +484,41 @@ save_call_clobbered_regs (void)
|
|||
if (n_regs_saved)
|
||||
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||||
if (TEST_HARD_REG_BIT (hard_regs_saved, regno))
|
||||
regno += insert_restore (chain, GET_CODE (insn) == JUMP_INSN,
|
||||
regno += insert_restore (chain, JUMP_P (insn),
|
||||
regno, MOVE_MAX_WORDS, save_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Here from note_stores when an insn stores a value in a register.
|
||||
/* Here from note_stores, or directly from save_call_clobbered_regs, when
|
||||
an insn stores a value in a register.
|
||||
Set the proper bit or bits in this_insn_sets. All pseudos that have
|
||||
been assigned hard regs have had their register number changed already,
|
||||
so we can ignore pseudos. */
|
||||
static void
|
||||
mark_set_regs (rtx reg, rtx setter ATTRIBUTE_UNUSED,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
mark_set_regs (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *data)
|
||||
{
|
||||
int regno, endregno, i;
|
||||
enum machine_mode mode = GET_MODE (reg);
|
||||
HARD_REG_SET *this_insn_sets = data;
|
||||
|
||||
if (GET_CODE (reg) == SUBREG)
|
||||
{
|
||||
rtx inner = SUBREG_REG (reg);
|
||||
if (GET_CODE (inner) != REG || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
|
||||
if (!REG_P (inner) || REGNO (inner) >= FIRST_PSEUDO_REGISTER)
|
||||
return;
|
||||
|
||||
regno = subreg_hard_regno (reg, 1);
|
||||
regno = subreg_regno (reg);
|
||||
}
|
||||
else if (GET_CODE (reg) == REG
|
||||
else if (REG_P (reg)
|
||||
&& REGNO (reg) < FIRST_PSEUDO_REGISTER)
|
||||
regno = REGNO (reg);
|
||||
else
|
||||
return;
|
||||
|
||||
endregno = regno + HARD_REGNO_NREGS (regno, mode);
|
||||
endregno = regno + hard_regno_nregs[regno][mode];
|
||||
|
||||
for (i = regno; i < endregno; i++)
|
||||
SET_HARD_REG_BIT (this_insn_sets, i);
|
||||
SET_HARD_REG_BIT (*this_insn_sets, i);
|
||||
}
|
||||
|
||||
/* Here from note_stores when an insn stores a value in a register.
|
||||
|
|
@ -535,7 +535,7 @@ add_stored_regs (rtx reg, rtx setter, void *data)
|
|||
if (GET_CODE (setter) == CLOBBER)
|
||||
return;
|
||||
|
||||
if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
|
||||
if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
|
||||
{
|
||||
offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
|
||||
GET_MODE (SUBREG_REG (reg)),
|
||||
|
|
@ -544,11 +544,11 @@ add_stored_regs (rtx reg, rtx setter, void *data)
|
|||
reg = SUBREG_REG (reg);
|
||||
}
|
||||
|
||||
if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
|
||||
if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
|
||||
return;
|
||||
|
||||
regno = REGNO (reg) + offset;
|
||||
endregno = regno + HARD_REGNO_NREGS (regno, mode);
|
||||
endregno = regno + hard_regno_nregs[regno][mode];
|
||||
|
||||
for (i = regno; i < endregno; i++)
|
||||
SET_REGNO_REG_SET ((regset) data, i);
|
||||
|
|
@ -570,7 +570,7 @@ mark_referenced_regs (rtx x)
|
|||
code = GET_CODE (x);
|
||||
if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
|
||||
|| code == PC || code == CC0
|
||||
|| (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
|
||||
|| (code == SUBREG && REG_P (SUBREG_REG (x))
|
||||
&& REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
|
||||
/* If we're setting only part of a multi-word register,
|
||||
we shall mark it as referenced, because the words
|
||||
|
|
@ -595,7 +595,7 @@ mark_referenced_regs (rtx x)
|
|||
|
||||
if (hardregno >= 0)
|
||||
{
|
||||
int nregs = HARD_REGNO_NREGS (hardregno, GET_MODE (x));
|
||||
int nregs = hard_regno_nregs[hardregno][GET_MODE (x)];
|
||||
while (nregs-- > 0)
|
||||
SET_HARD_REG_BIT (referenced_regs, hardregno + nregs);
|
||||
}
|
||||
|
|
@ -644,15 +644,13 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
|
|||
struct insn_chain *new;
|
||||
rtx mem;
|
||||
|
||||
/* A common failure mode if register status is not correct in the RTL
|
||||
is for this routine to be called with a REGNO we didn't expect to
|
||||
save. That will cause us to write an insn with a (nil) SET_DEST
|
||||
or SET_SRC. Instead of doing so and causing a crash later, check
|
||||
for this common case and abort here instead. This will remove one
|
||||
step in debugging such problems. */
|
||||
|
||||
if (regno_save_mem[regno][1] == 0)
|
||||
abort ();
|
||||
/* A common failure mode if register status is not correct in the
|
||||
RTL is for this routine to be called with a REGNO we didn't
|
||||
expect to save. That will cause us to write an insn with a (nil)
|
||||
SET_DEST or SET_SRC. Instead of doing so and causing a crash
|
||||
later, check for this common case here instead. This will remove
|
||||
one step in debugging such problems. */
|
||||
gcc_assert (regno_save_mem[regno][1]);
|
||||
|
||||
/* Get the pattern to emit and update our status.
|
||||
|
||||
|
|
@ -683,8 +681,10 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
|
|||
mem = regno_save_mem [regno][numregs];
|
||||
if (save_mode [regno] != VOIDmode
|
||||
&& save_mode [regno] != GET_MODE (mem)
|
||||
&& numregs == (unsigned int) HARD_REGNO_NREGS (regno, save_mode [regno]))
|
||||
&& numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]])
|
||||
mem = adjust_address (mem, save_mode[regno], 0);
|
||||
else
|
||||
mem = copy_rtx (mem);
|
||||
pat = gen_rtx_SET (VOIDmode,
|
||||
gen_rtx_REG (GET_MODE (mem),
|
||||
regno), mem);
|
||||
|
|
@ -717,15 +717,13 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
|
|||
struct insn_chain *new;
|
||||
rtx mem;
|
||||
|
||||
/* A common failure mode if register status is not correct in the RTL
|
||||
is for this routine to be called with a REGNO we didn't expect to
|
||||
save. That will cause us to write an insn with a (nil) SET_DEST
|
||||
or SET_SRC. Instead of doing so and causing a crash later, check
|
||||
for this common case and abort here instead. This will remove one
|
||||
/* A common failure mode if register status is not correct in the
|
||||
RTL is for this routine to be called with a REGNO we didn't
|
||||
expect to save. That will cause us to write an insn with a (nil)
|
||||
SET_DEST or SET_SRC. Instead of doing so and causing a crash
|
||||
later, check for this common case here. This will remove one
|
||||
step in debugging such problems. */
|
||||
|
||||
if (regno_save_mem[regno][1] == 0)
|
||||
abort ();
|
||||
gcc_assert (regno_save_mem[regno][1]);
|
||||
|
||||
/* Get the pattern to emit and update our status.
|
||||
|
||||
|
|
@ -755,8 +753,10 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
|
|||
mem = regno_save_mem [regno][numregs];
|
||||
if (save_mode [regno] != VOIDmode
|
||||
&& save_mode [regno] != GET_MODE (mem)
|
||||
&& numregs == (unsigned int) HARD_REGNO_NREGS (regno, save_mode [regno]))
|
||||
&& numregs == (unsigned int) hard_regno_nregs[regno][save_mode [regno]])
|
||||
mem = adjust_address (mem, save_mode[regno], 0);
|
||||
else
|
||||
mem = copy_rtx (mem);
|
||||
pat = gen_rtx_SET (VOIDmode, mem,
|
||||
gen_rtx_REG (GET_MODE (mem),
|
||||
regno));
|
||||
|
|
@ -789,7 +789,7 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
|
|||
isn't a problem. We do, however, assume here that CALL_INSNs don't
|
||||
reference CC0. Guard against non-INSN's like CODE_LABEL. */
|
||||
|
||||
if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
|
||||
if ((NONJUMP_INSN_P (insn) || JUMP_P (insn))
|
||||
&& before_p
|
||||
&& reg_referenced_p (cc0_rtx, PATTERN (insn)))
|
||||
chain = chain->prev, insn = chain->insn;
|
||||
|
|
@ -820,15 +820,13 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
|
|||
rtx reg = XEXP (link, 0);
|
||||
int regno, i;
|
||||
|
||||
if (GET_CODE (reg) != REG)
|
||||
abort ();
|
||||
|
||||
gcc_assert (REG_P (reg));
|
||||
regno = REGNO (reg);
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
regno = reg_renumber[regno];
|
||||
if (regno < 0)
|
||||
continue;
|
||||
for (i = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1;
|
||||
for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
|
||||
i >= 0; i--)
|
||||
SET_REGNO_REG_SET (&new->live_throughout, regno + i);
|
||||
}
|
||||
|
|
@ -849,7 +847,7 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
|
|||
registers from the live sets, and observe REG_UNUSED notes. */
|
||||
COPY_REG_SET (&new->live_throughout, &chain->live_throughout);
|
||||
/* Registers that are set in CHAIN->INSN live in the new insn.
|
||||
(Unless there is a REG_UNUSED note for them, but we don't
|
||||
(Unless there is a REG_UNUSED note for them, but we don't
|
||||
look for them here.) */
|
||||
note_stores (PATTERN (chain->insn), add_stored_regs,
|
||||
&new->live_throughout);
|
||||
|
|
|
|||
1739
contrib/gcc/calls.c
1739
contrib/gcc/calls.c
File diff suppressed because it is too large
Load diff
1188
contrib/gcc/cfg.c
1188
contrib/gcc/cfg.c
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/* Control flow graph building code for GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* find_basic_blocks divides the current function's rtl into basic
|
||||
blocks and constructs the CFG. The blocks are recorded in the
|
||||
|
|
@ -28,9 +28,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
|
||||
Available functionality:
|
||||
- CFG construction
|
||||
find_basic_blocks
|
||||
- Local CFG construction
|
||||
find_sub_basic_blocks */
|
||||
find_basic_blocks */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -50,10 +48,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
|
||||
static int count_basic_blocks (rtx);
|
||||
static void find_basic_blocks_1 (rtx);
|
||||
static rtx find_label_refs (rtx, rtx);
|
||||
static void make_edges (rtx, basic_block, basic_block, int);
|
||||
static void make_label_edge (sbitmap *, basic_block, rtx, int);
|
||||
static void make_eh_edge (sbitmap *, basic_block, rtx);
|
||||
static void make_edges (basic_block, basic_block, int);
|
||||
static void make_label_edge (sbitmap, basic_block, rtx, int);
|
||||
static void find_bb_boundaries (basic_block);
|
||||
static void compute_outgoing_frequencies (basic_block);
|
||||
|
||||
|
|
@ -68,7 +64,7 @@ inside_basic_block_p (rtx insn)
|
|||
case CODE_LABEL:
|
||||
/* Avoid creating of basic block for jumptables. */
|
||||
return (NEXT_INSN (insn) == 0
|
||||
|| GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
|
||||
|| !JUMP_P (NEXT_INSN (insn))
|
||||
|| (GET_CODE (PATTERN (NEXT_INSN (insn))) != ADDR_VEC
|
||||
&& GET_CODE (PATTERN (NEXT_INSN (insn))) != ADDR_DIFF_VEC));
|
||||
|
||||
|
|
@ -85,7 +81,7 @@ inside_basic_block_p (rtx insn)
|
|||
return false;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +105,12 @@ control_flow_insn_p (rtx insn)
|
|||
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
|
||||
|
||||
case CALL_INSN:
|
||||
/* Noreturn and sibling call instructions terminate the basic blocks
|
||||
(but only if they happen unconditionally). */
|
||||
if ((SIBLING_CALL_P (insn)
|
||||
|| find_reg_note (insn, REG_NORETURN, 0))
|
||||
&& GET_CODE (PATTERN (insn)) != COND_EXEC)
|
||||
return true;
|
||||
/* Call insn may return to the nonlocal goto handler. */
|
||||
return ((nonlocal_goto_handler_labels
|
||||
&& (0 == (note = find_reg_note (insn, REG_EH_REGION,
|
||||
|
|
@ -118,16 +120,21 @@ control_flow_insn_p (rtx insn)
|
|||
|| can_throw_internal (insn));
|
||||
|
||||
case INSN:
|
||||
/* Treat trap instructions like noreturn calls (same provision). */
|
||||
if (GET_CODE (PATTERN (insn)) == TRAP_IF
|
||||
&& XEXP (PATTERN (insn), 0) == const1_rtx)
|
||||
return true;
|
||||
|
||||
return (flag_non_call_exceptions && can_throw_internal (insn));
|
||||
|
||||
case BARRIER:
|
||||
/* It is nonsense to reach barrier when looking for the
|
||||
end of basic block, but before dead code is eliminated
|
||||
this may happen. */
|
||||
end of basic block, but before dead code is eliminated
|
||||
this may happen. */
|
||||
return false;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,15 +143,15 @@ control_flow_insn_p (rtx insn)
|
|||
static int
|
||||
count_basic_blocks (rtx f)
|
||||
{
|
||||
int count = 0;
|
||||
int count = NUM_FIXED_BLOCKS;
|
||||
bool saw_insn = false;
|
||||
rtx insn;
|
||||
|
||||
for (insn = f; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
/* Code labels and barriers causes current basic block to be
|
||||
terminated at previous real insn. */
|
||||
if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
|
||||
terminated at previous real insn. */
|
||||
if ((LABEL_P (insn) || BARRIER_P (insn))
|
||||
&& saw_insn)
|
||||
count++, saw_insn = false;
|
||||
|
||||
|
|
@ -162,59 +169,14 @@ count_basic_blocks (rtx f)
|
|||
|
||||
/* The rest of the compiler works a bit smoother when we don't have to
|
||||
check for the edge case of do-nothing functions with no basic blocks. */
|
||||
if (count == 0)
|
||||
if (count == NUM_FIXED_BLOCKS)
|
||||
{
|
||||
emit_insn (gen_rtx_USE (VOIDmode, const0_rtx));
|
||||
count = 1;
|
||||
count = NUM_FIXED_BLOCKS + 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Scan a list of insns for labels referred to other than by jumps.
|
||||
This is used to scan the alternatives of a call placeholder. */
|
||||
|
||||
static rtx
|
||||
find_label_refs (rtx f, rtx lvl)
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
for (insn = f; insn; insn = NEXT_INSN (insn))
|
||||
if (INSN_P (insn) && GET_CODE (insn) != JUMP_INSN)
|
||||
{
|
||||
rtx note;
|
||||
|
||||
/* Make a list of all labels referred to other than by jumps
|
||||
(which just don't have the REG_LABEL notes).
|
||||
|
||||
Make a special exception for labels followed by an ADDR*VEC,
|
||||
as this would be a part of the tablejump setup code.
|
||||
|
||||
Make a special exception to registers loaded with label
|
||||
values just before jump insns that use them. */
|
||||
|
||||
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
|
||||
if (REG_NOTE_KIND (note) == REG_LABEL)
|
||||
{
|
||||
rtx lab = XEXP (note, 0), next;
|
||||
|
||||
if ((next = next_nonnote_insn (lab)) != NULL
|
||||
&& GET_CODE (next) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
|
||||
;
|
||||
else if (GET_CODE (lab) == NOTE)
|
||||
;
|
||||
else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
|
||||
&& find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
|
||||
;
|
||||
else
|
||||
lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
|
||||
}
|
||||
}
|
||||
|
||||
return lvl;
|
||||
}
|
||||
|
||||
/* Create an edge between two basic blocks. FLAGS are auxiliary information
|
||||
about the edge that is accumulated between calls. */
|
||||
|
|
@ -222,10 +184,9 @@ find_label_refs (rtx f, rtx lvl)
|
|||
/* Create an edge from a basic block to a label. */
|
||||
|
||||
static void
|
||||
make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags)
|
||||
make_label_edge (sbitmap edge_cache, basic_block src, rtx label, int flags)
|
||||
{
|
||||
if (GET_CODE (label) != CODE_LABEL)
|
||||
abort ();
|
||||
gcc_assert (LABEL_P (label));
|
||||
|
||||
/* If the label was never emitted, this insn is junk, but avoid a
|
||||
crash trying to refer to BLOCK_FOR_INSN (label). This can happen
|
||||
|
|
@ -240,10 +201,10 @@ make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags)
|
|||
|
||||
/* Create the edges generated by INSN in REGION. */
|
||||
|
||||
static void
|
||||
make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
|
||||
void
|
||||
rtl_make_eh_edge (sbitmap edge_cache, basic_block src, rtx insn)
|
||||
{
|
||||
int is_call = GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0;
|
||||
int is_call = CALL_P (insn) ? EDGE_ABNORMAL_CALL : 0;
|
||||
rtx handlers, i;
|
||||
|
||||
handlers = reachable_handlers (insn);
|
||||
|
|
@ -255,55 +216,78 @@ make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
|
|||
free_INSN_LIST_list (&handlers);
|
||||
}
|
||||
|
||||
/* Identify the edges between basic blocks MIN to MAX.
|
||||
/* States of basic block as seen by find_many_sub_basic_blocks. */
|
||||
enum state {
|
||||
/* Basic blocks created via split_block belong to this state.
|
||||
make_edges will examine these basic blocks to see if we need to
|
||||
create edges going out of them. */
|
||||
BLOCK_NEW = 0,
|
||||
|
||||
NONLOCAL_LABEL_LIST is a list of non-local labels in the function. Blocks
|
||||
that are otherwise unreachable may be reachable with a non-local goto.
|
||||
/* Basic blocks that do not need examining belong to this state.
|
||||
These blocks will be left intact. In particular, make_edges will
|
||||
not create edges going out of these basic blocks. */
|
||||
BLOCK_ORIGINAL,
|
||||
|
||||
BB_EH_END is an array indexed by basic block number in which we record
|
||||
the list of exception regions active at the end of the basic block. */
|
||||
/* Basic blocks that may need splitting (due to a label appearing in
|
||||
the middle, etc) belong to this state. After splitting them,
|
||||
make_edges will create edges going out of them as needed. */
|
||||
BLOCK_TO_SPLIT
|
||||
};
|
||||
|
||||
#define STATE(BB) (enum state) ((size_t) (BB)->aux)
|
||||
#define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
|
||||
|
||||
/* Used internally by purge_dead_tablejump_edges, ORed into state. */
|
||||
#define BLOCK_USED_BY_TABLEJUMP 32
|
||||
#define FULL_STATE(BB) ((size_t) (BB)->aux)
|
||||
|
||||
/* Identify the edges going out of basic blocks between MIN and MAX,
|
||||
inclusive, that have their states set to BLOCK_NEW or
|
||||
BLOCK_TO_SPLIT.
|
||||
|
||||
UPDATE_P should be nonzero if we are updating CFG and zero if we
|
||||
are building CFG from scratch. */
|
||||
|
||||
static void
|
||||
make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p)
|
||||
make_edges (basic_block min, basic_block max, int update_p)
|
||||
{
|
||||
basic_block bb;
|
||||
sbitmap *edge_cache = NULL;
|
||||
|
||||
/* Assume no computed jump; revise as we create edges. */
|
||||
current_function_has_computed_jump = 0;
|
||||
sbitmap edge_cache = NULL;
|
||||
|
||||
/* Heavy use of computed goto in machine-generated code can lead to
|
||||
nearly fully-connected CFGs. In that case we spend a significant
|
||||
amount of time searching the edge lists for duplicates. */
|
||||
if (forced_labels || label_value_list || cfun->max_jumptable_ents > 100)
|
||||
{
|
||||
edge_cache = sbitmap_vector_alloc (last_basic_block, last_basic_block);
|
||||
sbitmap_vector_zero (edge_cache, last_basic_block);
|
||||
|
||||
if (update_p)
|
||||
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
|
||||
{
|
||||
edge e;
|
||||
|
||||
for (e = bb->succ; e ; e = e->succ_next)
|
||||
if (e->dest != EXIT_BLOCK_PTR)
|
||||
SET_BIT (edge_cache[bb->index], e->dest->index);
|
||||
}
|
||||
}
|
||||
if (forced_labels || cfun->max_jumptable_ents > 100)
|
||||
edge_cache = sbitmap_alloc (last_basic_block);
|
||||
|
||||
/* By nature of the way these get numbered, ENTRY_BLOCK_PTR->next_bb block
|
||||
is always the entry. */
|
||||
if (min == ENTRY_BLOCK_PTR->next_bb)
|
||||
cached_make_edge (edge_cache, ENTRY_BLOCK_PTR, min,
|
||||
EDGE_FALLTHRU);
|
||||
make_edge (ENTRY_BLOCK_PTR, min, EDGE_FALLTHRU);
|
||||
|
||||
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
|
||||
{
|
||||
rtx insn, x;
|
||||
enum rtx_code code;
|
||||
int force_fallthru = 0;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
if (GET_CODE (BB_HEAD (bb)) == CODE_LABEL
|
||||
if (STATE (bb) == BLOCK_ORIGINAL)
|
||||
continue;
|
||||
|
||||
/* If we have an edge cache, cache edges going out of BB. */
|
||||
if (edge_cache)
|
||||
{
|
||||
sbitmap_zero (edge_cache);
|
||||
if (update_p)
|
||||
{
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
if (e->dest != EXIT_BLOCK_PTR)
|
||||
SET_BIT (edge_cache, e->dest->index);
|
||||
}
|
||||
}
|
||||
|
||||
if (LABEL_P (BB_HEAD (bb))
|
||||
&& LABEL_ALT_ENTRY_P (BB_HEAD (bb)))
|
||||
cached_make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
|
||||
|
||||
|
|
@ -320,7 +304,7 @@ make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p
|
|||
|
||||
/* Recognize exception handling placeholders. */
|
||||
if (GET_CODE (PATTERN (insn)) == RESX)
|
||||
make_eh_edge (edge_cache, bb, insn);
|
||||
rtl_make_eh_edge (edge_cache, bb, insn);
|
||||
|
||||
/* Recognize a non-local goto as a branch outside the
|
||||
current function. */
|
||||
|
|
@ -351,23 +335,12 @@ make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p
|
|||
&& GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
|
||||
make_label_edge (edge_cache, bb,
|
||||
XEXP (XEXP (SET_SRC (tmp), 2), 0), 0);
|
||||
|
||||
#ifdef CASE_DROPS_THROUGH
|
||||
/* Silly VAXen. The ADDR_VEC is going to be in the way of
|
||||
us naturally detecting fallthru into the next block. */
|
||||
force_fallthru = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If this is a computed jump, then mark it as reaching
|
||||
everything on the label_value_list and forced_labels list. */
|
||||
everything on the forced_labels list. */
|
||||
else if (computed_jump_p (insn))
|
||||
{
|
||||
current_function_has_computed_jump = 1;
|
||||
|
||||
for (x = label_value_list; x; x = XEXP (x, 1))
|
||||
make_label_edge (edge_cache, bb, XEXP (x, 0), EDGE_ABNORMAL);
|
||||
|
||||
for (x = forced_labels; x; x = XEXP (x, 1))
|
||||
make_label_edge (edge_cache, bb, XEXP (x, 0), EDGE_ABNORMAL);
|
||||
}
|
||||
|
|
@ -379,8 +352,7 @@ make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p
|
|||
/* Otherwise, we have a plain conditional or unconditional jump. */
|
||||
else
|
||||
{
|
||||
if (! JUMP_LABEL (insn))
|
||||
abort ();
|
||||
gcc_assert (JUMP_LABEL (insn));
|
||||
make_label_edge (edge_cache, bb, JUMP_LABEL (insn), 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -400,7 +372,7 @@ make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p
|
|||
else if (code == CALL_INSN || flag_non_call_exceptions)
|
||||
{
|
||||
/* Add any appropriate EH edges. */
|
||||
make_eh_edge (edge_cache, bb, insn);
|
||||
rtl_make_eh_edge (edge_cache, bb, insn);
|
||||
|
||||
if (code == CALL_INSN && nonlocal_goto_handler_labels)
|
||||
{
|
||||
|
|
@ -424,16 +396,20 @@ make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p
|
|||
|
||||
/* Find out if we can drop through to the next block. */
|
||||
insn = NEXT_INSN (insn);
|
||||
e = find_edge (bb, EXIT_BLOCK_PTR);
|
||||
if (e && e->flags & EDGE_FALLTHRU)
|
||||
insn = NULL;
|
||||
|
||||
while (insn
|
||||
&& GET_CODE (insn) == NOTE
|
||||
&& NOTE_P (insn)
|
||||
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
|
||||
insn = NEXT_INSN (insn);
|
||||
|
||||
if (!insn || (bb->next_bb == EXIT_BLOCK_PTR && force_fallthru))
|
||||
if (!insn)
|
||||
cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
|
||||
else if (bb->next_bb != EXIT_BLOCK_PTR)
|
||||
{
|
||||
if (force_fallthru || insn == BB_HEAD (bb->next_bb))
|
||||
if (insn == BB_HEAD (bb->next_bb))
|
||||
cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
|
||||
}
|
||||
}
|
||||
|
|
@ -452,8 +428,6 @@ find_basic_blocks_1 (rtx f)
|
|||
{
|
||||
rtx insn, next;
|
||||
rtx bb_note = NULL_RTX;
|
||||
rtx lvl = NULL_RTX;
|
||||
rtx trll = NULL_RTX;
|
||||
rtx head = NULL_RTX;
|
||||
rtx end = NULL_RTX;
|
||||
basic_block prev = ENTRY_BLOCK_PTR;
|
||||
|
|
@ -470,7 +444,7 @@ find_basic_blocks_1 (rtx f)
|
|||
|
||||
next = NEXT_INSN (insn);
|
||||
|
||||
if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
|
||||
if ((LABEL_P (insn) || BARRIER_P (insn))
|
||||
&& head)
|
||||
{
|
||||
prev = create_basic_block_structure (head, end, bb_note, prev);
|
||||
|
|
@ -514,57 +488,13 @@ find_basic_blocks_1 (rtx f)
|
|||
|
||||
case CODE_LABEL:
|
||||
case JUMP_INSN:
|
||||
case CALL_INSN:
|
||||
case INSN:
|
||||
case BARRIER:
|
||||
break;
|
||||
|
||||
case CALL_INSN:
|
||||
if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
|
||||
{
|
||||
/* Scan each of the alternatives for label refs. */
|
||||
lvl = find_label_refs (XEXP (PATTERN (insn), 0), lvl);
|
||||
lvl = find_label_refs (XEXP (PATTERN (insn), 1), lvl);
|
||||
lvl = find_label_refs (XEXP (PATTERN (insn), 2), lvl);
|
||||
/* Record its tail recursion label, if any. */
|
||||
if (XEXP (PATTERN (insn), 3) != NULL_RTX)
|
||||
trll = alloc_EXPR_LIST (0, XEXP (PATTERN (insn), 3), trll);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
|
||||
{
|
||||
rtx note;
|
||||
|
||||
/* Make a list of all labels referred to other than by jumps.
|
||||
|
||||
Make a special exception for labels followed by an ADDR*VEC,
|
||||
as this would be a part of the tablejump setup code.
|
||||
|
||||
Make a special exception to registers loaded with label
|
||||
values just before jump insns that use them. */
|
||||
|
||||
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
|
||||
if (REG_NOTE_KIND (note) == REG_LABEL)
|
||||
{
|
||||
rtx lab = XEXP (note, 0), next;
|
||||
|
||||
if ((next = next_nonnote_insn (lab)) != NULL
|
||||
&& GET_CODE (next) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (next)) == ADDR_VEC
|
||||
|| GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
|
||||
;
|
||||
else if (GET_CODE (lab) == NOTE)
|
||||
;
|
||||
else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
|
||||
&& find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
|
||||
;
|
||||
else
|
||||
lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
|
||||
}
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -573,22 +503,17 @@ find_basic_blocks_1 (rtx f)
|
|||
else if (bb_note)
|
||||
delete_insn (bb_note);
|
||||
|
||||
if (last_basic_block != n_basic_blocks)
|
||||
abort ();
|
||||
gcc_assert (last_basic_block == n_basic_blocks);
|
||||
|
||||
label_value_list = lvl;
|
||||
tail_recursion_label_list = trll;
|
||||
clear_aux_for_blocks ();
|
||||
}
|
||||
|
||||
|
||||
/* Find basic blocks of the current function.
|
||||
F is the first insn of the function and NREGS the number of register
|
||||
numbers in use. */
|
||||
F is the first insn of the function. */
|
||||
|
||||
void
|
||||
find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
|
||||
FILE *file ATTRIBUTE_UNUSED)
|
||||
find_basic_blocks (rtx f)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
|
|
@ -605,14 +530,15 @@ find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
|
|||
FOR_EACH_BB (bb)
|
||||
bb->aux = NULL;
|
||||
|
||||
VARRAY_FREE (basic_block_info);
|
||||
basic_block_info = NULL;
|
||||
}
|
||||
|
||||
n_basic_blocks = count_basic_blocks (f);
|
||||
last_basic_block = 0;
|
||||
last_basic_block = NUM_FIXED_BLOCKS;
|
||||
ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
|
||||
EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
|
||||
|
||||
|
||||
/* Size the basic block table. The actual structures will be allocated
|
||||
by find_basic_blocks_1, since we want to keep the structure pointers
|
||||
stable across calls to find_basic_blocks. */
|
||||
|
|
@ -621,12 +547,23 @@ find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
|
|||
instructions at all until close to the end of compilation when we
|
||||
actually lay them out. */
|
||||
|
||||
VARRAY_BB_INIT (basic_block_info, n_basic_blocks, "basic_block_info");
|
||||
basic_block_info = VEC_alloc (basic_block, gc, n_basic_blocks);
|
||||
VEC_safe_grow (basic_block, gc, basic_block_info, n_basic_blocks);
|
||||
memset (VEC_address (basic_block, basic_block_info), 0,
|
||||
sizeof (basic_block) * n_basic_blocks);
|
||||
SET_BASIC_BLOCK (ENTRY_BLOCK, ENTRY_BLOCK_PTR);
|
||||
SET_BASIC_BLOCK (EXIT_BLOCK, EXIT_BLOCK_PTR);
|
||||
|
||||
find_basic_blocks_1 (f);
|
||||
|
||||
profile_status = PROFILE_ABSENT;
|
||||
|
||||
/* Tell make_edges to examine every block for out-going edges. */
|
||||
FOR_EACH_BB (bb)
|
||||
SET_STATE (bb, BLOCK_NEW);
|
||||
|
||||
/* Discover the edges of our cfg. */
|
||||
make_edges (label_value_list, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, 0);
|
||||
make_edges (ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, 0);
|
||||
|
||||
/* Do very simple cleanup now, for the benefit of code that runs between
|
||||
here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns. */
|
||||
|
|
@ -638,11 +575,58 @@ find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
|
|||
timevar_pop (TV_CFG);
|
||||
}
|
||||
|
||||
/* State of basic block as seen by find_sub_basic_blocks. */
|
||||
enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT};
|
||||
static void
|
||||
mark_tablejump_edge (rtx label)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
#define STATE(BB) (enum state) ((size_t) (BB)->aux)
|
||||
#define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
|
||||
gcc_assert (LABEL_P (label));
|
||||
/* See comment in make_label_edge. */
|
||||
if (INSN_UID (label) == 0)
|
||||
return;
|
||||
bb = BLOCK_FOR_INSN (label);
|
||||
SET_STATE (bb, FULL_STATE (bb) | BLOCK_USED_BY_TABLEJUMP);
|
||||
}
|
||||
|
||||
static void
|
||||
purge_dead_tablejump_edges (basic_block bb, rtx table)
|
||||
{
|
||||
rtx insn = BB_END (bb), tmp;
|
||||
rtvec vec;
|
||||
int j;
|
||||
edge_iterator ei;
|
||||
edge e;
|
||||
|
||||
if (GET_CODE (PATTERN (table)) == ADDR_VEC)
|
||||
vec = XVEC (PATTERN (table), 0);
|
||||
else
|
||||
vec = XVEC (PATTERN (table), 1);
|
||||
|
||||
for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
|
||||
mark_tablejump_edge (XEXP (RTVEC_ELT (vec, j), 0));
|
||||
|
||||
/* Some targets (eg, ARM) emit a conditional jump that also
|
||||
contains the out-of-range target. Scan for these and
|
||||
add an edge if necessary. */
|
||||
if ((tmp = single_set (insn)) != NULL
|
||||
&& SET_DEST (tmp) == pc_rtx
|
||||
&& GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
|
||||
&& GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
|
||||
mark_tablejump_edge (XEXP (XEXP (SET_SRC (tmp), 2), 0));
|
||||
|
||||
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
|
||||
{
|
||||
if (FULL_STATE (e->dest) & BLOCK_USED_BY_TABLEJUMP)
|
||||
SET_STATE (e->dest, FULL_STATE (e->dest)
|
||||
& ~(size_t) BLOCK_USED_BY_TABLEJUMP);
|
||||
else if (!(e->flags & (EDGE_ABNORMAL | EDGE_EH)))
|
||||
{
|
||||
remove_edge (e);
|
||||
continue;
|
||||
}
|
||||
ei_next (&ei);
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan basic block BB for possible BB boundaries inside the block
|
||||
and create new basic blocks in the progress. */
|
||||
|
|
@ -650,15 +634,17 @@ enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT};
|
|||
static void
|
||||
find_bb_boundaries (basic_block bb)
|
||||
{
|
||||
basic_block orig_bb = bb;
|
||||
rtx insn = BB_HEAD (bb);
|
||||
rtx end = BB_END (bb);
|
||||
rtx table;
|
||||
rtx flow_transfer_insn = NULL_RTX;
|
||||
edge fallthru = NULL;
|
||||
|
||||
if (insn == BB_END (bb))
|
||||
return;
|
||||
|
||||
if (GET_CODE (insn) == CODE_LABEL)
|
||||
if (LABEL_P (insn))
|
||||
insn = NEXT_INSN (insn);
|
||||
|
||||
/* Scan insn chain and try to find new basic block boundaries. */
|
||||
|
|
@ -708,6 +694,11 @@ find_bb_boundaries (basic_block bb)
|
|||
followed by cleanup at fallthru edge, so the outgoing edges may
|
||||
be dead. */
|
||||
purge_dead_edges (bb);
|
||||
|
||||
/* purge_dead_edges doesn't handle tablejump's, but if we have split the
|
||||
basic block, we might need to kill some edges. */
|
||||
if (bb != orig_bb && tablejump_p (BB_END (bb), NULL, &table))
|
||||
purge_dead_tablejump_edges (bb, table);
|
||||
}
|
||||
|
||||
/* Assume that frequency of basic block B is known. Compute frequencies
|
||||
|
|
@ -717,35 +708,44 @@ static void
|
|||
compute_outgoing_frequencies (basic_block b)
|
||||
{
|
||||
edge e, f;
|
||||
edge_iterator ei;
|
||||
|
||||
if (b->succ && b->succ->succ_next && !b->succ->succ_next->succ_next)
|
||||
if (EDGE_COUNT (b->succs) == 2)
|
||||
{
|
||||
rtx note = find_reg_note (BB_END (b), REG_BR_PROB, NULL);
|
||||
int probability;
|
||||
|
||||
if (!note)
|
||||
return;
|
||||
|
||||
probability = INTVAL (XEXP (note, 0));
|
||||
e = BRANCH_EDGE (b);
|
||||
e->probability = probability;
|
||||
e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
|
||||
/ REG_BR_PROB_BASE);
|
||||
f = FALLTHRU_EDGE (b);
|
||||
f->probability = REG_BR_PROB_BASE - probability;
|
||||
f->count = b->count - e->count;
|
||||
if (note)
|
||||
{
|
||||
probability = INTVAL (XEXP (note, 0));
|
||||
e = BRANCH_EDGE (b);
|
||||
e->probability = probability;
|
||||
e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
|
||||
/ REG_BR_PROB_BASE);
|
||||
f = FALLTHRU_EDGE (b);
|
||||
f->probability = REG_BR_PROB_BASE - probability;
|
||||
f->count = b->count - e->count;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (b->succ && !b->succ->succ_next)
|
||||
if (single_succ_p (b))
|
||||
{
|
||||
e = b->succ;
|
||||
e = single_succ_edge (b);
|
||||
e->probability = REG_BR_PROB_BASE;
|
||||
e->count = b->count;
|
||||
return;
|
||||
}
|
||||
guess_outgoing_edge_probabilities (b);
|
||||
if (b->count)
|
||||
FOR_EACH_EDGE (e, ei, b->succs)
|
||||
e->count = ((b->count * e->probability + REG_BR_PROB_BASE / 2)
|
||||
/ REG_BR_PROB_BASE);
|
||||
}
|
||||
|
||||
/* Assume that someone emitted code with control flow instructions to the
|
||||
basic block. Update the data structure. */
|
||||
/* Assume that some pass has inserted labels or control flow
|
||||
instructions within a basic block. Split basic blocks as needed
|
||||
and create edges. */
|
||||
|
||||
void
|
||||
find_many_sub_basic_blocks (sbitmap blocks)
|
||||
|
|
@ -771,67 +771,32 @@ find_many_sub_basic_blocks (sbitmap blocks)
|
|||
|
||||
/* Now re-scan and wire in all edges. This expect simple (conditional)
|
||||
jumps at the end of each new basic blocks. */
|
||||
make_edges (NULL, min, max, 1);
|
||||
make_edges (min, max, 1);
|
||||
|
||||
/* Update branch probabilities. Expect only (un)conditional jumps
|
||||
to be created with only the forward edges. */
|
||||
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
|
||||
{
|
||||
edge e;
|
||||
if (profile_status != PROFILE_ABSENT)
|
||||
FOR_BB_BETWEEN (bb, min, max->next_bb, next_bb)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
if (STATE (bb) == BLOCK_ORIGINAL)
|
||||
continue;
|
||||
if (STATE (bb) == BLOCK_NEW)
|
||||
{
|
||||
bb->count = 0;
|
||||
bb->frequency = 0;
|
||||
for (e = bb->pred; e; e = e->pred_next)
|
||||
{
|
||||
bb->count += e->count;
|
||||
bb->frequency += EDGE_FREQUENCY (e);
|
||||
}
|
||||
}
|
||||
if (STATE (bb) == BLOCK_ORIGINAL)
|
||||
continue;
|
||||
if (STATE (bb) == BLOCK_NEW)
|
||||
{
|
||||
bb->count = 0;
|
||||
bb->frequency = 0;
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
bb->count += e->count;
|
||||
bb->frequency += EDGE_FREQUENCY (e);
|
||||
}
|
||||
}
|
||||
|
||||
compute_outgoing_frequencies (bb);
|
||||
}
|
||||
compute_outgoing_frequencies (bb);
|
||||
}
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
SET_STATE (bb, 0);
|
||||
}
|
||||
|
||||
/* Like above but for single basic block only. */
|
||||
|
||||
void
|
||||
find_sub_basic_blocks (basic_block bb)
|
||||
{
|
||||
basic_block min, max, b;
|
||||
basic_block next = bb->next_bb;
|
||||
|
||||
min = bb;
|
||||
find_bb_boundaries (bb);
|
||||
max = next->prev_bb;
|
||||
|
||||
/* Now re-scan and wire in all edges. This expect simple (conditional)
|
||||
jumps at the end of each new basic blocks. */
|
||||
make_edges (NULL, min, max, 1);
|
||||
|
||||
/* Update branch probabilities. Expect only (un)conditional jumps
|
||||
to be created with only the forward edges. */
|
||||
FOR_BB_BETWEEN (b, min, max->next_bb, next_bb)
|
||||
{
|
||||
edge e;
|
||||
|
||||
if (b != min)
|
||||
{
|
||||
b->count = 0;
|
||||
b->frequency = 0;
|
||||
for (e = b->pred; e; e = e->pred_next)
|
||||
{
|
||||
b->count += e->count;
|
||||
b->frequency += EDGE_FREQUENCY (e);
|
||||
}
|
||||
}
|
||||
|
||||
compute_outgoing_frequencies (b);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
1732
contrib/gcc/cfgexpand.c
Normal file
1732
contrib/gcc/cfgexpand.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Hooks for cfg representation specific functions.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Sebastian Pop <s.pop@laposte.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,8 +16,8 @@ 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. */
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
|
|
@ -26,12 +26,12 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "tree.h"
|
||||
#include "rtl.h"
|
||||
#include "basic-block.h"
|
||||
|
||||
extern struct cfg_hooks rtl_cfg_hooks;
|
||||
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
|
||||
#include "tree-flow.h"
|
||||
#include "timevar.h"
|
||||
#include "toplev.h"
|
||||
|
||||
/* A pointer to one of the hooks containers. */
|
||||
struct cfg_hooks *cfg_hooks;
|
||||
static struct cfg_hooks *cfg_hooks;
|
||||
|
||||
/* Initialization of functions specific to the rtl IR. */
|
||||
void
|
||||
|
|
@ -46,3 +46,845 @@ cfg_layout_rtl_register_cfg_hooks (void)
|
|||
{
|
||||
cfg_hooks = &cfg_layout_rtl_cfg_hooks;
|
||||
}
|
||||
|
||||
/* Initialization of functions specific to the tree IR. */
|
||||
|
||||
void
|
||||
tree_register_cfg_hooks (void)
|
||||
{
|
||||
cfg_hooks = &tree_cfg_hooks;
|
||||
}
|
||||
|
||||
/* Returns current ir type (rtl = 0, trees = 1). */
|
||||
|
||||
int
|
||||
ir_type (void)
|
||||
{
|
||||
return cfg_hooks == &tree_cfg_hooks ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Verify the CFG consistency.
|
||||
|
||||
Currently it does following: checks edge and basic block list correctness
|
||||
and calls into IL dependent checking then. */
|
||||
|
||||
void
|
||||
verify_flow_info (void)
|
||||
{
|
||||
size_t *edge_checksum;
|
||||
int err = 0;
|
||||
basic_block bb, last_bb_seen;
|
||||
basic_block *last_visited;
|
||||
|
||||
timevar_push (TV_CFG_VERIFY);
|
||||
last_visited = XCNEWVEC (basic_block, last_basic_block);
|
||||
edge_checksum = XCNEWVEC (size_t, last_basic_block);
|
||||
|
||||
/* Check bb chain & numbers. */
|
||||
last_bb_seen = ENTRY_BLOCK_PTR;
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
|
||||
{
|
||||
if (bb != EXIT_BLOCK_PTR
|
||||
&& bb != BASIC_BLOCK (bb->index))
|
||||
{
|
||||
error ("bb %d on wrong place", bb->index);
|
||||
err = 1;
|
||||
}
|
||||
|
||||
if (bb->prev_bb != last_bb_seen)
|
||||
{
|
||||
error ("prev_bb of %d should be %d, not %d",
|
||||
bb->index, last_bb_seen->index, bb->prev_bb->index);
|
||||
err = 1;
|
||||
}
|
||||
|
||||
last_bb_seen = bb;
|
||||
}
|
||||
|
||||
/* Now check the basic blocks (boundaries etc.) */
|
||||
FOR_EACH_BB_REVERSE (bb)
|
||||
{
|
||||
int n_fallthru = 0;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
if (bb->count < 0)
|
||||
{
|
||||
error ("verify_flow_info: Wrong count of block %i %i",
|
||||
bb->index, (int)bb->count);
|
||||
err = 1;
|
||||
}
|
||||
if (bb->frequency < 0)
|
||||
{
|
||||
error ("verify_flow_info: Wrong frequency of block %i %i",
|
||||
bb->index, bb->frequency);
|
||||
err = 1;
|
||||
}
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
{
|
||||
if (last_visited [e->dest->index] == bb)
|
||||
{
|
||||
error ("verify_flow_info: Duplicate edge %i->%i",
|
||||
e->src->index, e->dest->index);
|
||||
err = 1;
|
||||
}
|
||||
if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
|
||||
{
|
||||
error ("verify_flow_info: Wrong probability of edge %i->%i %i",
|
||||
e->src->index, e->dest->index, e->probability);
|
||||
err = 1;
|
||||
}
|
||||
if (e->count < 0)
|
||||
{
|
||||
error ("verify_flow_info: Wrong count of edge %i->%i %i",
|
||||
e->src->index, e->dest->index, (int)e->count);
|
||||
err = 1;
|
||||
}
|
||||
|
||||
last_visited [e->dest->index] = bb;
|
||||
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
n_fallthru++;
|
||||
|
||||
if (e->src != bb)
|
||||
{
|
||||
error ("verify_flow_info: Basic block %d succ edge is corrupted",
|
||||
bb->index);
|
||||
fprintf (stderr, "Predecessor: ");
|
||||
dump_edge_info (stderr, e, 0);
|
||||
fprintf (stderr, "\nSuccessor: ");
|
||||
dump_edge_info (stderr, e, 1);
|
||||
fprintf (stderr, "\n");
|
||||
err = 1;
|
||||
}
|
||||
|
||||
edge_checksum[e->dest->index] += (size_t) e;
|
||||
}
|
||||
if (n_fallthru > 1)
|
||||
{
|
||||
error ("wrong amount of branch edges after unconditional jump %i", bb->index);
|
||||
err = 1;
|
||||
}
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
{
|
||||
if (e->dest != bb)
|
||||
{
|
||||
error ("basic block %d pred edge is corrupted", bb->index);
|
||||
fputs ("Predecessor: ", stderr);
|
||||
dump_edge_info (stderr, e, 0);
|
||||
fputs ("\nSuccessor: ", stderr);
|
||||
dump_edge_info (stderr, e, 1);
|
||||
fputc ('\n', stderr);
|
||||
err = 1;
|
||||
}
|
||||
|
||||
if (ei.index != e->dest_idx)
|
||||
{
|
||||
error ("basic block %d pred edge is corrupted", bb->index);
|
||||
error ("its dest_idx should be %d, not %d",
|
||||
ei.index, e->dest_idx);
|
||||
fputs ("Predecessor: ", stderr);
|
||||
dump_edge_info (stderr, e, 0);
|
||||
fputs ("\nSuccessor: ", stderr);
|
||||
dump_edge_info (stderr, e, 1);
|
||||
fputc ('\n', stderr);
|
||||
err = 1;
|
||||
}
|
||||
|
||||
edge_checksum[e->dest->index] -= (size_t) e;
|
||||
}
|
||||
}
|
||||
|
||||
/* Complete edge checksumming for ENTRY and EXIT. */
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
|
||||
edge_checksum[e->dest->index] += (size_t) e;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
|
||||
edge_checksum[e->dest->index] -= (size_t) e;
|
||||
}
|
||||
|
||||
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
|
||||
if (edge_checksum[bb->index])
|
||||
{
|
||||
error ("basic block %i edge lists are corrupted", bb->index);
|
||||
err = 1;
|
||||
}
|
||||
|
||||
last_bb_seen = ENTRY_BLOCK_PTR;
|
||||
|
||||
/* Clean up. */
|
||||
free (last_visited);
|
||||
free (edge_checksum);
|
||||
|
||||
if (cfg_hooks->verify_flow_info)
|
||||
err |= cfg_hooks->verify_flow_info ();
|
||||
if (err)
|
||||
internal_error ("verify_flow_info failed");
|
||||
timevar_pop (TV_CFG_VERIFY);
|
||||
}
|
||||
|
||||
/* Print out one basic block. This function takes care of the purely
|
||||
graph related information. The cfg hook for the active representation
|
||||
should dump representation-specific information. */
|
||||
|
||||
void
|
||||
dump_bb (basic_block bb, FILE *outf, int indent)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
char *s_indent;
|
||||
|
||||
s_indent = alloca ((size_t) indent + 1);
|
||||
memset (s_indent, ' ', (size_t) indent);
|
||||
s_indent[indent] = '\0';
|
||||
|
||||
fprintf (outf, ";;%s basic block %d, loop depth %d, count ",
|
||||
s_indent, bb->index, bb->loop_depth);
|
||||
fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
|
||||
putc ('\n', outf);
|
||||
|
||||
fprintf (outf, ";;%s prev block ", s_indent);
|
||||
if (bb->prev_bb)
|
||||
fprintf (outf, "%d, ", bb->prev_bb->index);
|
||||
else
|
||||
fprintf (outf, "(nil), ");
|
||||
fprintf (outf, "next block ");
|
||||
if (bb->next_bb)
|
||||
fprintf (outf, "%d", bb->next_bb->index);
|
||||
else
|
||||
fprintf (outf, "(nil)");
|
||||
putc ('\n', outf);
|
||||
|
||||
fprintf (outf, ";;%s pred: ", s_indent);
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
dump_edge_info (outf, e, 0);
|
||||
putc ('\n', outf);
|
||||
|
||||
fprintf (outf, ";;%s succ: ", s_indent);
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
dump_edge_info (outf, e, 1);
|
||||
putc ('\n', outf);
|
||||
|
||||
if (cfg_hooks->dump_bb)
|
||||
cfg_hooks->dump_bb (bb, outf, indent);
|
||||
}
|
||||
|
||||
/* Redirect edge E to the given basic block DEST and update underlying program
|
||||
representation. Returns edge representing redirected branch (that may not
|
||||
be equivalent to E in the case of duplicate edges being removed) or NULL
|
||||
if edge is not easily redirectable for whatever reason. */
|
||||
|
||||
edge
|
||||
redirect_edge_and_branch (edge e, basic_block dest)
|
||||
{
|
||||
edge ret;
|
||||
|
||||
if (!cfg_hooks->redirect_edge_and_branch)
|
||||
internal_error ("%s does not support redirect_edge_and_branch",
|
||||
cfg_hooks->name);
|
||||
|
||||
ret = cfg_hooks->redirect_edge_and_branch (e, dest);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Redirect the edge E to basic block DEST even if it requires creating
|
||||
of a new basic block; then it returns the newly created basic block.
|
||||
Aborts when redirection is impossible. */
|
||||
|
||||
basic_block
|
||||
redirect_edge_and_branch_force (edge e, basic_block dest)
|
||||
{
|
||||
basic_block ret;
|
||||
|
||||
if (!cfg_hooks->redirect_edge_and_branch_force)
|
||||
internal_error ("%s does not support redirect_edge_and_branch_force",
|
||||
cfg_hooks->name);
|
||||
|
||||
ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Splits basic block BB after the specified instruction I (but at least after
|
||||
the labels). If I is NULL, splits just after labels. The newly created edge
|
||||
is returned. The new basic block is created just after the old one. */
|
||||
|
||||
edge
|
||||
split_block (basic_block bb, void *i)
|
||||
{
|
||||
basic_block new_bb;
|
||||
|
||||
if (!cfg_hooks->split_block)
|
||||
internal_error ("%s does not support split_block", cfg_hooks->name);
|
||||
|
||||
new_bb = cfg_hooks->split_block (bb, i);
|
||||
if (!new_bb)
|
||||
return NULL;
|
||||
|
||||
new_bb->count = bb->count;
|
||||
new_bb->frequency = bb->frequency;
|
||||
new_bb->loop_depth = bb->loop_depth;
|
||||
|
||||
if (dom_info_available_p (CDI_DOMINATORS))
|
||||
{
|
||||
redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
|
||||
set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
|
||||
}
|
||||
|
||||
return make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
|
||||
}
|
||||
|
||||
/* Splits block BB just after labels. The newly created edge is returned. */
|
||||
|
||||
edge
|
||||
split_block_after_labels (basic_block bb)
|
||||
{
|
||||
return split_block (bb, NULL);
|
||||
}
|
||||
|
||||
/* Moves block BB immediately after block AFTER. Returns false if the
|
||||
movement was impossible. */
|
||||
|
||||
bool
|
||||
move_block_after (basic_block bb, basic_block after)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (!cfg_hooks->move_block_after)
|
||||
internal_error ("%s does not support move_block_after", cfg_hooks->name);
|
||||
|
||||
ret = cfg_hooks->move_block_after (bb, after);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Deletes the basic block BB. */
|
||||
|
||||
void
|
||||
delete_basic_block (basic_block bb)
|
||||
{
|
||||
if (!cfg_hooks->delete_basic_block)
|
||||
internal_error ("%s does not support delete_basic_block", cfg_hooks->name);
|
||||
|
||||
cfg_hooks->delete_basic_block (bb);
|
||||
|
||||
/* Remove the edges into and out of this block. Note that there may
|
||||
indeed be edges in, if we are removing an unreachable loop. */
|
||||
while (EDGE_COUNT (bb->preds) != 0)
|
||||
remove_edge (EDGE_PRED (bb, 0));
|
||||
while (EDGE_COUNT (bb->succs) != 0)
|
||||
remove_edge (EDGE_SUCC (bb, 0));
|
||||
|
||||
if (dom_computed[CDI_DOMINATORS])
|
||||
delete_from_dominance_info (CDI_DOMINATORS, bb);
|
||||
if (dom_computed[CDI_POST_DOMINATORS])
|
||||
delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
|
||||
|
||||
/* Remove the basic block from the array. */
|
||||
expunge_block (bb);
|
||||
}
|
||||
|
||||
/* Splits edge E and returns the newly created basic block. */
|
||||
|
||||
basic_block
|
||||
split_edge (edge e)
|
||||
{
|
||||
basic_block ret;
|
||||
gcov_type count = e->count;
|
||||
int freq = EDGE_FREQUENCY (e);
|
||||
edge f;
|
||||
bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
|
||||
|
||||
if (!cfg_hooks->split_edge)
|
||||
internal_error ("%s does not support split_edge", cfg_hooks->name);
|
||||
|
||||
ret = cfg_hooks->split_edge (e);
|
||||
ret->count = count;
|
||||
ret->frequency = freq;
|
||||
single_succ_edge (ret)->probability = REG_BR_PROB_BASE;
|
||||
single_succ_edge (ret)->count = count;
|
||||
|
||||
if (irr)
|
||||
{
|
||||
ret->flags |= BB_IRREDUCIBLE_LOOP;
|
||||
single_pred_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
|
||||
single_succ_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
|
||||
}
|
||||
|
||||
if (dom_computed[CDI_DOMINATORS])
|
||||
set_immediate_dominator (CDI_DOMINATORS, ret, single_pred (ret));
|
||||
|
||||
if (dom_computed[CDI_DOMINATORS] >= DOM_NO_FAST_QUERY)
|
||||
{
|
||||
/* There are two cases:
|
||||
|
||||
If the immediate dominator of e->dest is not e->src, it
|
||||
remains unchanged.
|
||||
|
||||
If immediate dominator of e->dest is e->src, it may become
|
||||
ret, provided that all other predecessors of e->dest are
|
||||
dominated by e->dest. */
|
||||
|
||||
if (get_immediate_dominator (CDI_DOMINATORS, single_succ (ret))
|
||||
== single_pred (ret))
|
||||
{
|
||||
edge_iterator ei;
|
||||
FOR_EACH_EDGE (f, ei, single_succ (ret)->preds)
|
||||
{
|
||||
if (f == single_succ_edge (ret))
|
||||
continue;
|
||||
|
||||
if (!dominated_by_p (CDI_DOMINATORS, f->src,
|
||||
single_succ (ret)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!f)
|
||||
set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret);
|
||||
}
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Creates a new basic block just after the basic block AFTER.
|
||||
HEAD and END are the first and the last statement belonging
|
||||
to the block. If both are NULL, an empty block is created. */
|
||||
|
||||
basic_block
|
||||
create_basic_block (void *head, void *end, basic_block after)
|
||||
{
|
||||
basic_block ret;
|
||||
|
||||
if (!cfg_hooks->create_basic_block)
|
||||
internal_error ("%s does not support create_basic_block", cfg_hooks->name);
|
||||
|
||||
ret = cfg_hooks->create_basic_block (head, end, after);
|
||||
|
||||
if (dom_computed[CDI_DOMINATORS])
|
||||
add_to_dominance_info (CDI_DOMINATORS, ret);
|
||||
if (dom_computed[CDI_POST_DOMINATORS])
|
||||
add_to_dominance_info (CDI_POST_DOMINATORS, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Creates an empty basic block just after basic block AFTER. */
|
||||
|
||||
basic_block
|
||||
create_empty_bb (basic_block after)
|
||||
{
|
||||
return create_basic_block (NULL, NULL, after);
|
||||
}
|
||||
|
||||
/* Checks whether we may merge blocks BB1 and BB2. */
|
||||
|
||||
bool
|
||||
can_merge_blocks_p (basic_block bb1, basic_block bb2)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if (!cfg_hooks->can_merge_blocks_p)
|
||||
internal_error ("%s does not support can_merge_blocks_p", cfg_hooks->name);
|
||||
|
||||
ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
predict_edge (edge e, enum br_predictor predictor, int probability)
|
||||
{
|
||||
if (!cfg_hooks->predict_edge)
|
||||
internal_error ("%s does not support predict_edge", cfg_hooks->name);
|
||||
|
||||
cfg_hooks->predict_edge (e, predictor, probability);
|
||||
}
|
||||
|
||||
bool
|
||||
predicted_by_p (basic_block bb, enum br_predictor predictor)
|
||||
{
|
||||
if (!cfg_hooks->predict_edge)
|
||||
internal_error ("%s does not support predicted_by_p", cfg_hooks->name);
|
||||
|
||||
return cfg_hooks->predicted_by_p (bb, predictor);
|
||||
}
|
||||
|
||||
/* Merges basic block B into basic block A. */
|
||||
|
||||
void
|
||||
merge_blocks (basic_block a, basic_block b)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
|
||||
if (!cfg_hooks->merge_blocks)
|
||||
internal_error ("%s does not support merge_blocks", cfg_hooks->name);
|
||||
|
||||
cfg_hooks->merge_blocks (a, b);
|
||||
|
||||
/* Normally there should only be one successor of A and that is B, but
|
||||
partway though the merge of blocks for conditional_execution we'll
|
||||
be merging a TEST block with THEN and ELSE successors. Free the
|
||||
whole lot of them and hope the caller knows what they're doing. */
|
||||
|
||||
while (EDGE_COUNT (a->succs) != 0)
|
||||
remove_edge (EDGE_SUCC (a, 0));
|
||||
|
||||
/* Adjust the edges out of B for the new owner. */
|
||||
FOR_EACH_EDGE (e, ei, b->succs)
|
||||
e->src = a;
|
||||
a->succs = b->succs;
|
||||
a->flags |= b->flags;
|
||||
|
||||
/* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
|
||||
b->preds = b->succs = NULL;
|
||||
|
||||
if (dom_computed[CDI_DOMINATORS])
|
||||
redirect_immediate_dominators (CDI_DOMINATORS, b, a);
|
||||
|
||||
if (dom_computed[CDI_DOMINATORS])
|
||||
delete_from_dominance_info (CDI_DOMINATORS, b);
|
||||
if (dom_computed[CDI_POST_DOMINATORS])
|
||||
delete_from_dominance_info (CDI_POST_DOMINATORS, b);
|
||||
|
||||
expunge_block (b);
|
||||
}
|
||||
|
||||
/* Split BB into entry part and the rest (the rest is the newly created block).
|
||||
Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
|
||||
part. Returns the edge connecting the entry part to the rest. */
|
||||
|
||||
edge
|
||||
make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
|
||||
void (*new_bb_cbk) (basic_block))
|
||||
{
|
||||
edge e, fallthru;
|
||||
edge_iterator ei;
|
||||
basic_block dummy, jump;
|
||||
|
||||
if (!cfg_hooks->make_forwarder_block)
|
||||
internal_error ("%s does not support make_forwarder_block",
|
||||
cfg_hooks->name);
|
||||
|
||||
fallthru = split_block_after_labels (bb);
|
||||
dummy = fallthru->src;
|
||||
bb = fallthru->dest;
|
||||
|
||||
/* Redirect back edges we want to keep. */
|
||||
for (ei = ei_start (dummy->preds); (e = ei_safe_edge (ei)); )
|
||||
{
|
||||
if (redirect_edge_p (e))
|
||||
{
|
||||
ei_next (&ei);
|
||||
continue;
|
||||
}
|
||||
|
||||
dummy->frequency -= EDGE_FREQUENCY (e);
|
||||
dummy->count -= e->count;
|
||||
if (dummy->frequency < 0)
|
||||
dummy->frequency = 0;
|
||||
if (dummy->count < 0)
|
||||
dummy->count = 0;
|
||||
fallthru->count -= e->count;
|
||||
if (fallthru->count < 0)
|
||||
fallthru->count = 0;
|
||||
|
||||
jump = redirect_edge_and_branch_force (e, bb);
|
||||
if (jump)
|
||||
new_bb_cbk (jump);
|
||||
}
|
||||
|
||||
if (dom_info_available_p (CDI_DOMINATORS))
|
||||
{
|
||||
basic_block doms_to_fix[2];
|
||||
|
||||
doms_to_fix[0] = dummy;
|
||||
doms_to_fix[1] = bb;
|
||||
iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, 2);
|
||||
}
|
||||
|
||||
cfg_hooks->make_forwarder_block (fallthru);
|
||||
|
||||
return fallthru;
|
||||
}
|
||||
|
||||
void
|
||||
tidy_fallthru_edge (edge e)
|
||||
{
|
||||
if (cfg_hooks->tidy_fallthru_edge)
|
||||
cfg_hooks->tidy_fallthru_edge (e);
|
||||
}
|
||||
|
||||
/* Fix up edges that now fall through, or rather should now fall through
|
||||
but previously required a jump around now deleted blocks. Simplify
|
||||
the search by only examining blocks numerically adjacent, since this
|
||||
is how find_basic_blocks created them. */
|
||||
|
||||
void
|
||||
tidy_fallthru_edges (void)
|
||||
{
|
||||
basic_block b, c;
|
||||
|
||||
if (!cfg_hooks->tidy_fallthru_edge)
|
||||
return;
|
||||
|
||||
if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
|
||||
return;
|
||||
|
||||
FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, next_bb)
|
||||
{
|
||||
edge s;
|
||||
|
||||
c = b->next_bb;
|
||||
|
||||
/* We care about simple conditional or unconditional jumps with
|
||||
a single successor.
|
||||
|
||||
If we had a conditional branch to the next instruction when
|
||||
find_basic_blocks was called, then there will only be one
|
||||
out edge for the block which ended with the conditional
|
||||
branch (since we do not create duplicate edges).
|
||||
|
||||
Furthermore, the edge will be marked as a fallthru because we
|
||||
merge the flags for the duplicate edges. So we do not want to
|
||||
check that the edge is not a FALLTHRU edge. */
|
||||
|
||||
if (single_succ_p (b))
|
||||
{
|
||||
s = single_succ_edge (b);
|
||||
if (! (s->flags & EDGE_COMPLEX)
|
||||
&& s->dest == c
|
||||
&& !find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX))
|
||||
tidy_fallthru_edge (s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns true if we can duplicate basic block BB. */
|
||||
|
||||
bool
|
||||
can_duplicate_block_p (basic_block bb)
|
||||
{
|
||||
edge e;
|
||||
|
||||
if (!cfg_hooks->can_duplicate_block_p)
|
||||
internal_error ("%s does not support can_duplicate_block_p",
|
||||
cfg_hooks->name);
|
||||
|
||||
if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
|
||||
return false;
|
||||
|
||||
/* Duplicating fallthru block to exit would require adding a jump
|
||||
and splitting the real last BB. */
|
||||
e = find_edge (bb, EXIT_BLOCK_PTR);
|
||||
if (e && (e->flags & EDGE_FALLTHRU))
|
||||
return false;
|
||||
|
||||
return cfg_hooks->can_duplicate_block_p (bb);
|
||||
}
|
||||
|
||||
/* Duplicates basic block BB and redirects edge E to it. Returns the
|
||||
new basic block. The new basic block is placed after the basic block
|
||||
AFTER. */
|
||||
|
||||
basic_block
|
||||
duplicate_block (basic_block bb, edge e, basic_block after)
|
||||
{
|
||||
edge s, n;
|
||||
basic_block new_bb;
|
||||
gcov_type new_count = e ? e->count : 0;
|
||||
edge_iterator ei;
|
||||
|
||||
if (!cfg_hooks->duplicate_block)
|
||||
internal_error ("%s does not support duplicate_block",
|
||||
cfg_hooks->name);
|
||||
|
||||
if (bb->count < new_count)
|
||||
new_count = bb->count;
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (can_duplicate_block_p (bb));
|
||||
#endif
|
||||
|
||||
new_bb = cfg_hooks->duplicate_block (bb);
|
||||
if (after)
|
||||
move_block_after (new_bb, after);
|
||||
|
||||
new_bb->loop_depth = bb->loop_depth;
|
||||
new_bb->flags = bb->flags;
|
||||
FOR_EACH_EDGE (s, ei, bb->succs)
|
||||
{
|
||||
/* Since we are creating edges from a new block to successors
|
||||
of another block (which therefore are known to be disjoint), there
|
||||
is no need to actually check for duplicated edges. */
|
||||
n = unchecked_make_edge (new_bb, s->dest, s->flags);
|
||||
n->probability = s->probability;
|
||||
if (e && bb->count)
|
||||
{
|
||||
/* Take care for overflows! */
|
||||
n->count = s->count * (new_count * 10000 / bb->count) / 10000;
|
||||
s->count -= n->count;
|
||||
}
|
||||
else
|
||||
n->count = s->count;
|
||||
n->aux = s->aux;
|
||||
}
|
||||
|
||||
if (e)
|
||||
{
|
||||
new_bb->count = new_count;
|
||||
bb->count -= new_count;
|
||||
|
||||
new_bb->frequency = EDGE_FREQUENCY (e);
|
||||
bb->frequency -= EDGE_FREQUENCY (e);
|
||||
|
||||
redirect_edge_and_branch_force (e, new_bb);
|
||||
|
||||
if (bb->count < 0)
|
||||
bb->count = 0;
|
||||
if (bb->frequency < 0)
|
||||
bb->frequency = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_bb->count = bb->count;
|
||||
new_bb->frequency = bb->frequency;
|
||||
}
|
||||
|
||||
set_bb_original (new_bb, bb);
|
||||
set_bb_copy (bb, new_bb);
|
||||
|
||||
return new_bb;
|
||||
}
|
||||
|
||||
/* Return 1 if BB ends with a call, possibly followed by some
|
||||
instructions that must stay with the call, 0 otherwise. */
|
||||
|
||||
bool
|
||||
block_ends_with_call_p (basic_block bb)
|
||||
{
|
||||
if (!cfg_hooks->block_ends_with_call_p)
|
||||
internal_error ("%s does not support block_ends_with_call_p", cfg_hooks->name);
|
||||
|
||||
return (cfg_hooks->block_ends_with_call_p) (bb);
|
||||
}
|
||||
|
||||
/* Return 1 if BB ends with a conditional branch, 0 otherwise. */
|
||||
|
||||
bool
|
||||
block_ends_with_condjump_p (basic_block bb)
|
||||
{
|
||||
if (!cfg_hooks->block_ends_with_condjump_p)
|
||||
internal_error ("%s does not support block_ends_with_condjump_p",
|
||||
cfg_hooks->name);
|
||||
|
||||
return (cfg_hooks->block_ends_with_condjump_p) (bb);
|
||||
}
|
||||
|
||||
/* Add fake edges to the function exit for any non constant and non noreturn
|
||||
calls, volatile inline assembly in the bitmap of blocks specified by
|
||||
BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
|
||||
that were split.
|
||||
|
||||
The goal is to expose cases in which entering a basic block does not imply
|
||||
that all subsequent instructions must be executed. */
|
||||
|
||||
int
|
||||
flow_call_edges_add (sbitmap blocks)
|
||||
{
|
||||
if (!cfg_hooks->flow_call_edges_add)
|
||||
internal_error ("%s does not support flow_call_edges_add",
|
||||
cfg_hooks->name);
|
||||
|
||||
return (cfg_hooks->flow_call_edges_add) (blocks);
|
||||
}
|
||||
|
||||
/* This function is called immediately after edge E is added to the
|
||||
edge vector E->dest->preds. */
|
||||
|
||||
void
|
||||
execute_on_growing_pred (edge e)
|
||||
{
|
||||
if (cfg_hooks->execute_on_growing_pred)
|
||||
cfg_hooks->execute_on_growing_pred (e);
|
||||
}
|
||||
|
||||
/* This function is called immediately before edge E is removed from
|
||||
the edge vector E->dest->preds. */
|
||||
|
||||
void
|
||||
execute_on_shrinking_pred (edge e)
|
||||
{
|
||||
if (cfg_hooks->execute_on_shrinking_pred)
|
||||
cfg_hooks->execute_on_shrinking_pred (e);
|
||||
}
|
||||
|
||||
/* This is used inside loop versioning when we want to insert
|
||||
stmts/insns on the edges, which have a different behavior
|
||||
in tree's and in RTL, so we made a CFG hook. */
|
||||
void
|
||||
lv_flush_pending_stmts (edge e)
|
||||
{
|
||||
if (cfg_hooks->flush_pending_stmts)
|
||||
cfg_hooks->flush_pending_stmts (e);
|
||||
}
|
||||
|
||||
/* Loop versioning uses the duplicate_loop_to_header_edge to create
|
||||
a new version of the loop basic-blocks, the parameters here are
|
||||
exactly the same as in duplicate_loop_to_header_edge or
|
||||
tree_duplicate_loop_to_header_edge; while in tree-ssa there is
|
||||
additional work to maintain ssa information that's why there is
|
||||
a need to call the tree_duplicate_loop_to_header_edge rather
|
||||
than duplicate_loop_to_header_edge when we are in tree mode. */
|
||||
bool
|
||||
cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge e,
|
||||
struct loops *loops, unsigned int ndupl,
|
||||
sbitmap wont_exit, edge orig,
|
||||
edge *to_remove,
|
||||
unsigned int *n_to_remove, int flags)
|
||||
{
|
||||
gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_to_header_edge);
|
||||
return cfg_hooks->cfg_hook_duplicate_loop_to_header_edge (loop, e, loops,
|
||||
ndupl, wont_exit,
|
||||
orig, to_remove,
|
||||
n_to_remove, flags);
|
||||
}
|
||||
|
||||
/* Conditional jumps are represented differently in trees and RTL,
|
||||
this hook takes a basic block that is known to have a cond jump
|
||||
at its end and extracts the taken and not taken eges out of it
|
||||
and store it in E1 and E2 respectively. */
|
||||
void
|
||||
extract_cond_bb_edges (basic_block b, edge *e1, edge *e2)
|
||||
{
|
||||
gcc_assert (cfg_hooks->extract_cond_bb_edges);
|
||||
cfg_hooks->extract_cond_bb_edges (b, e1, e2);
|
||||
}
|
||||
|
||||
/* Responsible for updating the ssa info (PHI nodes) on the
|
||||
new condition basic block that guards the versioned loop. */
|
||||
void
|
||||
lv_adjust_loop_header_phi (basic_block first, basic_block second,
|
||||
basic_block new, edge e)
|
||||
{
|
||||
if (cfg_hooks->lv_adjust_loop_header_phi)
|
||||
cfg_hooks->lv_adjust_loop_header_phi (first, second, new, e);
|
||||
}
|
||||
|
||||
/* Conditions in trees and RTL are different so we need
|
||||
a different handling when we add the condition to the
|
||||
versioning code. */
|
||||
void
|
||||
lv_add_condition_to_bb (basic_block first, basic_block second,
|
||||
basic_block new, void *cond)
|
||||
{
|
||||
gcc_assert (cfg_hooks->lv_add_condition_to_bb);
|
||||
cfg_hooks->lv_add_condition_to_bb (first, second, new, cond);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Hooks for cfg representation specific functions.
|
||||
Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Sebastian Pop <s.pop@laposte.net>
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,18 +16,20 @@ 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. */
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_CFGHOOKS_H
|
||||
#define GCC_CFGHOOKS_H
|
||||
|
||||
struct cfg_hooks
|
||||
{
|
||||
/* Debugging. Do not use macros to hook these so they can be called from
|
||||
debugger! */
|
||||
int (*cfgh_verify_flow_info) (void);
|
||||
void (*dump_bb) (basic_block, FILE *);
|
||||
/* Name of the corresponding ir. */
|
||||
const char *name;
|
||||
|
||||
/* Debugging. */
|
||||
int (*verify_flow_info) (void);
|
||||
void (*dump_bb) (basic_block, FILE *, int);
|
||||
|
||||
/* Basic CFG manipulation. */
|
||||
|
||||
|
|
@ -35,20 +37,25 @@ struct cfg_hooks
|
|||
basic_block (*create_basic_block) (void *head, void *end, basic_block after);
|
||||
|
||||
/* Redirect edge E to the given basic block B and update underlying program
|
||||
representation. Returns false when edge is not easily redirectable for
|
||||
whatever reason. */
|
||||
bool (*redirect_edge_and_branch) (edge e, basic_block b);
|
||||
representation. Returns edge representing redirected branch (that may not
|
||||
be equivalent to E in the case of duplicate edges being removed) or NULL
|
||||
if edge is not easily redirectable for whatever reason. */
|
||||
edge (*redirect_edge_and_branch) (edge e, basic_block b);
|
||||
|
||||
/* Same as the above but allows redirecting of fallthru edges. In that case
|
||||
newly created forwarder basic block is returned. It aborts when called
|
||||
on abnormal edge. */
|
||||
newly created forwarder basic block is returned. The edge must
|
||||
not be abnormal. */
|
||||
basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
|
||||
|
||||
/* Remove given basic block and all edges possibly pointing into it. */
|
||||
void (*delete_block) (basic_block);
|
||||
/* Remove statements corresponding to a given basic block. */
|
||||
void (*delete_basic_block) (basic_block);
|
||||
|
||||
/* Split basic block B after specified instruction I. */
|
||||
edge (*split_block) (basic_block b, void * i);
|
||||
/* Creates a new basic block just after basic block B by splitting
|
||||
everything after specified instruction I. */
|
||||
basic_block (*split_block) (basic_block b, void * i);
|
||||
|
||||
/* Move block B immediately after block A. */
|
||||
bool (*move_block_after) (basic_block b, basic_block a);
|
||||
|
||||
/* Return true when blocks A and B can be merged into single basic block. */
|
||||
bool (*can_merge_blocks_p) (basic_block a, basic_block b);
|
||||
|
|
@ -56,28 +63,130 @@ struct cfg_hooks
|
|||
/* Merge blocks A and B. */
|
||||
void (*merge_blocks) (basic_block a, basic_block b);
|
||||
|
||||
/* Predict edge E using PREDICTOR to given PROBABILITY. */
|
||||
void (*predict_edge) (edge e, enum br_predictor predictor, int probability);
|
||||
|
||||
/* Return true if the one of outgoing edges is already predicted by
|
||||
PREDICTOR. */
|
||||
bool (*predicted_by_p) (basic_block bb, enum br_predictor predictor);
|
||||
|
||||
/* Return true when block A can be duplicated. */
|
||||
bool (*can_duplicate_block_p) (basic_block a);
|
||||
|
||||
/* Duplicate block A. */
|
||||
basic_block (*duplicate_block) (basic_block a);
|
||||
|
||||
/* Higher level functions representable by primitive operations above if
|
||||
we didn't have some oddities in RTL and Tree representations. */
|
||||
basic_block (*cfgh_split_edge) (edge);
|
||||
basic_block (*split_edge) (edge);
|
||||
void (*make_forwarder_block) (edge);
|
||||
|
||||
/* Tries to make the edge fallthru. */
|
||||
void (*tidy_fallthru_edge) (edge);
|
||||
|
||||
/* Say whether a block ends with a call, possibly followed by some
|
||||
other code that must stay with the call. */
|
||||
bool (*block_ends_with_call_p) (basic_block);
|
||||
|
||||
/* Say whether a block ends with a conditional branch. Switches
|
||||
and unconditional branches do not qualify. */
|
||||
bool (*block_ends_with_condjump_p) (basic_block);
|
||||
|
||||
/* Add fake edges to the function exit for any non constant and non noreturn
|
||||
calls, volatile inline assembly in the bitmap of blocks specified by
|
||||
BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
|
||||
that were split.
|
||||
|
||||
The goal is to expose cases in which entering a basic block does not imply
|
||||
that all subsequent instructions must be executed. */
|
||||
int (*flow_call_edges_add) (sbitmap);
|
||||
|
||||
/* This function is called immediately after edge E is added to the
|
||||
edge vector E->dest->preds. */
|
||||
void (*execute_on_growing_pred) (edge);
|
||||
|
||||
/* This function is called immediately before edge E is removed from
|
||||
the edge vector E->dest->preds. */
|
||||
void (*execute_on_shrinking_pred) (edge);
|
||||
|
||||
/* A hook for duplicating loop in CFG, currently this is used
|
||||
in loop versioning. */
|
||||
bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *loop, edge e,
|
||||
struct loops *loops,
|
||||
unsigned int ndupl,
|
||||
sbitmap wont_exit,
|
||||
edge orig, edge *to_remove,
|
||||
unsigned int *n_to_remove,
|
||||
int flags);
|
||||
|
||||
/* Add condition to new basic block and update CFG used in loop
|
||||
versioning. */
|
||||
void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block,
|
||||
void *);
|
||||
/* Update the PHI nodes in case of loop versioning. */
|
||||
void (*lv_adjust_loop_header_phi) (basic_block, basic_block,
|
||||
basic_block, edge);
|
||||
|
||||
/* Given a condition BB extract the true/false taken/not taken edges
|
||||
(depending if we are on tree's or RTL). */
|
||||
void (*extract_cond_bb_edges) (basic_block, edge *, edge *);
|
||||
|
||||
|
||||
/* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
|
||||
E->dest (only in tree-ssa loop versioning. */
|
||||
void (*flush_pending_stmts) (edge);
|
||||
};
|
||||
|
||||
#define redirect_edge_and_branch(e,b) cfg_hooks->redirect_edge_and_branch (e,b)
|
||||
#define redirect_edge_and_branch_force(e,b) cfg_hooks->redirect_edge_and_branch_force (e,b)
|
||||
#define split_block(e,i) cfg_hooks->split_block (e,i)
|
||||
#define delete_block(b) cfg_hooks->delete_block (b)
|
||||
#define split_edge(e) cfg_hooks->cfgh_split_edge (e)
|
||||
#define create_basic_block(h,e,a) cfg_hooks->create_basic_block (h,e,a)
|
||||
#define can_merge_blocks_p(a,b) cfg_hooks->can_merge_blocks_p (a,b)
|
||||
#define merge_blocks(a,b) cfg_hooks->merge_blocks (a,b)
|
||||
extern void verify_flow_info (void);
|
||||
extern void dump_bb (basic_block, FILE *, int);
|
||||
extern edge redirect_edge_and_branch (edge, basic_block);
|
||||
extern basic_block redirect_edge_and_branch_force (edge, basic_block);
|
||||
extern edge split_block (basic_block, void *);
|
||||
extern edge split_block_after_labels (basic_block);
|
||||
extern bool move_block_after (basic_block, basic_block);
|
||||
extern void delete_basic_block (basic_block);
|
||||
extern basic_block split_edge (edge);
|
||||
extern basic_block create_basic_block (void *, void *, basic_block);
|
||||
extern basic_block create_empty_bb (basic_block);
|
||||
extern bool can_merge_blocks_p (basic_block, basic_block);
|
||||
extern void merge_blocks (basic_block, basic_block);
|
||||
extern edge make_forwarder_block (basic_block, bool (*)(edge),
|
||||
void (*) (basic_block));
|
||||
extern void tidy_fallthru_edge (edge);
|
||||
extern void tidy_fallthru_edges (void);
|
||||
extern void predict_edge (edge e, enum br_predictor predictor, int probability);
|
||||
extern bool predicted_by_p (basic_block bb, enum br_predictor predictor);
|
||||
extern bool can_duplicate_block_p (basic_block);
|
||||
extern basic_block duplicate_block (basic_block, edge, basic_block);
|
||||
extern bool block_ends_with_call_p (basic_block bb);
|
||||
extern bool block_ends_with_condjump_p (basic_block bb);
|
||||
extern int flow_call_edges_add (sbitmap);
|
||||
extern void execute_on_growing_pred (edge);
|
||||
extern void execute_on_shrinking_pred (edge);
|
||||
extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge,
|
||||
struct loops *loops,
|
||||
unsigned int ndupl,
|
||||
sbitmap wont_exit,
|
||||
edge orig, edge *to_remove,
|
||||
unsigned int *n_to_remove,
|
||||
int flags);
|
||||
|
||||
extern void lv_flush_pending_stmts (edge);
|
||||
extern void extract_cond_bb_edges (basic_block, edge *, edge*);
|
||||
extern void lv_adjust_loop_header_phi (basic_block, basic_block, basic_block,
|
||||
edge);
|
||||
extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block,
|
||||
void *);
|
||||
|
||||
/* Hooks containers. */
|
||||
extern struct cfg_hooks tree_cfg_hooks;
|
||||
extern struct cfg_hooks rtl_cfg_hooks;
|
||||
|
||||
/* A pointer to one of the hooks containers. */
|
||||
extern struct cfg_hooks *cfg_hooks;
|
||||
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
|
||||
|
||||
/* Declarations. */
|
||||
extern int ir_type (void);
|
||||
extern void rtl_register_cfg_hooks (void);
|
||||
extern void cfg_layout_rtl_register_cfg_hooks (void);
|
||||
extern void tree_register_cfg_hooks (void);
|
||||
|
||||
#endif /* GCC_CFGHOOKS_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Basic block reordering routines for the GNU compiler.
|
||||
Copyright (C) 2000, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -15,33 +15,24 @@
|
|||
|
||||
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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* Structure to hold information about the blocks during reordering. */
|
||||
typedef struct reorder_block_def
|
||||
{
|
||||
rtx header;
|
||||
rtx footer;
|
||||
basic_block next;
|
||||
basic_block original;
|
||||
/* Used by loop copying. */
|
||||
basic_block copy;
|
||||
int duplicated;
|
||||
#ifndef GCC_CFGLAYOUT_H
|
||||
#define GCC_CFGLAYOUT_H
|
||||
|
||||
/* These fields are used by bb-reorder pass. */
|
||||
int visited;
|
||||
} *reorder_block_def;
|
||||
#include "basic-block.h"
|
||||
|
||||
extern rtx cfg_layout_function_footer;
|
||||
|
||||
extern void cfg_layout_initialize (unsigned int);
|
||||
extern void cfg_layout_finalize (void);
|
||||
extern bool cfg_layout_can_duplicate_bb_p (basic_block);
|
||||
extern basic_block cfg_layout_duplicate_bb (basic_block, edge);
|
||||
extern void insn_locators_initialize (void);
|
||||
extern unsigned int insn_locators_initialize (void);
|
||||
extern void reemit_insn_block_notes (void);
|
||||
extern bool can_copy_bbs_p (basic_block *, unsigned);
|
||||
extern void copy_bbs (basic_block *, unsigned, basic_block *,
|
||||
edge *, unsigned, edge *, struct loop *);
|
||||
extern void cfg_layout_initialize_rbi (basic_block);
|
||||
edge *, unsigned, edge *, struct loop *,
|
||||
basic_block);
|
||||
extern rtx duplicate_insn_chain (rtx, rtx);
|
||||
|
||||
#endif /* GCC_CFGLAYOUT_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Natural loop functions
|
||||
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,8 +16,15 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_CFGLOOP_H
|
||||
#define GCC_CFGLOOP_H
|
||||
|
||||
#include "basic-block.h"
|
||||
/* For rtx_code. */
|
||||
#include "rtl.h"
|
||||
|
||||
/* Structure to hold decision about unrolling/peeling. */
|
||||
enum lpt_dec
|
||||
|
|
@ -36,27 +43,16 @@ struct lpt_decision
|
|||
unsigned times;
|
||||
};
|
||||
|
||||
/* Description of loop for simple loop unrolling. */
|
||||
struct loop_desc
|
||||
/* The structure describing a bound on number of iterations of a loop. */
|
||||
|
||||
struct nb_iter_bound
|
||||
{
|
||||
int postincr; /* 1 if increment/decrement is done after loop exit condition. */
|
||||
rtx stride; /* Value added to VAR in each iteration. */
|
||||
rtx var; /* Loop control variable. */
|
||||
enum machine_mode inner_mode;
|
||||
/* The mode from that it is extended. */
|
||||
enum rtx_code extend; /* With this extend. */
|
||||
rtx var_alts; /* List of definitions of its initial value. */
|
||||
rtx lim; /* Expression var is compared with. */
|
||||
rtx lim_alts; /* List of definitions of its initial value. */
|
||||
bool const_iter; /* True if it iterates constant number of times. */
|
||||
unsigned HOST_WIDE_INT niter;
|
||||
/* Number of iterations if it is constant. */
|
||||
bool may_be_zero; /* If we cannot determine that the first iteration will pass. */
|
||||
enum rtx_code cond; /* Exit condition. */
|
||||
int neg; /* Set to 1 if loop ends when condition is satisfied. */
|
||||
edge out_edge; /* The exit edge. */
|
||||
edge in_edge; /* And the other one. */
|
||||
int n_branches; /* Number of branches inside the loop. */
|
||||
tree bound; /* The constant expression whose value is an upper
|
||||
bound on the number of executions of ... */
|
||||
tree at_stmt; /* ... this statement during one execution of
|
||||
a loop. */
|
||||
struct nb_iter_bound *next;
|
||||
/* The next bound in a list. */
|
||||
};
|
||||
|
||||
/* Structure to hold information for each natural loop. */
|
||||
|
|
@ -71,60 +67,18 @@ struct loop
|
|||
/* Basic block of loop latch. */
|
||||
basic_block latch;
|
||||
|
||||
/* Basic block of loop preheader or NULL if it does not exist. */
|
||||
basic_block pre_header;
|
||||
|
||||
/* For loop unrolling/peeling decision. */
|
||||
struct lpt_decision lpt_decision;
|
||||
|
||||
/* Simple loop description. */
|
||||
int simple;
|
||||
struct loop_desc desc;
|
||||
int has_desc;
|
||||
|
||||
/* Number of loop insns. */
|
||||
unsigned ninsns;
|
||||
|
||||
/* Average number of executed insns per iteration. */
|
||||
unsigned av_ninsns;
|
||||
|
||||
/* Array of edges along the preheader extended basic block trace.
|
||||
The source of the first edge is the root node of preheader
|
||||
extended basic block, if it exists. */
|
||||
edge *pre_header_edges;
|
||||
|
||||
/* Number of edges along the pre_header extended basic block trace. */
|
||||
int num_pre_header_edges;
|
||||
|
||||
/* The first block in the loop. This is not necessarily the same as
|
||||
the loop header. */
|
||||
basic_block first;
|
||||
|
||||
/* The last block in the loop. This is not necessarily the same as
|
||||
the loop latch. */
|
||||
basic_block last;
|
||||
|
||||
/* Bitmap of blocks contained within the loop. */
|
||||
sbitmap nodes;
|
||||
|
||||
/* Number of blocks contained within the loop. */
|
||||
unsigned num_nodes;
|
||||
|
||||
/* Array of edges that enter the loop. */
|
||||
edge *entry_edges;
|
||||
|
||||
/* Number of edges that enter the loop. */
|
||||
int num_entries;
|
||||
|
||||
/* Array of edges that exit the loop. */
|
||||
edge *exit_edges;
|
||||
|
||||
/* Number of edges that exit the loop. */
|
||||
int num_exits;
|
||||
|
||||
/* Bitmap of blocks that dominate all exits of the loop. */
|
||||
sbitmap exits_doms;
|
||||
|
||||
/* The loop nesting depth. */
|
||||
int depth;
|
||||
|
||||
|
|
@ -147,55 +101,32 @@ struct loop
|
|||
/* Loop that is copy of this loop. */
|
||||
struct loop *copy;
|
||||
|
||||
/* Nonzero if the loop is invalid (e.g., contains setjmp.). */
|
||||
int invalid;
|
||||
|
||||
/* Auxiliary info specific to a pass. */
|
||||
void *aux;
|
||||
|
||||
/* The following are currently used by loop.c but they are likely to
|
||||
disappear as loop.c is converted to use the CFG. */
|
||||
/* The probable number of times the loop is executed at runtime.
|
||||
This is an INTEGER_CST or an expression containing symbolic
|
||||
names. Don't access this field directly:
|
||||
number_of_iterations_in_loop computes and caches the computed
|
||||
information in this field. */
|
||||
tree nb_iterations;
|
||||
|
||||
/* Nonzero if the loop has a NOTE_INSN_LOOP_VTOP. */
|
||||
rtx vtop;
|
||||
/* An INTEGER_CST estimation of the number of iterations. NULL_TREE
|
||||
if there is no estimation. */
|
||||
tree estimated_nb_iterations;
|
||||
|
||||
/* Nonzero if the loop has a NOTE_INSN_LOOP_CONT.
|
||||
A continue statement will generate a branch to NEXT_INSN (cont). */
|
||||
rtx cont;
|
||||
/* Upper bound on number of iterations of a loop. */
|
||||
struct nb_iter_bound *bounds;
|
||||
|
||||
/* The dominator of cont. */
|
||||
rtx cont_dominator;
|
||||
/* If not NULL, loop has just single exit edge stored here (edges to the
|
||||
EXIT_BLOCK_PTR do not count. */
|
||||
edge single_exit;
|
||||
|
||||
/* The NOTE_INSN_LOOP_BEG. */
|
||||
rtx start;
|
||||
|
||||
/* The NOTE_INSN_LOOP_END. */
|
||||
rtx end;
|
||||
|
||||
/* For a rotated loop that is entered near the bottom,
|
||||
this is the label at the top. Otherwise it is zero. */
|
||||
rtx top;
|
||||
|
||||
/* Place in the loop where control enters. */
|
||||
rtx scan_start;
|
||||
|
||||
/* The position where to sink insns out of the loop. */
|
||||
rtx sink;
|
||||
|
||||
/* List of all LABEL_REFs which refer to code labels outside the
|
||||
loop. Used by routines that need to know all loop exits, such as
|
||||
final_biv_value and final_giv_value.
|
||||
|
||||
This does not include loop exits due to return instructions.
|
||||
This is because all bivs and givs are pseudos, and hence must be
|
||||
dead after a return, so the presence of a return does not affect
|
||||
any of the optimizations that use this info. It is simpler to
|
||||
just not include return instructions on this list. */
|
||||
rtx exit_labels;
|
||||
|
||||
/* The number of LABEL_REFs on exit_labels for this loop and all
|
||||
loops nested inside it. */
|
||||
int exit_count;
|
||||
/* True when the loop does not carry data dependences, and
|
||||
consequently the iterations can be executed in any order. False
|
||||
when the loop carries data dependences, or when the property is
|
||||
not decidable. */
|
||||
bool parallel_p;
|
||||
};
|
||||
|
||||
/* Flags for state of loop structure. */
|
||||
|
|
@ -203,25 +134,26 @@ enum
|
|||
{
|
||||
LOOPS_HAVE_PREHEADERS = 1,
|
||||
LOOPS_HAVE_SIMPLE_LATCHES = 2,
|
||||
LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4
|
||||
LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4,
|
||||
LOOPS_HAVE_MARKED_SINGLE_EXITS = 8
|
||||
};
|
||||
|
||||
#define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \
|
||||
| LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
|
||||
|
||||
/* Structure to hold CFG information about natural loops within a function. */
|
||||
struct loops
|
||||
{
|
||||
/* Number of natural loops in the function. */
|
||||
unsigned num;
|
||||
|
||||
/* Maximum nested loop level in the function. */
|
||||
unsigned levels;
|
||||
/* State of loops. */
|
||||
int state;
|
||||
|
||||
/* Array of natural loop descriptors (scanning this array in reverse order
|
||||
will find the inner loops before their enclosing outer loops). */
|
||||
struct loop *array;
|
||||
|
||||
/* The above array is unused in new loop infrastructure and is kept only for
|
||||
purposes of the old loop optimizer. Instead we store just pointers to
|
||||
loops here. */
|
||||
/* We store just pointers to loops here.
|
||||
Note that a loop in this array may actually be NULL, if the loop
|
||||
has been removed and the entire loops structure has not been
|
||||
recomputed since that time. */
|
||||
struct loop **parray;
|
||||
|
||||
/* Pointer to root of loop hierarchy tree. */
|
||||
|
|
@ -240,45 +172,45 @@ struct loops
|
|||
|
||||
/* Headers shared by multiple loops that should be merged. */
|
||||
sbitmap shared_headers;
|
||||
|
||||
/* State of loops. */
|
||||
int state;
|
||||
};
|
||||
|
||||
/* Flags for loop discovery. */
|
||||
/* The loop tree currently optimized. */
|
||||
|
||||
#define LOOP_TREE 1 /* Build loop hierarchy tree. */
|
||||
#define LOOP_PRE_HEADER 2 /* Analyze loop preheader. */
|
||||
#define LOOP_ENTRY_EDGES 4 /* Find entry edges. */
|
||||
#define LOOP_EXIT_EDGES 8 /* Find exit edges. */
|
||||
#define LOOP_EDGES (LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
|
||||
#define LOOP_ALL 15 /* All of the above */
|
||||
extern struct loops *current_loops;
|
||||
|
||||
/* Loop recognition. */
|
||||
extern int flow_loops_find (struct loops *, int flags);
|
||||
extern int flow_loops_update (struct loops *, int flags);
|
||||
extern int flow_loops_find (struct loops *);
|
||||
extern void flow_loops_free (struct loops *);
|
||||
extern void flow_loops_dump (const struct loops *, FILE *,
|
||||
void (*)(const struct loop *, FILE *, int), int);
|
||||
extern void flow_loop_dump (const struct loop *, FILE *,
|
||||
void (*)(const struct loop *, FILE *, int), int);
|
||||
extern int flow_loop_scan (struct loop *, int);
|
||||
extern void flow_loop_free (struct loop *);
|
||||
int flow_loop_nodes_find (basic_block, struct loop *);
|
||||
void fix_loop_structure (struct loops *, bitmap changed_bbs);
|
||||
void mark_irreducible_loops (struct loops *);
|
||||
void mark_single_exit_loops (struct loops *);
|
||||
|
||||
/* Loop data structure manipulation/querying. */
|
||||
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
|
||||
extern void flow_loop_tree_node_remove (struct loop *);
|
||||
extern bool flow_loop_outside_edge_p (const struct loop *, edge);
|
||||
extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
|
||||
extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block);
|
||||
extern struct loop * find_common_loop (struct loop *, struct loop *);
|
||||
struct loop *superloop_at_depth (struct loop *, unsigned);
|
||||
extern unsigned tree_num_loop_insns (struct loop *);
|
||||
extern int num_loop_insns (struct loop *);
|
||||
extern int average_num_loop_insns (struct loop *);
|
||||
extern unsigned get_loop_level (const struct loop *);
|
||||
extern bool loop_exit_edge_p (const struct loop *, edge);
|
||||
extern void mark_loop_exit_edges (struct loops *);
|
||||
|
||||
/* Loops & cfg manipulation. */
|
||||
extern basic_block *get_loop_body (const struct loop *);
|
||||
extern basic_block *get_loop_body_in_dom_order (const struct loop *);
|
||||
extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
|
||||
extern edge *get_loop_exit_edges (const struct loop *, unsigned *);
|
||||
extern unsigned num_loop_branches (const struct loop *);
|
||||
|
||||
extern edge loop_preheader_edge (const struct loop *);
|
||||
extern edge loop_latch_edge (const struct loop *);
|
||||
|
|
@ -286,7 +218,6 @@ extern edge loop_latch_edge (const struct loop *);
|
|||
extern void add_bb_to_loop (basic_block, struct loop *);
|
||||
extern void remove_bb_from_loops (basic_block);
|
||||
|
||||
extern void cancel_loop (struct loops *, struct loop *);
|
||||
extern void cancel_loop_tree (struct loops *, struct loop *);
|
||||
|
||||
extern basic_block loop_split_edge_with (edge, rtx);
|
||||
|
|
@ -303,28 +234,156 @@ extern void force_single_succ_latches (struct loops *);
|
|||
extern void verify_loop_structure (struct loops *);
|
||||
|
||||
/* Loop analysis. */
|
||||
extern bool simple_loop_p (struct loop *, struct loop_desc *);
|
||||
extern rtx count_loop_iterations (struct loop_desc *, rtx, rtx);
|
||||
extern bool just_once_each_iteration_p (struct loop *, basic_block);
|
||||
extern bool just_once_each_iteration_p (const struct loop *, basic_block);
|
||||
extern unsigned expected_loop_iterations (const struct loop *);
|
||||
extern rtx doloop_condition_get (rtx);
|
||||
|
||||
/* Loop manipulation. */
|
||||
extern bool can_duplicate_loop_p (struct loop *loop);
|
||||
|
||||
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
|
||||
duplicate_loop_to_header_edge. */
|
||||
#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux
|
||||
field of newly create BB. */
|
||||
#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting
|
||||
a complete peeling. */
|
||||
|
||||
extern int duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
|
||||
unsigned, sbitmap, edge, edge *,
|
||||
unsigned *, int);
|
||||
extern struct loop *loopify (struct loops *, edge, edge, basic_block);
|
||||
extern void unloop (struct loops *, struct loop *);
|
||||
extern struct loop * duplicate_loop (struct loops *, struct loop *,
|
||||
struct loop *);
|
||||
extern bool duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
|
||||
unsigned, sbitmap, edge, edge *,
|
||||
unsigned *, int);
|
||||
extern struct loop *loopify (struct loops *, edge, edge,
|
||||
basic_block, edge, edge, bool);
|
||||
struct loop * loop_version (struct loops *, struct loop *, void *,
|
||||
basic_block *, bool);
|
||||
extern bool remove_path (struct loops *, edge);
|
||||
extern edge split_loop_bb (basic_block, rtx);
|
||||
|
||||
/* Induction variable analysis. */
|
||||
|
||||
/* The description of induction variable. The things are a bit complicated
|
||||
due to need to handle subregs and extends. The value of the object described
|
||||
by it can be obtained as follows (all computations are done in extend_mode):
|
||||
|
||||
Value in i-th iteration is
|
||||
delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)).
|
||||
|
||||
If first_special is true, the value in the first iteration is
|
||||
delta + mult * base
|
||||
|
||||
If extend = UNKNOWN, first_special must be false, delta 0, mult 1 and value is
|
||||
subreg_{mode} (base + i * step)
|
||||
|
||||
The get_iv_value function can be used to obtain these expressions.
|
||||
|
||||
??? Add a third mode field that would specify the mode in that inner
|
||||
computation is done, which would enable it to be different from the
|
||||
outer one? */
|
||||
|
||||
struct rtx_iv
|
||||
{
|
||||
/* Its base and step (mode of base and step is supposed to be extend_mode,
|
||||
see the description above). */
|
||||
rtx base, step;
|
||||
|
||||
/* The type of extend applied to it (SIGN_EXTEND, ZERO_EXTEND or UNKNOWN). */
|
||||
enum rtx_code extend;
|
||||
|
||||
/* Operations applied in the extended mode. */
|
||||
rtx delta, mult;
|
||||
|
||||
/* The mode it is extended to. */
|
||||
enum machine_mode extend_mode;
|
||||
|
||||
/* The mode the variable iterates in. */
|
||||
enum machine_mode mode;
|
||||
|
||||
/* Whether the first iteration needs to be handled specially. */
|
||||
unsigned first_special : 1;
|
||||
};
|
||||
|
||||
/* The description of an exit from the loop and of the number of iterations
|
||||
till we take the exit. */
|
||||
|
||||
struct niter_desc
|
||||
{
|
||||
/* The edge out of the loop. */
|
||||
edge out_edge;
|
||||
|
||||
/* The other edge leading from the condition. */
|
||||
edge in_edge;
|
||||
|
||||
/* True if we are able to say anything about number of iterations of the
|
||||
loop. */
|
||||
bool simple_p;
|
||||
|
||||
/* True if the loop iterates the constant number of times. */
|
||||
bool const_iter;
|
||||
|
||||
/* Number of iterations if constant. */
|
||||
unsigned HOST_WIDEST_INT niter;
|
||||
|
||||
/* Upper bound on the number of iterations. */
|
||||
unsigned HOST_WIDEST_INT niter_max;
|
||||
|
||||
/* Assumptions under that the rest of the information is valid. */
|
||||
rtx assumptions;
|
||||
|
||||
/* Assumptions under that the loop ends before reaching the latch,
|
||||
even if value of niter_expr says otherwise. */
|
||||
rtx noloop_assumptions;
|
||||
|
||||
/* Condition under that the loop is infinite. */
|
||||
rtx infinite;
|
||||
|
||||
/* Whether the comparison is signed. */
|
||||
bool signed_p;
|
||||
|
||||
/* The mode in that niter_expr should be computed. */
|
||||
enum machine_mode mode;
|
||||
|
||||
/* The number of iterations of the loop. */
|
||||
rtx niter_expr;
|
||||
};
|
||||
|
||||
extern void iv_analysis_loop_init (struct loop *);
|
||||
extern bool iv_analyze (rtx, rtx, struct rtx_iv *);
|
||||
extern bool iv_analyze_result (rtx, rtx, struct rtx_iv *);
|
||||
extern bool iv_analyze_expr (rtx, rtx, enum machine_mode, struct rtx_iv *);
|
||||
extern rtx get_iv_value (struct rtx_iv *, rtx);
|
||||
extern bool biv_p (rtx, rtx);
|
||||
extern void find_simple_exit (struct loop *, struct niter_desc *);
|
||||
extern void iv_analysis_done (void);
|
||||
extern struct df *iv_current_loop_df (void);
|
||||
|
||||
extern struct niter_desc *get_simple_loop_desc (struct loop *loop);
|
||||
extern void free_simple_loop_desc (struct loop *loop);
|
||||
|
||||
static inline struct niter_desc *
|
||||
simple_loop_desc (struct loop *loop)
|
||||
{
|
||||
return (struct niter_desc *) loop->aux;
|
||||
}
|
||||
|
||||
/* The properties of the target. */
|
||||
|
||||
extern unsigned target_avail_regs; /* Number of available registers. */
|
||||
extern unsigned target_res_regs; /* Number of reserved registers. */
|
||||
extern unsigned target_small_cost; /* The cost for register when there
|
||||
is a free one. */
|
||||
extern unsigned target_pres_cost; /* The cost for register when there are
|
||||
not too many free ones. */
|
||||
extern unsigned target_spill_cost; /* The cost for register when we need
|
||||
to spill. */
|
||||
|
||||
/* Register pressure estimation for induction variable optimizations & loop
|
||||
invariant motion. */
|
||||
extern unsigned global_cost_for_size (unsigned, unsigned, unsigned);
|
||||
extern void init_set_costs (void);
|
||||
|
||||
/* Loop optimizer initialization. */
|
||||
extern struct loops *loop_optimizer_init (FILE *);
|
||||
extern void loop_optimizer_finalize (struct loops *, FILE *);
|
||||
extern struct loops *loop_optimizer_init (unsigned);
|
||||
extern void loop_optimizer_finalize (struct loops *);
|
||||
|
||||
/* Optimization passes. */
|
||||
extern void unswitch_loops (struct loops *);
|
||||
|
|
@ -337,5 +396,8 @@ enum
|
|||
};
|
||||
|
||||
extern void unroll_and_peel_loops (struct loops *, int);
|
||||
extern bool is_bct_cond (rtx);
|
||||
extern rtx get_var_set_from_bct (rtx);
|
||||
extern void doloop_optimize_loops (struct loops *);
|
||||
extern void move_loop_invariants (struct loops *);
|
||||
extern void record_estimate (struct loop *, tree, tree, tree);
|
||||
|
||||
#endif /* GCC_CFGLOOP_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1857
contrib/gcc/cfgrtl.c
1857
contrib/gcc/cfgrtl.c
File diff suppressed because it is too large
Load diff
1208
contrib/gcc/cgraph.c
1208
contrib/gcc/cgraph.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Callgraph handling code.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Jan Hubicka
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -16,11 +16,35 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_CGRAPH_H
|
||||
#define GCC_CGRAPH_H
|
||||
#include "tree.h"
|
||||
#include "basic-block.h"
|
||||
|
||||
enum availability
|
||||
{
|
||||
/* Not yet set by cgraph_function_body_availability. */
|
||||
AVAIL_UNSET,
|
||||
/* Function body/variable initializer is unknown. */
|
||||
AVAIL_NOT_AVAILABLE,
|
||||
/* Function body/variable initializer is known but might be replaced
|
||||
by a different one from other compilation unit and thus needs to
|
||||
be dealt with a care. Like AVAIL_NOT_AVAILABLE it can have
|
||||
arbitrary side effects on escaping variables and functions, while
|
||||
like AVAILABLE it might access static variables. */
|
||||
AVAIL_OVERWRITABLE,
|
||||
/* Function body/variable initializer is known and will be used in final
|
||||
program. */
|
||||
AVAIL_AVAILABLE,
|
||||
/* Function body/variable initializer is known and all it's uses are explicitly
|
||||
visible within current unit (ie it's address is never taken and it is not
|
||||
exported to other units).
|
||||
Currently used only for functions. */
|
||||
AVAIL_LOCAL
|
||||
};
|
||||
|
||||
/* Information about the function collected locally.
|
||||
Available after function is analyzed. */
|
||||
|
|
@ -31,18 +55,32 @@ struct cgraph_local_info GTY(())
|
|||
int self_insns;
|
||||
|
||||
/* Set when function function is visible in current compilation unit only
|
||||
and it's address is never taken. */
|
||||
bool local;
|
||||
and its address is never taken. */
|
||||
unsigned local : 1;
|
||||
|
||||
/* Set when function is visible by other units. */
|
||||
unsigned externally_visible : 1;
|
||||
|
||||
/* Set once it has been finalized so we consider it to be output. */
|
||||
bool finalized;
|
||||
unsigned finalized : 1;
|
||||
|
||||
/* False when there something makes inlining impossible (such as va_arg). */
|
||||
bool inlinable;
|
||||
/* True when function should be inlined independently on it's size. */
|
||||
bool disregard_inline_limits;
|
||||
unsigned inlinable : 1;
|
||||
|
||||
/* True when function should be inlined independently on its size. */
|
||||
unsigned disregard_inline_limits : 1;
|
||||
|
||||
/* True when the function has been originally extern inline, but it is
|
||||
redefined now. */
|
||||
bool redefined_extern_inline;
|
||||
unsigned redefined_extern_inline : 1;
|
||||
|
||||
/* True if statics_read_for_function and
|
||||
statics_written_for_function contain valid data. */
|
||||
unsigned for_functions_valid : 1;
|
||||
|
||||
/* True if the function is going to be emitted in some other translation
|
||||
unit, referenced from vtable. */
|
||||
unsigned vtable_method : 1;
|
||||
};
|
||||
|
||||
/* Information about the function that needs to be computed globally
|
||||
|
|
@ -50,21 +88,16 @@ struct cgraph_local_info GTY(())
|
|||
|
||||
struct cgraph_global_info GTY(())
|
||||
{
|
||||
/* For inline clones this points to the function they will be inlined into. */
|
||||
struct cgraph_node *inlined_to;
|
||||
|
||||
/* Estimated size of the function after inlining. */
|
||||
int insns;
|
||||
|
||||
/* Number of times given function will be cloned during output. */
|
||||
int cloned_times;
|
||||
/* Estimated growth after inlining. INT_MIN if not computed. */
|
||||
int estimated_growth;
|
||||
|
||||
/* Set when the function will be inlined exactly once. */
|
||||
bool inline_once;
|
||||
|
||||
/* Set to true for all reachable functions before inlining is decided.
|
||||
Once we inline all calls to the function and the function is local,
|
||||
it is set to false. */
|
||||
bool will_be_output;
|
||||
|
||||
/* Set iff at least one of the caller edges has inline_call flag set. */
|
||||
/* Set iff the function has been inlined at least once. */
|
||||
bool inlined;
|
||||
};
|
||||
|
||||
|
|
@ -73,12 +106,9 @@ struct cgraph_global_info GTY(())
|
|||
|
||||
struct cgraph_rtl_info GTY(())
|
||||
{
|
||||
bool const_function;
|
||||
bool pure_function;
|
||||
int preferred_incoming_stack_boundary;
|
||||
};
|
||||
|
||||
|
||||
/* The cgraph data structure.
|
||||
Each function decl has assigned cgraph_node listing callees and callers. */
|
||||
|
||||
|
|
@ -97,96 +127,208 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
|
|||
struct cgraph_node *next_nested;
|
||||
/* Pointer to the next function in cgraph_nodes_queue. */
|
||||
struct cgraph_node *next_needed;
|
||||
PTR GTY ((skip (""))) aux;
|
||||
/* Pointer to the next clone. */
|
||||
struct cgraph_node *next_clone;
|
||||
struct cgraph_node *prev_clone;
|
||||
/* Pointer to a single unique cgraph node for this function. If the
|
||||
function is to be output, this is the copy that will survive. */
|
||||
struct cgraph_node *master_clone;
|
||||
/* For functions with many calls sites it holds map from call expression
|
||||
to the edge to speed up cgraph_edge function. */
|
||||
htab_t GTY((param_is (struct cgraph_edge))) call_site_hash;
|
||||
|
||||
PTR GTY ((skip)) aux;
|
||||
|
||||
struct cgraph_local_info local;
|
||||
struct cgraph_global_info global;
|
||||
struct cgraph_rtl_info rtl;
|
||||
|
||||
/* Expected number of executions: calculated in profile.c. */
|
||||
gcov_type count;
|
||||
/* Unique id of the node. */
|
||||
int uid;
|
||||
/* Ordering of all cgraph nodes. */
|
||||
int order;
|
||||
|
||||
/* Set when function must be output - it is externally visible
|
||||
or it's address is taken. */
|
||||
bool needed;
|
||||
or its address is taken. */
|
||||
unsigned needed : 1;
|
||||
/* Set when function is reachable by call from other function
|
||||
that is either reachable or needed. */
|
||||
bool reachable;
|
||||
unsigned reachable : 1;
|
||||
/* Set once the function is lowered (i.e. its CFG is built). */
|
||||
unsigned lowered : 1;
|
||||
/* Set once the function has been instantiated and its callee
|
||||
lists created. */
|
||||
bool analyzed;
|
||||
unsigned analyzed : 1;
|
||||
/* Set when function is scheduled to be assembled. */
|
||||
bool output;
|
||||
unsigned output : 1;
|
||||
/* Set for aliases once they got through assemble_alias. */
|
||||
unsigned alias : 1;
|
||||
|
||||
/* In non-unit-at-a-time mode the function body of inline candidates is saved
|
||||
into clone before compiling so the function in original form can be
|
||||
inlined later. This pointer points to the clone. */
|
||||
tree inline_decl;
|
||||
};
|
||||
|
||||
struct cgraph_edge GTY(())
|
||||
struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller")))
|
||||
{
|
||||
struct cgraph_node *caller;
|
||||
struct cgraph_node *callee;
|
||||
struct cgraph_edge *prev_caller;
|
||||
struct cgraph_edge *next_caller;
|
||||
struct cgraph_edge *prev_callee;
|
||||
struct cgraph_edge *next_callee;
|
||||
tree call_stmt;
|
||||
PTR GTY ((skip (""))) aux;
|
||||
/* When NULL, inline this call. When non-NULL, points to the explanation
|
||||
why function was not inlined. */
|
||||
const char *inline_failed;
|
||||
/* Expected number of executions: calculated in profile.c. */
|
||||
gcov_type count;
|
||||
/* Depth of loop nest, 1 means no loop nest. */
|
||||
int loop_nest;
|
||||
};
|
||||
|
||||
typedef struct cgraph_edge *cgraph_edge_p;
|
||||
|
||||
DEF_VEC_P(cgraph_edge_p);
|
||||
DEF_VEC_ALLOC_P(cgraph_edge_p,heap);
|
||||
|
||||
/* The cgraph_varpool data structure.
|
||||
Each static variable decl has assigned cgraph_varpool_node. */
|
||||
|
||||
struct cgraph_varpool_node GTY(())
|
||||
{
|
||||
tree decl;
|
||||
/* Pointer to the next function in cgraph_varpool_nodes. */
|
||||
struct cgraph_varpool_node *next;
|
||||
/* Pointer to the next function in cgraph_varpool_nodes_queue. */
|
||||
struct cgraph_varpool_node *next_needed;
|
||||
/* Ordering of all cgraph nodes. */
|
||||
int order;
|
||||
|
||||
/* Set when function must be output - it is externally visible
|
||||
or it's address is taken. */
|
||||
bool needed;
|
||||
or its address is taken. */
|
||||
unsigned needed : 1;
|
||||
/* Needed variables might become dead by optimization. This flag
|
||||
forces the variable to be output even if it appears dead otherwise. */
|
||||
unsigned force_output : 1;
|
||||
/* Set once the variable has been instantiated and its callee
|
||||
lists created. */
|
||||
unsigned analyzed : 1;
|
||||
/* Set once it has been finalized so we consider it to be output. */
|
||||
bool finalized;
|
||||
/* Set when function is scheduled to be assembled. */
|
||||
bool output;
|
||||
unsigned finalized : 1;
|
||||
/* Set when variable is scheduled to be assembled. */
|
||||
unsigned output : 1;
|
||||
/* Set when function is visible by other units. */
|
||||
unsigned externally_visible : 1;
|
||||
/* Set for aliases once they got through assemble_alias. */
|
||||
unsigned alias : 1;
|
||||
};
|
||||
|
||||
/* Every top level asm statement is put into a cgraph_asm_node. */
|
||||
|
||||
struct cgraph_asm_node GTY(())
|
||||
{
|
||||
/* Next asm node. */
|
||||
struct cgraph_asm_node *next;
|
||||
/* String for this asm node. */
|
||||
tree asm_str;
|
||||
/* Ordering of all cgraph nodes. */
|
||||
int order;
|
||||
};
|
||||
|
||||
extern GTY(()) struct cgraph_node *cgraph_nodes;
|
||||
extern GTY(()) int cgraph_n_nodes;
|
||||
extern GTY(()) int cgraph_max_uid;
|
||||
extern bool cgraph_global_info_ready;
|
||||
extern bool cgraph_function_flags_ready;
|
||||
extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
|
||||
extern FILE *cgraph_dump_file;
|
||||
extern GTY(()) struct cgraph_node *cgraph_expand_queue;
|
||||
|
||||
extern GTY(()) int cgraph_varpool_n_nodes;
|
||||
extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node;
|
||||
extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_last_needed_node;
|
||||
extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
|
||||
|
||||
extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes;
|
||||
extern GTY(()) struct cgraph_asm_node *cgraph_asm_nodes;
|
||||
extern GTY(()) int cgraph_order;
|
||||
|
||||
/* In cgraph.c */
|
||||
void dump_cgraph (FILE *);
|
||||
void cgraph_remove_edge (struct cgraph_node *, struct cgraph_node *);
|
||||
void cgraph_remove_call (tree, tree);
|
||||
void dump_cgraph_node (FILE *, struct cgraph_node *);
|
||||
void cgraph_insert_node_to_hashtable (struct cgraph_node *node);
|
||||
void dump_varpool (FILE *);
|
||||
void dump_cgraph_varpool_node (FILE *, struct cgraph_varpool_node *);
|
||||
void cgraph_remove_edge (struct cgraph_edge *);
|
||||
void cgraph_remove_node (struct cgraph_node *);
|
||||
struct cgraph_edge *cgraph_record_call (tree, tree);
|
||||
struct cgraph_node *cgraph_node (tree decl);
|
||||
struct cgraph_node *cgraph_node_for_identifier (tree id);
|
||||
bool cgraph_calls_p (tree, tree);
|
||||
void cgraph_node_remove_callees (struct cgraph_node *node);
|
||||
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
|
||||
struct cgraph_node *,
|
||||
tree, gcov_type, int);
|
||||
struct cgraph_node *cgraph_node (tree);
|
||||
struct cgraph_node *cgraph_node_for_asm (tree asmname);
|
||||
struct cgraph_edge *cgraph_edge (struct cgraph_node *, tree);
|
||||
void cgraph_set_call_stmt (struct cgraph_edge *, tree);
|
||||
struct cgraph_local_info *cgraph_local_info (tree);
|
||||
struct cgraph_global_info *cgraph_global_info (tree);
|
||||
struct cgraph_rtl_info *cgraph_rtl_info (tree);
|
||||
const char * cgraph_node_name (struct cgraph_node *);
|
||||
struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
|
||||
struct cgraph_node *,
|
||||
tree, gcov_type, int, bool);
|
||||
struct cgraph_node * cgraph_clone_node (struct cgraph_node *, gcov_type,
|
||||
int, bool);
|
||||
|
||||
struct cgraph_varpool_node *cgraph_varpool_node (tree decl);
|
||||
struct cgraph_varpool_node *cgraph_varpool_node_for_identifier (tree id);
|
||||
struct cgraph_varpool_node *cgraph_varpool_node (tree);
|
||||
struct cgraph_varpool_node *cgraph_varpool_node_for_asm (tree asmname);
|
||||
void cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *);
|
||||
void cgraph_varpool_finalize_decl (tree);
|
||||
bool cgraph_varpool_assemble_pending_decls (void);
|
||||
void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
|
||||
|
||||
struct cgraph_asm_node *cgraph_add_asm_node (tree);
|
||||
|
||||
bool cgraph_function_possibly_inlined_p (tree);
|
||||
void cgraph_unnest_node (struct cgraph_node *);
|
||||
void cgraph_varpool_enqueue_needed_node (struct cgraph_varpool_node *);
|
||||
void cgraph_varpool_reset_queue (void);
|
||||
bool decide_is_variable_needed (struct cgraph_varpool_node *, tree);
|
||||
|
||||
enum availability cgraph_function_body_availability (struct cgraph_node *);
|
||||
enum availability cgraph_variable_initializer_availability (struct cgraph_varpool_node *);
|
||||
bool cgraph_is_master_clone (struct cgraph_node *);
|
||||
struct cgraph_node *cgraph_master_clone (struct cgraph_node *);
|
||||
void cgraph_add_new_function (tree);
|
||||
|
||||
/* In cgraphunit.c */
|
||||
bool cgraph_assemble_pending_functions (void);
|
||||
bool cgraph_varpool_assemble_pending_decls (void);
|
||||
void cgraph_finalize_function (tree, bool);
|
||||
void cgraph_finalize_compilation_unit (void);
|
||||
void cgraph_create_edges (tree, tree);
|
||||
void cgraph_optimize (void);
|
||||
void cgraph_mark_needed_node (struct cgraph_node *);
|
||||
void cgraph_mark_reachable_node (struct cgraph_node *);
|
||||
bool cgraph_inline_p (tree, tree, const char **reason);
|
||||
bool cgraph_inline_p (struct cgraph_edge *, const char **reason);
|
||||
bool cgraph_preserve_function_body_p (tree);
|
||||
void verify_cgraph (void);
|
||||
void verify_cgraph_node (struct cgraph_node *);
|
||||
void cgraph_build_static_cdtor (char which, tree body, int priority);
|
||||
void cgraph_reset_static_var_maps (void);
|
||||
void init_cgraph (void);
|
||||
struct cgraph_node *cgraph_function_versioning (struct cgraph_node *,
|
||||
VEC(cgraph_edge_p,heap)*,
|
||||
varray_type);
|
||||
void cgraph_analyze_function (struct cgraph_node *);
|
||||
struct cgraph_node *save_inline_function_body (struct cgraph_node *);
|
||||
|
||||
/* In ipa.c */
|
||||
bool cgraph_remove_unreachable_nodes (bool, FILE *);
|
||||
int cgraph_postorder (struct cgraph_node **);
|
||||
|
||||
/* In ipa-inline.c */
|
||||
bool cgraph_decide_inlining_incrementally (struct cgraph_node *, bool);
|
||||
void cgraph_clone_inlined_nodes (struct cgraph_edge *, bool, bool);
|
||||
void cgraph_mark_inline_edge (struct cgraph_edge *, bool);
|
||||
bool cgraph_default_inline_p (struct cgraph_node *, const char **);
|
||||
#endif /* GCC_CGRAPH_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/* Header file for collect/tlink routines.
|
||||
Copyright (C) 1998, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
|
@ -15,31 +15,32 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
#ifndef GCC_COLLECT2_H
|
||||
#define GCC_COLLECT2_H
|
||||
|
||||
extern void do_tlink (char **, char **);
|
||||
|
||||
extern void collect_execute (const char *, char **, const char *);
|
||||
extern struct pex_obj *collect_execute (const char *, char **, const char *,
|
||||
const char *);
|
||||
|
||||
extern void collect_exit (int) ATTRIBUTE_NORETURN;
|
||||
|
||||
extern int collect_wait (const char *);
|
||||
extern int collect_wait (const char *, struct pex_obj *);
|
||||
|
||||
extern void dump_file (const char *);
|
||||
extern void dump_file (const char *, FILE *);
|
||||
|
||||
extern int file_exists (const char *);
|
||||
|
||||
extern const char *ldout;
|
||||
extern const char *lderrout;
|
||||
extern const char *c_file_name;
|
||||
extern struct obstack temporary_obstack;
|
||||
extern char *temporary_firstobj;
|
||||
extern int vflag, debug;
|
||||
|
||||
extern void fancy_abort (void) ATTRIBUTE_NORETURN;
|
||||
extern void error (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||||
extern void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
|
||||
extern void fatal (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -15,8 +15,8 @@ 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. */
|
||||
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* None of the things in the files exist if we don't use CC0. */
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#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.
|
||||
#Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
#02110-1301, USA.
|
||||
|
||||
# This is the GCC build-specific configuration file
|
||||
# where a configuration type is mapped to different system-specific
|
||||
|
|
@ -90,15 +90,10 @@ case $build in
|
|||
build_install_headers_dir=install-headers-cpio
|
||||
;;
|
||||
i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4* )
|
||||
build_xm_defines="SMALL_ARG_MAX"
|
||||
build_install_headers_dir=install-headers-cpio
|
||||
;;
|
||||
i[34567]86-*-solaris2*)
|
||||
build_xm_defines="SMALL_ARG_MAX"
|
||||
;;
|
||||
i[34567]86-*-sysv4*)
|
||||
# Intel x86 running system V r4
|
||||
build_xm_defines="SMALL_ARG_MAX"
|
||||
build_install_headers_dir=install-headers-cpio
|
||||
;;
|
||||
i[34567]86-*-udk*)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
# GCC host-specific configuration file.
|
||||
# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GCC.
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#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.
|
||||
#Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
#02110-1301, USA.
|
||||
|
||||
# This is the GCC host-specific configuration file
|
||||
# where a configuration type is mapped to different system-specific
|
||||
|
|
@ -49,6 +49,13 @@
|
|||
# be linked into the gcc driver.
|
||||
#
|
||||
# out_host_hook_obj An object file that provides the host hooks.
|
||||
#
|
||||
# host_can_use_collect2 Set to yes normally; to no if the host cannot
|
||||
# link or otherwise use collect2
|
||||
# use_long_long_for_widest_fast_int Set this to 'yes' if 'long long'
|
||||
# (or '__int64') is wider than 'long' but still
|
||||
# efficeiently supported by the host hardware.
|
||||
# Only affects compile speed. Default is 'no'.
|
||||
|
||||
# When setting any of these variables, check to see if a corresponding
|
||||
# variable is present in config.build; if so, you will likely want to
|
||||
|
|
@ -62,6 +69,8 @@ host_exeext=
|
|||
host_extra_objs=
|
||||
host_extra_gcc_objs=
|
||||
out_host_hook_obj=host-default.o
|
||||
host_can_use_collect2=yes
|
||||
use_long_long_for_widest_fast_int=no
|
||||
|
||||
# Unsupported hosts list. Generally, only include hosts known to fail here,
|
||||
# since we allow hosts not listed to be supported generically.
|
||||
|
|
@ -76,12 +85,35 @@ case ${host} in
|
|||
;;
|
||||
esac
|
||||
|
||||
# Common parts for widely ported systems.
|
||||
case ${host} in
|
||||
*-darwin*)
|
||||
# Generic darwin host support.
|
||||
out_host_hook_obj=host-darwin.o
|
||||
host_xmake_file="${host_xmake_file} x-darwin"
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${host} in
|
||||
i[34567]86-*-* \
|
||||
| x86_64-*-* )
|
||||
case ${target} in
|
||||
i[34567]86-*-* \
|
||||
| x86_64-*-* )
|
||||
host_extra_gcc_objs="driver-i386.o"
|
||||
host_xmake_file="${host_xmake_file} i386/x-i386"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Machine-specific settings.
|
||||
case ${host} in
|
||||
alpha*-dec-*vms*)
|
||||
host_xm_file=alpha/xm-vms.h
|
||||
host_xmake_file=alpha/x-vms
|
||||
host_xmake_file="${host_xmake_file} alpha/x-vms"
|
||||
host_exeext=.exe
|
||||
host_can_use_collect2=no
|
||||
# This removes the cpu type and manufacturer components and
|
||||
# replaces "." with "_" in the operating system version.
|
||||
target_noncanonical=`echo $host | sed 's/.*-.*-\(.*\)$/\1/' | sed 's/\./_/g'`
|
||||
|
|
@ -89,40 +121,36 @@ case ${host} in
|
|||
local_prefix=/gnu
|
||||
;;
|
||||
hppa1.1-*-pro*)
|
||||
host_xmake_file="pa/x-ada"
|
||||
host_xmake_file="${host_xmake_file} pa/x-ada"
|
||||
;;
|
||||
hppa1.1-*-osf*)
|
||||
host_xmake_file="pa/x-ada"
|
||||
host_xmake_file="${host_xmake_file} pa/x-ada"
|
||||
;;
|
||||
hppa1.1-*-rtems*)
|
||||
host_xmake_file="pa/x-ada"
|
||||
host_xmake_file="${host_xmake_file} pa/x-ada"
|
||||
;;
|
||||
hppa1.1-*-bsd*)
|
||||
host_xmake_file="pa/x-ada"
|
||||
host_xmake_file="${host_xmake_file} pa/x-ada"
|
||||
;;
|
||||
hppa1.0-*-hpux10* | hppa1.1-*-hpux10* | hppa2*-*-hpux10*)
|
||||
out_host_hook_obj=host-hpux.o
|
||||
host_xmake_file="${host_xmake_file} pa/x-ada-hpux10 x-hpux"
|
||||
;;
|
||||
hppa1.0-*-hpux10* | hppa1.1-*-hpux10* | hppa2*-*-hpux10* | \
|
||||
hppa1.0-*-hpux11* | hppa1.1-*-hpux11* | hppa2*-*-hpux11* | \
|
||||
hppa*64*-*-hpux11*)
|
||||
out_host_hook_obj=pa-host.o
|
||||
host_xmake_file=pa/x-hpux
|
||||
out_host_hook_obj=host-hpux.o
|
||||
host_xmake_file="${host_xmake_file} pa/x-ada x-hpux"
|
||||
;;
|
||||
hppa*-*-linux*)
|
||||
out_host_hook_obj=pa-host.o
|
||||
host_xmake_file=pa/x-linux
|
||||
out_host_hook_obj=host-hpux.o
|
||||
host_xmake_file="${host_xmake_file} x-hpux"
|
||||
;;
|
||||
i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture
|
||||
host_xm_defines='FATAL_EXIT_CODE=12'
|
||||
;;
|
||||
i[34567]86-sequent-ptx4*)
|
||||
host_xm_defines="SMALL_ARG_MAX"
|
||||
;;
|
||||
i[34567]86-*-solaris2*)
|
||||
host_xm_defines="SMALL_ARG_MAX"
|
||||
out_host_hook_obj=host-solaris.o
|
||||
host_xmake_file=x-solaris
|
||||
;;
|
||||
i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4
|
||||
host_xm_defines="SMALL_ARG_MAX"
|
||||
host_xmake_file="${host_xmake_file} x-solaris"
|
||||
;;
|
||||
i[34567]86-pc-msdosdjgpp*)
|
||||
host_xm_file=i386/xm-djgpp.h
|
||||
|
|
@ -136,12 +164,15 @@ case ${host} in
|
|||
;;
|
||||
i[34567]86-*-pe | i[34567]86-*-cygwin*)
|
||||
host_xm_file=i386/xm-cygwin.h
|
||||
out_host_hook_obj=host-cygwin.o
|
||||
host_xmake_file="${host_xmake_file} i386/x-cygwin"
|
||||
host_exeext=.exe
|
||||
;;
|
||||
i[34567]86-*-mingw32*)
|
||||
host_xm_file=i386/xm-mingw32.h
|
||||
host_xmake_file=i386/x-mingw32
|
||||
host_xmake_file="${host_xmake_file} i386/x-mingw32"
|
||||
host_exeext=.exe
|
||||
out_host_hook_obj=host-mingw32.o
|
||||
;;
|
||||
i[34567]86-*-uwin*)
|
||||
echo "*** UWIN may not be used as a host platform because"
|
||||
|
|
@ -149,22 +180,34 @@ case ${host} in
|
|||
exit 1
|
||||
;;
|
||||
i[34567]86-*-interix3*)
|
||||
host_xmake_file="x-interix"
|
||||
host_xmake_file="${host_xmake_file} x-interix"
|
||||
;;
|
||||
i860-*-sysv4*)
|
||||
host_xmake_file=i860/x-sysv4
|
||||
i[34567]86-*-darwin* | x86_64-*-darwin*)
|
||||
out_host_hook_obj="${out_host_hook_obj} host-i386-darwin.o"
|
||||
host_xmake_file="${host_xmake_file} i386/x-darwin"
|
||||
;;
|
||||
powerpc-*-beos*)
|
||||
host_can_use_collect2=no
|
||||
;;
|
||||
powerpc-*-darwin*)
|
||||
# powerpc-darwin host support.
|
||||
out_host_hook_obj=host-darwin.o
|
||||
host_xmake_file=rs6000/x-darwin
|
||||
out_host_hook_obj="${out_host_hook_obj} host-ppc-darwin.o"
|
||||
host_xmake_file="${host_xmake_file} rs6000/x-darwin"
|
||||
;;
|
||||
powerpc64-*-darwin*)
|
||||
out_host_hook_obj="${out_host_hook_obj} host-ppc64-darwin.o"
|
||||
host_xmake_file="${host_xmake_file} rs6000/x-darwin64"
|
||||
;;
|
||||
*-*-solaris2*)
|
||||
out_host_hook_obj=host-solaris.o
|
||||
host_xmake_file=x-solaris
|
||||
host_xmake_file="${host_xmake_file} x-solaris"
|
||||
;;
|
||||
*-*-linux*)
|
||||
out_host_hook_obj=host-linux.o
|
||||
host_xmake_file=x-linux
|
||||
host_xmake_file="${host_xmake_file} x-linux"
|
||||
;;
|
||||
ia64-*-hpux*)
|
||||
use_long_long_for_widest_fast_int=yes
|
||||
out_host_hook_obj=host-hpux.o
|
||||
host_xmake_file="${host_xmake_file} x-hpux"
|
||||
;;
|
||||
esac
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -78,7 +78,7 @@ then the following rules must be obeyed:
|
|||
|
||||
* All externally visible functions which should be entered in
|
||||
Thumb mode must have the .thumb_func pseudo op specified just
|
||||
before their entry point. eg:
|
||||
before their entry point. e.g.:
|
||||
|
||||
.code 16
|
||||
.global function
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* Definitions of target machine for GNU compiler, for Advanced RISC Machines
|
||||
ARM compilation, AOF Assembler.
|
||||
Copyright (C) 1995, 1996, 1997, 2000, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 1997, 2000, 2003, 2004
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk)
|
||||
|
||||
This file is part of GCC.
|
||||
|
|
@ -17,8 +18,8 @@
|
|||
|
||||
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. */
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
|
||||
|
||||
|
|
@ -34,8 +35,7 @@
|
|||
#define ENDFILE_SPEC "crtend.o%s"
|
||||
|
||||
#ifndef ASM_SPEC
|
||||
#define ASM_SPEC "%{g -g} -arch 4 \
|
||||
-apcs 3%{mapcs-32:/32bit}%{mapcs-26:/26bit}%{!mapcs-26:%{!macps-32:/26bit}}"
|
||||
#define ASM_SPEC "%{g -g} -arch 4 -apcs 3/32bit"
|
||||
#endif
|
||||
|
||||
#ifndef LIB_SPEC
|
||||
|
|
@ -44,48 +44,6 @@
|
|||
|
||||
#define LIBGCC_SPEC "libgcc.a%s"
|
||||
|
||||
/* Dividing the Output into Sections (Text, Data, ...) */
|
||||
/* AOF Assembler syntax is a nightmare when it comes to areas, since once
|
||||
we change from one area to another, we can't go back again. Instead,
|
||||
we must create a new area with the same attributes and add the new output
|
||||
to that. Unfortunately, there is nothing we can do here to guarantee that
|
||||
two areas with the same attributes will be linked adjacently in the
|
||||
resulting executable, so we have to be careful not to do pc-relative
|
||||
addressing across such boundaries. */
|
||||
#define TEXT_SECTION_ASM_OP aof_text_section ()
|
||||
|
||||
#define DATA_SECTION_ASM_OP aof_data_section ()
|
||||
|
||||
#define EXTRA_SECTIONS in_zero_init, in_common
|
||||
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
ZERO_INIT_SECTION \
|
||||
COMMON_SECTION
|
||||
|
||||
#define ZERO_INIT_SECTION \
|
||||
void \
|
||||
zero_init_section () \
|
||||
{ \
|
||||
static int zero_init_count = 1; \
|
||||
\
|
||||
if (in_section != in_zero_init) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
|
||||
zero_init_count++); \
|
||||
in_section = in_zero_init; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Used by ASM_OUTPUT_COMMON (below) to tell varasm.c that we've
|
||||
changed areas. */
|
||||
#define COMMON_SECTION \
|
||||
void \
|
||||
common_section () \
|
||||
{ \
|
||||
if (in_section != in_common) \
|
||||
in_section = in_common; \
|
||||
}
|
||||
|
||||
#define CTOR_LIST_BEGIN \
|
||||
asm (CTORS_SECTION_ASM_OP); \
|
||||
extern func_ptr __CTOR_END__[1]; \
|
||||
|
|
@ -130,6 +88,8 @@
|
|||
whole table generation until the end of the function. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
|
||||
#define TARGET_ASM_INIT_SECTIONS aof_asm_init_sections
|
||||
|
||||
/* Some systems use __main in a way incompatible with its use in gcc, in these
|
||||
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
|
||||
give the same symbol without quotes for an alternative entry point. You
|
||||
|
|
@ -159,7 +119,7 @@
|
|||
/* Output of Uninitialized Variables. */
|
||||
|
||||
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
|
||||
(common_section (), \
|
||||
(in_section = NULL, \
|
||||
fprintf ((STREAM), "\tAREA "), \
|
||||
assemble_name ((STREAM), (NAME)), \
|
||||
fprintf ((STREAM), ", DATA, COMMON\n\t%% %d\t%s size=%d\n", \
|
||||
|
|
@ -246,7 +206,12 @@ do { \
|
|||
"wr0", "wr1", "wr2", "wr3", \
|
||||
"wr4", "wr5", "wr6", "wr7", \
|
||||
"wr8", "wr9", "wr10", "wr11", \
|
||||
"wr12", "wr13", "wr14", "wr15" \
|
||||
"wr12", "wr13", "wr14", "wr15", \
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
|
||||
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", \
|
||||
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", \
|
||||
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", \
|
||||
"vfpcc" \
|
||||
}
|
||||
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
|
|
@ -266,7 +231,23 @@ do { \
|
|||
{"r12", 12}, {"ip", 12}, \
|
||||
{"r13", 13}, {"sp", 13}, \
|
||||
{"r14", 14}, {"lr", 14}, \
|
||||
{"r15", 15}, {"pc", 15} \
|
||||
{"r15", 15}, {"pc", 15}, \
|
||||
{"d0", 63}, \
|
||||
{"d1", 65}, \
|
||||
{"d2", 67}, \
|
||||
{"d3", 69}, \
|
||||
{"d4", 71}, \
|
||||
{"d5", 73}, \
|
||||
{"d6", 75}, \
|
||||
{"d7", 77}, \
|
||||
{"d8", 79}, \
|
||||
{"d9", 81}, \
|
||||
{"d10", 83}, \
|
||||
{"d11", 85}, \
|
||||
{"d12", 87}, \
|
||||
{"d13", 89}, \
|
||||
{"d14", 91}, \
|
||||
{"d15", 93} \
|
||||
}
|
||||
|
||||
#define REGISTER_PREFIX "__"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Definitions of target machine for GNU compiler, for ARM with a.out
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk).
|
||||
|
||||
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
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. */
|
||||
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef ASM_APP_ON
|
||||
#define ASM_APP_ON ""
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
/* The assembler's names for the registers. */
|
||||
#ifndef REGISTER_NAMES
|
||||
#define REGISTER_NAMES \
|
||||
#define REGISTER_NAMES \
|
||||
{ \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
|
||||
"r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc", \
|
||||
|
|
@ -63,7 +63,12 @@
|
|||
"wr0", "wr1", "wr2", "wr3", \
|
||||
"wr4", "wr5", "wr6", "wr7", \
|
||||
"wr8", "wr9", "wr10", "wr11", \
|
||||
"wr12", "wr13", "wr14", "wr15" \
|
||||
"wr12", "wr13", "wr14", "wr15", \
|
||||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
|
||||
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", \
|
||||
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", \
|
||||
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", \
|
||||
"vfpcc" \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -152,7 +157,23 @@
|
|||
{"mvdx12", 39}, \
|
||||
{"mvdx13", 40}, \
|
||||
{"mvdx14", 41}, \
|
||||
{"mvdx15", 42} \
|
||||
{"mvdx15", 42}, \
|
||||
{"d0", 63}, \
|
||||
{"d1", 65}, \
|
||||
{"d2", 67}, \
|
||||
{"d3", 69}, \
|
||||
{"d4", 71}, \
|
||||
{"d5", 73}, \
|
||||
{"d6", 75}, \
|
||||
{"d7", 77}, \
|
||||
{"d8", 79}, \
|
||||
{"d9", 81}, \
|
||||
{"d10", 83}, \
|
||||
{"d11", 85}, \
|
||||
{"d12", 87}, \
|
||||
{"d13", 89}, \
|
||||
{"d14", 91}, \
|
||||
{"d15", 93}, \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -172,19 +193,6 @@
|
|||
#define DBX_CONTIN_LENGTH 0
|
||||
#endif
|
||||
|
||||
/* Output a source filename for the debugger. RISCiX dbx insists that the
|
||||
``desc'' field is set to compiler version number >= 315 (sic). */
|
||||
#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM, NAME) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, ".stabs "); \
|
||||
output_quoted_string (STREAM, NAME); \
|
||||
fprintf (STREAM, ",%d,0,315,%s\n", N_SO, <ext_label_name[1]); \
|
||||
text_section (); \
|
||||
(*targetm.asm_out.internal_label) (STREAM, "Ltext", 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Output a function label definition. */
|
||||
#ifndef ASM_DECLARE_FUNCTION_NAME
|
||||
#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
|
||||
|
|
@ -265,7 +273,7 @@
|
|||
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
|
||||
do \
|
||||
{ \
|
||||
bss_section (); \
|
||||
switch_to_section (bss_section); \
|
||||
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
ASM_OUTPUT_LABEL (STREAM, NAME); \
|
||||
fprintf (STREAM, "\t.space\t%d\n", (int)(SIZE)); \
|
||||
|
|
|
|||
117
contrib/gcc/config/arm/arm-cores.def
Normal file
117
contrib/gcc/config/arm/arm-cores.def
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/* ARM CPU Cores
|
||||
Copyright (C) 2003, 2005 Free Software Foundation, Inc.
|
||||
Written by CodeSourcery, LLC
|
||||
|
||||
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, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA. */
|
||||
|
||||
/* Before using #include to read this file, define a macro:
|
||||
|
||||
ARM_CORE(CORE_NAME, CORE_IDENT, ARCH, FLAGS, COSTS)
|
||||
|
||||
The CORE_NAME is the name of the core, represented as a string constant.
|
||||
The CORE_IDENT is the name of the core, represented as an identifier.
|
||||
ARCH is the architecture revision implemented by the chip.
|
||||
FLAGS are the bitwise-or of the traits that apply to that core.
|
||||
This need not include flags implied by the architecture.
|
||||
COSTS is the name of the rtx_costs routine to use.
|
||||
|
||||
If you update this table, you must update the "tune" attribute in
|
||||
arm.md.
|
||||
|
||||
Some tools assume no whitespace up to the first "," in each entry. */
|
||||
|
||||
/* V2/V2A Architecture Processors */
|
||||
ARM_CORE("arm2", arm2, 2, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm250", arm250, 2, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm3", arm3, 2, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
|
||||
/* V3 Architecture Processors */
|
||||
ARM_CORE("arm6", arm6, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm60", arm60, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm600", arm600, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm610", arm610, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm620", arm620, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm7", arm7, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm7d", arm7d, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm7di", arm7di, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm70", arm70, 3, FL_CO_PROC | FL_MODE26, slowmul)
|
||||
ARM_CORE("arm700", arm700, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm700i", arm700i, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm710", arm710, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm720", arm720, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm710c", arm710c, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm7100", arm7100, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
ARM_CORE("arm7500", arm7500, 3, FL_MODE26 | FL_WBUF, slowmul)
|
||||
/* Doesn't have an external co-proc, but does have embedded fpa. */
|
||||
ARM_CORE("arm7500fe", arm7500fe, 3, FL_CO_PROC | FL_MODE26 | FL_WBUF, slowmul)
|
||||
|
||||
/* V3M Architecture Processors */
|
||||
/* arm7m doesn't exist on its own, but only with D, ("and", and I), but
|
||||
those don't alter the code, so arm7m is sometimes used. */
|
||||
ARM_CORE("arm7m", arm7m, 3M, FL_CO_PROC | FL_MODE26, fastmul)
|
||||
ARM_CORE("arm7dm", arm7dm, 3M, FL_CO_PROC | FL_MODE26, fastmul)
|
||||
ARM_CORE("arm7dmi", arm7dmi, 3M, FL_CO_PROC | FL_MODE26, fastmul)
|
||||
|
||||
/* V4 Architecture Processors */
|
||||
ARM_CORE("arm8", arm8, 4, FL_MODE26 | FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm810", arm810, 4, FL_MODE26 | FL_LDSCHED, fastmul)
|
||||
ARM_CORE("strongarm", strongarm, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
ARM_CORE("strongarm110", strongarm110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
ARM_CORE("strongarm1100", strongarm1100, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
ARM_CORE("strongarm1110", strongarm1110, 4, FL_MODE26 | FL_LDSCHED | FL_STRONG, fastmul)
|
||||
|
||||
/* V4T Architecture Processors */
|
||||
ARM_CORE("arm7tdmi", arm7tdmi, 4T, FL_CO_PROC , fastmul)
|
||||
ARM_CORE("arm7tdmi-s", arm7tdmis, 4T, FL_CO_PROC , fastmul)
|
||||
ARM_CORE("arm710t", arm710t, 4T, FL_WBUF, fastmul)
|
||||
ARM_CORE("arm720t", arm720t, 4T, FL_WBUF, fastmul)
|
||||
ARM_CORE("arm740t", arm740t, 4T, FL_WBUF, fastmul)
|
||||
ARM_CORE("arm9", arm9, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm9tdmi", arm9tdmi, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm920", arm920, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm920t", arm920t, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm922t", arm922t, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm940t", arm940t, 4T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("ep9312", ep9312, 4T, FL_LDSCHED | FL_CIRRUS, fastmul)
|
||||
|
||||
/* V5T Architecture Processors */
|
||||
ARM_CORE("arm10tdmi", arm10tdmi, 5T, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm1020t", arm1020t, 5T, FL_LDSCHED, fastmul)
|
||||
|
||||
/* V5TE Architecture Processors */
|
||||
ARM_CORE("arm9e", arm9e, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm946e-s", arm946es, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm966e-s", arm966es, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm968e-s", arm968es, 5TE, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm10e", arm10e, 5TE, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm1020e", arm1020e, 5TE, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("arm1022e", arm1022e, 5TE, FL_LDSCHED, fastmul)
|
||||
ARM_CORE("xscale", xscale, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE, xscale)
|
||||
ARM_CORE("iwmmxt", iwmmxt, 5TE, FL_LDSCHED | FL_STRONG | FL_XSCALE | FL_IWMMXT, xscale)
|
||||
|
||||
/* V5TEJ Architecture Processors */
|
||||
ARM_CORE("arm926ej-s", arm926ejs, 5TEJ, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm1026ej-s", arm1026ejs, 5TEJ, FL_LDSCHED, 9e)
|
||||
|
||||
/* V6 Architecture Processors */
|
||||
ARM_CORE("arm1136j-s", arm1136js, 6J, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm1136jf-s", arm1136jfs, 6J, FL_LDSCHED | FL_VFPV2, 9e)
|
||||
ARM_CORE("arm1176jz-s", arm1176jzs, 6ZK, FL_LDSCHED, 9e)
|
||||
ARM_CORE("arm1176jzf-s", arm1176jzfs, 6ZK, FL_LDSCHED | FL_VFPV2, 9e)
|
||||
ARM_CORE("mpcorenovfp", mpcorenovfp, 6K, FL_LDSCHED, 9e)
|
||||
ARM_CORE("mpcore", mpcore, 6K, FL_LDSCHED | FL_VFPV2, 9e)
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue