Bring updated versions of libcpp and libgomp.

While GCC 4.3 changed license, the library components remained under
LGPLv2.1 all the during all the existence of the branch.
From gcclibs, only libcpp and libgomp have some value for us in the base
gcc 4.2.1: bring updated versions from GCC 4.3.5 as reference as we have
already been including some of the fixes.

These not expected to become part of any FreeBSD release.
This commit is contained in:
Pedro F. Giffuni 2015-04-28 16:28:29 +00:00
parent d279946991
commit e7884e61f4
39 changed files with 13222 additions and 1647 deletions

View File

@ -1,23 +1,381 @@
2007-07-19 Release Manager
2010-05-22 Release Manager
* GCC 4.2.1 released.
* GCC 4.3.5 released.
2007-05-13 Release Manager
2009-08-04 Release Manager
* GCC 4.2.0 released.
* GCC 4.3.4 released.
2007-04-23 Tom Tromey <tromey@redhat.com>
2009-01-24 Release Manager
PR preprocessor/30468:
* GCC 4.3.3 released.
2008-08-27 Release Manager
* GCC 4.3.2 released.
2008-07-31 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/36649
* files.c (struct report_missing_guard_data): New type.
(report_missing_guard): Put paths into an array instead of printing
them right away. Return 1 rather than 0.
(report_missing_guard_cmp): New function.
(_cpp_report_missing_guards): Sort and print paths gathered by
report_missing_guard callback.
2008-06-06 Release Manager
* GCC 4.3.1 released.
2008-03-05 Release Manager
* GCC 4.3.0 released.
2008-01-25 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/34692
* macro.c (collect_args): Add pragma_buff argument. Push
CPP_PRAGMA ... CPP_PRAGMA_EOL tokens to *pragma_buff, rather
than into arguments. Reset prevent_expansion and parsing_args
state at CPP_PRAGMA_EOL/CPP_EOF.
(funlike_invocation_p): Add pragma_buff argument, pass it through
to collect_args.
(enter_macro_context): Add result argument. Adjust
funlike_invocation_p caller. Emit all deferred pragma tokens
gathered during collect_args before the expansion, add a padding
token. Return 2 instead of 1 if any pragma tokens were prepended.
(cpp_get_token): If enter_macro_context returns 2, don't return
a padding token, instead cycle to grab CPP_PRAGMA token.
* directives.c (_cpp_handle_directive): If was_parsing_args
in deferred pragma, leave parsing_args and prevent_expansion as is.
2008-01-22 Tom Tromey <tromey@redhat.com>
PR c++/34859
* macro.c (_cpp_create_definition): Handle __STDC_LIMIT_MACROS and
__STDC_CONSTANT_MACROS.
2008-01-07 Fred Fish <fnf@specifix.com>
PR preprocessor/30363
* traditional.c (replace_args_and_push): Add local variable
cxtquote, calculate the replacement text size assuming a
worst case of every input character quoted with backslash,
and properly handle output quoting of quote characters in
actual arguments used in function-like macros.
2008-01-03 Tom Tromey <tromey@redhat.com>
PR preprocessor/34602
* directives.c (do_line): Don't try to spell EOF token.
(do_linemarker): Add comment.
2007-12-11 DJ Delorie <dj@redhat.com>
* charset.c (convert_using_iconv): Close out any shift states,
returning to the initial state.
2007-12-06 Tom Tromey <tromey@redhat.com>
PR c/29172
* internal.h (struct cpp_reader) <file_hash_entries>: Changed
type.
<file_hash_entries_allocated, file_hash_entries_used>: Removed.
* files.c (FILE_HASH_POOL_SIZE): New macro.
(struct file_hash_entry_pool): New.
(destroy_all_cpp_files): New function.
(allocate_file_hash_entries): Allocate a file_hash_entry_pool.
(new_file_hash_entry): Update.
(free_file_hash_entries): New function.
(_cpp_cleanup_files): Call free_file_hash_entries and
destroy_all_cpp_files.
(cpp_clear_file_cache): New function.
* include/cpplib.h (cpp_clear_file_cache): Declare.
2007-12-03 Tom Tromey <tromey@redhat.com>
PR preprocessor/34288
* configure.ac, config.in: Rebuilt.
* configure.ac: Check for ssize_t.
2007-11-30 Tom Tromey <tromey@redhat.com>
PR preprocessor/32868
* macro.c (_cpp_create_definition): Special case
__STDC_FORMAT_MACROS.
2007-11-16 Michael Matz <matz@suse.de>
* files.c (search_path_head): Fix check for absolute paths.
2007-11-11 Tom Tromey <tromey@redhat.com>
PR c++/17557
* include/cpplib.h (cpp_included_before): Declare.
* files.c (struct file_hash_entry) <location>: New field.
(_cpp_find_file): Initialize new field.
(make_cpp_dir): Likewise.
(cpp_included_before): New function.
2007-11-01 Tom Tromey <tromey@redhat.com>
PR preprocessor/30805
* macro.c (paste_tokens): Handle padding token.
(paste_tokens): Don't abort unless padding has PASTE_LEFT flag.
2007-10-31 Tom Tromey <tromey@redhat.com>
PR preprocessor/30786
* macro.c (builtin_macro): Return result of _cpp_do__Pragma.
* directives.c (_cpp_do__Pragma): Return error status.
* internal.h (_cpp_do__Pragma): Update.
* directives.c (get__Pragma_string): Back up if EOF seen.
2007-09-06 Tom Tromey <tromey@redhat.com>
* internal.h (struct cpp_reader) <invocation_location>: New
field.
(struct cpp_reader) <set_invocation_location>: Likewise.
* init.c (cpp_set_line_map): New function.
* line-map.c (linemap_add): Use linemap's allocator.
* include/line-map.h (GTY): Define.
(line_map_realloc): New typedef.
(struct line_map): Mark with GTY.
(struct line_maps): Likewise.
(struct line_maps) <maps>: Likewise.
(struct line_maps) <reallocator>: New field.
* include/symtab.h (GTY): Conditionally define.
* include/cpplib.h (cpp_set_line_map): Declare.
(cpp_get_token_with_location): Declare.
* macro.c (cpp_get_token): Set invocation_location on the reader.
(cpp_get_token_with_location): New function.
2007-08-30 Chao-ying Fu <fu@mips.com>
* expr.c (interpret_float_suffix): Support hr, r, lr, llr, uhr, ur,
ulr, ullr, hk, k, lk, llk, uhk, uk, ulk, ullk.
(cpp_classify_number): Support decimal fixed-point constants without
exponents.
Warn about fixed-point constants when -pedantic.
* include/cpplib.h (CPP_N_SMALL, CPP_N_MEDIUM, CPP_N_LARGE): Change
comments to support fixed-point values.
(CPP_N_FRACT, CPP_N_ACCUM): Define.
2007-08-18 Tom Tromey <tromey@redhat.com>
PR preprocessor/32974
* directives.c (parse_include): Don't check for EOL when
processing #pragma dependency.
2007-07-30 Ollie Wild <aaw@google.com>
* directives-only.c: New file.
* internal.h (struct _cpp_dir_only_callbacks): New.
(_cpp_preprocess_dir_only): New function.
* directives.c (_cpp_handle_directive): Check directives_only before
disabling execution of indented directives.
* files.c (_cpp_stack_file): Add directives_only check.
* include/cpplib.h (struct cpp_options): Add directives_only.
(cpp_init_special_builtins): New function.
* init.c (cpp_init_special_builtins): New function.
(cpp_init_builtins): Move builtin_array initialization to
cpp_init_special_builtins.
(post_options): Check directives_only before setting
pfile->state.prevent_expansion = 1.
* macro.c (_cpp_builtin_macro_text): Print an error if __COUNTER__
is expanded inside a directive while -fdirectives-only is enabled.
* Makefile.in (libcpp_a_OBJS): Add directives-only.o.
(libcpp_a_SOURCES): Add directives-only.c.
2007-07-04 Uros Bizjak <ubizjak@gmail.com>
* traditional.c (_cpp_scan_out_logical_line): Initialize
fmacro.args, fmacro.node, fmacro.offset, fmacro.line and
fmacro.args to prevent 'may be used uninitialized' warning.
2007-07-03 Uros Bizjak <ubizjak@gmail.com>
* include/cpplib.h (CPP_N_WIDTH_MD, CPP_N_MD_W, CPP_N_MD_Q):
Add new constants.
* expr.c (interpret_float_suffix): Process 'w', 'W', 'q' and 'Q'
suffixes. Return CPP_N_MD_W for 'w' or 'W' suffixes and CPP_N_MD_Q
for 'q' or 'Q' suffixes.
2007-06-17 Danny Smith <dannysmith@users.sourceforge.net
* files.c (open_file): Correct typo.
2007-06-16 Vladimir Prus <vladimir@codesourcery.com>
* files.c (open_file): Prevent the call
for stat from overwriting errno.
2007-06-09 Vladimir Prus <vladimir@codesourcery.com>
* files.c (open_file): Account for the
fact that on windows, opening a directory gives
EACCES.
2007-06-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
PR preprocessor/23479
* expr.c (cpp_classify_number): Implement 0b-prefixed binary
integer constants.
(append_digit): Likewise.
* include/cpplib.h: Add CPP_N_BINARY, to be used for 0b-prefixed
binary integer constants.
2007-05-31 Dave Korn <dave.korn@artimi.com>
PR preprocessor/14331
* lex.c (_cpp_get_fresh_line): Don't warn if no newline at EOF.
2007-05-24 Ollie Wild <aaw@google.com>
* macro.c (_cpp_builtin_macro_text): Handle BT_COUNTER.
* pch.c (cpp_write_pch_deps): Save __COUNTER__ state.
(cpp_write_pch_state): Save __COUNTER__ state.
(cpp_valid_state): Check valid __COUNTER__ state.
(cpp_read_state): Read new __COUNTER__ state.
* include/cpplib.h (enum builtin_type): Add BT_COUNTER enumerator.
* init.c (builtin_array): Add __COUNTER__/BT_COUNTER.
* internal.h (struct cpp_reader): Add counter member.
2007-05-23 Simon Martin <simartin@users.sourceforge.net>
PR preprocessor/20077
* macro.c (create_iso_definition): Fixed the method to determine
whether the token-pasting operator appears at the beginning or the end
of a macro.
2007-05-21 Ian Lance Taylor <iant@google.com>
* internal.h (struct cpp_reader): Add new fields:
nonexistent_file_hash and nonexistent_file_ob.
* files.c: Include "obstack.h".
(find_file_in_dir): Before trying to open the file, look up the
path name in the hash table of nonexistent files. After failing
to open the file, add the path name to the hash table.
(_cpp_find_file): Cache the results of looking up the file name
starting with the quote and bracket chain heads, if we can.
(nonexistent_file_hash_eq): New static function.
(_cpp_init_files): Initialize pfile->nonexistent_file_hash and
pfile->nonexistent_file_ob.
(_cpp_cleanup_files): Free pfile->nonexistent_file_hash and
pfile->nonexistent_file_ob.
2007-05-14 Janis Johnson <janis187@us.ibm.com>
* expr.c (cpp_classify_number): Warn about dfp constant for -pedantic.
PR c/31924
* expr.c (interpret_float_suffix): Check for invalid suffix.
2007-05-02 Eric Christopher <echristo@apple.com>
* expr.c (num_div_op): Don't overflow if the result is
zero.
2007-05-02 Tom Tromey <tromey@redhat.com>
PR preprocessor/28709
* macro.c (paste_tokens): Remove PASTE_LEFT from the old lhs.
2007-03-30 Michael Meissner <michael.meissner@amd.com>
* directives.c (lex_macro_node_from_str): Fix alloca call to be
type correct.
2007-03-30 Richard Henderson <rth@redhat.com>
* directives.c (lex_macro_node_from_str): New.
(cpp_push_definition, cpp_pop_definition): New.
* include/cpplib.h (cpp_push_definition, cpp_pop_definition): Declare.
2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
* Makefile.in: Add dummy install-pdf target.
2007-01-30 Tom Tromey <tromey@redhat.com>
PR preprocessor/30468
* mkdeps.c (apply_vpath): Strip successive '/'s if we stripped
'./'.
2007-01-30 Tom Tromey <tromey@redhat.com>
PR preprocessor/29966
* macro.c (lex_expansion_token): Save and restore cpp_reader's
cur_token.
(_cpp_create_definition): Don't restore cur_token here.
* lex.c (_cpp_lex_token): Added assertion.
2007-01-27 Tom Tromey <tromey@redhat.com>
* configure: Rebuilt.
2007-01-12 Tom Tromey <tromey@redhat.com>
PR preprocessor/28227
* directives.c (lex_macro_node): Added 'is_def_or_undef'
argument.
(do_define): Update.
(do_undef): Update.
(do_ifdef): Update.
(do_ifndef): Update.
2007-01-11 Paolo Bonzini <bonzini@gnu.org>
* configure: Regenerate.
2007-01-11 Paolo Bonzini <bonzini@gnu.org>
* configure: Regenerate.
2007-01-04 Tom Tromey <tromey@redhat.com>
PR preprocessor/28165
* internal.h (cpp_in_primary_file): New function.
* directives.c (do_include_next): Use cpp_in_primary_file.
(do_pragma_once): Likewise.
(do_pragma_system_header): Likewise.
2006-12-29 Ian Lance Taylor <iant@google.com>
* lex.c (_cpp_clean_line): Add uses of __builtin_expect. Don't
look backward at the end of the line unless we saw a backslash.
2006-12-29 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/29612
* directives.c (do_linemarker): Set pfile->buffer->sysp always, not
only when new_sysp is non-zero.
2006-12-28 Tom Tromey <tromey@redhat.com>
PR preprocessor/30001
* charset.c (_cpp_convert_input): Check that to.len is greater
than zero.
2006-11-20 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
* configure.ac (need_64bit_hwint): Need 64bit hwint for SPU.
* configure: Rebuilt.
2006-11-01 Douglas Gregor <doug.gregor@gmail.com>
* include/cpplib.h (enum c_lang): Add CLK_GNUCXX0X and CLK_CXX0X
for experimental C++0x mode.
* init.c (lang_defaults): Add defaults for C++0x modes. C++0x has
adopted the preprocessor changes introduced in C99.
2006-10-29 Joseph Myers <joseph@codesourcery.com>
* configure.ac (need_64bit_hwint): Set for i[34567]86-*-linux*
depending on --enable-targets=all.
* configure: Regenerate.
2006-10-12 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/28709

View File

@ -69,14 +69,14 @@ INCLUDES = -I$(srcdir) -I. -I$(srcdir)/../include @INCINTL@ \
ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS)
libcpp_a_OBJS = charset.o directives.o errors.o expr.o files.o \
identifiers.o init.o lex.o line-map.o macro.o mkdeps.o \
pch.o symtab.o traditional.o
libcpp_a_OBJS = charset.o directives.o directives-only.o errors.o \
expr.o files.o identifiers.o init.o lex.o line-map.o macro.o \
mkdeps.o pch.o symtab.o traditional.o
makedepend_OBJS = makedepend.o
libcpp_a_SOURCES = charset.c directives.c errors.c expr.c files.c \
identifiers.c init.c lex.c line-map.c macro.c mkdeps.c \
pch.c symtab.c traditional.c
libcpp_a_SOURCES = charset.c directives.c directives-only.c errors.c \
expr.c files.c identifiers.c init.c lex.c line-map.c macro.c \
mkdeps.c pch.c symtab.c traditional.c
all: libcpp.a makedepend$(EXEEXT) $(USED_CATALOGS)
@ -184,6 +184,7 @@ pdf:
html:
info:
install-info:
install-pdf:
install-man:
install-html:

View File

@ -1,5 +1,5 @@
/* CPP Library - charsets
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
Free Software Foundation, Inc.
Broken out of c-lex.c Apr 2003, adding valid C99 UCN ranges.
@ -548,6 +548,15 @@ convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
/* And this one uses the system iconv primitive. It's a little
different, since iconv's interface is a little different. */
#if HAVE_ICONV
#define CONVERT_ICONV_GROW_BUFFER \
do { \
outbytesleft += OUTBUF_BLOCK_SIZE; \
to->asize += OUTBUF_BLOCK_SIZE; \
to->text = XRESIZEVEC (uchar, to->text, to->asize); \
outbuf = (char *)to->text + to->asize - outbytesleft; \
} while (0)
static bool
convert_using_iconv (iconv_t cd, const uchar *from, size_t flen,
struct _cpp_strbuf *to)
@ -570,16 +579,24 @@ convert_using_iconv (iconv_t cd, const uchar *from, size_t flen,
iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
if (__builtin_expect (inbytesleft == 0, 1))
{
/* Close out any shift states, returning to the initial state. */
if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1)
{
if (errno != E2BIG)
return false;
CONVERT_ICONV_GROW_BUFFER;
if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1)
return false;
}
to->len = to->asize - outbytesleft;
return true;
}
if (errno != E2BIG)
return false;
outbytesleft += OUTBUF_BLOCK_SIZE;
to->asize += OUTBUF_BLOCK_SIZE;
to->text = XRESIZEVEC (uchar, to->text, to->asize);
outbuf = (char *)to->text + to->asize - outbytesleft;
CONVERT_ICONV_GROW_BUFFER;
}
}
#else
@ -1628,7 +1645,7 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset,
terminate with another \r, not an \n, so that we do not mistake
the \r\n sequence for a single DOS line ending and erroneously
issue the "No newline at end of file" diagnostic. */
if (to.text[to.len - 1] == '\r')
if (to.len && to.text[to.len - 1] == '\r')
to.text[to.len] = '\r';
else
to.text[to.len] = '\n';

View File

@ -280,3 +280,6 @@
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t

83
libcpp/configure vendored
View File

@ -2816,7 +2816,7 @@ fi
echo "$as_me:$LINENO: result: $acx_cv_prog_cc_pedantic__Wno_long_long" >&5
echo "${ECHO_T}$acx_cv_prog_cc_pedantic__Wno_long_long" >&6
if test $acx_cv_prog_cc_pedantic__Wno_long_long = yes; then
WARN_PEDANTIC="-pedantic -Wno-long-long"
WARN_PEDANTIC="$WARN_PEDANTIC${WARN_PEDANTIC:+ }-pedantic -Wno-long-long"
fi
@ -2835,11 +2835,12 @@ else
enable_werror_always=no
fi;
if test $enable_werror_always = yes; then
WERROR=-Werror
WERROR="$WERROR${WERROR:+ }-Werror"
fi
# Dependency checking.
rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
@ -4113,6 +4114,72 @@ _ACEOF
fi
echo "$as_me:$LINENO: checking for ssize_t" >&5
echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
if test "${ac_cv_type_ssize_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
if ((ssize_t *) 0)
return 0;
if (sizeof (ssize_t))
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_type_ssize_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_type_ssize_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
if test $ac_cv_type_ssize_t = yes; then
:
else
cat >>confdefs.h <<_ACEOF
#define ssize_t int
_ACEOF
fi
echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
if test "${ac_cv_struct_tm+set}" = set; then
@ -8244,8 +8311,16 @@ case $target in
sparc64*-*-* | ultrasparc-*-freebsd* | \
sparcv9-*-solaris2* | \
sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
spu-*-* | \
sh[123456789l]*-*-*)
need_64bit_hwint=yes ;;
i[34567]86-*-linux*)
if test "x$enable_targets" = xall; then
need_64bit_hwint=yes
else
need_64bit_hwint=no
fi
;;
*)
need_64bit_hwint=no ;;
esac
@ -8792,7 +8867,7 @@ cat >>$CONFIG_STATUS <<_ACEOF
# INIT-COMMANDS section.
#
DEPDIR=$DEPDIR
ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR
_ACEOF
@ -9526,7 +9601,7 @@ esac
{ echo "$as_me:$LINENO: executing $ac_dest commands" >&5
echo "$as_me: executing $ac_dest commands" >&6;}
case $ac_dest in
depdir ) mkdir $DEPDIR ;;
depdir ) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;;
esac
done
_ACEOF

View File

@ -46,6 +46,7 @@ AC_C_INLINE
AC_FUNC_OBSTACK
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
AC_STRUCT_TM
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
@ -128,8 +129,16 @@ case $target in
sparc64*-*-* | ultrasparc-*-freebsd* | \
sparcv9-*-solaris2* | \
sparc-*-solaris2.[789] | sparc-*-solaris2.1[0-9]* | \
spu-*-* | \
sh[123456789l]*-*-*)
need_64bit_hwint=yes ;;
i[34567]86-*-linux*)
if test "x$enable_targets" = xall; then
need_64bit_hwint=yes
else
need_64bit_hwint=no
fi
;;
*)
need_64bit_hwint=no ;;
esac

240
libcpp/directives-only.c Normal file
View File

@ -0,0 +1,240 @@
/* CPP Library - directive only preprocessing for distributed compilation.
Copyright (C) 2007
Free Software Foundation, Inc.
Contributed by Ollie Wild <aaw@google.com>.
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
Free Software Foundation; either version 2, or (at your option) any
later version.
This program 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 this program; 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 "cpplib.h"
#include "internal.h"
/* DO (Directive only) flags. */
#define DO_BOL (1 << 0) /* At the beginning of a logical line. */
#define DO_STRING (1 << 1) /* In a string constant. */
#define DO_CHAR (1 << 2) /* In a character constant. */
#define DO_BLOCK_COMMENT (1 << 3) /* In a block comment. */
#define DO_LINE_COMMENT (1 << 4) /* In a single line "//-style" comment. */
#define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT)
#define DO_SPECIAL (DO_LINE_SPECIAL | DO_BLOCK_COMMENT)
/* Writes out the preprocessed file, handling spacing and paste
avoidance issues. */
void
_cpp_preprocess_dir_only (cpp_reader *pfile,
const struct _cpp_dir_only_callbacks *cb)
{
struct cpp_buffer *buffer;
const unsigned char *cur, *base, *next_line, *rlimit;
cppchar_t c, last_c;
unsigned flags;
int lines, col;
source_location loc;
restart:
/* Buffer initialization ala _cpp_clean_line(). */
buffer = pfile->buffer;
buffer->cur_note = buffer->notes_used = 0;
buffer->cur = buffer->line_base = buffer->next_line;
buffer->need_line = false;
/* This isn't really needed. It prevents a compiler warning, though. */
loc = pfile->line_table->highest_line;
/* Scan initialization. */
next_line = cur = base = buffer->cur;
rlimit = buffer->rlimit;
flags = DO_BOL;
lines = 0;
col = 1;
for (last_c = '\n', c = *cur; cur < rlimit; last_c = c, c = *++cur, ++col)
{
/* Skip over escaped newlines. */
if (__builtin_expect (c == '\\', false))
{
const unsigned char *tmp = cur + 1;
while (is_nvspace (*tmp) && tmp < rlimit)
tmp++;
if (*tmp == '\r')
tmp++;
if (*tmp == '\n' && tmp < rlimit)
{
CPP_INCREMENT_LINE (pfile, 0);
lines++;
col = 0;
cur = tmp;
c = last_c;
continue;
}
}
if (__builtin_expect (last_c == '#', false) && !(flags & DO_SPECIAL))
{
if (c != '#' && (flags & DO_BOL))
{
struct line_maps *line_table;
if (!pfile->state.skipping && next_line != base)
cb->print_lines (lines, base, next_line - base);
/* Prep things for directive handling. */
buffer->next_line = cur;
buffer->need_line = true;
_cpp_get_fresh_line (pfile);
/* Ensure proper column numbering for generated error messages. */
buffer->line_base -= col - 1;
_cpp_handle_directive (pfile, 0 /* ignore indented */);
/* Sanitize the line settings. Duplicate #include's can mess
things up. */
line_table = pfile->line_table;
line_table->highest_location = line_table->highest_line;
/* The if block prevents us from outputing line information when
the file ends with a directive and no newline. Note that we
must use pfile->buffer, not buffer. */
if (pfile->buffer->next_line < pfile->buffer->rlimit)
cb->maybe_print_line (pfile->line_table->highest_line);
goto restart;
}
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
else if (__builtin_expect (last_c == '/', false) \
&& !(flags & DO_SPECIAL) && c != '*' && c != '/')
{
/* If a previous slash is not starting a block comment, clear the
DO_BOL flag. */
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
switch (c)
{
case '/':
if ((flags & DO_BLOCK_COMMENT) && last_c == '*')
{
flags &= ~DO_BLOCK_COMMENT;
c = 0;
}
else if (!(flags & DO_SPECIAL) && last_c == '/')
flags |= DO_LINE_COMMENT;
else if (!(flags & DO_SPECIAL))
/* Mark the position for possible error reporting. */
LINEMAP_POSITION_FOR_COLUMN (loc, pfile->line_table, col);
break;
case '*':
if (!(flags & DO_SPECIAL))
{
if (last_c == '/')
flags |= DO_BLOCK_COMMENT;
else
{
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
}
break;
case '\'':
case '"':
{
unsigned state = (c == '"') ? DO_STRING : DO_CHAR;
if (!(flags & DO_SPECIAL))
{
flags |= state;
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
else if ((flags & state) && last_c != '\\')
flags &= ~state;
break;
}
case '\\':
{
if ((flags & (DO_STRING | DO_CHAR)) && last_c == '\\')
c = 0;
if (!(flags & DO_SPECIAL))
{
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
break;
}
case '\n':
CPP_INCREMENT_LINE (pfile, 0);
lines++;
col = 0;
flags &= ~DO_LINE_SPECIAL;
if (!(flags & DO_SPECIAL))
flags |= DO_BOL;
break;
case '#':
next_line = cur;
/* Don't update DO_BOL yet. */
break;
case ' ': case '\t': case '\f': case '\v': case '\0':
break;
default:
if (!(flags & DO_SPECIAL))
{
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
break;
}
}
if (flags & DO_BLOCK_COMMENT)
cpp_error_with_line (pfile, CPP_DL_ERROR, loc, 0, "unterminated comment");
if (!pfile->state.skipping && cur != base)
{
/* If the file was not newline terminated, add rlimit, which is
guaranteed to point to a newline, to the end of our range. */
if (cur[-1] != '\n')
{
cur++;
CPP_INCREMENT_LINE (pfile, 0);
lines++;
}
cb->print_lines (lines, base, cur - base);
}
_cpp_pop_buffer (pfile);
if (pfile->buffer)
goto restart;
}

View File

@ -1,6 +1,7 @@
/* CPP Library. (Directive handling.)
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005,
2007, 2008 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@ -102,7 +103,7 @@ static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
static unsigned int read_flag (cpp_reader *, unsigned int);
static int strtoul_for_line (const uchar *, unsigned int, unsigned long *);
static void do_diagnostic (cpp_reader *, int, int);
static cpp_hashnode *lex_macro_node (cpp_reader *);
static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
static void do_include_common (cpp_reader *, enum include_type);
static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *,
@ -423,8 +424,13 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
does not cause '#define foo bar' to get executed when
compiled with -save-temps, we recognize directives in
-fpreprocessed mode only if the # is in column 1. macro.c
puts a space in front of any '#' at the start of a macro. */
puts a space in front of any '#' at the start of a macro.
We exclude the -fdirectives-only case because macro expansion
has not been performed yet, and block comments can cause spaces
to preceed the directive. */
if (CPP_OPTION (pfile, preprocessed)
&& !CPP_OPTION (pfile, directives_only)
&& (indented || !(dir->flags & IN_I)))
{
skip = 0;
@ -469,7 +475,7 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
_cpp_backup_tokens (pfile, 1);
end_directive (pfile, skip);
if (was_parsing_args)
if (was_parsing_args && !pfile->state.in_deferred_pragma)
{
/* Restore state when within macro args. */
pfile->state.parsing_args = 2;
@ -502,9 +508,11 @@ run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count)
}
/* Checks for validity the macro name in #define, #undef, #ifdef and
#ifndef directives. */
#ifndef directives. IS_DEF_OR_UNDEF is true if this call is
processing a #define or #undefine directive, and false
otherwise. */
static cpp_hashnode *
lex_macro_node (cpp_reader *pfile)
lex_macro_node (cpp_reader *pfile, bool is_def_or_undef)
{
const cpp_token *token = _cpp_lex_token (pfile);
@ -519,7 +527,7 @@ lex_macro_node (cpp_reader *pfile)
{
cpp_hashnode *node = token->val.node;
if (node == pfile->spec_nodes.n_defined)
if (is_def_or_undef && node == pfile->spec_nodes.n_defined)
cpp_error (pfile, CPP_DL_ERROR,
"\"defined\" cannot be used as a macro name");
else if (! (node->flags & NODE_POISONED))
@ -542,7 +550,7 @@ lex_macro_node (cpp_reader *pfile)
static void
do_define (cpp_reader *pfile)
{
cpp_hashnode *node = lex_macro_node (pfile);
cpp_hashnode *node = lex_macro_node (pfile, true);
if (node)
{
@ -561,7 +569,7 @@ do_define (cpp_reader *pfile)
static void
do_undef (cpp_reader *pfile)
{
cpp_hashnode *node = lex_macro_node (pfile);
cpp_hashnode *node = lex_macro_node (pfile, true);
if (node)
{
@ -690,7 +698,11 @@ parse_include (cpp_reader *pfile, int *pangle_brackets,
return NULL;
}
if (buf == NULL || CPP_OPTION (pfile, discard_comments))
if (pfile->directive == &dtable[T_PRAGMA])
{
/* This pragma allows extra tokens after the file name. */
}
else if (buf == NULL || CPP_OPTION (pfile, discard_comments))
check_eol (pfile);
else
{
@ -772,7 +784,7 @@ do_include_next (cpp_reader *pfile)
/* If this is the primary source file, warn and use the normal
search logic. */
if (! pfile->buffer->prev)
if (cpp_in_primary_file (pfile))
{
cpp_error (pfile, CPP_DL_WARNING,
"#include_next in primary source file");
@ -852,9 +864,12 @@ do_line (cpp_reader *pfile)
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" after #line is not a positive integer",
cpp_token_as_text (pfile, token));
if (token->type == CPP_EOF)
cpp_error (pfile, CPP_DL_ERROR, "unexpected end of file after #line");
else
cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" after #line is not a positive integer",
cpp_token_as_text (pfile, token));
return;
}
@ -908,6 +923,8 @@ do_linemarker (cpp_reader *pfile)
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
/* Unlike #line, there does not seem to be a way to get an EOF
here. So, it should be safe to always spell the token. */
cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" after # is not a positive integer",
cpp_token_as_text (pfile, token));
@ -1346,7 +1363,7 @@ do_pragma (cpp_reader *pfile)
static void
do_pragma_once (cpp_reader *pfile)
{
if (pfile->buffer->prev == NULL)
if (cpp_in_primary_file (pfile))
cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file");
check_eol (pfile);
@ -1396,9 +1413,7 @@ do_pragma_poison (cpp_reader *pfile)
static void
do_pragma_system_header (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
if (buffer->prev == 0)
if (cpp_in_primary_file (pfile))
cpp_error (pfile, CPP_DL_WARNING,
"#pragma system_header ignored outside include file");
else
@ -1457,15 +1472,24 @@ static const cpp_token *
get__Pragma_string (cpp_reader *pfile)
{
const cpp_token *string;
const cpp_token *paren;
if (get_token_no_padding (pfile)->type != CPP_OPEN_PAREN)
paren = get_token_no_padding (pfile);
if (paren->type == CPP_EOF)
_cpp_backup_tokens (pfile, 1);
if (paren->type != CPP_OPEN_PAREN)
return NULL;
string = get_token_no_padding (pfile);
if (string->type == CPP_EOF)
_cpp_backup_tokens (pfile, 1);
if (string->type != CPP_STRING && string->type != CPP_WSTRING)
return NULL;
if (get_token_no_padding (pfile)->type != CPP_CLOSE_PAREN)
paren = get_token_no_padding (pfile);
if (paren->type == CPP_EOF)
_cpp_backup_tokens (pfile, 1);
if (paren->type != CPP_CLOSE_PAREN)
return NULL;
return string;
@ -1585,18 +1609,21 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
_cpp_push_token_context (pfile, NULL, toks, count);
}
/* Handle the _Pragma operator. */
void
/* Handle the _Pragma operator. Return 0 on error, 1 if ok. */
int
_cpp_do__Pragma (cpp_reader *pfile)
{
const cpp_token *string = get__Pragma_string (pfile);
pfile->directive_result.type = CPP_PADDING;
if (string)
destringize_and_run (pfile, &string->val.str);
else
cpp_error (pfile, CPP_DL_ERROR,
"_Pragma takes a parenthesized string literal");
{
destringize_and_run (pfile, &string->val.str);
return 1;
}
cpp_error (pfile, CPP_DL_ERROR,
"_Pragma takes a parenthesized string literal");
return 0;
}
/* Handle #ifdef. */
@ -1607,7 +1634,7 @@ do_ifdef (cpp_reader *pfile)
if (! pfile->state.skipping)
{
const cpp_hashnode *node = lex_macro_node (pfile);
const cpp_hashnode *node = lex_macro_node (pfile, false);
if (node)
{
@ -1629,7 +1656,7 @@ do_ifndef (cpp_reader *pfile)
if (! pfile->state.skipping)
{
node = lex_macro_node (pfile);
node = lex_macro_node (pfile, false);
if (node)
{
@ -2077,6 +2104,65 @@ cpp_undef (cpp_reader *pfile, const char *macro)
run_directive (pfile, T_UNDEF, buf, len);
}
/* Like lex_macro_node, but read the input from STR. */
static cpp_hashnode *
lex_macro_node_from_str (cpp_reader *pfile, const char *str)
{
size_t len = strlen (str);
uchar *buf = (uchar *) alloca (len + 1);
cpp_hashnode *node;
memcpy (buf, str, len);
buf[len] = '\n';
cpp_push_buffer (pfile, buf, len, true);
node = lex_macro_node (pfile, true);
_cpp_pop_buffer (pfile);
return node;
}
/* If STR is a defined macro, return its definition node, else return NULL. */
cpp_macro *
cpp_push_definition (cpp_reader *pfile, const char *str)
{
cpp_hashnode *node = lex_macro_node_from_str (pfile, str);
if (node && node->type == NT_MACRO)
return node->value.macro;
else
return NULL;
}
/* Replace a previous definition DFN of the macro STR. If DFN is NULL,
then the macro should be undefined. */
void
cpp_pop_definition (cpp_reader *pfile, const char *str, cpp_macro *dfn)
{
cpp_hashnode *node = lex_macro_node_from_str (pfile, str);
if (node == NULL)
return;
if (node->type == NT_MACRO)
{
if (pfile->cb.undef)
pfile->cb.undef (pfile, pfile->directive_line, node);
if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL);
}
if (node->type != NT_VOID)
_cpp_free_definition (node);
if (dfn)
{
node->type = NT_MACRO;
node->value.macro = dfn;
if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
node->flags |= NODE_WARN;
if (pfile->cb.define)
pfile->cb.define (pfile, pfile->directive_line, node);
}
}
/* Process the string STR as if it appeared as the body of a #assert. */
void
cpp_assert (cpp_reader *pfile, const char *str)

View File

@ -82,26 +82,77 @@ static void check_promotion (cpp_reader *, const struct op *);
static unsigned int
interpret_float_suffix (const uchar *s, size_t len)
{
size_t f = 0, l = 0, i = 0, d = 0;
size_t f, l, w, q, i, d;
size_t r, k, u, h;
f = l = w = q = i = d = 0;
r = k = u = h = 0;
while (len--)
switch (s[len])
{
case 'f': case 'F': f++; break;
case 'l': case 'L': l++; break;
case 'r': case 'R': r++; break;
case 'k': case 'K': k++; break;
case 'u': case 'U': u++; break;
case 'h': case 'H': h++; break;
case 'f': case 'F':
if (d > 0)
return 0;
f++;
break;
case 'l': case 'L':
if (d > 0)
return 0;
l++;
/* If there are two Ls, they must be adjacent and the same case. */
if (l == 2 && s[len] != s[len + 1])
return 0;
break;
case 'w': case 'W':
if (d > 0)
return 0;
w++;
break;
case 'q': case 'Q':
if (d > 0)
return 0;
q++;
break;
case 'i': case 'I':
case 'j': case 'J': i++; break;
case 'd': case 'D':
/* Disallow fd, ld suffixes. */
if (d && (f || l))
return 0;
d++;
break;
case 'd': case 'D': d++; break;
default:
return 0;
}
if (f + l > 1 || i > 1)
if (r + k > 1 || h > 1 || l > 2 || u > 1)
return 0;
if (r == 1)
{
if (f || i || d || w || q)
return 0;
return (CPP_N_FRACT
| (u ? CPP_N_UNSIGNED : 0)
| (h ? CPP_N_SMALL :
l == 2 ? CPP_N_LARGE :
l == 1 ? CPP_N_MEDIUM : 0));
}
if (k == 1)
{
if (f || i || d || w || q)
return 0;
return (CPP_N_ACCUM
| (u ? CPP_N_UNSIGNED : 0)
| (h ? CPP_N_SMALL :
l == 2 ? CPP_N_LARGE :
l == 1 ? CPP_N_MEDIUM : 0));
}
if (f + l + w + q > 1 || i > 1 || h + u > 0)
return 0;
/* Allow dd, df, dl suffixes for decimal float constants. */
@ -110,7 +161,9 @@ interpret_float_suffix (const uchar *s, size_t len)
return ((i ? CPP_N_IMAGINARY : 0)
| (f ? CPP_N_SMALL :
l ? CPP_N_LARGE : CPP_N_MEDIUM)
l ? CPP_N_LARGE :
w ? CPP_N_MD_W :
q ? CPP_N_MD_Q : CPP_N_MEDIUM)
| (d ? CPP_N_DFLOAT : 0));
}
@ -182,6 +235,11 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
radix = 16;
str++;
}
else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1'))
{
radix = 2;
str++;
}
}
/* Now scan for a well-formed integer or float. */
@ -216,14 +274,46 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
}
}
/* The suffix may be for decimal fixed-point constants without exponent. */
if (radix != 16 && float_flag == NOT_FLOAT)
{
result = interpret_float_suffix (str, limit - str);
if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM))
{
result |= CPP_N_FLOATING;
/* We need to restore the radix to 10, if the radix is 8. */
if (radix == 8)
radix = 10;
if (CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"fixed-point constants are a GCC extension");
goto syntax_ok;
}
else
result = 0;
}
if (float_flag != NOT_FLOAT && radix == 8)
radix = 10;
if (max_digit >= radix)
SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
{
if (radix == 2)
SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + max_digit);
else
SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
}
if (float_flag != NOT_FLOAT)
{
if (radix == 2)
{
cpp_error (pfile, CPP_DL_ERROR,
"invalid prefix \"0b\" for floating constant");
return CPP_N_INVALID;
}
if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
cpp_error (pfile, CPP_DL_PEDWARN,
"use of C99 hexadecimal floating constant");
@ -270,6 +360,14 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
return CPP_N_INVALID;
}
if ((result & (CPP_N_FRACT | CPP_N_ACCUM)) && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"fixed-point constants are a GCC extension");
if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"decimal float constants are a GCC extension");
result |= CPP_N_FLOATING;
}
else
@ -305,14 +403,20 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
result |= CPP_N_INTEGER;
}
syntax_ok:
if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"imaginary constants are a GCC extension");
if (radix == 2 && CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN,
"binary constants are a GCC extension");
if (radix == 10)
result |= CPP_N_DECIMAL;
else if (radix == 16)
result |= CPP_N_HEX;
else if (radix == 2)
result |= CPP_N_BINARY;
else
result |= CPP_N_OCTAL;
@ -363,6 +467,11 @@ cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token,
base = 16;
p += 2;
}
else if ((type & CPP_N_RADIX) == CPP_N_BINARY)
{
base = 2;
p += 2;
}
/* We can add a digit to numbers strictly less than this without
needing the precision and slowness of double integers. */
@ -418,12 +527,25 @@ static cpp_num
append_digit (cpp_num num, int digit, int base, size_t precision)
{
cpp_num result;
unsigned int shift = 3 + (base == 16);
unsigned int shift;
bool overflow;
cpp_num_part add_high, add_low;
/* Multiply by 8 or 16. Catching this overflow here means we don't
/* Multiply by 2, 8 or 16. Catching this overflow here means we don't
need to worry about add_high overflowing. */
switch (base)
{
case 2:
shift = 1;
break;
case 16:
shift = 4;
break;
default:
shift = 3;
}
overflow = !!(num.high >> (PART_PRECISION - shift));
result.high = num.high << shift;
result.low = num.low << shift;
@ -441,7 +563,7 @@ append_digit (cpp_num num, int digit, int base, size_t precision)
if (add_low + digit < add_low)
add_high++;
add_low += digit;
if (result.low + add_low < result.low)
add_high++;
if (result.high + add_high < result.high)
@ -1527,7 +1649,8 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
if (negate)
result = num_negate (result, precision);
result.overflow = num_positive (result, precision) ^ !negate;
result.overflow = (num_positive (result, precision) ^ !negate
&& !num_zerop (result));
}
return result;

View File

@ -1,6 +1,7 @@
/* Part of CPP library. File handling.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Written by Per Bothner, 1994.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@ -26,6 +27,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include "cpplib.h"
#include "internal.h"
#include "mkdeps.h"
#include "obstack.h"
#include "hashtab.h"
#include "md5.h"
#include <dirent.h>
@ -140,6 +142,7 @@ struct file_hash_entry
{
struct file_hash_entry *next;
cpp_dir *start_dir;
source_location location;
union
{
_cpp_file *file;
@ -147,6 +150,21 @@ struct file_hash_entry
} u;
};
/* Number of entries to put in a file_hash_entry pool. */
#define FILE_HASH_POOL_SIZE 127
/* A file hash entry pool. We allocate file_hash_entry object from
one of these. */
struct file_hash_entry_pool
{
/* Number of entries used from this pool. */
unsigned int file_hash_entries_used;
/* Next pool in the chain; used when freeing. */
struct file_hash_entry_pool *next;
/* The memory pool. */
struct file_hash_entry pool[FILE_HASH_POOL_SIZE];
};
static bool open_file (_cpp_file *file);
static bool pch_open_file (cpp_reader *pfile, _cpp_file *file,
bool *invalid_pch);
@ -226,6 +244,22 @@ open_file (_cpp_file *file)
close (file->fd);
file->fd = -1;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
else if (errno == EACCES)
{
/* On most UNIX systems, open succeeds on a directory. Above,
we check if we have opened a directory and if so, set errno
to ENOENT. However, on Windows, opening a directory
fails with EACCES. We want to return ENOENT in that
case too. */
if (stat (file->path, &file->st) == 0
&& S_ISDIR (file->st.st_mode))
errno = ENOENT;
else
/* The call to stat may have reset errno. */
errno = EACCES;
}
#endif
else if (errno == ENOTDIR)
errno = ENOENT;
@ -322,6 +356,16 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
if (path)
{
hashval_t hv = htab_hash_string (path);
char *copy;
void **pp;
if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL)
{
file->err_no = ENOENT;
return false;
}
file->path = path;
if (pch_open_file (pfile, file, invalid_pch))
return true;
@ -335,7 +379,16 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
return true;
}
/* We copy the path name onto an obstack partly so that we don't
leak the memory, but mostly so that we don't fragment the
heap. */
copy = obstack_copy0 (&pfile->nonexistent_file_ob, path,
strlen (path));
free (path);
pp = htab_find_slot_with_hash (pfile->nonexistent_file_hash,
copy, hv, INSERT);
*pp = copy;
file->path = file->name;
}
else
@ -396,6 +449,9 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
struct file_hash_entry *entry, **hash_slot;
_cpp_file *file;
bool invalid_pch = false;
bool saw_bracket_include = false;
bool saw_quote_include = false;
struct cpp_dir *found_in_cache = NULL;
/* Ensure we get no confusion between cached files and directories. */
if (start_dir == NULL)
@ -448,13 +504,19 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
/* Only check the cache for the starting location (done above)
and the quote and bracket chain heads because there are no
other possible starting points for searches. */
if (file->dir != pfile->bracket_include
&& file->dir != pfile->quote_include)
if (file->dir == pfile->bracket_include)
saw_bracket_include = true;
else if (file->dir == pfile->quote_include)
saw_quote_include = true;
else
continue;
entry = search_cache (*hash_slot, file->dir);
if (entry)
break;
{
found_in_cache = file->dir;
break;
}
}
if (entry)
@ -475,9 +537,35 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f
entry = new_file_hash_entry (pfile);
entry->next = *hash_slot;
entry->start_dir = start_dir;
entry->location = pfile->line_table->highest_location;
entry->u.file = file;
*hash_slot = entry;
/* If we passed the quote or bracket chain heads, cache them also.
This speeds up processing if there are lots of -I options. */
if (saw_bracket_include
&& pfile->bracket_include != start_dir
&& found_in_cache != pfile->bracket_include)
{
entry = new_file_hash_entry (pfile);
entry->next = *hash_slot;
entry->start_dir = pfile->bracket_include;
entry->location = pfile->line_table->highest_location;
entry->u.file = file;
*hash_slot = entry;
}
if (saw_quote_include
&& pfile->quote_include != start_dir
&& found_in_cache != pfile->quote_include)
{
entry = new_file_hash_entry (pfile);
entry->next = *hash_slot;
entry->start_dir = pfile->quote_include;
entry->location = pfile->line_table->highest_location;
entry->u.file = file;
*hash_slot = entry;
}
return file;
}
@ -722,7 +810,8 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
/* Stack the buffer. */
buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
CPP_OPTION (pfile, preprocessed));
CPP_OPTION (pfile, preprocessed)
&& !CPP_OPTION (pfile, directives_only));
buffer->file = file;
buffer->sysp = sysp;
@ -763,7 +852,8 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
/* For #include_next, skip in the search path past the dir in which
the current file was found, but if it was found via an absolute
path use the normal search logic. */
if (type == IT_INCLUDE_NEXT && file->dir)
if (type == IT_INCLUDE_NEXT && file->dir
&& file->dir != &pfile->no_search_path)
dir = file->dir->next;
else if (angle_brackets)
dir = pfile->bracket_include;
@ -889,6 +979,19 @@ destroy_cpp_file (_cpp_file *file)
free (file);
}
/* Release all the files allocated by this reader. */
static void
destroy_all_cpp_files (cpp_reader *pfile)
{
_cpp_file *iter = pfile->all_files;
while (iter)
{
_cpp_file *next = iter->next_file;
destroy_cpp_file (iter);
iter = next;
}
}
/* A hash of directory names. The directory names are the path names
of files which contain a #include "", the included file name is
appended to this directories.
@ -923,6 +1026,7 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
entry = new_file_hash_entry (pfile);
entry->next = *hash_slot;
entry->start_dir = NULL;
entry->location = pfile->line_table->highest_location;
entry->u.dir = dir;
*hash_slot = entry;
@ -933,20 +1037,35 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
static void
allocate_file_hash_entries (cpp_reader *pfile)
{
pfile->file_hash_entries_used = 0;
pfile->file_hash_entries_allocated = 127;
pfile->file_hash_entries = XNEWVEC (struct file_hash_entry,
pfile->file_hash_entries_allocated);
struct file_hash_entry_pool *pool = XNEW (struct file_hash_entry_pool);
pool->file_hash_entries_used = 0;
pool->next = pfile->file_hash_entries;
pfile->file_hash_entries = pool;
}
/* Return a new file hash entry. */
static struct file_hash_entry *
new_file_hash_entry (cpp_reader *pfile)
{
if (pfile->file_hash_entries_used == pfile->file_hash_entries_allocated)
unsigned int idx;
if (pfile->file_hash_entries->file_hash_entries_used == FILE_HASH_POOL_SIZE)
allocate_file_hash_entries (pfile);
return &pfile->file_hash_entries[pfile->file_hash_entries_used++];
idx = pfile->file_hash_entries->file_hash_entries_used++;
return &pfile->file_hash_entries->pool[idx];
}
/* Free the file hash entry pools. */
static void
free_file_hash_entries (cpp_reader *pfile)
{
struct file_hash_entry_pool *iter = pfile->file_hash_entries;
while (iter)
{
struct file_hash_entry_pool *next = iter->next;
free (iter);
iter = next;
}
}
/* Returns TRUE if a file FNAME has ever been successfully opened.
@ -966,6 +1085,25 @@ cpp_included (cpp_reader *pfile, const char *fname)
return entry != NULL;
}
/* Returns TRUE if a file FNAME has ever been successfully opened
before LOCATION. This routine is not intended to correctly handle
filenames aliased by links or redundant . or .. traversals etc. */
bool
cpp_included_before (cpp_reader *pfile, const char *fname,
source_location location)
{
struct file_hash_entry *entry;
entry = (struct file_hash_entry *)
htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname));
while (entry && (entry->start_dir == NULL || entry->u.file->err_no
|| entry->location > location))
entry = entry->next;
return entry != NULL;
}
/* Calculate the hash value of a file hash entry P. */
static hashval_t
@ -997,6 +1135,14 @@ file_hash_eq (const void *p, const void *q)
return strcmp (hname, fname) == 0;
}
/* Compare entries in the nonexistent file hash table. These are just
strings. */
static int
nonexistent_file_hash_eq (const void *p, const void *q)
{
return strcmp (p, q) == 0;
}
/* Initialize everything in this source file. */
void
_cpp_init_files (cpp_reader *pfile)
@ -1006,6 +1152,12 @@ _cpp_init_files (cpp_reader *pfile)
pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
NULL, xcalloc, free);
allocate_file_hash_entries (pfile);
pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string,
nonexistent_file_hash_eq,
NULL, xcalloc, free);
_obstack_begin (&pfile->nonexistent_file_ob, 0, 0,
(void *(*) (long)) xmalloc,
(void (*) (void *)) free);
}
/* Finalize everything in this source file. */
@ -1014,6 +1166,21 @@ _cpp_cleanup_files (cpp_reader *pfile)
{
htab_delete (pfile->file_hash);
htab_delete (pfile->dir_hash);
htab_delete (pfile->nonexistent_file_hash);
obstack_free (&pfile->nonexistent_file_ob, 0);
free_file_hash_entries (pfile);
destroy_all_cpp_files (pfile);
}
/* Make the parser forget about files it has seen. This can be useful
for resetting the parser to start another run. */
void
cpp_clear_file_cache (cpp_reader *pfile)
{
_cpp_cleanup_files (pfile);
pfile->file_hash_entries = NULL;
pfile->all_files = NULL;
_cpp_init_files (pfile);
}
/* Enter a file name in the hash for the sake of cpp_included. */
@ -1051,12 +1218,19 @@ cpp_change_file (cpp_reader *pfile, enum lc_reason reason,
_cpp_do_file_change (pfile, reason, new_name, 1, 0);
}
struct report_missing_guard_data
{
const char **paths;
size_t count;
};
/* Callback function for htab_traverse. */
static int
report_missing_guard (void **slot, void *b)
report_missing_guard (void **slot, void *d)
{
struct file_hash_entry *entry = (struct file_hash_entry *) *slot;
int *bannerp = (int *) b;
struct report_missing_guard_data *data
= (struct report_missing_guard_data *) d;
/* Skip directories. */
if (entry->start_dir != NULL)
@ -1066,19 +1240,25 @@ report_missing_guard (void **slot, void *b)
/* We don't want MI guard advice for the main file. */
if (file->cmacro == NULL && file->stack_count == 1 && !file->main_file)
{
if (*bannerp == 0)
if (data->paths == NULL)
{
fputs (_("Multiple include guards may be useful for:\n"),
stderr);
*bannerp = 1;
data->paths = XCNEWVEC (const char *, data->count);
data->count = 0;
}
fputs (entry->u.file->path, stderr);
putc ('\n', stderr);
data->paths[data->count++] = file->path;
}
}
return 0;
/* Keep traversing the hash table. */
return 1;
}
/* Comparison function for qsort. */
static int
report_missing_guard_cmp (const void *p1, const void *p2)
{
return strcmp (*(const char *const *) p1, *(const char *const *) p2);
}
/* Report on all files that might benefit from a multiple include guard.
@ -1086,9 +1266,29 @@ report_missing_guard (void **slot, void *b)
void
_cpp_report_missing_guards (cpp_reader *pfile)
{
int banner = 0;
struct report_missing_guard_data data;
htab_traverse (pfile->file_hash, report_missing_guard, &banner);
data.paths = NULL;
data.count = htab_elements (pfile->file_hash);
htab_traverse (pfile->file_hash, report_missing_guard, &data);
if (data.paths != NULL)
{
size_t i;
/* Sort the paths to avoid outputting them in hash table
order. */
qsort (data.paths, data.count, sizeof (const char *),
report_missing_guard_cmp);
fputs (_("Multiple include guards may be useful for:\n"),
stderr);
for (i = 0; i < data.count; i++)
{
fputs (data.paths[i], stderr);
putc ('\n', stderr);
}
free (data.paths);
}
}
/* Locate HEADER, and determine whether it is newer than the current

View File

@ -1,6 +1,6 @@
/* Definitions for CPP library.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005
2004, 2005, 2007
Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
@ -155,7 +155,7 @@ enum cpp_ttype
/* C language kind, used when calling cpp_create_reader. */
enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_STDC89, CLK_STDC94, CLK_STDC99,
CLK_GNUCXX, CLK_CXX98, CLK_ASM};
CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX0X, CLK_CXX0X, CLK_ASM};
/* Payload of a NUMBER, STRING, CHAR or COMMENT token. */
struct cpp_string GTY(())
@ -440,6 +440,9 @@ struct cpp_options
/* True means error callback should be used for diagnostics. */
bool client_diagnostic;
/* True disables tokenization outside of preprocessing directives. */
bool directives_only;
};
/* Callback for header lookup for HEADER, which is the name of a
@ -555,7 +558,8 @@ enum builtin_type
BT_TIME, /* `__TIME__' */
BT_STDC, /* `__STDC__' */
BT_PRAGMA, /* `_Pragma' operator */
BT_TIMESTAMP /* `__TIMESTAMP__' */
BT_TIMESTAMP, /* `__TIMESTAMP__' */
BT_COUNTER /* `__COUNTER__' */
};
#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE))
@ -619,6 +623,10 @@ struct cpp_hashnode GTY(())
extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *,
struct line_maps *);
/* Reset the cpp_reader's line_map. This is only used after reading a
PCH file. */
extern void cpp_set_line_map (cpp_reader *, struct line_maps *);
/* Call this to change the selected language standard (e.g. because of
command line options). */
extern void cpp_set_lang (cpp_reader *, enum c_lang);
@ -643,6 +651,10 @@ extern struct deps *cpp_get_deps (cpp_reader *);
too. If there was an error opening the file, it returns NULL. */
extern const char *cpp_read_main_file (cpp_reader *, const char *);
/* Set up built-ins with special behavior. Use cpp_init_builtins()
instead unless your know what you are doing. */
extern void cpp_init_special_builtins (cpp_reader *);
/* Set up built-ins like __FILE__. */
extern void cpp_init_builtins (cpp_reader *, int);
@ -679,6 +691,8 @@ extern void cpp_register_deferred_pragma (cpp_reader *, const char *,
extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
const cpp_token *);
extern const cpp_token *cpp_get_token (cpp_reader *);
extern const cpp_token *cpp_get_token_with_location (cpp_reader *,
source_location *);
extern const unsigned char *cpp_macro_definition (cpp_reader *,
const cpp_hashnode *);
extern void _cpp_backup_tokens (cpp_reader *, unsigned int);
@ -704,6 +718,9 @@ extern void cpp_assert (cpp_reader *, const char *);
extern void cpp_undef (cpp_reader *, const char *);
extern void cpp_unassert (cpp_reader *, const char *);
extern cpp_macro *cpp_push_definition (cpp_reader *, const char *);
extern void cpp_pop_definition (cpp_reader *, const char *, cpp_macro *);
/* Undefine all macros and assertions. */
extern void cpp_undef_all (cpp_reader *);
@ -736,19 +753,28 @@ struct cpp_num
#define CPP_N_FLOATING 0x0002
#define CPP_N_WIDTH 0x00F0
#define CPP_N_SMALL 0x0010 /* int, float. */
#define CPP_N_MEDIUM 0x0020 /* long, double. */
#define CPP_N_LARGE 0x0040 /* long long, long double. */
#define CPP_N_SMALL 0x0010 /* int, float, shrot _Fract/Accum */
#define CPP_N_MEDIUM 0x0020 /* long, double, long _Fract/_Accum. */
#define CPP_N_LARGE 0x0040 /* long long, long double,
long long _Fract/Accum. */
#define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */
#define CPP_N_MD_W 0x10000
#define CPP_N_MD_Q 0x20000
#define CPP_N_RADIX 0x0F00
#define CPP_N_DECIMAL 0x0100
#define CPP_N_HEX 0x0200
#define CPP_N_OCTAL 0x0400
#define CPP_N_BINARY 0x0800
#define CPP_N_UNSIGNED 0x1000 /* Properties. */
#define CPP_N_IMAGINARY 0x2000
#define CPP_N_DFLOAT 0x4000
#define CPP_N_FRACT 0x100000 /* Fract types. */
#define CPP_N_ACCUM 0x200000 /* Accum types. */
/* Classify a CPP_NUMBER token. The return value is a combination of
the flags from the above sets. */
extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *);
@ -827,6 +853,7 @@ extern unsigned char *cpp_quote_string (unsigned char *, const unsigned char *,
/* In cppfiles.c */
extern bool cpp_included (cpp_reader *, const char *);
extern bool cpp_included_before (cpp_reader *, const char *, source_location);
extern void cpp_make_system_header (cpp_reader *, int, int);
extern bool cpp_push_include (cpp_reader *, const char *);
extern void cpp_change_file (cpp_reader *, enum lc_reason, const char *);
@ -835,6 +862,7 @@ extern cpp_dir *cpp_get_dir (struct _cpp_file *);
extern cpp_buffer *cpp_get_buffer (cpp_reader *);
extern struct _cpp_file *cpp_get_file (cpp_buffer *);
extern cpp_buffer *cpp_get_prev (cpp_buffer *);
extern void cpp_clear_file_cache (cpp_reader *);
/* In cpppch.c */
struct save_macro_data;

View File

@ -1,5 +1,5 @@
/* Map logical line numbers to (source file, line number) pairs.
Copyright (C) 2001, 2003, 2004
Copyright (C) 2001, 2003, 2004, 2007
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@ -23,6 +23,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef LIBCPP_LINE_MAP_H
#define LIBCPP_LINE_MAP_H
#ifndef GTY
#define GTY(x) /* nothing */
#endif
/* Reason for adding a line change with add_line_map (). LC_ENTER is
when including a new file, e.g. a #include directive in C.
LC_LEAVE is when reaching a file's end. LC_RENAME is when a file
@ -35,6 +39,9 @@ enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
and effectively typedef source_location location_t. */
typedef unsigned int source_location;
/* Memory allocation function typedef. Works like xrealloc. */
typedef void *(*line_map_realloc) (void *, size_t);
/* Physical source file TO_FILE at line TO_LINE at column 0 is represented
by the logical START_LOCATION. TO_LINE+L at column C is represented by
START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
@ -47,7 +54,7 @@ typedef unsigned int source_location;
creation of this line map, SYSP is one for a system header, two for
a C system header file that therefore needs to be extern "C"
protected in C++, and zero otherwise. */
struct line_map
struct line_map GTY(())
{
const char *to_file;
unsigned int to_line;
@ -61,9 +68,9 @@ struct line_map
};
/* A set of chronological line_map structures. */
struct line_maps
struct line_maps GTY(())
{
struct line_map *maps;
struct line_map * GTY ((length ("%h.used"))) maps;
unsigned int allocated;
unsigned int used;
@ -89,6 +96,10 @@ struct line_maps
/* The maximum column number we can quickly allocate. Higher numbers
may require allocating a new line_map. */
unsigned int max_column_hint;
/* If non-null, the allocator to use when resizing 'maps'. If null,
xrealloc is used. */
line_map_realloc reallocator;
};
/* Initialize a line map set. */

View File

@ -1,5 +1,5 @@
/* Hash tables.
Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2003, 2004, 2007 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
@ -19,7 +19,9 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#define LIBCPP_SYMTAB_H
#include "obstack.h"
#ifndef GTY
#define GTY(x) /* nothing */
#endif
/* This is what each hash table entry points to. It may be embedded
deeply within another object. */

View File

@ -1,6 +1,6 @@
/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@ -80,18 +80,20 @@ struct lang_flags
static const struct lang_flags lang_defaults[] =
{ /* c99 c++ xnum xid std // digr */
/* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1 },
/* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1 },
/* STDC89 */ { 0, 0, 0, 0, 1, 0, 0 },
/* STDC94 */ { 0, 0, 0, 0, 1, 0, 1 },
/* STDC99 */ { 1, 0, 1, 0, 1, 1, 1 },
/* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1 },
/* CXX98 */ { 0, 1, 1, 0, 1, 1, 1 },
/* ASM */ { 0, 0, 1, 0, 0, 1, 0 }
/* xid should be 1 for GNUC99, STDC99, GNUCXX and CXX98 when no
longer experimental (when all uses of identifiers in the compiler
have been audited for correct handling of extended
identifiers). */
/* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1 },
/* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1 },
/* STDC89 */ { 0, 0, 0, 0, 1, 0, 0 },
/* STDC94 */ { 0, 0, 0, 0, 1, 0, 1 },
/* STDC99 */ { 1, 0, 1, 0, 1, 1, 1 },
/* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1 },
/* CXX98 */ { 0, 1, 1, 0, 1, 1, 1 },
/* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1 },
/* CXX0X */ { 1, 1, 1, 0, 1, 1, 1 },
/* ASM */ { 0, 0, 1, 0, 0, 1, 0 }
/* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX0X, and
CXX0X when no longer experimental (when all uses of identifiers
in the compiler have been audited for correct handling of
extended identifiers). */
};
/* Sets internal flags correctly for a given language. */
@ -225,6 +227,14 @@ cpp_create_reader (enum c_lang lang, hash_table *table,
return pfile;
}
/* Set the line_table entry in PFILE. This is called after reading a
PCH file, as the old line_table will be incorrect. */
void
cpp_set_line_map (cpp_reader *pfile, struct line_maps *line_table)
{
pfile->line_table = line_table;
}
/* Free resources used by PFILE. Accessing PFILE after this function
returns leads to undefined behavior. Returns the error count. */
void
@ -308,6 +318,7 @@ static const struct builtin builtin_array[] =
B("__BASE_FILE__", BT_BASE_FILE),
B("__LINE__", BT_SPECLINE),
B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
B("__COUNTER__", BT_COUNTER),
/* Keep builtins not used for -traditional-cpp at the end, and
update init_builtins() if any more are added. */
B("_Pragma", BT_PRAGMA),
@ -347,11 +358,8 @@ mark_named_operators (cpp_reader *pfile)
}
}
/* Read the builtins table above and enter them, and language-specific
macros, into the hash table. HOSTED is true if this is a hosted
environment. */
void
cpp_init_builtins (cpp_reader *pfile, int hosted)
cpp_init_special_builtins (cpp_reader *pfile)
{
const struct builtin *b;
size_t n = ARRAY_SIZE (builtin_array);
@ -360,10 +368,7 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
n -= 2;
else if (! CPP_OPTION (pfile, stdc_0_in_system_headers)
|| CPP_OPTION (pfile, std))
{
n--;
_cpp_define_builtin (pfile, "__STDC__ 1");
}
n--;
for (b = builtin_array; b < builtin_array + n; b++)
{
@ -372,6 +377,20 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
hp->flags |= NODE_BUILTIN | NODE_WARN;
hp->value.builtin = (enum builtin_type) b->value;
}
}
/* Read the builtins table above and enter them, and language-specific
macros, into the hash table. HOSTED is true if this is a hosted
environment. */
void
cpp_init_builtins (cpp_reader *pfile, int hosted)
{
cpp_init_special_builtins (pfile);
if (!CPP_OPTION (pfile, traditional)
&& (! CPP_OPTION (pfile, stdc_0_in_system_headers)
|| CPP_OPTION (pfile, std)))
_cpp_define_builtin (pfile, "__STDC__ 1");
if (CPP_OPTION (pfile, cplusplus))
_cpp_define_builtin (pfile, "__cplusplus 1");
@ -619,7 +638,8 @@ post_options (cpp_reader *pfile)
preprocessed text. Read preprocesed source in ISO mode. */
if (CPP_OPTION (pfile, preprocessed))
{
pfile->state.prevent_expansion = 1;
if (!CPP_OPTION (pfile, directives_only))
pfile->state.prevent_expansion = 1;
CPP_OPTION (pfile, traditional) = 0;
}

View File

@ -1,5 +1,5 @@
/* Part of CPP library.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@ -339,6 +339,14 @@ struct cpp_reader
/* Token generated while handling a directive, if any. */
cpp_token directive_result;
/* When expanding a macro at top-level, this is the location of the
macro invocation. */
source_location invocation_location;
/* True if this call to cpp_get_token should consider setting
invocation_location. */
bool set_invocation_location;
/* Search paths for include files. */
struct cpp_dir *quote_include; /* "" */
struct cpp_dir *bracket_include; /* <> */
@ -352,8 +360,11 @@ struct cpp_reader
/* File and directory hash table. */
struct htab *file_hash;
struct htab *dir_hash;
struct file_hash_entry *file_hash_entries;
unsigned int file_hash_entries_allocated, file_hash_entries_used;
struct file_hash_entry_pool *file_hash_entries;
/* Negative path lookup hash table. */
struct htab *nonexistent_file_hash;
struct obstack nonexistent_file_ob;
/* Nonzero means don't look for #include "foo" the source-file
directory. */
@ -448,6 +459,9 @@ struct cpp_reader
/* A saved list of the defined macros, for dependency checking
of precompiled headers. */
struct cpp_savedstate *savedstate;
/* Next value of __COUNTER__ macro. */
unsigned int counter;
};
/* Character classes. Based on the more primitive macros in safe-ctype.h.
@ -488,6 +502,13 @@ cpp_in_system_header (cpp_reader *pfile)
#define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic)
#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
static inline int cpp_in_primary_file (cpp_reader *);
static inline int
cpp_in_primary_file (cpp_reader *pfile)
{
return pfile->line_table->depth == 1;
}
/* In errors.c */
extern int _cpp_begin_message (cpp_reader *, int,
source_location, unsigned int);
@ -554,13 +575,24 @@ extern int _cpp_handle_directive (cpp_reader *, int);
extern void _cpp_define_builtin (cpp_reader *, const char *);
extern char ** _cpp_save_pragma_names (cpp_reader *);
extern void _cpp_restore_pragma_names (cpp_reader *, char **);
extern void _cpp_do__Pragma (cpp_reader *);
extern int _cpp_do__Pragma (cpp_reader *);
extern void _cpp_init_directives (cpp_reader *);
extern void _cpp_init_internal_pragmas (cpp_reader *);
extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *,
unsigned int, unsigned int);
extern void _cpp_pop_buffer (cpp_reader *);
/* In directives.c */
struct _cpp_dir_only_callbacks
{
/* Called to print a block of lines. */
void (*print_lines) (int, const void *, size_t);
void (*maybe_print_line) (source_location);
};
extern void _cpp_preprocess_dir_only (cpp_reader *,
const struct _cpp_dir_only_callbacks *);
/* In traditional.c. */
extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *);
extern bool _cpp_read_logical_line_trad (cpp_reader *);

View File

@ -111,31 +111,39 @@ _cpp_clean_line (cpp_reader *pfile)
if (!buffer->from_stage3)
{
const uchar *pbackslash = NULL;
/* Short circuit for the common case of an un-escaped line with
no trigraphs. The primary win here is by not writing any
data back to memory until we have to. */
for (;;)
{
c = *++s;
if (c == '\n' || c == '\r')
if (__builtin_expect (c == '\n', false)
|| __builtin_expect (c == '\r', false))
{
d = (uchar *) s;
if (s == buffer->rlimit)
if (__builtin_expect (s == buffer->rlimit, false))
goto done;
/* DOS line ending? */
if (c == '\r' && s[1] == '\n')
s++;
if (__builtin_expect (c == '\r', false)
&& s[1] == '\n')
{
s++;
if (s == buffer->rlimit)
goto done;
}
if (s == buffer->rlimit)
if (__builtin_expect (pbackslash == NULL, true))
goto done;
/* check for escaped newline */
/* Check for escaped newline. */
p = d;
while (p != buffer->next_line && is_nvspace (p[-1]))
while (is_nvspace (p[-1]))
p--;
if (p == buffer->next_line || p[-1] != '\\')
if (p - 1 != pbackslash)
goto done;
/* Have an escaped newline; process it and proceed to
@ -145,7 +153,11 @@ _cpp_clean_line (cpp_reader *pfile)
buffer->next_line = p - 1;
break;
}
if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
if (__builtin_expect (c == '\\', false))
pbackslash = s;
else if (__builtin_expect (c == '?', false)
&& __builtin_expect (s[1] == '?', false)
&& _cpp_trigraph_map[s[2]])
{
/* Have a trigraph. We may or may not have to convert
it. Add a line note regardless, for -Wtrigraphs. */
@ -754,6 +766,11 @@ _cpp_lex_token (cpp_reader *pfile)
pfile->cur_run = next_tokenrun (pfile->cur_run);
pfile->cur_token = pfile->cur_run->base;
}
/* We assume that the current token is somewhere in the current
run. */
if (pfile->cur_token < pfile->cur_run->base
|| pfile->cur_token >= pfile->cur_run->limit)
abort ();
if (pfile->lookaheads)
{
@ -835,11 +852,8 @@ _cpp_get_fresh_line (cpp_reader *pfile)
&& buffer->next_line > buffer->rlimit
&& !buffer->from_stage3)
{
/* Only warn once. */
/* Clip to buffer size. */
buffer->next_line = buffer->rlimit;
cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line,
CPP_BUF_COLUMN (buffer, buffer->cur),
"no newline at end of file");
}
return_at_eof = buffer->return_at_eof;

View File

@ -1,5 +1,5 @@
/* Map logical line numbers to (source file, line number) pairs.
Copyright (C) 2001, 2003, 2004
Copyright (C) 2001, 2003, 2004, 2007
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@ -96,8 +96,15 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
if (set->used == set->allocated)
{
line_map_realloc reallocator
= set->reallocator ? set->reallocator : xrealloc;
set->allocated = 2 * set->allocated + 256;
set->maps = XRESIZEVEC (struct line_map, set->maps, set->allocated);
set->maps
= (struct line_map *) (*reallocator) (set->maps,
set->allocated
* sizeof (struct line_map));
memset (&set->maps[set->used], 0, ((set->allocated - set->used)
* sizeof (struct line_map)));
}
map = &set->maps[set->used];

View File

@ -1,6 +1,7 @@
/* Part of CPP library. (Macro and #define handling.)
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008 Free Software Foundation, Inc.
Written by Per Bothner, 1994.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@ -40,11 +41,13 @@ struct macro_arg
/* Macro expansion. */
static int enter_macro_context (cpp_reader *, cpp_hashnode *);
static int enter_macro_context (cpp_reader *, cpp_hashnode *,
const cpp_token *);
static int builtin_macro (cpp_reader *, cpp_hashnode *);
static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
const cpp_token **, unsigned int);
static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *);
static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *,
_cpp_buff **);
static cpp_context *next_context (cpp_reader *);
static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
static void expand_arg (cpp_reader *, macro_arg *);
@ -54,7 +57,8 @@ static void paste_all_tokens (cpp_reader *, const cpp_token *);
static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *);
static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
macro_arg *);
static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *);
static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *,
_cpp_buff **);
static bool create_iso_definition (cpp_reader *, cpp_macro *);
/* #define directive parsing and handling. */
@ -262,6 +266,13 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
else
result = pfile->time;
break;
case BT_COUNTER:
if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive)
cpp_error (pfile, CPP_DL_ERROR,
"__COUNTER__ expanded inside directive with -fdirectives-only");
number = pfile->counter++;
break;
}
if (result == NULL)
@ -292,8 +303,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
if (pfile->state.in_directive)
return 0;
_cpp_do__Pragma (pfile);
return 1;
return _cpp_do__Pragma (pfile);
}
buf = _cpp_builtin_macro_text (pfile, node);
@ -431,21 +441,22 @@ static bool
paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
{
unsigned char *buf, *end, *lhsend;
const cpp_token *lhs;
cpp_token *lhs;
unsigned int len;
lhs = *plhs;
len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1;
buf = (unsigned char *) alloca (len);
end = lhsend = cpp_spell_token (pfile, lhs, buf, false);
end = lhsend = cpp_spell_token (pfile, *plhs, buf, false);
/* Avoid comment headers, since they are still processed in stage 3.
It is simpler to insert a space here, rather than modifying the
lexer to ignore comments in some circumstances. Simply returning
false doesn't work, since we want to clear the PASTE_LEFT flag. */
if (lhs->type == CPP_DIV && rhs->type != CPP_EQ)
if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
*end++ = ' ';
end = cpp_spell_token (pfile, rhs, end, false);
/* In one obscure case we might see padding here. */
if (rhs->type != CPP_PADDING)
end = cpp_spell_token (pfile, rhs, end, false);
*end = '\n';
cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true);
@ -453,13 +464,22 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
/* Set pfile->cur_token as required by _cpp_lex_direct. */
pfile->cur_token = _cpp_temp_token (pfile);
*plhs = _cpp_lex_direct (pfile);
lhs = _cpp_lex_direct (pfile);
if (pfile->buffer->cur != pfile->buffer->rlimit)
{
source_location saved_loc = lhs->src_loc;
_cpp_pop_buffer (pfile);
_cpp_backup_tokens (pfile, 1);
*lhsend = '\0';
/* We have to remove the PASTE_LEFT flag from the old lhs, but
we want to keep the new location. */
*lhs = **plhs;
*plhs = lhs;
lhs->src_loc = saved_loc;
lhs->flags &= ~PASTE_LEFT;
/* Mandatory error for all apart from assembler. */
if (CPP_OPTION (pfile, lang) != CLK_ASM)
cpp_error (pfile, CPP_DL_ERROR,
@ -468,6 +488,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
return false;
}
*plhs = lhs;
_cpp_pop_buffer (pfile);
return true;
}
@ -498,8 +519,10 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
rhs = *FIRST (context).ptoken++;
if (rhs->type == CPP_PADDING)
abort ();
{
if (rhs->flags & PASTE_LEFT)
abort ();
}
if (!paste_tokens (pfile, &lhs, rhs))
break;
}
@ -555,9 +578,12 @@ _cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node
invocation. Assumes the opening parenthesis has been processed.
If there is an error, emits an appropriate diagnostic and returns
NULL. Each argument is terminated by a CPP_EOF token, for the
future benefit of expand_arg(). */
future benefit of expand_arg(). If there are any deferred
#pragma directives among macro arguments, store pointers to the
CPP_PRAGMA ... CPP_PRAGMA_EOL tokens into *PRAGMA_BUFF buffer. */
static _cpp_buff *
collect_args (cpp_reader *pfile, const cpp_hashnode *node)
collect_args (cpp_reader *pfile, const cpp_hashnode *node,
_cpp_buff **pragma_buff)
{
_cpp_buff *buff, *base_buff;
cpp_macro *macro;
@ -625,6 +651,51 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node)
else if (token->type == CPP_EOF
|| (token->type == CPP_HASH && token->flags & BOL))
break;
else if (token->type == CPP_PRAGMA)
{
cpp_token *newtok = _cpp_temp_token (pfile);
/* CPP_PRAGMA token lives in directive_result, which will
be overwritten on the next directive. */
*newtok = *token;
token = newtok;
do
{
if (*pragma_buff == NULL
|| BUFF_ROOM (*pragma_buff) < sizeof (cpp_token *))
{
_cpp_buff *next;
if (*pragma_buff == NULL)
*pragma_buff
= _cpp_get_buff (pfile, 32 * sizeof (cpp_token *));
else
{
next = *pragma_buff;
*pragma_buff
= _cpp_get_buff (pfile,
(BUFF_FRONT (*pragma_buff)
- (*pragma_buff)->base) * 2);
(*pragma_buff)->next = next;
}
}
*(const cpp_token **) BUFF_FRONT (*pragma_buff) = token;
BUFF_FRONT (*pragma_buff) += sizeof (cpp_token *);
if (token->type == CPP_PRAGMA_EOL)
break;
token = cpp_get_token (pfile);
}
while (token->type != CPP_EOF);
/* In deferred pragmas parsing_args and prevent_expansion
had been changed, reset it. */
pfile->state.parsing_args = 2;
pfile->state.prevent_expansion = 1;
if (token->type == CPP_EOF)
break;
else
continue;
}
arg->first[ntokens++] = token;
}
@ -689,9 +760,11 @@ collect_args (cpp_reader *pfile, const cpp_hashnode *node)
/* Search for an opening parenthesis to the macro of NODE, in such a
way that, if none is found, we don't lose the information in any
intervening padding tokens. If we find the parenthesis, collect
the arguments and return the buffer containing them. */
the arguments and return the buffer containing them. PRAGMA_BUFF
argument is the same as in collect_args. */
static _cpp_buff *
funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
_cpp_buff **pragma_buff)
{
const cpp_token *token, *padding = NULL;
@ -708,7 +781,7 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
if (token->type == CPP_OPEN_PAREN)
{
pfile->state.parsing_args = 2;
return collect_args (pfile, node);
return collect_args (pfile, node, pragma_buff);
}
/* CPP_EOF can be the end of macro arguments, or the end of the
@ -729,9 +802,13 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
/* Push the context of a macro with hash entry NODE onto the context
stack. If we can successfully expand the macro, we push a context
containing its yet-to-be-rescanned replacement list and return one.
Otherwise, we don't push a context and return zero. */
If there were additionally any unexpanded deferred #pragma directives
among macro arguments, push another context containing the
pragma tokens before the yet-to-be-rescanned replacement list
and return two. Otherwise, we don't push a context and return zero. */
static int
enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
const cpp_token *result)
{
/* The presence of a macro invalidates a file's controlling macro. */
pfile->mi_valid = false;
@ -742,6 +819,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
if (! (node->flags & NODE_BUILTIN))
{
cpp_macro *macro = node->value.macro;
_cpp_buff *pragma_buff = NULL;
if (macro->fun_like)
{
@ -750,7 +828,7 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
pfile->state.prevent_expansion++;
pfile->keep_tokens++;
pfile->state.parsing_args = 1;
buff = funlike_invocation_p (pfile, node);
buff = funlike_invocation_p (pfile, node, &pragma_buff);
pfile->state.parsing_args = 0;
pfile->keep_tokens--;
pfile->state.prevent_expansion--;
@ -762,6 +840,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
"function-like macro \"%s\" must be used with arguments in traditional C",
NODE_NAME (node));
if (pragma_buff)
_cpp_release_buff (pfile, pragma_buff);
return 0;
}
@ -778,6 +859,25 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
if (macro->paramc == 0)
_cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count);
if (pragma_buff)
{
if (!pfile->state.in_directive)
_cpp_push_token_context (pfile, NULL,
padding_token (pfile, result), 1);
do
{
_cpp_buff *tail = pragma_buff->next;
pragma_buff->next = NULL;
push_ptoken_context (pfile, NULL, pragma_buff,
(const cpp_token **) pragma_buff->base,
((const cpp_token **) BUFF_FRONT (pragma_buff)
- (const cpp_token **) pragma_buff->base));
pragma_buff = tail;
}
while (pragma_buff != NULL);
return 2;
}
return 1;
}
@ -1077,6 +1177,8 @@ const cpp_token *
cpp_get_token (cpp_reader *pfile)
{
const cpp_token *result;
bool can_set = pfile->set_invocation_location;
pfile->set_invocation_location = false;
for (;;)
{
@ -1122,10 +1224,17 @@ cpp_get_token (cpp_reader *pfile)
if (!(node->flags & NODE_DISABLED))
{
if (!pfile->state.prevent_expansion
&& enter_macro_context (pfile, node))
int ret;
/* If not in a macro context, and we're going to start an
expansion, record the location. */
if (can_set && !context->macro)
pfile->invocation_location = result->src_loc;
if (pfile->state.prevent_expansion)
break;
ret = enter_macro_context (pfile, node, result);
if (ret)
{
if (pfile->state.in_directive)
if (pfile->state.in_directive || ret == 2)
continue;
return padding_token (pfile, result);
}
@ -1147,6 +1256,27 @@ cpp_get_token (cpp_reader *pfile)
return result;
}
/* Like cpp_get_token, but also returns a location separate from the
one provided by the returned token. LOC is an out parameter; *LOC
is set to the location "as expected by the user". This matters
when a token results from macro expansion -- the token's location
will indicate where the macro is defined, but *LOC will be the
location of the start of the expansion. */
const cpp_token *
cpp_get_token_with_location (cpp_reader *pfile, source_location *loc)
{
const cpp_token *result;
pfile->set_invocation_location = true;
result = cpp_get_token (pfile);
if (pfile->context->macro)
*loc = pfile->invocation_location;
else
*loc = result->src_loc;
return result;
}
/* Returns true if we're expanding an object-like macro that was
defined in a system header. Just checks the macro at the top of
the stack. Used for diagnostic suppression. */
@ -1398,10 +1528,12 @@ alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro)
static cpp_token *
lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
{
cpp_token *token;
cpp_token *token, *saved_cur_token;
saved_cur_token = pfile->cur_token;
pfile->cur_token = alloc_expansion_token (pfile, macro);
token = _cpp_lex_direct (pfile);
pfile->cur_token = saved_cur_token;
/* Is this a parameter? */
if (token->type == CPP_NAME
@ -1422,6 +1554,9 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
{
cpp_token *token;
const cpp_token *ctoken;
bool following_paste_op = false;
const char *paste_op_error_msg =
N_("'##' cannot appear at either end of a macro expansion");
/* Get the first token of the expansion (or the '(' of a
function-like macro). */
@ -1515,26 +1650,34 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
}
if (token->type == CPP_EOF)
break;
{
/* Paste operator constraint 6.10.3.3.1:
Token-paste ##, can appear in both object-like and
function-like macros, but not at the end. */
if (following_paste_op)
{
cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
return false;
}
break;
}
/* Paste operator constraint 6.10.3.3.1. */
if (token->type == CPP_PASTE)
{
/* Token-paste ##, can appear in both object-like and
function-like macros, but not at the ends. */
if (--macro->count > 0)
token = lex_expansion_token (pfile, macro);
if (macro->count == 0 || token->type == CPP_EOF)
function-like macros, but not at the beginning. */
if (macro->count == 1)
{
cpp_error (pfile, CPP_DL_ERROR,
"'##' cannot appear at either end of a macro expansion");
cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg);
return false;
}
--macro->count;
token[-1].flags |= PASTE_LEFT;
}
following_paste_op = (token->type == CPP_PASTE);
token = lex_expansion_token (pfile, macro);
}
@ -1590,18 +1733,12 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
ok = _cpp_create_trad_definition (pfile, macro);
else
{
cpp_token *saved_cur_token = pfile->cur_token;
ok = create_iso_definition (pfile, macro);
/* Restore lexer position because of games lex_expansion_token()
plays lexing the macro. We set the type for SEEN_EOL() in
directives.c.
/* We set the type for SEEN_EOL() in directives.c.
Longer term we should lex the whole line before coming here,
and just copy the expansion. */
saved_cur_token[-1].type = pfile->cur_token[-1].type;
pfile->cur_token = saved_cur_token;
/* Stop the lexer accepting __VA_ARGS__. */
pfile->state.va_args_ok = 0;
@ -1641,7 +1778,14 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
/* Enter definition in hash table. */
node->type = NT_MACRO;
node->value.macro = macro;
if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")))
if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))
&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS")
/* __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are mentioned
in the C standard, as something that one must use in C++.
However DR#593 indicates that these aren't actually mentioned
in the C++ standard. We special-case them anyway. */
&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_LIMIT_MACROS")
&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS"))
node->flags |= NODE_WARN;
return ok;

View File

@ -35,14 +35,14 @@ static int write_defs (cpp_reader *, cpp_hashnode *, void *);
static int save_macros (cpp_reader *, cpp_hashnode *, void *);
/* This structure represents a macro definition on disk. */
struct macrodef_struct
struct macrodef_struct
{
unsigned int definition_length;
unsigned short name_length;
unsigned short flags;
};
/* This is how we write out a macro definition.
/* This is how we write out a macro definition.
Suitable for being called by cpp_forall_identifiers. */
static int
@ -54,7 +54,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
case NT_VOID:
if (! (hn->flags & NODE_POISONED))
return 1;
case NT_MACRO:
if ((hn->flags & NODE_BUILTIN))
return 1;
@ -76,7 +76,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
defn = NODE_NAME (hn);
s.definition_length = s.name_length;
}
if (fwrite (&s, sizeof (s), 1, f) != 1
|| fwrite (defn, 1, s.definition_length, f) != s.definition_length)
{
@ -86,7 +86,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
}
}
return 1;
case NT_ASSERTION:
/* Not currently implemented. */
return 1;
@ -123,7 +123,7 @@ static int
save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
{
struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
if (hn->type != NT_VOID)
{
struct cpp_string news;
@ -136,7 +136,7 @@ save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
{
struct cpp_string *sp;
unsigned char *text;
sp = XNEW (struct cpp_string);
*slot = sp;
@ -157,7 +157,7 @@ hashmem (const void *p_p, size_t sz)
const unsigned char *p = (const unsigned char *)p_p;
size_t i;
hashval_t h;
h = 0;
for (i = 0; i < sz; i++)
h = h * 67 - (*p++ - 113);
@ -194,10 +194,10 @@ cpp_save_state (cpp_reader *r, FILE *f)
{
/* Save the list of non-void identifiers for the dependency checking. */
r->savedstate = XNEW (struct cpp_savedstate);
r->savedstate->definedhash = htab_create (100, cpp_string_hash,
r->savedstate->definedhash = htab_create (100, cpp_string_hash,
cpp_string_eq, NULL);
cpp_forall_identifiers (r, save_idents, r->savedstate);
/* Write out the list of defined identifiers. */
cpp_forall_identifiers (r, write_macdef, f);
@ -210,20 +210,20 @@ static int
count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
{
struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
switch (hn->type)
{
case NT_MACRO:
if (hn->flags & NODE_BUILTIN)
return 1;
/* else fall through. */
case NT_VOID:
{
struct cpp_string news;
void **slot;
news.len = NODE_LEN (hn);
news.text = NODE_NAME (hn);
slot = (void **) htab_find (ss->definedhash, &news);
@ -249,20 +249,20 @@ static int
write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
{
struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
switch (hn->type)
{
case NT_MACRO:
if (hn->flags & NODE_BUILTIN)
return 1;
/* else fall through. */
case NT_VOID:
{
struct cpp_string news;
void **slot;
news.len = NODE_LEN (hn);
news.text = NODE_NAME (hn);
slot = (void **) htab_find (ss->definedhash, &news);
@ -303,7 +303,7 @@ cpp_write_pch_deps (cpp_reader *r, FILE *f)
struct cpp_savedstate *const ss = r->savedstate;
unsigned char *definedstrs;
size_t i;
/* Collect the list of identifiers which have been seen and
weren't defined to anything previously. */
ss->hashsize = 0;
@ -337,6 +337,14 @@ cpp_write_pch_deps (cpp_reader *r, FILE *f)
/* Free the saved state. */
free (ss);
r->savedstate = NULL;
/* Save the next value of __COUNTER__. */
if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1)
{
cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
return -1;
}
return 0;
}
@ -361,6 +369,15 @@ cpp_write_pch_state (cpp_reader *r, FILE *f)
return -1;
}
/* Save the next __COUNTER__ value. When we include a precompiled header,
we need to start at the offset we would have if the header had been
included normally. */
if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1)
{
cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
return -1;
}
return 0;
}
@ -404,7 +421,7 @@ collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn,
with the preprocessor's current definitions. It will be consistent
when:
- anything that was defined just before the PCH was generated
- anything that was defined just before the PCH was generated
is defined the same way now; and
- anything that was not defined then, but is defined now, was not
used by the PCH.
@ -423,17 +440,18 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
struct ht_node_list nl = { 0, 0, 0 };
unsigned char *first, *last;
unsigned int i;
unsigned int counter;
/* Read in the list of identifiers that must be defined
Check that they are defined in the same way. */
for (;;)
{
cpp_hashnode *h;
const unsigned char *newdefn;
if (read (fd, &m, sizeof (m)) != sizeof (m))
goto error;
if (m.name_length == 0)
break;
@ -453,10 +471,10 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
namebuf = XNEWVEC (unsigned char, namebufsz);
}
if ((size_t)read (fd, namebuf, m.definition_length)
if ((size_t)read (fd, namebuf, m.definition_length)
!= m.definition_length)
goto error;
h = cpp_lookup (r, namebuf, m.name_length);
if (m.flags & NODE_POISONED
|| h->type != NT_MACRO
@ -470,7 +488,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
}
newdefn = cpp_macro_definition (r, h);
if (m.definition_length != ustrlen (newdefn)
|| memcmp (namebuf, newdefn, m.definition_length) != 0)
{
@ -498,17 +516,17 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
nl.defs = XNEWVEC (cpp_hashnode *, nl.asize);
cpp_forall_identifiers (r, &collect_ht_nodes, &nl);
qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
/* Loop through nl.defs and undeftab, both of which are sorted lists.
There should be no matches. */
first = undeftab;
last = undeftab + m.definition_length;
i = 0;
while (first < last && i < nl.n_defs)
{
int cmp = ustrcmp (first, NODE_NAME (nl.defs[i]));
if (cmp < 0)
first += ustrlen (first) + 1;
else if (cmp > 0)
@ -516,15 +534,31 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
else
{
if (CPP_OPTION (r, warn_invalid_pch))
cpp_error (r, CPP_DL_WARNING_SYSHDR,
cpp_error (r, CPP_DL_WARNING_SYSHDR,
"%s: not used because `%s' is defined",
name, first);
goto fail;
}
}
free(nl.defs);
nl.defs = NULL;
free (undeftab);
undeftab = NULL;
/* Read in the next value of __COUNTER__.
Check that (a) __COUNTER__ was not used in the pch or (b) __COUNTER__
has not been used in this translation unit. */
if (read (fd, &counter, sizeof (counter)) != sizeof (counter))
goto error;
if (counter && r->counter)
{
if (CPP_OPTION (r, warn_invalid_pch))
cpp_error (r, CPP_DL_WARNING_SYSHDR,
"%s: not used because `__COUNTER__' is invalid",
name);
goto fail;
}
/* We win! */
return 0;
@ -545,7 +579,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
/* Save all the existing macros. */
struct save_macro_data
struct save_macro_data
{
uchar **defns;
size_t count;
@ -567,7 +601,7 @@ struct save_macro_data
file were not saved in this way, but this is not done (yet), except
for builtins, and for #assert by default. */
static int
static int
save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
{
struct save_macro_data *data = (struct save_macro_data *)data_p;
@ -577,9 +611,9 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
if (data->count == data->array_size)
{
data->array_size *= 2;
data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size));
data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size));
}
switch (h->type)
{
case NT_ASSERTION:
@ -596,7 +630,7 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
data->defns[data->count][defnlen] = '\n';
}
break;
default:
abort ();
}
@ -612,7 +646,7 @@ void
cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
{
struct save_macro_data *d = XNEW (struct save_macro_data);
d->array_size = 512;
d->defns = XNEWVEC (uchar *, d->array_size);
d->count = 0;
@ -622,7 +656,7 @@ cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
}
/* Given a precompiled header that was previously determined to be valid,
apply all its definitions (and undefinitions) to the current state.
apply all its definitions (and undefinitions) to the current state.
DEPNAME is passed to deps_restore. */
int
@ -631,8 +665,9 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
{
size_t i;
struct lexer_state old_state;
unsigned int counter;
/* Restore spec_nodes, which will be full of references to the old
/* Restore spec_nodes, which will be full of references to the old
hashtable entries and so will now be invalid. */
{
struct spec_nodes *s = &r->spec_nodes;
@ -690,8 +725,14 @@ cpp_read_state (cpp_reader *r, const char *name, FILE *f,
if (! _cpp_read_file_entries (r, f))
goto error;
if (fread (&counter, sizeof (counter), 1, f) != 1)
goto error;
if (!r->counter)
r->counter = counter;
return 0;
error:
cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");
return -1;

View File

@ -1,5 +1,5 @@
/* CPP Library - traditional lexical analysis and macro expansion.
Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
Contributed by Neil Booth, May 2002
This program is free software; you can redistribute it and/or modify it
@ -353,6 +353,11 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
const uchar *start_of_input_line;
fmacro.buff = NULL;
fmacro.args = NULL;
fmacro.node = NULL;
fmacro.offset = 0;
fmacro.line = 0;
fmacro.argc = 0;
quote = 0;
header_ok = pfile->state.angled_headers;
@ -827,8 +832,11 @@ replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro)
uchar *p;
_cpp_buff *buff;
size_t len = 0;
int cxtquote = 0;
/* Calculate the length of the argument-replaced text. */
/* Get an estimate of the length of the argument-replaced text.
This is a worst case estimate, assuming that every replacement
text character needs quoting. */
for (exp = macro->exp.text;;)
{
struct block *b = (struct block *) exp;
@ -836,8 +844,8 @@ replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro)
len += b->text_len;
if (b->arg_index == 0)
break;
len += (fmacro->args[b->arg_index]
- fmacro->args[b->arg_index - 1] - 1);
len += 2 * (fmacro->args[b->arg_index]
- fmacro->args[b->arg_index - 1] - 1);
exp += BLOCK_LEN (b->text_len);
}
@ -845,21 +853,69 @@ replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro)
buff = _cpp_get_buff (pfile, len + 1);
/* Copy the expansion and replace arguments. */
/* Accumulate actual length, including quoting as necessary */
p = BUFF_FRONT (buff);
len = 0;
for (exp = macro->exp.text;;)
{
struct block *b = (struct block *) exp;
size_t arglen;
int argquote;
uchar *base;
uchar *in;
memcpy (p, b->text, b->text_len);
p += b->text_len;
len += b->text_len;
/* Copy the non-argument text literally, keeping
track of whether matching quotes have been seen. */
for (arglen = b->text_len, in = b->text; arglen > 0; arglen--)
{
if (*in == '"')
cxtquote = ! cxtquote;
*p++ = *in++;
}
/* Done if no more arguments */
if (b->arg_index == 0)
break;
arglen = (fmacro->args[b->arg_index]
- fmacro->args[b->arg_index - 1] - 1);
memcpy (p, pfile->out.base + fmacro->args[b->arg_index - 1],
arglen);
p += arglen;
base = pfile->out.base + fmacro->args[b->arg_index - 1];
in = base;
#if 0
/* Skip leading whitespace in the text for the argument to
be substituted. To be compatible with gcc 2.95, we would
also need to trim trailing whitespace. Gcc 2.95 trims
leading and trailing whitespace, which may be a bug. The
current gcc testsuite explicitly checks that this leading
and trailing whitespace in actual arguments is
preserved. */
while (arglen > 0 && is_space (*in))
{
in++;
arglen--;
}
#endif
for (argquote = 0; arglen > 0; arglen--)
{
if (cxtquote && *in == '"')
{
if (in > base && *(in-1) != '\\')
argquote = ! argquote;
/* Always add backslash before double quote if argument
is expanded in a quoted context */
*p++ = '\\';
len++;
}
else if (cxtquote && argquote && *in == '\\')
{
/* Always add backslash before a backslash in an argument
that is expanded in a quoted context and also in the
range of a quoted context in the argument itself. */
*p++ = '\\';
len++;
}
*p++ = *in++;
len++;
}
exp += BLOCK_LEN (b->text_len);
}

View File

@ -1,6 +1,223 @@
2007-07-19 Release Manager
2010-05-22 Release Manager
* GCC 4.2.1 released.
* GCC 4.3.5 released.
2010-05-06 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
PR other/43620
* configure.ac (AM_INIT_AUTOMAKE): Add no-dist.
* configure: Regenerate.
* aclocal.m4: Regenerate.
* config.h.in: Regenerate.
* Makefile.in: Regenerate.
* testsuite/Makefile.in: Regenerate.
2009-08-19 Tobias Burnus <burnus@net-b.de>
PR fortran/41102
omp_lib.h.in: Fix -std=f95 errors.
2009-08-14 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline:
2008-12-26 Uros Bizjak <ubizjak@gmail.com>
* testsuite/libgomp.c/atomic-6.c: Add -mieee for alpha*-*-* targets.
2009-08-04 Release Manager
* GCC 4.3.4 released.
2009-01-24 Release Manager
* GCC 4.3.3 released.
2008-12-05 Janis Johnson <janis187@us.ibm.com>
Backport from mainline:
2008-05-15 Janis Johnson <janis187@us.ibm.com>
* testsuite/lib/libgomp.exp: Load new torture support.
2008-12-02 Janis Johnson <janis187@us.ibm.com>
Backport from mainline:
2008-11-26 Janis Johnson <janis187@us.ibm.com>
PR testsuite/28870
* testsuite/lib/libgomp.exp: Include new timeout library files.
(libgomp_target_compile): Set timeout value from new proc.
2008-08-27 Release Manager
* GCC 4.3.2 released.
2008-06-12 Jakub Jelinek <jakub@redhat.com>
PR middle-end/36506
* testsuite/libgomp.c/reduction-5.c: New test.
2008-06-06 Release Manager
* GCC 4.3.1 released.
2008-05-23 Jakub Jelinek <jakub@redhat.com>
PR c++/36308
* testsuite/libgomp.c++/ctor-11.C: New test.
* testsuite/libgomp.c++/ctor-12.C: New test.
2008-05-07 Jakub Jelinek <jakub@redhat.com>
PR middle-end/36106
* testsuite/libgomp.c/atomic-5.c: New test.
* testsuite/libgomp.c/atomic-6.c: New test.
* testsuite/libgomp.c/autopar-1.c: New test.
2008-03-18 Jakub Jelinek <jakub@redhat.com>
PR middle-end/35611
* testsuite/libgomp.c/atomic-4.c: New test.
PR libgomp/35625
* iter.c (gomp_iter_guided_next_locked): If q > n, set end to ws->end.
(gomp_iter_guided_next): Likewise.
* testsuite/libgomp.c/pr35625.c: New test.
2008-03-13 Jakub Jelinek <jakub@redhat.com>
PR middle-end/35185
* testsuite/libgomp.c++/pr35185.C: New test.
2008-03-12 Jakub Jelinek <jakub@redhat.com>
PR middle-end/35549
* testsuite/libgomp.c/pr35549.c: New test.
2008-03-06 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c/atomic-3.c: New test.
2008-03-05 Release Manager
* GCC 4.3.0 released.
2008-02-15 Jakub Jelinek <jakub@redhat.com>
PR middle-end/35196
* testsuite/libgomp.c/pr35196.c: New test.
PR middle-end/35130
* testsuite/libgomp.fortran/pr35130.f90: New test.
* testsuite/libgomp.c/pr35130.c: New test.
2008-01-25 Jakub Jelinek <jakub@redhat.com>
PR middle-end/33880
* testsuite/libgomp.c/pr33880.c: New test.
* testsuite/libgomp.fortran/pr33880.f90: New test.
2008-01-24 David Edelsohn <edelsohn@gnu.org>
* configure: Regenerate.
2008-01-08 Jakub Jelinek <jakub@redhat.com>
* configure.ac: Move futex checking into ../config/futex.m4.
* configure: Rebuilt.
* aclocal.m4: Rebuilt.
* Makefile.in: Rebuilt.
* configure.tgt: Rename have_tls to gcc_cv_have_tls to match
2007-10-15 ../config/tls.m4 change.
2007-12-19 Jakub Jelinek <jakub@redhat.com>
PR c++/34513
* testsuite/libgomp.c/pr34513.c: New test.
* testsuite/libgomp.c++/pr34513.C: New test.
2007-12-17 Jack Howarth <howarth@bromo.med.uc.edu>
PR target/32765
* testsuite/libgomp.fortran/crayptr2.f90: Move dg-options for darwin.
2007-12-04 Jakub Jelinek <jakub@redhat.com>
* omp.h.in (__GOMP_NOTHROW): Define. Use it on omp_* prototypes.
2007-12-03 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c/private-1.c: New test.
2007-11-29 Andris Pavenis <andris.pavenis@iki.fi>
Paolo Bonzini <bonzini@gnu.org>
* Makefile.am: Use space as vpath separator. Use 'vpath %'
instead of 'VPATH ='.
* Makefile.in: Regenerate.
2007-11-23 Matthias Klose <doko@ubuntu.com>
* configure.ac: Adjust makeinfo version check.
* configure: Regenerate.
2007-11-10 Jakub Jelinek <jakub@redhat.com>
PR fortran/34020
* testsuite/libgomp.fortran/pr34020.f90: New test.
2007-11-06 Jakub Jelinek <jakub@redhat.com>
PR c++/33894
* testsuite/libgomp.c++/atomic-1.C: New test.
2007-10-25 Jakub Jelinek <jakub@redhat.com>
PR libgomp/33275
* testsuite/libgomp.fortran/omp_parse3.f90 (test_threadprivate):
Make x and y integers rather than (implicit) reals. Add private (j)
clause to the last omp parallel.
2007-10-15 Maciej W. Rozycki <macro@linux-mips.org>
* configure: Regenerate following changes to ../config/tls.m4.
2007-09-28 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.fortran/stack.f90: New test.
2007-09-10 Danny Smith <dannysmith@users.sourceforge.net>
* config/mingw32/proc.c: New file.
2007-09-05 Uros Bizjak <ubizjak@gmail.com>
* testsuite/libgomp.c/atomic-1.c: Include cpuid.h for i386 targets.
(main): Use __get_cpuid to get i386 target fetaures.
* testsuite/libgomp.c/atomic-2.c: Include cpuid.h for x86_64 targets.
(main): Use __get_cpuid to get x86_64 target fetaures.
2007-08-15 Jack Howarth <howarth@bromo.med.uc.edu>
PR target/32765
* testsuite/libgomp.fortran/pr32550.f90: Use -static-libgcc on Darwin.
* testsuite/libgomp.fortran/crayptr2.f90: Likwise.
2007-07-12 Jakub Jelinek <jakub@redhat.com>
PR fortran/32550
* testsuite/libgomp.fortran/pr32550.f90: New test.
* testsuite/libgomp.fortran/crayptr2.f90: New test.
2007-07-05 H.J. Lu <hongjiu.lu@intel.com>
* aclocal.m4: Regenerated.
2007-07-05 Tobias Burnus <burnus@net-b.de>
PR fortran/32359
* testsuite/libgomp.fortran/pr32359.f90: New.
2007-07-02 Jakub Jelinek <jakub@redhat.com>
@ -21,9 +238,117 @@
* testsuite/libgomp.c/pr32362-2.c: New test.
* testsuite/libgomp.c/pr32362-3.c: New test.
2007-05-13 Release Manager
2007-06-07 Jakub Jelinek <jakub@redhat.com>
* GCC 4.2.0 released.
* team.c (gomp_team_start): Fix setting up thread_attr
stack size.
2007-06-02 Paolo Bonzini <bonzini@gnu.org>
* configure: Regenerate.
2007-05-23 Steve Ellcey <sje@cup.hp.com>
* Makefile.in: Regenerate.
* configure: Regenerate.
* aclocal.m4: Regenerate.
* testsuite/Makefile.in: Regenerate.
2007-05-04 Jakub Jelinek <jakub@redhat.com>
* config/linux/proc.c: New file.
PR libgomp/28482
* configure.tgt: Don't link with -Wl,-z,nodlopen even on Linux.
2007-04-19 Daniel Franke <franke.daniel@gmail.com>
* libgomp.texi (GOMP_CPU_AFFINITY): Updated.
2007-04-16 Matthias Klose <doko@debian.org>
* configure.tgt (i[456]86-*-linux*): Only add ia32 specific
flags if not building with -m64.
* testsuite/lib/libgomp-dg.exp (libgomp_init): Don't add -march
flag for i?86-*-* targets, if current target matches -m64.
2007-04-14 Steve Ellcey <sje@cup.hp.com>
* Makefile.am: Add -I .. to ACLOCAL_AMFLAGS.
* Makefile.in: Regenerate.
2007-04-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR testsuite/31369
* testsuite/libgomp.c++/c++.exp: Don't use concat when setting
ld_library_path.
* testsuite/libgomp.fortran/fortran.exp: Likewise.
2007-04-04 Jakub Jelinek <jakub@redhat.com>
* libgomp.h (gomp_cpu_affinity, gomp_cpu_affinity_len): New extern
decls.
(gomp_init_affinity, gomp_init_thread_affinity): New prototypes.
* env.c (gomp_cpu_affinity, gomp_cpu_affinity_len): New variables.
(parse_affinity): New function.
(initialize_env): Call it and gomp_init_affinity.
* team.c (gomp_team_start): If gomp_cpu_affinity != NULL,
create new pthread_attr_t and call gomp_init_thread_affinity
on it for each thread before passing the attribute to pthread_create.
* config/linux/affinity.c: New file.
* config/posix/affinity.c: New file.
* configure.ac (HAVE_PTHREAD_AFFINITY_NP): New test.
* configure: Rebuilt.
* config.h.in: Rebuilt.
* Makefile.am (libgomp_la_SOURCES): Add affinity.c.
* Makefile.in: Rebuilt.
2007-03-23 Andreas Tobler <a.tobler@schweiz.org>
* testsuite/lib/libgomp.exp (libgomp_init): Add -shared-libgcc for
*-*-darwin*.
* testsuite/libgomp.c++/c++.exp: Look for shared libstdc++ library
and use it if found.
2007-03-18 Uros Bizjak <ubizjak@gmail.com>
* testsuite/config/default.exp: New file.
* testsuite/lib/libgomp.exp: New file.
* testsuite/lib/libgomp.dg (load_gcc_lib, libgomp_init,
libgomp_target_compile, libgomp_option_help, libgomp_option_proc,
load_lib *, load_gcc_lib *): Move to libgomp.exp.
(libgomp_load): Remove.
* testsuite/lib/libgomp.exp (libgomp_init): Compute
always_ld_library_path, not ld_library_path. Set additional_flags
to -march=i486 for ilp32 x86_64-*-* and i386-*-* targets.
(target_compile): Do not call libgomp_init. Append lang_library_path
and lang_link_flags to options.
* testsuite/libgomp.c/c.exp: Set DEFAULT_FLAGS to -O2. Set
ld_library_path from always_ld_library_path. Set LD_LIBRARY_PATH
here.
* testsuite/libgomp.c++/c++.exp: Set ld_library_path from
always_ld_library_path. Set LD_LIBRARY_PATH here.
* testsuite/libgomp.fortran/fortran.exp: Ditto.
* testsuite/libgomp.c/atomic-1.c: Set dg-options to
"-O2 -march=pentium" for ilp32 x86 targets. Simplify check for
CX8 flag.
* testsuite/libgomp.c/atomic-2.c: Set dg-options to "-O2 -mcx16" for
lp64 x86 targets. Do not check for SSE3 bit. Do not define bit_SSE3.
* testsuite/libgomp.c/pr29947-1.c: Remove default dg-options.
* testsuite/libgomp.c/pr29947-1.c: Ditto.
* testsuite/libgomp.c/atomic-10.c: Ditto.
2007-03-21 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.fortran/appendix-a/a.22.8.f90: Add
dg-final cleanup-modules line.
* testsuite/libgomp.fortran/appendix-a/a.40.1.f90: Likewise.
* testsuite/libgomp.fortran/appendix-a/a.31.5.f90: Likewise.
* testsuite/libgomp.fortran/appendix-a/a.31.4.f90: Likewise.
* testsuite/libgomp.fortran/threadprivate2.f90: Likewise.
* testsuite/libgomp.fortran/reduction5.f90: Likewise.
* testsuite/libgomp.fortran/threadprivate3.f90: Likewise.
* testsuite/libgomp.fortran/threadprivate1.f90: Likewise.
2007-03-18 Andreas Schwab <schwab@suse.de>
@ -31,15 +356,32 @@
extraction.
* configure: Regenerate.
2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
* Makefile.am: Add install-pdf target as copied from
automake v1.10 rules.
* Makefile.in: Regenerate
2007-02-07 Jakub Jelinek <jakub@redhat.com>
PR libgomp/28486
* configure: Regenerate.
PR c++/30703
* testsuite/libgomp.c++/pr30703.C: New test.
2007-02-07 Daniel Franke <franke.daniel@gmail.com>
2007-02-02 Jakub Jelinek <jakub@redhat.com>
Backport from mainline:
2007-01-31 Daniel Franke <franke.daniel@gmail.com>
Revert:
2006-07-05 Eric Christopher <echristo@apple.com>
* configure.ac: Depend addition of -pthread on host OS.
* configure: Regenerate.
2007-01-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* libgomp.texi: Fix spacing after abbreviations.
2007-01-31 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/30546
* configure.ac: Add check for makeinfo
@ -50,74 +392,47 @@
* Makefile.in: Regenerated.
* testsuite/Makefile.in: Regenerated.
2007-02-07 Daniel Franke <franke.daniel@gmail.com>
Backport from mainline:
2007-01-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* libgomp.texi: Fix spacing after abbreviations.
Backport from mainline:
2007-01-29 Daniel Franke <franke.daniel@gmail.com>
2007-01-29 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/30540
* libgomp.texi: More about implementation-dependent settings.
2007-02-06 Roger Sayle <roger@eyesopen.com>
PR libgomp/28296
Backport from mainline.
Revert:
2006-07-05 Eric Christopher <echristo@apple.com>
* configure.ac: Depend addition of -pthread on host OS.
* configure: Regenerate.
2007-01-30 Tobias Burnus <burnus@net-b.de>
Backport from mainline.
2007-01-26 Tobias Burnus <burnus@net-b.de>
2007-01-26 Tobias Burnus <burnus@net-b.de>
* testsuite/libgomp.fortran/fortran.exp: Support .f03 extension.
2007-01-25 Daniel Franke <franke.daniel@gmail.com>
Backport from mainline:
2006-12-21 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/28209
* libgomp.texi: New file.
* configure.ac: Add --enable-generated-files-in-srcdir option.
* Makefile.am: Add info, dvi, pdf, html targets. On request,
copy files to srcdir.
* Makefile.in: Regenerated.
* testsuite/Makefile.in: Regenerated.
* NOTES: Removed.
Backport from mainline:
2007-01-14 Daniel Franke <franke.daniel@gmail.com>
* libgomp.texi: Document implementation specific default values of
environment variables.
2007-01-24 Jakub Jelinek <jakub@redhat.com>
PR middle-end/30494
* testsuite/libgomp.c/pr30494.c: New test.
2006-12-18 Daniel Franke <franke.daniel@gmail.com>
2007-01-15 Tom Tromey <tromey@redhat.com>
Backport from mainline:
2006-12-04 Daniel Franke <franke.daniel@gmail.com>
* configure: Rebuilt.
* configure.ac: Fixed comment.
2007-01-14 Daniel Franke <franke.daniel@gmail.com>
* libgomp.texi: Document implementation specific default values of
environment variables.
2006-12-21 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/28209
* libgomp.texi: New file.
* configure.ac: Add --enable-generated-files-in-srcdir option.
* Makefile.am: Add info, dvi, pdf, html targets. On request, copy
files to srcdir.
* Makefile.in: Regenerated.
* config.h.in: Regenerated.
* testsuite/Makefile.in: Regenerated.
* NOTES: Removed.
2006-12-04 Daniel Franke <franke.daniel@gmail.com>
PR libgomp/29949
* env.c (omp_set_num_threads): Set illegal thread count to 1.
Backport from mainline:
2006-11-09 Uros Bizjak <ubizjak@gmail.com>
* env.c (parse_schedule): Reject out of range values.
(parse_unsigned_long): Reject out of range, negative
or zero values.
2006-12-04 Eric Botcazou <ebotcazou@libertysurf.fr>
* configure: Regenerate.
@ -135,6 +450,15 @@
* configure.tgt: Force initial-exec TLS model on Linux only.
2006-11-13 Daniel Jacobowitz <dan@codesourcery.com>
* configure: Regenerated.
2006-11-09 Uros Bizjak <ubizjak@gmail.com>
* env.c (parse_schedule): Reject out of range values.
(parse_unsigned_long): Reject out of range, negative or zero values.
2006-10-29 Jakub Jelinek <jakub@redhat.com>
PR fortran/29629

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
ACLOCAL_AMFLAGS = -I ../config
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite
## May be used by toolexeclibdir.
@ -12,9 +12,7 @@ search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) $(top_srcdir)
fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/finclude
libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
empty =
space = $(empty) $(empty)
VPATH = $(subst $(space),:,$(strip $(search_path)))
vpath % $(strip $(search_path))
AM_CPPFLAGS = $(addprefix -I, $(search_path))
AM_CFLAGS = $(XCFLAGS)
@ -33,7 +31,7 @@ libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script)
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c
nodist_noinst_HEADERS = libgomp_f.h
nodist_libsubinclude_HEADERS = omp.h
@ -51,10 +49,19 @@ env.lo: libgomp_f.h
env.o: libgomp_f.h
# No install-html target
.PHONY: install-html
# No install-html or install-pdf support in automake yet
.PHONY: install-html install-pdf
install-html:
install-pdf: $(PDFS)
@$(NORMAL_INSTALL)
test -z "$(pdfdir)" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)"
@list='$(PDFS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/$$f'"; \
$(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/$$f"; \
done
# Automake Documentation:
# If your package has Texinfo files in many directories, you can use the

View File

@ -17,6 +17,7 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
@ -37,24 +38,27 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
DIST_COMMON = $(am__configure_deps) $(srcdir)/../config.guess \
$(srcdir)/../config.sub $(srcdir)/../depcomp \
$(srcdir)/../install-sh $(srcdir)/../ltmain.sh \
$(srcdir)/../missing $(srcdir)/../mkinstalldirs \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/config.h.in $(srcdir)/libgomp.spec.in \
$(srcdir)/libgomp_f.h.in $(srcdir)/omp.h.in \
$(srcdir)/omp_lib.f90.in $(srcdir)/omp_lib.h.in \
$(top_srcdir)/configure ChangeLog
DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub \
ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \
$(srcdir)/omp.h.in $(srcdir)/omp_lib.h.in \
$(srcdir)/omp_lib.f90.in $(srcdir)/libgomp_f.h.in \
$(srcdir)/libgomp.spec.in $(srcdir)/../depcomp \
$(srcdir)/../ltmain.sh $(srcdir)/../config.guess \
$(srcdir)/../config.sub
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
$(top_srcdir)/../config/enable.m4 \
$(top_srcdir)/../config/futex.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/stdint.m4 \
$(top_srcdir)/../config/tls.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../config/tls.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@ -79,21 +83,20 @@ libgomp_la_LIBADD =
am_libgomp_la_OBJECTS = alloc.lo barrier.lo critical.lo env.lo \
error.lo iter.lo loop.lo ordered.lo parallel.lo sections.lo \
single.lo team.lo work.lo lock.lo mutex.lo proc.lo sem.lo \
bar.lo time.lo fortran.lo
bar.lo time.lo fortran.lo affinity.lo
libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libgomp_la_SOURCES)
DIST_SOURCES = $(libgomp_la_SOURCES)
MULTISRCTOP =
MULTIBUILDTOP =
MULTIDIRS =
@ -126,18 +129,6 @@ HEADERS = $(nodist_finclude_HEADERS) $(nodist_libsubinclude_HEADERS) \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
VPATH = $(subst $(space),:,$(strip $(search_path)))
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
@ -157,6 +148,7 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@ -164,12 +156,15 @@ EGREP = @EGREP@
EXEEXT = @EXEEXT@
FC = @FC@
FCFLAGS = @FCFLAGS@
FGREP = @FGREP@
GENINSRC_FALSE = @GENINSRC_FALSE@
GENINSRC_TRUE = @GENINSRC_TRUE@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE = @LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE@
LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE = @LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@
@ -182,6 +177,7 @@ MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
NM = @NM@
OBJEXT = @OBJEXT@
OMP_LOCK_ALIGN = @OMP_LOCK_ALIGN@
OMP_LOCK_KIND = @OMP_LOCK_KIND@
@ -200,6 +196,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
RANLIB = @RANLIB@
SECTION_LDFLAGS = @SECTION_LDFLAGS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -210,6 +207,7 @@ XCFLAGS = @XCFLAGS@
XLDFLAGS = @XLDFLAGS@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_FC = @ac_ct_FC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
@ -244,6 +242,7 @@ libexecdir = @libexecdir@
libtool_VERSION = @libtool_VERSION@
link_gomp = @link_gomp@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
multi_basedir = @multi_basedir@
@ -260,14 +259,12 @@ target_os = @target_os@
target_vendor = @target_vendor@
toolexecdir = @toolexecdir@
toolexeclibdir = @toolexeclibdir@
ACLOCAL_AMFLAGS = -I ../config
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = testsuite
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
search_path = $(addprefix $(top_srcdir)/config/, $(config_path)) $(top_srcdir)
fincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/finclude
libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
empty =
space = $(empty) $(empty)
AM_CPPFLAGS = $(addprefix -I, $(search_path))
AM_CFLAGS = $(XCFLAGS)
AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS)
@ -279,7 +276,7 @@ libgomp_version_info = -version-info $(libtool_VERSION)
libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script)
libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
loop.c ordered.c parallel.c sections.c single.c team.c work.c \
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c
lock.c mutex.c proc.c sem.c bar.c time.c fortran.c affinity.c
nodist_noinst_HEADERS = libgomp_f.h
nodist_libsubinclude_HEADERS = omp.h
@ -406,6 +403,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affinity.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bar.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/barrier.Plo@am__quote@
@ -733,152 +731,6 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkdir_p) $(distdir)/. $(distdir)/.. $(distdir)/../config
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(mkdir_p) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-info
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) all-multi $(HEADERS) \
@ -1011,16 +863,13 @@ uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am all-local \
all-multi am--refresh check check-am clean clean-generic \
clean-libtool clean-multi clean-recursive \
clean-toolexeclibLTLIBRARIES ctags ctags-recursive dist \
dist-all dist-bzip2 dist-gzip dist-info dist-shar dist-tarZ \
dist-zip distcheck distclean distclean-compile \
distclean-generic distclean-hdr distclean-libtool \
distclean-multi distclean-recursive distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-multi \
install-nodist_fincludeHEADERS \
clean-toolexeclibLTLIBRARIES ctags ctags-recursive dist-info \
distclean distclean-compile distclean-generic distclean-hdr \
distclean-libtool distclean-multi distclean-recursive \
distclean-tags dvi dvi-am html html-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-multi install-nodist_fincludeHEADERS \
install-nodist_libsubincludeHEADERS \
install-nodist_toolexeclibHEADERS install-strip \
install-toolexeclibLTLIBRARIES installcheck installcheck-am \
@ -1036,6 +885,8 @@ uninstall-info: uninstall-info-recursive
uninstall-toolexeclibLTLIBRARIES
vpath % $(strip $(search_path))
omp_lib_kinds.mod: omp_lib.mod
:
omp_lib.mod: omp_lib.f90
@ -1045,10 +896,20 @@ fortran.o: libgomp_f.h
env.lo: libgomp_f.h
env.o: libgomp_f.h
# No install-html target
.PHONY: install-html
# No install-html or install-pdf support in automake yet
.PHONY: install-html install-pdf
install-html:
install-pdf: $(PDFS)
@$(NORMAL_INSTALL)
test -z "$(pdfdir)" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)"
@list='$(PDFS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/$$f'"; \
$(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/$$f"; \
done
all-local: $(STAMP_GENINSRC)
stamp-geninsrc: libgomp.info

5
libgomp/aclocal.m4 vendored
View File

@ -859,8 +859,13 @@ AC_SUBST([am__untar])
m4_include([../config/acx.m4])
m4_include([../config/depstand.m4])
m4_include([../config/enable.m4])
m4_include([../config/futex.m4])
m4_include([../config/lead-dot.m4])
m4_include([../config/multi.m4])
m4_include([../config/stdint.m4])
m4_include([../config/tls.m4])
m4_include([../ltoptions.m4])
m4_include([../ltsugar.m4])
m4_include([../ltversion.m4])
m4_include([../lt~obsolete.m4])
m4_include([acinclude.m4])

View File

@ -12,9 +12,15 @@
/* Define if the POSIX Semaphores do not work on your system. */
#undef HAVE_BROKEN_POSIX_SEMAPHORES
/* Define to 1 if the target assembler supports thread-local storage. */
#undef HAVE_CC_TLS
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `getloadavg' function. */
#undef HAVE_GETLOADAVG
@ -24,6 +30,9 @@
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define if pthread_{,attr_}{g,s}etaffinity_np is supported. */
#undef HAVE_PTHREAD_AFFINITY_NP
/* Define to 1 if you have the <semaphore.h> header file. */
#undef HAVE_SEMAPHORE_H
@ -60,6 +69,10 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Name of package */
#undef PACKAGE

View File

@ -0,0 +1,107 @@
/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
Libgomp 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 Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with libgomp; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* As a special exception, if you link this library with other files, some
of which are compiled with GCC, to produce an executable, this library
does not by itself cause the resulting executable to be covered by the
GNU General Public License. This exception does not however invalidate
any other reasons why the executable file might be covered by the GNU
General Public License. */
/* This is a Linux specific implementation of a CPU affinity setting. */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include "libgomp.h"
#include <sched.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_PTHREAD_AFFINITY_NP
static unsigned int affinity_counter;
#ifndef HAVE_SYNC_BUILTINS
static gomp_mutex_t affinity_lock;
#endif
void
gomp_init_affinity (void)
{
cpu_set_t cpuset;
size_t idx, widx;
if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset))
{
gomp_error ("could not get CPU affinity set");
free (gomp_cpu_affinity);
gomp_cpu_affinity = NULL;
gomp_cpu_affinity_len = 0;
return;
}
for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
if (gomp_cpu_affinity[idx] < CPU_SETSIZE
&& CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];
if (widx == 0)
{
gomp_error ("no CPUs left for affinity setting");
free (gomp_cpu_affinity);
gomp_cpu_affinity = NULL;
gomp_cpu_affinity_len = 0;
return;
}
gomp_cpu_affinity_len = widx;
CPU_ZERO (&cpuset);
CPU_SET (gomp_cpu_affinity[0], &cpuset);
pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset);
affinity_counter = 1;
#ifndef HAVE_SYNC_BUILTINS
gomp_mutex_init (&affinity_lock);
#endif
}
void
gomp_init_thread_affinity (pthread_attr_t *attr)
{
unsigned int cpu;
cpu_set_t cpuset;
#ifdef HAVE_SYNC_BUILTINS
cpu = __sync_fetch_and_add (&affinity_counter, 1);
#else
gomp_mutex_lock (&affinity_lock);
cpu = affinity_counter++;
gomp_mutex_unlock (&affinity_lock);
#endif
cpu %= gomp_cpu_affinity_len;
CPU_ZERO (&cpuset);
CPU_SET (gomp_cpu_affinity[cpu], &cpuset);
pthread_attr_setaffinity_np (attr, sizeof (cpu_set_t), &cpuset);
}
#else
#include "../posix/affinity.c"
#endif

179
libgomp/config/linux/proc.c Normal file
View File

@ -0,0 +1,179 @@
/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
Libgomp 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 Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with libgomp; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* As a special exception, if you link this library with other files, some
of which are compiled with GCC, to produce an executable, this library
does not by itself cause the resulting executable to be covered by the
GNU General Public License. This exception does not however invalidate
any other reasons why the executable file might be covered by the GNU
General Public License. */
/* This file contains system specific routines related to counting
online processors and dynamic load balancing. */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include "libgomp.h"
#include <sched.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_GETLOADAVG
# ifdef HAVE_SYS_LOADAVG_H
# include <sys/loadavg.h>
# endif
#endif
#ifdef HAVE_PTHREAD_AFFINITY_NP
static unsigned long
cpuset_popcount (cpu_set_t *cpusetp)
{
#ifdef CPU_COUNT
/* glibc 2.6 and above provide a macro for this. */
return CPU_COUNT (cpusetp);
#else
size_t i;
unsigned long ret = 0;
extern int check[sizeof (cpusetp->__bits[0]) == sizeof (unsigned long int)];
(void) check;
for (i = 0; i < sizeof (*cpusetp) / sizeof (cpusetp->__bits[0]); i++)
{
unsigned long int mask = cpusetp->__bits[i];
if (mask == 0)
continue;
ret += __builtin_popcountl (mask);
}
return ret;
#endif
}
#endif
/* At startup, determine the default number of threads. It would seem
this should be related to the number of cpus online. */
void
gomp_init_num_threads (void)
{
#ifdef HAVE_PTHREAD_AFFINITY_NP
cpu_set_t cpuset;
if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset) == 0)
{
/* Count only the CPUs this process can use. */
gomp_nthreads_var = cpuset_popcount (&cpuset);
if (gomp_nthreads_var == 0)
gomp_nthreads_var = 1;
return;
}
#endif
#ifdef _SC_NPROCESSORS_ONLN
gomp_nthreads_var = sysconf (_SC_NPROCESSORS_ONLN);
#endif
}
static int
get_num_procs (void)
{
#ifdef HAVE_PTHREAD_AFFINITY_NP
cpu_set_t cpuset;
if (gomp_cpu_affinity == NULL)
{
/* Count only the CPUs this process can use. */
if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset),
&cpuset) == 0)
{
int ret = cpuset_popcount (&cpuset);
return ret != 0 ? ret : 1;
}
}
else
{
size_t idx;
static int affinity_cpus;
/* We can't use pthread_getaffinity_np in this case
(we have changed it ourselves, it binds to just one CPU).
Count instead the number of different CPUs we are
using. */
CPU_ZERO (&cpuset);
if (affinity_cpus == 0)
{
int cpus = 0;
for (idx = 0; idx < gomp_cpu_affinity_len; idx++)
if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
{
cpus++;
CPU_SET (gomp_cpu_affinity[idx], &cpuset);
}
affinity_cpus = cpus;
}
return affinity_cpus;
}
#endif
#ifdef _SC_NPROCESSORS_ONLN
return sysconf (_SC_NPROCESSORS_ONLN);
#else
return gomp_nthreads_var;
#endif
}
/* When OMP_DYNAMIC is set, at thread launch determine the number of
threads we should spawn for this team. */
/* ??? I have no idea what best practice for this is. Surely some
function of the number of processors that are *still* online and
the load average. Here I use the number of processors online
minus the 15 minute load average. */
unsigned
gomp_dynamic_max_threads (void)
{
unsigned n_onln, loadavg;
n_onln = get_num_procs ();
if (n_onln > gomp_nthreads_var)
n_onln = gomp_nthreads_var;
loadavg = 0;
#ifdef HAVE_GETLOADAVG
{
double dloadavg[3];
if (getloadavg (dloadavg, 3) == 3)
{
/* Add 0.1 to get a kind of biased rounding. */
loadavg = dloadavg[2] + 0.1;
}
}
#endif
if (loadavg >= n_onln)
return 1;
else
return n_onln - loadavg;
}
int
omp_get_num_procs (void)
{
return get_num_procs ();
}
ialias (omp_get_num_procs)

View File

@ -0,0 +1,82 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
Contributed by Danny Smith <dannysmith@users.sourceforge.net>
This file is part of the GNU OpenMP Library (libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
Libgomp 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 Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with libgomp; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* As a special exception, if you link this library with other files, some
of which are compiled with GCC, to produce an executable, this library
does not by itself cause the resulting executable to be covered by the
GNU General Public License. This exception does not however invalidate
any other reasons why the executable file might be covered by the GNU
General Public License. */
/* This file contains system specific routines related to counting
online processors and dynamic load balancing. It is expected that
a system may well want to write special versions of each of these.
The following implementation uses win32 API routines. */
#include "libgomp.h"
#include <windows.h>
/* Count the CPU's currently available to this process. */
static int
count_avail_process_cpus ()
{
DWORD_PTR process_cpus;
DWORD_PTR system_cpus;
if (GetProcessAffinityMask (GetCurrentProcess (),
&process_cpus, &system_cpus))
{
unsigned int count;
for (count = 0; process_cpus != 0; process_cpus >>= 1)
if (process_cpus & 1)
count++;
return count;
}
return 1;
}
/* At startup, determine the default number of threads. It would seem
this should be related to the number of cpus available to the process. */
void
gomp_init_num_threads (void)
{
gomp_nthreads_var = count_avail_process_cpus ();
}
/* When OMP_DYNAMIC is set, at thread launch determine the number of
threads we should spawn for this team. FIXME: How do we adjust for
load average on MS Windows? */
unsigned
gomp_dynamic_max_threads (void)
{
int n_onln = count_avail_process_cpus ();
return n_onln > gomp_nthreads_var ? gomp_nthreads_var : n_onln;
}
int
omp_get_num_procs (void)
{
return count_avail_process_cpus ();
}
ialias (omp_get_num_procs)

View File

@ -0,0 +1,41 @@
/* Copyright (C) 2006 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
Libgomp 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 Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with libgomp; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/* As a special exception, if you link this library with other files, some
of which are compiled with GCC, to produce an executable, this library
does not by itself cause the resulting executable to be covered by the
GNU General Public License. This exception does not however invalidate
any other reasons why the executable file might be covered by the GNU
General Public License. */
/* This is a generic stub implementation of a CPU affinity setting. */
#include "libgomp.h"
void
gomp_init_affinity (void)
{
}
void
gomp_init_thread_affinity (pthread_attr_t *attr)
{
(void) attr;
}

11486
libgomp/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -15,12 +15,6 @@ LIBGOMP_ENABLE(version-specific-runtime-libs, no, ,
permit yes|no)
AC_MSG_RESULT($enable_version_specific_runtime_libs)
AC_MSG_CHECKING([for --enable-linux-futex])
LIBGOMP_ENABLE(linux-futex, default, ,
[Use the Linux futex system call],
permit yes|no|default)
AC_MSG_RESULT($enable_linux_futex)
# We would like our source tree to be readonly. However when releases or
# pre-releases are generated, the flex/bison generated files as well as the
# various formats of manuals need to be included along with the rest of the
@ -64,11 +58,11 @@ target_alias=${target_alias-$host_alias}
# we can do about that; they come from AC_INIT).
# foreign: we don't follow the normal rules for GNU packages (no COPYING
# file in the top srcdir, etc, etc), so stop complaining.
# no-dependencies: turns off auto dependency generation (just for now)
# no-dist: we don't want 'dist' and related rules.
# -Wall: turns on all automake warnings...
# -Wno-portability: ...except this one, since GNU make is required.
# -Wno-override: ... and this one, since we do want this in testsuite.
AM_INIT_AUTOMAKE([1.9.0 foreign -Wall -Wno-portability -Wno-override])
AM_INIT_AUTOMAKE([1.9.0 foreign no-dist -Wall -Wno-portability -Wno-override])
AM_ENABLE_MULTILIB(, ..)
# Calculate toolexeclibdir
@ -135,7 +129,7 @@ AC_PROG_INSTALL
# that we can use it.
ACX_CHECK_PROG_VER([MAKEINFO], [makeinfo], [--version],
[GNU texinfo.* \([0-9][0-9.]*\)],
[4.[4-9]*])
[4.[4-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*])
AM_CONDITIONAL(BUILD_INFO, test $gcc_cv_prog_makeinfo_modern = "yes")
@ -193,50 +187,29 @@ case "$host" in
AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1,
Define if the POSIX Semaphores do not work on your system.)
;;
*-linux*)
case "$enable_linux_futex" in
default)
# If headers don't have gettid/futex syscalls definition, then
# default to no, otherwise there will be compile time failures.
# Otherwise, default to yes. If we don't detect we are
# compiled/linked against NPTL and not cross-compiling, check
# if programs are run by default against NPTL and if not, issue
# a warning.
enable_linux_futex=no
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#include <sys/syscall.h>
int lk;],
[syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);])],
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <pthread.h>
pthread_t th; void *status;],
[pthread_tryjoin_np (th, &status);])],[enable_linux_futex=yes],
[if test x$cross_compiling = xno; then
if getconf GNU_LIBPTHREAD_VERSION 2>/dev/null \
| LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then
AC_MSG_WARN([The kernel might not support futex or gettid syscalls.
If so, please configure with --disable-linux-futex])
fi
fi
enable_linux_futex=yes])])
;;
yes)
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#include <sys/syscall.h>
int lk;],
[syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);])],[],
[AC_MSG_ERROR([SYS_gettid and SYS_futex required for --enable-linux-futex])])
;;
esac
;;
esac
GCC_LINUX_FUTEX(:)
# Check for pthread_{,attr_}[sg]etaffinity_np.
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#define _GNU_SOURCE
#include <pthread.h>],
[cpu_set_t cpuset;
pthread_attr_t attr;
pthread_getaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
if (CPU_ISSET (0, &cpuset))
CPU_SET (1, &cpuset);
else
CPU_ZERO (&cpuset);
pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
pthread_attr_init (&attr);
pthread_attr_getaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);
pthread_attr_setaffinity_np (&attr, sizeof (cpu_set_t), &cpuset);])],
AC_DEFINE(HAVE_PTHREAD_AFFINITY_NP, 1,
[ Define if pthread_{,attr_}{g,s}etaffinity_np is supported.]))
# At least for glibc, clock_gettime is in librt. But don't pull that
# in if it still doesn't give us the function we want.
if test $ac_cv_func_clock_gettime = no; then

View File

@ -11,14 +11,11 @@
# XLDFLAGS Add extra link flags to use.
# Optimize TLS usage by avoiding the overhead of dynamic allocation.
# This does require that the library be present during process
# startup, so mark the library as not to be dlopened.
if test $have_tls = yes ; then
if test $gcc_cv_have_tls = yes ; then
case "${target}" in
*-*-linux*)
XCFLAGS="${XCFLAGS} -ftls-model=initial-exec"
XLDFLAGS="${XLDFLAGS} -Wl,-z,nodlopen"
;;
esac
fi
@ -49,9 +46,14 @@ if test $enable_linux_futex = yes; then
# Note that bare i386 is not included here. We need cmpxchg.
i[456]86-*-linux*)
config_path="linux/x86 linux posix"
if test -z "$with_arch"; then
XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
fi
case " ${CC} ${CFLAGS} " in
*" -m64 "*)
;;
*)
if test -z "$with_arch"; then
XCFLAGS="${XCFLAGS} -march=i486 -mtune=${target_cpu}"
fi
esac
;;
# Similar jiggery-pokery for x86_64 multilibs, except here we

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@ -42,6 +42,8 @@ bool gomp_dyn_var = false;
bool gomp_nest_var = false;
enum gomp_schedule_type gomp_run_sched_var = GFS_DYNAMIC;
unsigned long gomp_run_sched_chunk = 1;
unsigned short *gomp_cpu_affinity;
size_t gomp_cpu_affinity_len;
/* Parse the OMP_SCHEDULE environment variable. */
@ -177,6 +179,97 @@ parse_boolean (const char *name, bool *value)
gomp_error ("Invalid value for environment variable %s", name);
}
/* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
present and it was successfully parsed. */
static bool
parse_affinity (void)
{
char *env, *end;
unsigned long cpu_beg, cpu_end, cpu_stride;
unsigned short *cpus = NULL;
size_t allocated = 0, used = 0, needed;
env = getenv ("GOMP_CPU_AFFINITY");
if (env == NULL)
return false;
do
{
while (*env == ' ' || *env == '\t')
env++;
cpu_beg = strtoul (env, &end, 0);
cpu_end = cpu_beg;
cpu_stride = 1;
if (env == end || cpu_beg >= 65536)
goto invalid;
env = end;
if (*env == '-')
{
cpu_end = strtoul (++env, &end, 0);
if (env == end || cpu_end >= 65536 || cpu_end < cpu_beg)
goto invalid;
env = end;
if (*env == ':')
{
cpu_stride = strtoul (++env, &end, 0);
if (env == end || cpu_stride == 0 || cpu_stride >= 65536)
goto invalid;
env = end;
}
}
needed = (cpu_end - cpu_beg) / cpu_stride + 1;
if (used + needed >= allocated)
{
unsigned short *new_cpus;
if (allocated < 64)
allocated = 64;
if (allocated > needed)
allocated <<= 1;
else
allocated += 2 * needed;
new_cpus = realloc (cpus, allocated * sizeof (unsigned short));
if (new_cpus == NULL)
{
free (cpus);
gomp_error ("not enough memory to store GOMP_CPU_AFFINITY list");
return false;
}
cpus = new_cpus;
}
while (needed--)
{
cpus[used++] = cpu_beg;
cpu_beg += cpu_stride;
}
while (*env == ' ' || *env == '\t')
env++;
if (*env == ',')
env++;
else if (*env == '\0')
break;
}
while (1);
gomp_cpu_affinity = cpus;
gomp_cpu_affinity_len = used;
return true;
invalid:
gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
return false;
}
static void __attribute__((constructor))
initialize_env (void)
{
@ -190,6 +283,8 @@ initialize_env (void)
parse_boolean ("OMP_NESTED", &gomp_nest_var);
if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var))
gomp_init_num_threads ();
if (parse_affinity ())
gomp_init_affinity ();
/* Not strictly environment related, but ordering constructors is tricky. */
pthread_attr_init (&gomp_thread_attr);

View File

@ -242,16 +242,16 @@ gomp_iter_guided_next_locked (long *pstart, long *pend)
if (ws->next == ws->end)
return false;
n = (ws->end - ws->next) / ws->incr;
start = ws->next;
n = (ws->end - start) / ws->incr;
q = (n + nthreads - 1) / nthreads;
if (q < ws->chunk_size)
q = ws->chunk_size;
if (q > n)
q = n;
start = ws->next;
end = start + q * ws->incr;
if (q <= n)
end = start + q * ws->incr;
else
end = ws->end;
ws->next = end;
*pstart = start;
@ -286,15 +286,15 @@ gomp_iter_guided_next (long *pstart, long *pend)
if (start == end)
return false;
n = (end - start) / ws->incr;
n = (end - start) / incr;
q = (n + nthreads - 1) / nthreads;
if (q < chunk_size)
q = chunk_size;
if (q > n)
q = n;
nend = start + q * incr;
if (__builtin_expect (q <= n, 1))
nend = start + q * incr;
else
nend = end;
tmp = __sync_val_compare_and_swap (&ws->next, start, nend);
if (__builtin_expect (tmp == start, 1))

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@ -246,8 +246,18 @@ extern unsigned long gomp_run_sched_chunk;
/* The attributes to be used during thread creation. */
extern pthread_attr_t gomp_thread_attr;
/* Other variables. */
extern unsigned short *gomp_cpu_affinity;
extern size_t gomp_cpu_affinity_len;
/* Function prototypes. */
/* affinity.c */
extern void gomp_init_affinity (void);
extern void gomp_init_thread_affinity (pthread_attr_t *);
/* alloc.c */
extern void *gomp_malloc (size_t) __attribute__((malloc));

View File

@ -895,14 +895,25 @@ dynamic scheduling and a chunk size of 1 is used.
@cindex Environment Variable
@table @asis
@item @emph{Description}:
A patch for this extension has been submitted, but was not yet applied at the
time of writing.
Binds threads to specific CPUs. The variable should contain a space- or
comma-separated list of CPUs. This list may contain different kind of
entries: either single CPU numbers in any order, a range of CPUs (M-N)
or a range with some stride (M-N:S). CPU numbers are zero based. For example,
@code{GOMP_CPU_AFFINITY="0 3 1-2 4-15:2"} will bind the initial thread
to CPU 0, the second to CPU 3, the third to CPU 1, the fourth to
CPU 2, the fifth to CPU 4, the sixth through tenth to CPUs 6, 8, 10, 12,
and 14 respectively and then start assigning back from the beginning of
the list. @code{GOMP_CPU_AFFINITY=0} binds all threads to CPU 0.
@item @emph{Reference}:
@uref{http://gcc.gnu.org/ml/gcc-patches/2006-05/msg00982.html,
GCC Patches Mailinglist}
@uref{http://gcc.gnu.org/ml/gcc-patches/2006-05/msg01133.html,
GCC Patches Mailinglist}
There is no GNU OpenMP library routine to determine whether a CPU affinity
specification is in effect. As a workaround, language-specific library
functions, e.g., @code{getenv} in C or @code{GET_ENVIRONMENT_VARIABLE} in
Fortran, may be used to query the setting of the @code{GOMP_CPU_AFFINITY}
environment variable. A defined CPU affinity on startup cannot be changed
or disabled during the runtime of the application.
If this environment variable is omitted, the host system will handle the
assignment of threads to CPUs.
@end table

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@ -49,36 +49,39 @@ typedef struct
#ifdef __cplusplus
extern "C" {
# define __GOMP_NOTHROW throw ()
#else
# define __GOMP_NOTHROW __attribute__((__nothrow__))
#endif
extern void omp_set_num_threads (int);
extern int omp_get_num_threads (void);
extern int omp_get_max_threads (void);
extern int omp_get_thread_num (void);
extern int omp_get_num_procs (void);
extern void omp_set_num_threads (int) __GOMP_NOTHROW;
extern int omp_get_num_threads (void) __GOMP_NOTHROW;
extern int omp_get_max_threads (void) __GOMP_NOTHROW;
extern int omp_get_thread_num (void) __GOMP_NOTHROW;
extern int omp_get_num_procs (void) __GOMP_NOTHROW;
extern int omp_in_parallel (void);
extern int omp_in_parallel (void) __GOMP_NOTHROW;
extern void omp_set_dynamic (int);
extern int omp_get_dynamic (void);
extern void omp_set_dynamic (int) __GOMP_NOTHROW;
extern int omp_get_dynamic (void) __GOMP_NOTHROW;
extern void omp_set_nested (int);
extern int omp_get_nested (void);
extern void omp_set_nested (int) __GOMP_NOTHROW;
extern int omp_get_nested (void) __GOMP_NOTHROW;
extern void omp_init_lock (omp_lock_t *);
extern void omp_destroy_lock (omp_lock_t *);
extern void omp_set_lock (omp_lock_t *);
extern void omp_unset_lock (omp_lock_t *);
extern int omp_test_lock (omp_lock_t *);
extern void omp_init_lock (omp_lock_t *) __GOMP_NOTHROW;
extern void omp_destroy_lock (omp_lock_t *) __GOMP_NOTHROW;
extern void omp_set_lock (omp_lock_t *) __GOMP_NOTHROW;
extern void omp_unset_lock (omp_lock_t *) __GOMP_NOTHROW;
extern int omp_test_lock (omp_lock_t *) __GOMP_NOTHROW;
extern void omp_init_nest_lock (omp_nest_lock_t *);
extern void omp_destroy_nest_lock (omp_nest_lock_t *);
extern void omp_set_nest_lock (omp_nest_lock_t *);
extern void omp_unset_nest_lock (omp_nest_lock_t *);
extern int omp_test_nest_lock (omp_nest_lock_t *);
extern void omp_init_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
extern void omp_destroy_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
extern void omp_set_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
extern void omp_unset_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
extern int omp_test_nest_lock (omp_nest_lock_t *) __GOMP_NOTHROW;
extern double omp_get_wtime (void);
extern double omp_get_wtick (void);
extern double omp_get_wtime (void) __GOMP_NOTHROW;
extern double omp_get_wtick (void) __GOMP_NOTHROW;
#ifdef __cplusplus
}

View File

@ -38,16 +38,16 @@
external omp_set_num_threads
external omp_get_dynamic, omp_get_nested
logical*4 omp_get_dynamic, omp_get_nested
logical(4) omp_get_dynamic, omp_get_nested
external omp_test_lock, omp_in_parallel
logical*4 omp_test_lock, omp_in_parallel
logical(4) omp_test_lock, omp_in_parallel
external omp_get_max_threads, omp_get_num_procs
integer*4 omp_get_max_threads, omp_get_num_procs
integer(4) omp_get_max_threads, omp_get_num_procs
external omp_get_num_threads, omp_get_thread_num
integer*4 omp_get_num_threads, omp_get_thread_num
integer(4) omp_get_num_threads, omp_get_thread_num
external omp_test_nest_lock
integer*4 omp_test_nest_lock
integer(4) omp_test_nest_lock
external omp_get_wtick, omp_get_wtime
double precision omp_get_wtick, omp_get_wtime

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005 Free Software Foundation, Inc.
/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@ -183,6 +183,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
struct gomp_team *team;
bool nested;
unsigned i, n, old_threads_used = 0;
pthread_attr_t thread_attr, *attr;
thr = gomp_thread ();
nested = thr->ts.team != NULL;
@ -265,6 +266,17 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
}
}
attr = &gomp_thread_attr;
if (gomp_cpu_affinity != NULL)
{
size_t stacksize;
pthread_attr_init (&thread_attr);
pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
pthread_attr_setstacksize (&thread_attr, stacksize);
attr = &thread_attr;
}
start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
* (nthreads-i));
@ -283,12 +295,17 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
start_data->fn_data = data;
start_data->nested = nested;
err = pthread_create (&pt, &gomp_thread_attr,
gomp_thread_start, start_data);
if (gomp_cpu_affinity != NULL)
gomp_init_thread_affinity (attr);
err = pthread_create (&pt, attr, gomp_thread_start, start_data);
if (err != 0)
gomp_fatal ("Thread creation failed: %s", strerror (err));
}
if (gomp_cpu_affinity != NULL)
pthread_attr_destroy (&thread_attr);
do_release:
gomp_barrier_wait (nested ? &team->barrier : &gomp_threads_dock);