From 2ce3c6c615fa735693e1de39e9777919ba4fd106 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 13 Aug 1998 17:29:30 +0000 Subject: [PATCH] tree.h: De-conditionalize init_priority code. * tree.h: De-conditionalize init_priority code. * mips.h (NM_FLAGS): Change from -Bp to -Bn. * collect2.c (NM_FLAGS): Change from -p to -n. * configure.in: Turn on collect2 for mipstx39-elf. Handle use_collect2=no properly. * c-common.c: De-conditionalize init_priority code. * collect2.c (extract_init_priority, sort_ids): New fns. (main): Call sort_ids. Move sequence_number to file scope. * configure.in: Handle --enable-init-priority. * c-common.c (attrs): Add A_INIT_PRIORITY. (init_attributes, decl_attributes): Likewise. * tree.h (DEFAULT_INIT_PRIORITY, MAX_INIT_PRIORITY): New macros. * tree.c (get_file_function_name_long): Split out... (get_file_function_name): ...from here. cp/: * lang-options.h: Add -finit-priority. * decl2.c: Likewise. Check flag_init_priority instead of USE_INIT_PRIORITY. * decl2.c (setup_initp): New fn. (start_objects, finish_objects, do_ctors): Handle init_priority. (do_dtors, finish_file): Likewise. From-SVN: r21701 --- gcc/ChangeLog | 22 ++++ gcc/c-common.c | 66 ++++++++++- gcc/collect2.c | 72 +++++++++++- gcc/config/mips/mips.h | 2 +- gcc/configure | 301 ++++++++++++++++++++++++++++++++----------------- gcc/configure.in | 23 ++++ gcc/cp/ChangeLog | 10 ++ gcc/cp/decl2.c | 220 +++++++++++++++++++++++++++++++----- gcc/cp/lang-options.h | 2 + gcc/invoke.texi | 5 + gcc/tree.c | 36 ++++-- gcc/tree.h | 6 + 12 files changed, 615 insertions(+), 150 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cda0da44..eee41bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +Thu Aug 13 17:08:11 1998 Jason Merrill + + * tree.h: De-conditionalize init_priority code. + + * mips.h (NM_FLAGS): Change from -Bp to -Bn. + * collect2.c (NM_FLAGS): Change from -p to -n. + + * configure.in: Turn on collect2 for mipstx39-elf. + Handle use_collect2=no properly. + + * c-common.c: De-conditionalize init_priority code. + * collect2.c (extract_init_priority, sort_ids): New fns. + (main): Call sort_ids. + Move sequence_number to file scope. + + * configure.in: Handle --enable-init-priority. + * c-common.c (attrs): Add A_INIT_PRIORITY. + (init_attributes, decl_attributes): Likewise. + * tree.h (DEFAULT_INIT_PRIORITY, MAX_INIT_PRIORITY): New macros. + * tree.c (get_file_function_name_long): Split out... + (get_file_function_name): ...from here. + Thu Aug 13 16:09:53 1998 Martin von Loewis * expr.c (safe_from_p): Change code to ERROR_MARK only when not diff --git a/gcc/c-common.c b/gcc/c-common.c index 8405a41..6f14579 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -52,7 +52,8 @@ int skip_evaluation; enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION, A_NO_INSTRUMENT_FUNCTION, A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED, - A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS}; + A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS, + A_INIT_PRIORITY}; enum format_type { printf_format_type, scanf_format_type, strftime_format_type }; @@ -89,6 +90,12 @@ static int if_stack_pointer = 0; /* Generate RTL for the start of an if-then, and record the start of it for ambiguous else detection. */ +/* A list of objects which have constructors or destructors which + reside in the global scope, and have an init_priority attribute + associated with them. The decl is stored in the TREE_VALUE slot + and the priority number is stored in the TREE_PURPOSE slot. */ +tree static_aggregates_initp; + void c_expand_start_cond (cond, exitflag, compstmt_count) tree cond; @@ -383,6 +390,7 @@ init_attributes () add_attribute (A_FORMAT_ARG, "format_arg", 1, 1, 1); add_attribute (A_WEAK, "weak", 0, 0, 1); add_attribute (A_ALIAS, "alias", 1, 1, 1); + add_attribute (A_INIT_PRIORITY, "init_priority", 0, 1, 0); add_attribute (A_NO_INSTRUMENT_FUNCTION, "no_instrument_function", 0, 0, 1); } @@ -859,6 +867,62 @@ decl_attributes (node, attributes, prefix_attributes) warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); break; + case A_INIT_PRIORITY: + { + tree initp_expr = (args ? TREE_VALUE (args): NULL_TREE); + int pri; + + if (initp_expr) + STRIP_NOPS (initp_expr); + + if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST) + { + error ("requested init_priority is not an integer constant"); + continue; + } + + pri = TREE_INT_CST_LOW (initp_expr); + + if (is_type || TREE_CODE (decl) != VAR_DECL + || ! TREE_STATIC (decl) + || DECL_EXTERNAL (decl) + || (TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE + && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE) + /* Static objects in functions are initialized the + first time control passes through that + function. This is not precise enough to pin down an + init_priority value, so don't allow it. */ + || current_function_decl) + { + error ("can only use init_priority attribute on file-scope definitions of objects of class type"); + continue; + } + + /* Check for init_priorities that are reserved for + implementation. Reserved for language and runtime + support implementations.*/ + if ((10 <= pri && pri <= 99) + /* Reserved for standard library implementations. */ + || (500 <= pri && pri <= 999) + /* Reserved for objects with no attributes. */ + || pri > (MAX_INIT_PRIORITY - 50)) + { + warning + ("requested init_priority is reserved for internal use"); + continue; + } + + if (pri > MAX_INIT_PRIORITY || pri <= 0) + { + error ("requested init_priority is out of range"); + continue; + } + + static_aggregates_initp + = perm_tree_cons (initp_expr, decl, static_aggregates_initp); + break; + } + case A_NO_INSTRUMENT_FUNCTION: if (TREE_CODE (decl) != FUNCTION_DECL) { diff --git a/gcc/collect2.c b/gcc/collect2.c index 539e088..c9b471d 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -137,7 +137,7 @@ extern char *make_temp_file PROTO ((char *)); /* Default flags to pass to nm. */ #ifndef NM_FLAGS -#define NM_FLAGS "-p" +#define NM_FLAGS "-n" #endif #endif /* OBJECT_FORMAT_NONE */ @@ -280,6 +280,8 @@ static void do_wait PROTO((char *)); static void fork_execute PROTO((char *, char **)); static void maybe_unlink PROTO((char *)); static void add_to_list PROTO((struct head *, char *)); +static int extract_init_priority PROTO((char *)); +static void sort_ids PROTO((struct head *)); static void write_list PROTO((FILE *, char *, struct id *)); #ifdef COLLECT_EXPORT_LIST static void dump_list PROTO((FILE *, char *, struct id *)); @@ -1483,6 +1485,10 @@ main (argc, argv) return 0; } + /* Sort ctor and dtor lists by priority. */ + sort_ids (&constructors); + sort_ids (&destructors); + maybe_unlink(output_file); outf = fopen (c_file, "w"); if (outf == (FILE *) 0) @@ -1697,6 +1703,8 @@ maybe_unlink (file) } +static long sequence_number = 0; + /* Add a name to a linked list. */ static void @@ -1707,7 +1715,6 @@ add_to_list (head_ptr, name) struct id *newid = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1); struct id *p; - static long sequence_number = 0; strcpy (newid->name, name); if (head_ptr->first) @@ -1732,6 +1739,67 @@ add_to_list (head_ptr, name) head_ptr->number++; } +/* Grab the init priority number from an init function name that + looks like "_GLOBAL_.I.12345.foo". */ + +static int +extract_init_priority (name) + char *name; +{ + int pos = 0; + + while (name[pos] == '_') + ++pos; + pos += 10; /* strlen ("GLOBAL__X_") */ + + /* Extract init_p number from ctor/dtor name. */ + return strtoul(name + pos, NULL, 10); +} + +/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order. + ctors will be run from right to left, dtors from left to right. */ + +static void +sort_ids (head_ptr) + struct head *head_ptr; +{ + /* id holds the current element to insert. id_next holds the next + element to insert. id_ptr iterates through the already sorted elements + looking for the place to insert id. */ + struct id *id, *id_next, **id_ptr; + int i; + + id = head_ptr->first; + + /* We don't have any sorted elements yet. */ + head_ptr->first = NULL; + + for (; id; id = id_next) + { + id_next = id->next; + id->sequence = extract_init_priority (id->name); + + for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next)) + if (*id_ptr == NULL + /* If the sequence numbers are the same, we put the id from the + file later on the command line later in the list. */ + || id->sequence > (*id_ptr)->sequence + /* Hack: do lexical compare, too. + || (id->sequence == (*id_ptr)->sequence + && strcmp (id->name, (*id_ptr)->name) > 0) */ + ) + { + id->next = *id_ptr; + *id_ptr = id; + break; + } + } + + /* Now set the sequence numbers properly so write_c_file works. */ + for (id = head_ptr->first; id; id = id->next) + id->sequence = ++sequence_number; +} + /* Write: `prefix', the names on list LIST, `suffix'. */ static void diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 8bf22c3..72e77b0 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -716,7 +716,7 @@ while (0) /* Tell collect what flags to pass to nm. */ #ifndef NM_FLAGS -#define NM_FLAGS "-Bp" +#define NM_FLAGS "-Bn" #endif diff --git a/gcc/configure b/gcc/configure index 0df76d5..2b76ae3 100755 --- a/gcc/configure +++ b/gcc/configure @@ -1,7 +1,7 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.12.1 +# Generated automatically using autoconf version 2.12.2 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -37,6 +37,11 @@ ac_help="$ac_help ac_help="$ac_help --with-fast-fixincludes Use a faster fixinclude program. Experimental" ac_help="$ac_help + --enable-init-priority Use attributes to assign initialization order + for static objects. + --disable-init-priority Conform to ISO C++ rules for ordering static objects + (i.e. initialized in order of declaration). " +ac_help="$ac_help --enable-threads enable thread usage for target GCC. --enable-threads=LIB use LIB thread package for target GCC." @@ -361,7 +366,7 @@ EOF verbose=yes ;; -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.12.1" + echo "configure generated by autoconf version 2.12.2" exit 0 ;; -with-* | --with-*) @@ -531,9 +536,11 @@ ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross +ac_exeext= +ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then @@ -694,6 +701,16 @@ else fi +# Enable init_priority. +# Check whether --enable-init-priority or --disable-init-priority was given. +if test "${enable_init_priority+set}" = set; then + enableval="$enable_init_priority" + if [ x$enable_init_priority != xno ]; then + extra_c_flags=-DUSE_INIT_PRIORITY +fi +fi + + # Enable threads # Pass with no value to take the default # Pass with a value to specify a thread package @@ -777,7 +794,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:781: checking host system type" >&5 +echo "configure:798: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -798,7 +815,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:802: checking target system type" >&5 +echo "configure:819: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -816,7 +833,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:820: checking build system type" >&5 +echo "configure:837: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -843,14 +860,14 @@ test "$host_alias" != "$target_alias" && # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:847: checking for $ac_word" >&5 +echo "configure:864: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -872,14 +889,14 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:876: checking for $ac_word" >&5 +echo "configure:893: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. @@ -916,25 +933,58 @@ else echo "$ac_t""no" 1>&6 fi + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:943: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:924: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:974: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -954,12 +1004,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:958: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1008: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:963: checking whether we are using GNU C" >&5 +echo "configure:1013: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -968,7 +1018,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:972: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1022: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -979,11 +1029,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes - ac_test_CFLAGS="${CFLAGS+set}" - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:987: checking whether ${CC-cc} accepts -g" >&5 +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1041: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -998,20 +1052,24 @@ rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 - if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" - elif test $ac_cv_prog_cc_g = yes; then +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then CFLAGS="-g -O2" else - CFLAGS="-O2" + CFLAGS="-g" fi else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi fi echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:1015: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:1073: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1044,14 +1102,14 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1048: checking for $ac_word" >&5 +echo "configure:1106: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1075,14 +1133,14 @@ done # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1079: checking for $ac_word" >&5 +echo "configure:1137: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1108,7 +1166,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:1112: checking for yywrap in -l$ac_lib" >&5 +echo "configure:1170: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1116,7 +1174,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1150,7 +1208,7 @@ fi fi echo $ac_n "checking whether ln works""... $ac_c" 1>&6 -echo "configure:1154: checking whether ln works" >&5 +echo "configure:1212: checking whether ln works" >&5 if eval "test \"`echo '$''{'gcc_cv_prog_LN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1182,7 +1240,7 @@ else fi echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1186: checking whether ln -s works" >&5 +echo "configure:1244: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'gcc_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1214,19 +1272,19 @@ else fi echo $ac_n "checking for volatile""... $ac_c" 1>&6 -echo "configure:1218: checking for volatile" >&5 +echo "configure:1276: checking for volatile" >&5 if eval "test \"`echo '$''{'gcc_cv_c_volatile'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1288: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gcc_cv_c_volatile=yes else @@ -1249,14 +1307,14 @@ fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1253: checking for $ac_word" >&5 +echo "configure:1311: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1280,14 +1338,14 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1284: checking for $ac_word" >&5 +echo "configure:1342: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then @@ -1320,7 +1378,7 @@ test -n "$YACC" || YACC="yacc" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1324: checking for a BSD compatible install" >&5 +echo "configure:1382: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1371,7 +1429,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1375: checking how to run the C preprocessor" >&5 +echo "configure:1433: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1386,14 +1444,14 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1396: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1454: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -1403,14 +1461,31 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1471: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1413: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1488: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -1423,6 +1498,8 @@ fi rm -f conftest* fi rm -f conftest* +fi +rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" @@ -1432,12 +1509,12 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1436: checking for ANSI C header files" >&5 +echo "configure:1513: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1445,8 +1522,8 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1449: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1526: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes @@ -1462,7 +1539,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1480,7 +1557,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1501,7 +1578,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1512,7 +1589,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1536,12 +1613,12 @@ EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:1540: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:1617: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1550,7 +1627,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:1554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1631: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -1574,18 +1651,18 @@ for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unist do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1578: checking for $ac_hdr" >&5 +echo "configure:1655: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1588: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -1614,18 +1691,18 @@ done # Check for thread headers. ac_safe=`echo "thread.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for thread.h""... $ac_c" 1>&6 -echo "configure:1618: checking for thread.h" >&5 +echo "configure:1695: checking for thread.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1628: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1705: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -1648,18 +1725,18 @@ fi ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for pthread.h""... $ac_c" 1>&6 -echo "configure:1652: checking for pthread.h" >&5 +echo "configure:1729: checking for pthread.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1662: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1739: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -1684,12 +1761,12 @@ fi # See if the system preprocessor understands the ANSI C preprocessor # stringification operator. echo $ac_n "checking whether cpp understands the stringify operator""... $ac_c" 1>&6 -echo "configure:1688: checking whether cpp understands the stringify operator" >&5 +echo "configure:1765: checking whether cpp understands the stringify operator" >&5 if eval "test \"`echo '$''{'gcc_cv_c_have_stringify'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1778: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gcc_cv_c_have_stringify=yes else @@ -1720,12 +1797,12 @@ fi # Use only if it exists, # doesn't clash with , and declares intmax_t. echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6 -echo "configure:1724: checking for inttypes.h" >&5 +echo "configure:1801: checking for inttypes.h" >&5 if eval "test \"`echo '$''{'gcc_cv_header_inttypes_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1733,7 +1810,7 @@ int main() { intmax_t i = -1; ; return 0; } EOF -if { (eval echo configure:1737: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1814: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <&6 -echo "configure:1760: checking for $ac_func" >&5 +echo "configure:1837: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1813,12 +1890,12 @@ done #AC_CHECK_TYPE(wchar_t, unsigned int) echo $ac_n "checking for vprintf""... $ac_c" 1>&6 -echo "configure:1817: checking for vprintf" >&5 +echo "configure:1894: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else @@ -1865,12 +1942,12 @@ fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:1869: checking for _doprnt" >&5 +echo "configure:1946: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1974: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else @@ -1929,7 +2006,7 @@ fi echo $ac_n "checking whether the printf functions support %p""... $ac_c" 1>&6 -echo "configure:1933: checking whether the printf functions support %p" >&5 +echo "configure:2010: checking whether the printf functions support %p" >&5 if eval "test \"`echo '$''{'gcc_cv_func_printf_ptr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1937,7 +2014,7 @@ else gcc_cv_func_printf_ptr=no else cat > conftest.$ac_ext < @@ -1950,7 +2027,7 @@ main() exit (p != q); } EOF -if { (eval echo configure:1954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then gcc_cv_func_printf_ptr=yes else @@ -1978,12 +2055,12 @@ for ac_func in malloc realloc calloc free bcopy bzero bcmp \ index rindex getenv atol sbrk abort atof strerror getcwd getwd do echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6 -echo "configure:1982: checking whether $ac_func must be declared" >&5 +echo "configure:2059: checking whether $ac_func must be declared" >&5 if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -2011,7 +2088,7 @@ int main() { char *(*pfn) = (char *(*)) $ac_func ; return 0; } EOF -if { (eval echo configure:2015: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2092: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "gcc_cv_decl_needed_$ac_func=no" else @@ -2040,12 +2117,12 @@ done for ac_func in getrlimit setrlimit do echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6 -echo "configure:2044: checking whether $ac_func must be declared" >&5 +echo "configure:2121: checking whether $ac_func must be declared" >&5 if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -2077,7 +2154,7 @@ int main() { char *(*pfn) = (char *(*)) $ac_func ; return 0; } EOF -if { (eval echo configure:2081: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2158: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "gcc_cv_decl_needed_$ac_func=no" else @@ -2104,12 +2181,12 @@ done echo $ac_n "checking for sys_siglist declaration in signal.h or unistd.h""... $ac_c" 1>&6 -echo "configure:2108: checking for sys_siglist declaration in signal.h or unistd.h" >&5 +echo "configure:2185: checking for sys_siglist declaration in signal.h or unistd.h" >&5 if eval "test \"`echo '$''{'ac_cv_decl_sys_siglist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2121,7 +2198,7 @@ int main() { char *msg = *(sys_siglist + 1); ; return 0; } EOF -if { (eval echo configure:2125: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_sys_siglist=yes else @@ -4138,6 +4215,8 @@ for machine in $build $host $target; do mipstx39-*-elf*) tm_file="mips/r3900.h mips/elf.h mips/abi64.h libgloss.h" tmake_file=mips/t-r3900 + # FIXME mips-elf should be fixed to use crtstuff. + use_collect2=yes ;; mips-*-*) # Default MIPS RISC-OS 4.0. if [ x$stabs = xyes ]; then @@ -5230,6 +5309,10 @@ else done fi +if [ x$use_collect2 = xno ]; then + use_collect2= +fi + # Add a definition of USE_COLLECT2 if system wants one. # Also tell toplev.c what to do. # This substitutes for lots of t-* files. @@ -5277,7 +5360,7 @@ fi # Figure out what assembler alignment features are present. echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6 -echo "configure:5281: checking assembler alignment features" >&5 +echo "configure:5364: checking assembler alignment features" >&5 gcc_cv_as= gcc_cv_as_alignment_features= gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,gcc$,gas,'` @@ -5530,6 +5613,14 @@ if [ x$enable_haifa != x ]; then done fi +# Warn if using init_priority. +echo $ac_n "checking whether to enable init_priority by default""... $ac_c" 1>&6 +echo "configure:5619: checking whether to enable init_priority by default" >&5 +if [ x$enable_init_priority != xyes ]; then + enable_init_priority=no +fi +echo "$ac_t""$enable_init_priority" 1>&6 + # Nothing to do for FLOAT_H, float_format already handled. objdir=`pwd` @@ -5719,7 +5810,7 @@ do echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.12.1" + echo "$CONFIG_STATUS generated by autoconf version 2.12.2" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; diff --git a/gcc/configure.in b/gcc/configure.in index 8a9f2cc..485deba 100644 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -130,6 +130,16 @@ AC_ARG_WITH(fast-fixincludes, fast_fixinc="$with_fast_fixincludes", fast_fixinc=no) +# Enable init_priority. +AC_ARG_ENABLE(init-priority, +[ --enable-init-priority Use attributes to assign initialization order + for static objects. + --disable-init-priority Conform to ISO C++ rules for ordering static objects + (i.e. initialized in order of declaration). ], +if [[[ x$enable_init_priority != xno ]]]; then + extra_c_flags=-DUSE_INIT_PRIORITY +fi) + # Enable threads # Pass with no value to take the default # Pass with a value to specify a thread package @@ -2231,6 +2241,8 @@ for machine in $build $host $target; do mipstx39-*-elf*) tm_file="mips/r3900.h mips/elf.h mips/abi64.h libgloss.h" tmake_file=mips/t-r3900 + # FIXME mips-elf should be fixed to use crtstuff. + use_collect2=yes ;; mips-*-*) # Default MIPS RISC-OS 4.0. if [[ x$stabs = xyes ]]; then @@ -3323,6 +3335,10 @@ else done fi +if [[ x$use_collect2 = xno ]]; then + use_collect2= +fi + # Add a definition of USE_COLLECT2 if system wants one. # Also tell toplev.c what to do. # This substitutes for lots of t-* files. @@ -3610,6 +3626,13 @@ if [[ x$enable_haifa != x ]]; then done fi +# Warn if using init_priority. +AC_MSG_CHECKING(whether to enable init_priority by default) +if [[ x$enable_init_priority != xyes ]]; then + enable_init_priority=no +fi +AC_MSG_RESULT($enable_init_priority) + # Nothing to do for FLOAT_H, float_format already handled. objdir=`pwd` AC_SUBST(objdir) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b99f23b..00566fc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,15 @@ 1998-08-13 Jason Merrill + * lang-options.h: Add -finit-priority. + * decl2.c: Likewise. Check flag_init_priority instead of + USE_INIT_PRIORITY. + + * decl2.c (setup_initp): New fn. + (start_objects, finish_objects, do_ctors): Handle init_priority. + (do_dtors, finish_file): Likewise. + +1998-08-13 Jason Merrill + * pt.c (tsubst_copy): Hush warning. * rtti.c (get_tinfo_fn): Also set DECL_IGNORED_P. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d8bc74f..1176047 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -173,6 +173,14 @@ int flag_alt_external_templates; int flag_implicit_templates = 1; +/* Nonzero means allow numerical priorities on constructors. */ + +#ifdef USE_INIT_PRIORITY +int flag_init_priority = 1; +#else +int flag_init_priority; +#endif + /* Nonzero means warn about implicit declarations. */ int warn_implicit = 1; @@ -492,6 +500,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = {"implement-inlines", &flag_implement_inlines, 1}, {"external-templates", &flag_external_templates, 1}, {"implicit-templates", &flag_implicit_templates, 1}, + {"init-priority", &flag_init_priority, 1}, {"huge-objects", &flag_huge_objects, 1}, {"conserve-space", &flag_conserve_space, 1}, {"vtable-thunks", &flag_vtable_thunks, 1}, @@ -2929,18 +2938,104 @@ get_sentry (base) return sentry; } +/* A list of objects which have constructors or destructors + which reside in the global scope. The decl is stored in + the TREE_VALUE slot and the initializer is stored + in the TREE_PURPOSE slot. */ +extern tree static_aggregates_initp; + +/* Set up the static_aggregates* lists for processing. Subroutine of + finish_file. Note that this function changes the format of + static_aggregates_initp, from (priority . decl) to + (priority . ((initializer . decl) ...)). */ + +static void +setup_initp () +{ + tree t, *p, next_t; + + if (! flag_init_priority) + { + for (t = static_aggregates_initp; t; t = TREE_CHAIN (t)) + cp_warning ("init_priority for `%#D' ignored without -finit-priority", + TREE_VALUE (t)); + return; + } + + /* First, remove any entries from static_aggregates that are also in + static_aggregates_initp, and update the entries in _initp to + include the initializer. */ + p = &static_aggregates; + for (; *p; ) + { + t = value_member (TREE_VALUE (*p), static_aggregates_initp); + + if (t) + { + TREE_VALUE (t) = *p; + *p = TREE_CHAIN (*p); + TREE_CHAIN (TREE_VALUE (t)) = NULL_TREE; + } + else + p = &TREE_CHAIN (*p); + } + + /* Then, group static_aggregates_initp. After this step, there will only + be one entry for each priority, with a chain coming off it. */ + t = static_aggregates_initp; + static_aggregates_initp = NULL_TREE; + + for (; t; t = next_t) + { + next_t = TREE_CHAIN (t); + + for (p = &static_aggregates_initp; ; p = &TREE_CHAIN (*p)) + { + if (*p == NULL_TREE + || tree_int_cst_lt (TREE_PURPOSE (*p), TREE_PURPOSE (t))) + { + TREE_CHAIN (t) = *p; + *p = t; + break; + } + else if (tree_int_cst_equal (TREE_PURPOSE (*p), TREE_PURPOSE (t))) + { + TREE_CHAIN (TREE_VALUE (t)) = TREE_VALUE (*p); + TREE_VALUE (*p) = TREE_VALUE (t); + break; + } + } + } + + /* Reverse each list to preserve the order (currently reverse declaration + order, for destructors). */ + for (t = static_aggregates_initp; t; t = TREE_CHAIN (t)) + TREE_VALUE (t) = nreverse (TREE_VALUE (t)); +} + /* Start the process of running a particular set of global constructors or destructors. Subroutine of do_[cd]tors. */ static void -start_objects (method_type) - int method_type; +start_objects (method_type, initp) + int method_type, initp; { tree fnname; + char type[10]; /* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */ - fnname = get_file_function_name (method_type); + if (flag_init_priority) + { + if (initp == 0) + initp = DEFAULT_INIT_PRIORITY; + + sprintf (type, "%c%c%.5u", method_type, JOINER, initp); + } + else + sprintf (type, "%c", method_type); + + fnname = get_file_function_name_long (type); start_function (void_list_node, make_call_declarator (fnname, void_list_node, NULL_TREE, @@ -2958,18 +3053,21 @@ start_objects (method_type) or destructors. Subroutine of do_[cd]tors. */ static void -finish_objects (method_type) - int method_type; +finish_objects (method_type, initp) + int method_type, initp; { char *fnname; - tree list = (method_type == 'I' ? static_ctors : static_dtors); + if (! initp) + { + tree list = (method_type == 'I' ? static_ctors : static_dtors); - if (! current_function_decl && list) - start_objects (method_type); + if (! current_function_decl && list) + start_objects (method_type, initp); - for (; list; list = TREE_CHAIN (list)) - expand_expr_stmt (build_function_call (TREE_VALUE (list), NULL_TREE)); + for (; list; list = TREE_CHAIN (list)) + expand_expr_stmt (build_function_call (TREE_VALUE (list), NULL_TREE)); + } if (! current_function_decl) return; @@ -2982,19 +3080,56 @@ finish_objects (method_type) pop_momentary (); finish_function (lineno, 0, 0); - if (method_type == 'I') - assemble_constructor (fnname); - else - assemble_destructor (fnname); + if (! flag_init_priority) + { + if (method_type == 'I') + assemble_constructor (fnname); + else + assemble_destructor (fnname); + } + +#ifdef ASM_OUTPUT_SECTION_NAME + /* If we're using init priority we can't use assemble_*tor, but on ELF + targets we can stick the references into named sections for GNU ld + to collect. */ + if (flag_init_priority) + { + char buf[15]; + if (initp == 0) + initp = DEFAULT_INIT_PRIORITY; + sprintf (buf, ".%ctors.%.5u", method_type == 'I' ? 'c' : 'd', + /* invert the numbering so the linker puts us in the proper + order; constructors are run from right to left, and the + linker sorts in increasing order. */ + MAX_INIT_PRIORITY - initp); + named_section (NULL_TREE, buf, 0); + assemble_integer (gen_rtx_SYMBOL_REF (Pmode, fnname), + POINTER_SIZE / BITS_PER_UNIT, 1); + } +#endif } -/* Generate a function to run a set of global destructors. Subroutine of - finish_file. */ +/* Generate a function to run a set of global destructors. START is either + NULL_TREE or a node indicating a set of destructors with the same + init priority. Subroutine of finish_file. */ static void -do_dtors () +do_dtors (start) + tree start; { - tree vars = static_aggregates; + tree vars; + int initp; + + if (start) + { + initp = TREE_INT_CST_LOW (TREE_PURPOSE (start)); + vars = TREE_VALUE (start); + } + else + { + initp = 0; + vars = static_aggregates; + } for (; vars; vars = TREE_CHAIN (vars)) { @@ -3010,7 +3145,7 @@ do_dtors () || DECL_WEAK (decl))); if (! current_function_decl) - start_objects ('D'); + start_objects ('D', initp); /* Because of: @@ -3053,16 +3188,30 @@ do_dtors () } } - finish_objects ('D'); + finish_objects ('D', initp); } -/* Generate a function to run a set of global constructors. Subroutine of - finish_file. */ +/* Generate a function to run a set of global constructors. START is + either NULL_TREE or a node indicating a set of constructors with the + same init priority. Subroutine of finish_file. */ static void -do_ctors () +do_ctors (start) + tree start; { - tree vars = static_aggregates; + tree vars; + int initp; + + if (start) + { + initp = TREE_INT_CST_LOW (TREE_PURPOSE (start)); + vars = TREE_VALUE (start); + } + else + { + initp = 0; + vars = static_aggregates; + } /* Reverse the list so it's in the right order for ctors. */ vars = nreverse (vars); @@ -3088,7 +3237,7 @@ do_ctors () || DECL_WEAK (decl))); if (! current_function_decl) - start_objects ('I'); + start_objects ('I', initp); /* Set these global variables so that GDB at least puts us near the declaration which required the initialization. */ @@ -3148,7 +3297,7 @@ do_ctors () my_friendly_abort (22); } - finish_objects ('I'); + finish_objects ('I', initp); } /* This routine is called from the last rule in yyparse (). @@ -3262,17 +3411,28 @@ finish_file () if (static_dtors || vars) needs_cleaning = 1; - /* The aggregates are listed in reverse declaration order, for cleaning. */ + setup_initp (); + + /* After setup_initp, the aggregates are listed in reverse declaration + order, for cleaning. */ if (needs_cleaning) { - do_dtors (); + do_dtors (NULL_TREE); + + if (flag_init_priority) + for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars)) + do_dtors (vars); } /* do_ctors will reverse the lists for messing up. */ if (needs_messing_up) { - do_ctors (); - } + do_ctors (NULL_TREE); + + if (flag_init_priority) + for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars)) + do_ctors (vars); + } permanent_allocation (1); diff --git a/gcc/cp/lang-options.h b/gcc/cp/lang-options.h index 5c50332..dc39d28 100644 --- a/gcc/cp/lang-options.h +++ b/gcc/cp/lang-options.h @@ -66,6 +66,8 @@ DEFINE_LANG_NAME ("C++") { "-fno-implement-inlines", "Export functions even if they can be inlined" }, { "-fimplicit-templates", "Emit implicit instatiations if needed" }, { "-fno-implicit-templates", "" }, + { "-finit-priority", "Handle the init_priority attribute" }, + { "-fno-init-priority", "" }, { "-flabels-ok", "Labels can be used as first class objects" }, { "-fno-labels-ok", "" }, { "-fmemoize-lookups", "Enable caching of member function resolutions" }, diff --git a/gcc/invoke.texi b/gcc/invoke.texi index 816adc9..3d6688b 100644 --- a/gcc/invoke.texi +++ b/gcc/invoke.texi @@ -1030,6 +1030,11 @@ your code with this flag (including the C++ library, if you use it). This flag is not useful when compiling with -fvtable-thunks. +@item -finit-priority +Support @samp{__attribute__ ((init_priority (n)))} for controlling the +order of initialization of file-scope objects. On ELF targets, this +requires GNU ld 2.10 or later. + @item -fno-implement-inlines To save space, do not emit out-of-line copies of inline functions controlled by @samp{#pragma implementation}. This will cause linker diff --git a/gcc/tree.c b/gcc/tree.c index 82b2cc5..59c02b4 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4806,24 +4806,24 @@ dump_tree_statistics () #define FILE_FUNCTION_PREFIX_LEN 9 #ifndef NO_DOLLAR_IN_LABEL -#define FILE_FUNCTION_FORMAT "_GLOBAL_$D$%s" +#define FILE_FUNCTION_FORMAT "_GLOBAL_$%s$%s" #else /* NO_DOLLAR_IN_LABEL */ #ifndef NO_DOT_IN_LABEL -#define FILE_FUNCTION_FORMAT "_GLOBAL_.D.%s" +#define FILE_FUNCTION_FORMAT "_GLOBAL_.%s.%s" #else /* NO_DOT_IN_LABEL */ -#define FILE_FUNCTION_FORMAT "_GLOBAL__D_%s" +#define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s" #endif /* NO_DOT_IN_LABEL */ #endif /* NO_DOLLAR_IN_LABEL */ extern char * first_global_object_name; extern char * weak_global_object_name; -/* If KIND=='I', return a suitable global initializer (constructor) name. - If KIND=='D', return a suitable global clean-up (destructor) name. */ +/* TYPE is some string to identify this function to the linker or + collect2. */ tree -get_file_function_name (kind) - int kind; +get_file_function_name_long (type) + char *type; { char *buf; register char *p; @@ -4837,13 +4837,14 @@ get_file_function_name (kind) else p = input_filename; - buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p)); + buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p) + + strlen (type)); /* Set up the name of the file-level functions we may need. */ /* Use a global object (which is already required to be unique over the program) rather than the file name (which imposes extra constraints). -- Raeburn@MIT.EDU, 10 Jan 1990. */ - sprintf (buf, FILE_FUNCTION_FORMAT, p); + sprintf (buf, FILE_FUNCTION_FORMAT, type, p); /* Don't need to pull weird characters out of global names. */ if (p != first_global_object_name) @@ -4866,10 +4867,23 @@ get_file_function_name (kind) *p = '_'; } - buf[FILE_FUNCTION_PREFIX_LEN] = kind; - return get_identifier (buf); } + +/* If KIND=='I', return a suitable global initializer (constructor) name. + If KIND=='D', return a suitable global clean-up (destructor) name. */ + +tree +get_file_function_name (kind) + int kind; +{ + char p[2]; + p[0] = kind; + p[1] = 0; + + return get_file_function_name_long (p); +} + /* Expand (the constant part of) a SET_TYPE CONSTRUCTOR node. The result is placed in BUFFER (which has length BIT_SIZE), diff --git a/gcc/tree.h b/gcc/tree.h index 401e5ee..948787a 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1124,6 +1124,11 @@ struct tree_type do not allocate storage, and refer to a definition elsewhere. */ #define DECL_EXTERNAL(NODE) (DECL_CHECK (NODE)->decl.external_flag) +/* In a VAR_DECL for a RECORD_TYPE, sets number for non-init_priority + initializatons. */ +#define DEFAULT_INIT_PRIORITY 65535 +#define MAX_INIT_PRIORITY 65535 + /* In a TYPE_DECL nonzero means the detail info about this type is not dumped into stabs. Instead it will generate cross reference ('x') of names. @@ -1843,6 +1848,7 @@ extern void (*incomplete_decl_finalize_hook) PROTO((tree)); /* In tree.c */ extern char *perm_calloc PROTO((int, long)); extern tree get_file_function_name PROTO((int)); +extern tree get_file_function_name_long PROTO((char *)); extern tree get_set_constructor_bits PROTO((tree, char *, int)); extern tree get_set_constructor_bytes PROTO((tree, unsigned char *, int)); -- 2.7.4